@vue-skuilder/standalone-ui 0.2.5 → 0.2.8
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/{TagViewer-B8eVlesm.js → TagViewer-BATBvQxc.js} +2 -2
- package/dist/assets/{TagViewer-B8eVlesm.js.map → TagViewer-BATBvQxc.js.map} +1 -1
- package/dist/assets/{common-ui.es-DlYghJUY.js → common-ui.es-DAD-mXog.js} +4 -4
- package/dist/assets/{common-ui.es-DlYghJUY.js.map → common-ui.es-DAD-mXog.js.map} +1 -1
- package/dist/assets/common-ui.es-DZ6JJfeZ.js +1 -0
- package/dist/assets/{dist-BA5iGova.js → dist-BYBX0RyH.js} +11 -11
- package/dist/assets/dist-BYBX0RyH.js.map +1 -0
- package/dist/assets/{index-jVsEPQR7.js → index-Ch4dDCy5.js} +5 -5
- package/dist/assets/{index-jVsEPQR7.js.map → index-Ch4dDCy5.js.map} +1 -1
- package/dist/index.html +3 -3
- package/dist-lib/questions.cjs.js +11 -11
- package/dist-lib/questions.cjs.js.map +1 -1
- package/dist-lib/questions.mjs +162 -27
- package/dist-lib/questions.mjs.map +1 -1
- package/package.json +6 -6
- package/dist/assets/common-ui.es-CckNkc_L.js +0 -1
- package/dist/assets/dist-BA5iGova.js.map +0 -1
|
@@ -91,10 +91,10 @@ Please double-check your map/reduce function.`),guardedConsole$1(`error`,c,u)}}f
|
|
|
91
91
|
You can debug this error by doing:
|
|
92
92
|
myDatabase.on('error', function (err) { debugger; });
|
|
93
93
|
Please double-check your map/reduce function.`),guardedConsole(`error`,c,u)}}function createAbstractMapReduce(t,c,u,d){function tryMap(t,c,u){try{c(u)}catch(d){emitError$1(t,d,{fun:c,doc:u})}}function tryReduce(t,c,u,d,m){try{return{output:c(u,d,m)}}catch(g){return emitError$1(t,g,{fun:c,keys:u,values:d,rereduce:m}),{error:g}}}function sortByKeyThenValue(t,c){let u=collate(t.key,c.key);return u===0?collate(t.value,c.value):u}function sliceResults(t,c,u){return u=u||0,typeof c==`number`?t.slice(u,c+u):u>0?t.slice(u):t}function rowToDocId(t){let c=t.value;return c&&typeof c==`object`&&c._id||t.id}function readAttachmentsAsBlobOrBuffer(t){for(let c of t.rows){let t=c.doc&&c.doc._attachments;if(t)for(let c of Object.keys(t)){let u=t[c];t[c].data=b64ToBluffer(u.data,u.content_type)}}}function postprocessAttachments(t){return function(c){return t.include_docs&&t.attachments&&t.binary&&readAttachmentsAsBlobOrBuffer(c),c}}function addHttpParam(t,c,u,d){let m=c[t];m!==void 0&&(d&&(m=encodeURIComponent(JSON.stringify(m))),u.push(t+`=`+m))}function coerceInteger(t){if(t!==void 0){let c=Number(t);return!isNaN(c)&&c===parseInt(t,10)?c:t}}function coerceOptions(t){return t.group_level=coerceInteger(t.group_level),t.limit=coerceInteger(t.limit),t.skip=coerceInteger(t.skip),t}function checkPositiveInteger(t){if(t){if(typeof t!=`number`)return new QueryParseError(`Invalid value for integer: "${t}"`);if(t<0)return new QueryParseError(`Invalid value for positive integer: "${t}"`)}}function checkQueryParseError(t,c){let u=t.descending?`endkey`:`startkey`,d=t.descending?`startkey`:`endkey`;if(t[u]!==void 0&&t[d]!==void 0&&collate(t[u],t[d])>0)throw new QueryParseError(`No rows can match your key range, reverse your start_key and end_key or set {descending : true}`);if(c.reduce&&t.reduce!==!1){if(t.include_docs)throw new QueryParseError(`{include_docs:true} is invalid for reduce`);if(t.keys&&t.keys.length>1&&!t.group&&!t.group_level)throw new QueryParseError(`Multi-key fetches for reduce views must use {group: true}`)}for(let c of[`group_level`,`limit`,`skip`]){let u=checkPositiveInteger(t[c]);if(u)throw u}}async function httpQuery(t,c,u){let d=[],m,g=`GET`,b;if(addHttpParam(`reduce`,u,d),addHttpParam(`include_docs`,u,d),addHttpParam(`attachments`,u,d),addHttpParam(`limit`,u,d),addHttpParam(`descending`,u,d),addHttpParam(`group`,u,d),addHttpParam(`group_level`,u,d),addHttpParam(`skip`,u,d),addHttpParam(`stale`,u,d),addHttpParam(`conflicts`,u,d),addHttpParam(`startkey`,u,d,!0),addHttpParam(`start_key`,u,d,!0),addHttpParam(`endkey`,u,d,!0),addHttpParam(`end_key`,u,d,!0),addHttpParam(`inclusive_end`,u,d),addHttpParam(`key`,u,d,!0),addHttpParam(`update_seq`,u,d),d=d.join(`&`),d=d===``?``:`?`+d,u.keys!==void 0){let t=2e3,b=`keys=${encodeURIComponent(JSON.stringify(u.keys))}`;b.length+d.length+1<=2e3?d+=(d[0]===`?`?`&`:`?`)+b:(g=`POST`,typeof c==`string`?m={keys:u.keys}:c.keys=u.keys)}if(typeof c==`string`){let S=parseViewName(c),C=await t.fetch(`_design/`+S[0]+`/_view/`+S[1]+d,{headers:new h({"Content-Type":`application/json`}),method:g,body:JSON.stringify(m)});b=C.ok;let w=await C.json();if(!b)throw w.status=C.status,generateErrorFromResponse(w);for(let t of w.rows)if(t.value&&t.value.error&&t.value.error===`builtin_reduce_error`)throw Error(t.reason);return new Promise(function(t){t(w)}).then(postprocessAttachments(u))}m=m||{};for(let t of Object.keys(c))Array.isArray(c[t])?m[t]=c[t]:m[t]=c[t].toString();let S=await t.fetch(`_temp_view`+d,{headers:new h({"Content-Type":`application/json`}),method:`POST`,body:JSON.stringify(m)});b=S.ok;let C=await S.json();if(!b)throw C.status=S.status,generateErrorFromResponse(C);return new Promise(function(t){t(C)}).then(postprocessAttachments(u))}function customQuery(t,c,u){return new Promise(function(d,m){t._query(c,u,function(t,c){if(t)return m(t);d(c)})})}function customViewCleanup(t){return new Promise(function(c,u){t._viewCleanup(function(t,d){if(t)return u(t);c(d)})})}function defaultsTo(t){return function(c){if(c.status===404)return t;throw c}}async function getDocsToPersist(t,c,u){let d=`_local/doc_`+t,m={_id:d,keys:[]},g=u.get(t),b=g[0],S=g[1];function getMetaDoc(){return isGenOne(S)?Promise.resolve(m):c.db.get(d).catch(defaultsTo(m))}function getKeyValueDocs(t){return t.keys.length?c.db.allDocs({keys:t.keys,include_docs:!0}):Promise.resolve({rows:[]})}function processKeyValueDocs(t,c){let u=[],d=new Set;for(let t of c.rows){let c=t.doc;if(c&&(u.push(c),d.add(c._id),c._deleted=!b.has(c._id),!c._deleted)){let t=b.get(c._id);`value`in t&&(c.value=t.value)}}let m=mapToKeysArray(b);for(let t of m)if(!d.has(t)){let c={_id:t},d=b.get(t);`value`in d&&(c.value=d.value),u.push(c)}return t.keys=uniq$1(m.concat(t.keys)),u.push(t),u}let C=await getMetaDoc();return processKeyValueDocs(C,await getKeyValueDocs(C))}function updatePurgeSeq(t){return t.sourceDB.get(`_local/purges`).then(function(c){let u=c.purgeSeq;return t.db.get(`_local/purgeSeq`).then(function(t){return t._rev}).catch(defaultsTo(void 0)).then(function(c){return t.db.put({_id:`_local/purgeSeq`,_rev:c,purgeSeq:u})})}).catch(function(t){if(t.status!==404)throw t})}function saveKeyValues(t,c,u){var d=`_local/lastSeq`;return t.db.get(d).catch(defaultsTo({_id:d,seq:0})).then(function(d){var m=mapToKeysArray(c);return Promise.all(m.map(function(u){return getDocsToPersist(u,t,c)})).then(function(c){var m=c.flat();return d.seq=u,m.push(d),t.db.bulkDocs({docs:m})}).then(()=>updatePurgeSeq(t))})}function getQueue(t){let c=typeof t==`string`?t:t.name,u=persistentQueues[c];return u||(u=persistentQueues[c]=new TaskQueue),u}async function updateView(t,c){return sequentialize(getQueue(t),function(){return updateViewInQueue(t,c)})()}async function updateViewInQueue(t,u){let d,m,g;function emit(t,c){let u={id:m._id,key:normalizeKey(t)};c!=null&&(u.value=normalizeKey(c)),d.push(u)}let b=c(t.mapFun,emit),S=t.seq||0;function createTask(){return t.sourceDB.info().then(function(c){g=t.sourceDB.activeTasks.add({name:`view_indexing`,total_items:c.update_seq-S})})}function processChange(c,u){return function(){return saveKeyValues(t,c,u)}}let C=0,w={view:t.name,indexed_docs:C};t.sourceDB.emit(`indexing`,w);let T=new TaskQueue;async function processNextBatch(){return processBatch(await t.sourceDB.changes({return_docs:!0,conflicts:!0,include_docs:!0,style:`all_docs`,since:S,limit:u.changes_batch_size}),await getRecentPurges())}function getRecentPurges(){return t.db.get(`_local/purgeSeq`).then(function(t){return t.purgeSeq}).catch(defaultsTo(-1)).then(function(c){return t.sourceDB.get(`_local/purges`).then(function(u){let d=u.purges.filter(function(t,u){return u>c}).map(t=>t.docId),m=d.filter(function(t,c){return d.indexOf(t)===c});return Promise.all(m.map(function(c){return t.sourceDB.get(c).then(function(t){return{docId:c,doc:t}}).catch(defaultsTo({docId:c}))}))}).catch(defaultsTo([]))})}function processBatch(c,d){let m=c.results;if(!m.length&&!d.length)return;for(let t of d)if(m.findIndex(function(c){return c.id===t.docId})<0){let c={_id:t.docId,doc:{_id:t.docId,_deleted:1},changes:[]};t.doc&&(c.doc=t.doc,c.changes.push({rev:t.doc._rev})),m.push(c)}let b=createDocIdsToChangesAndEmits(m);T.add(processChange(b,S)),C+=m.length;let w={view:t.name,last_seq:c.last_seq,results_count:m.length,indexed_docs:C};if(t.sourceDB.emit(`indexing`,w),t.sourceDB.activeTasks.update(g,{completed_items:C}),!(m.length<u.changes_batch_size))return processNextBatch()}function createDocIdsToChangesAndEmits(c){let u=new Map;for(let g of c){if(g.doc._id[0]!==`_`){d=[],m=g.doc,m._deleted||tryMap(t.sourceDB,b,m),d.sort(sortByKeyThenValue);let c=createIndexableKeysToKeyValues(d);u.set(g.doc._id,[c,g.changes])}S=g.seq}return u}function createIndexableKeysToKeyValues(t){let c=new Map,u;for(let d=0,m=t.length;d<m;d++){let m=t[d],g=[m.key,m.id];d>0&&collate(m.key,u)===0&&g.push(d),c.set(toIndexableString(g),m),u=m.key}return c}try{await createTask(),await processNextBatch(),await T.finish(),t.seq=S,t.sourceDB.activeTasks.remove(g)}catch(c){t.sourceDB.activeTasks.remove(g,c)}}function reduceView(t,c,d){d.group_level===0&&delete d.group_level;let m=d.group||d.group_level,g=u(t.reduceFun),b=[],S=isNaN(d.group_level)?1/0:d.group_level;for(let t of c){let c=b[b.length-1],u=m?t.key:null;if(m&&Array.isArray(u)&&(u=u.slice(0,S)),c&&collate(c.groupKey,u)===0){c.keys.push([t.key,t.id]),c.values.push(t.value);continue}b.push({keys:[[t.key,t.id]],values:[t.value],groupKey:u})}c=[];for(let u of b){let d=tryReduce(t.sourceDB,g,u.keys,u.values,!1);if(d.error&&d.error instanceof BuiltInError)throw d.error;c.push({value:d.error?null:d.output,key:u.groupKey})}return{rows:sliceResults(c,d.limit,d.skip)}}function queryView(t,c){return sequentialize(getQueue(t),function(){return queryViewInQueue(t,c)})()}async function queryViewInQueue(t,c){let u,d=t.reduceFun&&c.reduce!==!1,m=c.skip||0;c.keys!==void 0&&!c.keys.length&&(c.limit=0,delete c.keys);async function fetchFromView(c){c.include_docs=!0;let d=await t.db.allDocs(c);return u=d.total_rows,d.rows.map(function(t){if(`value`in t.doc&&typeof t.doc.value==`object`&&t.doc.value!==null){let c=Object.keys(t.doc.value).sort(),u=[`id`,`key`,`value`];if(!(c<u||c>u))return t.doc.value}let c=parseIndexableString(t.doc._id);return{key:c[0],id:c[1],value:`value`in t.doc?t.doc.value:null}})}async function onMapResultsReady(g){let b;if(b=d?reduceView(t,g,c):c.keys===void 0?{total_rows:u,offset:m,rows:g}:{total_rows:u,offset:m,rows:sliceResults(g,c.limit,c.skip)},c.update_seq&&(b.update_seq=t.seq),c.include_docs){let u=uniq$1(g.map(rowToDocId)),d=await t.sourceDB.allDocs({keys:u,include_docs:!0,conflicts:c.conflicts,attachments:c.attachments,binary:c.binary}),m=new Map;for(let t of d.rows)m.set(t.id,t.doc);for(let t of g){let c=rowToDocId(t),u=m.get(c);u&&(t.doc=u)}}return b}if(c.keys!==void 0){let t=c.keys.map(function(t){let u={startkey:toIndexableString([t]),endkey:toIndexableString([t,{}])};return c.update_seq&&(u.update_seq=!0),fetchFromView(u)});return onMapResultsReady((await Promise.all(t)).flat())}else{let t={descending:c.descending};c.update_seq&&(t.update_seq=!0);let u,g;if(`start_key`in c&&(u=c.start_key),`startkey`in c&&(u=c.startkey),`end_key`in c&&(g=c.end_key),`endkey`in c&&(g=c.endkey),u!==void 0&&(t.startkey=c.descending?toIndexableString([u,{}]):toIndexableString([u])),g!==void 0){let u=c.inclusive_end!==!1;c.descending&&(u=!u),t.endkey=toIndexableString(u?[g,{}]:[g])}if(c.key!==void 0){let u=toIndexableString([c.key]),d=toIndexableString([c.key,{}]);t.descending?(t.endkey=u,t.startkey=d):(t.startkey=u,t.endkey=d)}return d||(typeof c.limit==`number`&&(t.limit=c.limit),t.skip=m),onMapResultsReady(await fetchFromView(t))}}async function httpViewCleanup(t){return(await t.fetch(`_view_cleanup`,{headers:new h({"Content-Type":`application/json`}),method:`POST`})).json()}async function localViewCleanup(c){try{let u=await c.get(`_local/`+t),d=new Map;for(let t of Object.keys(u.views)){let c=parseViewName(t),u=`_design/`+c[0],m=c[1],g=d.get(u);g||(g=new Set,d.set(u,g)),g.add(m)}let m={keys:mapToKeysArray(d),include_docs:!0},g=await c.allDocs(m),b={};for(let t of g.rows){let c=t.key.substring(8);for(let m of d.get(t.key)){let d=c+`/`+m;u.views[d]||(d=m);let g=Object.keys(u.views[d]),S=t.doc&&t.doc.views&&t.doc.views[m];for(let t of g)b[t]=b[t]||S}}let S=Object.keys(b).filter(function(t){return!b[t]}).map(function(t){return sequentialize(getQueue(t),function(){return new c.constructor(t,c.__opts).destroy()})()});return Promise.all(S).then(function(){return{ok:!0}})}catch(t){if(t.status===404)return{ok:!0};throw t}}async function queryPromised(c,u,m){if(typeof c._query==`function`)return customQuery(c,u,m);if(isRemote(c))return httpQuery(c,u,m);let g={changes_batch_size:c.__opts.view_update_changes_batch_size||CHANGES_BATCH_SIZE};if(typeof u!=`string`)return checkQueryParseError(m,u),tempViewQueue.add(async function(){let d=await createView(c,`temp_view/temp_view`,u.map,u.reduce,!0,t);return fin(updateView(d,g).then(function(){return queryView(d,m)}),function(){return d.db.destroy()})}),tempViewQueue.finish();{let b=u,S=parseViewName(b),C=S[0],w=S[1],T=await c.get(`_design/`+C);if(u=T.views&&T.views[w],!u)throw new NotFoundError(`ddoc ${T._id} has no view named ${w}`);d(T,w),checkQueryParseError(m,u);let E=await createView(c,b,u.map,u.reduce,!1,t);return m.stale===`ok`||m.stale===`update_after`?(m.stale===`update_after`&&nextTick(function(){updateView(E,g)}),queryView(E,m)):(await updateView(E,g),queryView(E,m))}}function abstractQuery(t,c,u){let d=this;typeof c==`function`&&(u=c,c={}),c=c?coerceOptions(c):{},typeof t==`function`&&(t={map:t});let m=Promise.resolve().then(function(){return queryPromised(d,t,c)});return promisedCallback(m,u),m}return{query:abstractQuery,viewCleanup:callbackify(function(){let t=this;return typeof t._viewCleanup==`function`?customViewCleanup(t):isRemote(t)?httpViewCleanup(t):localViewCleanup(t)})}}var TaskQueue,persistentQueues,tempViewQueue,CHANGES_BATCH_SIZE,init_index_es$2=__esmMin((()=>{init_index_browser_es$3(),init_index_es$4(),init_index_es$5(),init_index_browser_es$4(),init_index_browser_es$1(),init_index_browser_es$2(),init_index_es$3(),TaskQueue=class{constructor(){this.promise=Promise.resolve()}add(t){return this.promise=this.promise.catch(()=>{}).then(()=>t()),this.promise}finish(){return this.promise}},persistentQueues={},tempViewQueue=new TaskQueue,CHANGES_BATCH_SIZE=50,__name$2(emitError$1,`emitError`)}));function getFieldFromDoc(t,c){for(var u=t,d=0,m=c.length;d<m;d++){var g=c[d];if(u=u[g],!u)break}return u}function setFieldInDoc(t,c,u){for(var d=0,m=c.length;d<m-1;d++){var g=c[d];t=t[g]=t[g]||{}}t[c[m-1]]=u}function compare(t,c){return t<c?-1:t>c?1:0}function parseField(t){for(var c=[],u=``,d=0,m=t.length;d<m;d++){var g=t[d];d>0&&t[d-1]===`\\`&&(g===`$`||g===`.`)?u=u.substring(0,u.length-1)+g:g===`.`?(c.push(u),u=``):u+=g}return c.push(u),c}function isCombinationalField(t){return combinationFields.indexOf(t)>-1}function getKey(t){return Object.keys(t)[0]}function getValue(t){return t[getKey(t)]}function mergeAndedSelectors(t){var c={},u={$or:!0,$nor:!0};return t.forEach(function(t){Object.keys(t).forEach(function(d){var m=t[d];if(typeof m!=`object`&&(m={$eq:m}),isCombinationalField(d))if(m instanceof Array){if(u[d]){u[d]=!1,c[d]=m;return}var g=[];c[d].forEach(function(t){Object.keys(m).forEach(function(c){var u=m[c],d=Math.max(Object.keys(t).length,Object.keys(u).length),b=mergeAndedSelectors([t,u]);Object.keys(b).length<=d||g.push(b)})}),c[d]=g}else c[d]=mergeAndedSelectors([m]);else{var b=c[d]=c[d]||{};Object.keys(m).forEach(function(t){var c=m[t];if(t===`$gt`||t===`$gte`)return mergeGtGte(t,c,b);if(t===`$lt`||t===`$lte`)return mergeLtLte(t,c,b);if(t===`$ne`)return mergeNe(c,b);if(t===`$eq`)return mergeEq(c,b);if(t===`$regex`)return mergeRegex(c,b);b[t]=c})}})}),c}function mergeGtGte(t,c,u){u.$eq===void 0&&(u.$gte===void 0?u.$gt===void 0?u[t]=c:t===`$gte`?c>u.$gt&&(delete u.$gt,u.$gte=c):c>u.$gt&&(u.$gt=c):t===`$gte`?c>u.$gte&&(u.$gte=c):c>=u.$gte&&(delete u.$gte,u.$gt=c))}function mergeLtLte(t,c,u){u.$eq===void 0&&(u.$lte===void 0?u.$lt===void 0?u[t]=c:t===`$lte`?c<u.$lt&&(delete u.$lt,u.$lte=c):c<u.$lt&&(u.$lt=c):t===`$lte`?c<u.$lte&&(u.$lte=c):c<=u.$lte&&(delete u.$lte,u.$lt=c))}function mergeNe(t,c){`$ne`in c?c.$ne.push(t):c.$ne=[t]}function mergeEq(t,c){delete c.$gt,delete c.$gte,delete c.$lt,delete c.$lte,delete c.$ne,c.$eq=t}function mergeRegex(t,c){`$regex`in c?c.$regex.push(t):c.$regex=[t]}function mergeAndedSelectorsNested(t){for(var c in t){if(Array.isArray(t))for(var u in t)t[u].$and&&(t[u]=mergeAndedSelectors(t[u].$and));var d=t[c];typeof d==`object`&&mergeAndedSelectorsNested(d)}return t}function isAndInSelector(t,c){for(var u in t){u===`$and`&&(c=!0);var d=t[u];typeof d==`object`&&(c=isAndInSelector(d,c))}return c}function massageSelector(t){var c=clone$1(t);isAndInSelector(c,!1)&&(c=mergeAndedSelectorsNested(c),`$and`in c&&(c=mergeAndedSelectors(c.$and))),[`$or`,`$nor`].forEach(function(t){t in c&&c[t].forEach(function(t){for(var c=Object.keys(t),u=0;u<c.length;u++){var d=c[u],m=t[d];(typeof m!=`object`||!m)&&(t[d]={$eq:m})}})}),`$not`in c&&(c.$not=mergeAndedSelectors([c.$not]));for(var u=Object.keys(c),d=0;d<u.length;d++){var m=u[d],g=c[m];(typeof g!=`object`||!g)&&(g={$eq:g}),c[m]=g}return normalizeArrayOperators(c),c}function normalizeArrayOperators(t){Object.keys(t).forEach(function(c){var u=t[c];Array.isArray(u)?u.forEach(function(t){t&&typeof t==`object`&&normalizeArrayOperators(t)}):c===`$ne`?t.$ne=[u]:c===`$regex`?t.$regex=[u]:u&&typeof u==`object`&&normalizeArrayOperators(u)})}function createFieldSorter(t){function getFieldValuesAsArray(c){return t.map(function(t){return getFieldFromDoc(c,parseField(getKey(t)))})}return function(t,c){var u=collate(getFieldValuesAsArray(t.doc),getFieldValuesAsArray(c.doc));return u===0?compare(t.doc._id,c.doc._id):u}}function filterInMemoryFields(t,c,u){if(t=t.filter(function(t){return rowFilter(t.doc,c.selector,u)}),c.sort){var d=createFieldSorter(c.sort);t=t.sort(d),typeof c.sort[0]!=`string`&&getValue(c.sort[0])===`desc`&&(t=t.reverse())}if(`limit`in c||`skip`in c){var m=c.skip||0,g=(`limit`in c?c.limit:t.length)+m;t=t.slice(m,g)}return t}function rowFilter(t,c,u){return u.every(function(u){var d=c[u],m=parseField(u),g=getFieldFromDoc(t,m);return isCombinationalField(u)?matchCominationalSelector(u,d,t):matchSelector(d,t,m,g)})}function matchSelector(t,c,u,d){return t?typeof t==`object`?Object.keys(t).every(function(m){var g=t[m];if(m.indexOf(`$`)===0)return match(m,c,g,u,d);var b=parseField(m);if(d===void 0&&typeof g!=`object`&&b.length>0)return!1;var S=getFieldFromDoc(d,b);return typeof g==`object`?matchSelector(g,c,u,S):match(`$eq`,c,g,b,S)}):t===d:!0}function matchCominationalSelector(t,c,u){return t===`$or`?c.some(function(t){return rowFilter(u,t,Object.keys(t))}):t===`$not`?!rowFilter(u,c,Object.keys(c)):!c.find(function(t){return rowFilter(u,t,Object.keys(t))})}function match(t,c,u,d,m){if(!matchers[t])throw Error(`unknown operator "`+t+`" - should be one of $eq, $lte, $lt, $gt, $gte, $exists, $ne, $in, $nin, $size, $mod, $regex, $elemMatch, $type, $allMatch or $all`);return matchers[t](c,u,d,m)}function fieldExists(t){return t!=null}function fieldIsNotUndefined(t){return t!==void 0}function modField(t,c){if(typeof t!=`number`||parseInt(t,10)!==t)return!1;var u=c[0],d=c[1];return t%u===d}function arrayContainsValue(t,c){return c.some(function(c){return t instanceof Array?t.some(function(t){return collate(c,t)===0}):collate(c,t)===0})}function arrayContainsAllValues(t,c){return c.every(function(c){return t.some(function(t){return collate(c,t)===0})})}function arraySize(t,c){return t.length===c}function regexMatch(t,c){return new RegExp(c).test(t)}function typeMatch(t,c){switch(c){case`null`:return t===null;case`boolean`:return typeof t==`boolean`;case`number`:return typeof t==`number`;case`string`:return typeof t==`string`;case`array`:return t instanceof Array;case`object`:return{}.toString.call(t)===`[object Object]`}}function matchesSelector(t,c){if(typeof c!=`object`)throw Error(`Selector error: expected a JSON object`);c=massageSelector(c);var u=filterInMemoryFields([{doc:t}],{selector:c},Object.keys(c));return u&&u.length===1}var combinationFields,matchers,init_index_es$1=__esmMin((()=>{init_index_browser_es$1(),init_index_es$4(),combinationFields=[`$or`,`$nor`,`$not`],matchers={$elemMatch:function(t,c,u,d){return!Array.isArray(d)||d.length===0?!1:typeof d[0]==`object`&&d[0]!==null?d.some(function(t){return rowFilter(t,c,Object.keys(c))}):d.some(function(d){return matchSelector(c,t,u,d)})},$allMatch:function(t,c,u,d){return!Array.isArray(d)||d.length===0?!1:typeof d[0]==`object`&&d[0]!==null?d.every(function(t){return rowFilter(t,c,Object.keys(c))}):d.every(function(d){return matchSelector(c,t,u,d)})},$eq:function(t,c,u,d){return fieldIsNotUndefined(d)&&collate(d,c)===0},$gte:function(t,c,u,d){return fieldIsNotUndefined(d)&&collate(d,c)>=0},$gt:function(t,c,u,d){return fieldIsNotUndefined(d)&&collate(d,c)>0},$lte:function(t,c,u,d){return fieldIsNotUndefined(d)&&collate(d,c)<=0},$lt:function(t,c,u,d){return fieldIsNotUndefined(d)&&collate(d,c)<0},$exists:function(t,c,u,d){return c?fieldIsNotUndefined(d):!fieldIsNotUndefined(d)},$mod:function(t,c,u,d){return fieldExists(d)&&modField(d,c)},$ne:function(t,c,u,d){return c.every(function(t){return collate(d,t)!==0})},$in:function(t,c,u,d){return fieldExists(d)&&arrayContainsValue(d,c)},$nin:function(t,c,u,d){return fieldExists(d)&&!arrayContainsValue(d,c)},$size:function(t,c,u,d){return fieldExists(d)&&Array.isArray(d)&&arraySize(d,c)},$all:function(t,c,u,d){return Array.isArray(d)&&arrayContainsAllValues(d,c)},$regex:function(t,c,u,d){return fieldExists(d)&&typeof d==`string`&&c.every(function(t){return regexMatch(d,t)})},$type:function(t,c,u,d){return typeMatch(d,c)}}}));function mergeObjects(t){let c={};for(let u of t)Object.assign(c,u);return c}function pick(t,c){let u={};for(let d of c){let c=parseField(d),m=getFieldFromDoc(t,c);m!==void 0&&setFieldInDoc(u,c,m)}return u}function oneArrayIsSubArrayOfOther(t,c){for(let u=0,d=Math.min(t.length,c.length);u<d;u++)if(t[u]!==c[u])return!1;return!0}function oneArrayIsStrictSubArrayOfOther(t,c){return t.length>c.length?!1:oneArrayIsSubArrayOfOther(t,c)}function oneSetIsSubArrayOfOther(t,c){t=t.slice();for(let u of c){if(!t.length)break;let c=t.indexOf(u);if(c===-1)return!1;t.splice(c,1)}return!0}function arrayToObject(t){let c={};for(let u of t)c[u]=!0;return c}function max(t,c){let u=null,d=-1;for(let m of t){let t=c(m);t>d&&(d=t,u=m)}return u}function arrayEquals(t,c){if(t.length!==c.length)return!1;for(let u=0,d=t.length;u<d;u++)if(t[u]!==c[u])return!1;return!0}function uniq(t){return Array.from(new Set(t))}function resolveToCallback(t){return function(...c){let u=c[c.length-1];if(typeof u==`function`){let d=u.bind(null,null),m=u.bind(null);t.apply(this,c.slice(0,-1)).then(d,m)}else return t.apply(this,c)}}function massageCreateIndexRequest(t){t=clone$1(t),t.index||(t.index={});for(let c of[`type`,`name`,`ddoc`])t.index[c]&&(t[c]=t.index[c],delete t.index[c]);return t.fields&&(t.index.fields=t.fields,delete t.fields),t.type||(t.type=`json`),t}function isNonNullObject(t){return typeof t==`object`&&!!t}function checkFieldValueType(t,c,u){let d=``,m=c,g=!0;if([`$in`,`$nin`,`$or`,`$and`,`$mod`,`$nor`,`$all`].indexOf(t)!==-1&&(Array.isArray(c)||(d=`Query operator `+t+` must be an array.`)),[`$not`,`$elemMatch`,`$allMatch`].indexOf(t)!==-1&&(!Array.isArray(c)&&isNonNullObject(c)||(d=`Query operator `+t+` must be an object.`)),t===`$mod`&&Array.isArray(c))if(c.length!==2)d=`Query operator $mod must be in the format [divisor, remainder], where divisor and remainder are both integers.`;else{let t=c[0],u=c[1];t===0&&(d=`Query operator $mod's divisor cannot be 0, cannot divide by zero.`,g=!1),(typeof t!=`number`||parseInt(t,10)!==t)&&(d=`Query operator $mod's divisor is not an integer.`,m=t),parseInt(u,10)!==u&&(d=`Query operator $mod's remainder is not an integer.`,m=u)}if(t===`$exists`&&typeof c!=`boolean`&&(d=`Query operator $exists must be a boolean.`),t===`$type`){let t=[`null`,`boolean`,`number`,`string`,`array`,`object`],u=`"`+t.slice(0,t.length-1).join(`", "`)+`", or "`+t[t.length-1]+`"`;typeof c==`string`?t.indexOf(c)==-1&&(d=`Query operator $type must be a string. Supported values: `+u+`.`):d=`Query operator $type must be a string. Supported values: `+u+`.`}if(t===`$size`&&parseInt(c,10)!==c&&(d=`Query operator $size must be a integer.`),t===`$regex`&&typeof c!=`string`&&(u?d=`Query operator $regex must be a string.`:c instanceof RegExp||(d=`Query operator $regex must be a string or an instance of a javascript regular expression.`)),d){if(g){let t=m===null?` `:Array.isArray(m)?` array`:` `+typeof m,c=isNonNullObject(m)?JSON.stringify(m,null,` `):m;d+=` Received`+t+`: `+c}throw Error(d)}}function validateSelector(t,c){if(Array.isArray(t))for(let u of t)isNonNullObject(u)&&validateSelector(u,c);else for(let[u,d]of Object.entries(t))requireValidation.indexOf(u)!==-1&&checkFieldValueType(u,d,c),equalityOperators.indexOf(u)===-1&&arrayTypeComparisonOperators.indexOf(u)===-1&&isNonNullObject(d)&&validateSelector(d,c)}async function dbFetch(t,c,u){u.body&&(u.body=JSON.stringify(u.body),u.headers=new h({"Content-type":`application/json`}));let d=await t.fetch(c,u),m=await d.json();if(!d.ok)throw m.status=d.status,generateErrorFromResponse(createError(m));return m}async function createIndex(t,c){return await dbFetch(t,`_index`,{method:`POST`,body:massageCreateIndexRequest(c)})}async function find$1(t,c){return validateSelector(c.selector,!0),await dbFetch(t,`_find`,{method:`POST`,body:c})}async function explain(t,c){return await dbFetch(t,`_explain`,{method:`POST`,body:c})}async function getIndexes(t){return await dbFetch(t,`_index`,{method:`GET`})}async function deleteIndex(t,c){let u=c.ddoc,d=c.type||`json`,m=c.name;if(!u)throw Error(`you must provide an index's ddoc`);if(!m)throw Error(`you must provide an index's name`);return await dbFetch(t,`_index/`+[u,d,m].map(encodeURIComponent).join(`/`),{method:`DELETE`})}function getDeepValue(t,c){for(let u of c)if(t=t[u],t===void 0)return;return t}function createDeepMultiMapper(t,c,u){return function(d){if(u&&!matchesSelector(d,u))return;let m=[];for(let c of t){let t=getDeepValue(d,parseField(c));if(t===void 0)return;m.push(t)}c(m)}}function createDeepSingleMapper(t,c,u){let d=parseField(t);return function(t){if(u&&!matchesSelector(t,u))return;let m=getDeepValue(t,d);m!==void 0&&c(m)}}function createShallowSingleMapper(t,c,u){return function(d){u&&!matchesSelector(d,u)||c(d[t])}}function createShallowMultiMapper(t,c,u){return function(d){u&&!matchesSelector(d,u)||c(t.map(t=>d[t]))}}function checkShallow(t){return t.every(t=>t.indexOf(`.`)===-1)}function createMapper(t,c,u){let d=checkShallow(t),m=t.length===1;return d?m?createShallowSingleMapper(t[0],c,u):createShallowMultiMapper(t,c,u):m?createDeepSingleMapper(t[0],c,u):createDeepMultiMapper(t,c,u)}function mapper(t,c){let u=Object.keys(t.fields),d=t.partial_filter_selector;return createMapper(u,c,d)}function reducer(){throw Error(`reduce not supported`)}function ddocValidator(t,c){let u=t.views[c];if(!u.map||!u.map.fields)throw Error(`ddoc `+t._id+` with view `+c+` doesn't have map.fields defined. maybe it wasn't created by this plugin?`)}function abstractMapper$1(t){return t._customFindAbstractMapper?{query:function addQueryFallback(c,u){let d=abstractMapper.query.bind(this);return t._customFindAbstractMapper.query.call(this,c,u,d)},viewCleanup:function addViewCleanupFallback(){let c=abstractMapper.viewCleanup.bind(this);return t._customFindAbstractMapper.viewCleanup.call(this,c)}}:abstractMapper}function massageSort(t){if(!Array.isArray(t))throw Error(`invalid sort json - should be an array`);return t.map(function(t){if(typeof t==`string`){let c={};return c[t]=`asc`,c}else return t})}function massageUseIndex(t){let c=[];return typeof t==`string`?c.push(t):c=t,c.map(function(t){return t.replace(ddocIdPrefix,``)})}function massageIndexDef(t){return t.fields=t.fields.map(function(t){if(typeof t==`string`){let c={};return c[t]=`asc`,c}return t}),t.partial_filter_selector&&(t.partial_filter_selector=massageSelector(t.partial_filter_selector)),t}function getKeyFromDoc(t,c){return c.def.fields.map(c=>getFieldFromDoc(t,parseField(getKey(c))))}function filterInclusiveStart(t,c,u){let d=u.def.fields,m=0;for(let g of t){let t=getKeyFromDoc(g.doc,u);if(d.length===1)t=t[0];else for(;t.length>c.length;)t.pop();if(Math.abs(collate(t,c))>0)break;++m}return m>0?t.slice(m):t}function reverseOptions(t){let c=clone$1(t);return delete c.startkey,delete c.endkey,delete c.inclusive_start,delete c.inclusive_end,`endkey`in t&&(c.startkey=t.endkey),`startkey`in t&&(c.endkey=t.startkey),`inclusive_start`in t&&(c.inclusive_end=t.inclusive_start),`inclusive_end`in t&&(c.inclusive_start=t.inclusive_end),c}function validateIndex(t){let c=t.fields.filter(function(t){return getValue(t)===`asc`});if(c.length!==0&&c.length!==t.fields.length)throw Error(`unsupported mixed sorting`)}function validateSort(t,c){if(c.defaultUsed&&t.sort){let c=t.sort.filter(function(t){return Object.keys(t)[0]!==`_id`}).map(function(t){return Object.keys(t)[0]});if(c.length>0)throw Error(`Cannot sort on field(s) "`+c.join(`,`)+`" when using the default index`)}c.defaultUsed}function validateFindRequest(t){if(typeof t.selector!=`object`)throw Error(`you must provide a selector when you find()`)}function getUserFields(t,c){let u=Object.keys(t),d=c?c.map(getKey):[],m;return m=u.length>=d.length?u:d,d.length===0?{fields:m}:(m=m.sort(function(t,c){let u=d.indexOf(t);u===-1&&(u=Number.MAX_VALUE);let m=d.indexOf(c);return m===-1&&(m=Number.MAX_VALUE),u<m?-1:u>m?1:0}),{fields:m,sortOrder:c.map(getKey)})}async function createIndex$1(t,c){c=massageCreateIndexRequest(c);let u=clone$1(c.index);c.index=massageIndexDef(c.index),validateIndex(c.index);let d;function getMd5(){return d||(d=stringMd5(JSON.stringify(c)))}let m=c.name||`idx-`+getMd5(),g=c.ddoc||`idx-`+getMd5(),b=`_design/`+g,S=!1,C=!1;function updateDdoc(t){return t._rev&&t.language!==`query`&&(S=!0),t.language=`query`,t.views=t.views||{},C=!!t.views[m],C?!1:(t.views[m]={map:{fields:mergeObjects(c.index.fields),partial_filter_selector:c.index.partial_filter_selector},reduce:`_count`,options:{def:u}},t)}if(t.constructor.emit(`debug`,[`find`,`creating index`,b]),await upsert(t,b,updateDdoc),S)throw Error(`invalid language for ddoc with id "`+b+`" (should be "query")`);let w=g+`/`+m;return await abstractMapper$1(t).query.call(t,w,{limit:0,reduce:!1}),{id:b,name:m,result:C?`exists`:`created`}}async function getIndexes$1(t){let c=await t.allDocs({startkey:`_design/`,endkey:`_design/`,include_docs:!0}),u={indexes:[{ddoc:null,name:`_all_docs`,type:`special`,def:{fields:[{_id:`asc`}]}}]};return u.indexes=flatten(u.indexes,c.rows.filter(function(t){return t.doc.language===`query`}).map(function(t){return(t.doc.views===void 0?[]:Object.keys(t.doc.views)).map(function(c){let u=t.doc.views[c];return{ddoc:t.id,name:c,type:`json`,def:massageIndexDef(u.options.def)}})})),u.indexes.sort(function(t,c){return compare(t.name,c.name)}),u.total_rows=u.indexes.length,u}function checkFieldInIndex(t,c){return t.def.fields.some(t=>getKey(t)===c)}function userOperatorLosesPrecision(t,c){let u=t[c];return getKey(u)!==`$eq`}function sortFieldsByIndex(t,c){let u=c.def.fields.map(getKey);return t.slice().sort(function(t,c){let d=u.indexOf(t),m=u.indexOf(c);return d===-1&&(d=Number.MAX_VALUE),m===-1&&(m=Number.MAX_VALUE),compare(d,m)})}function getBasicInMemoryFields(t,c,u){u=sortFieldsByIndex(u,t);let d=!1;for(let m=0,g=u.length;m<g;m++){let b=u[m];if(d||!checkFieldInIndex(t,b))return u.slice(m);m<g-1&&userOperatorLosesPrecision(c,b)&&(d=!0)}return[]}function getInMemoryFieldsFromNe(t){let c=[];for(let[u,d]of Object.entries(t))for(let t of Object.keys(d))t===`$ne`&&c.push(u);return c}function getInMemoryFields(t,c,u,d){return sortFieldsByIndex(uniq(flatten(t,getBasicInMemoryFields(c,u,d),getInMemoryFieldsFromNe(u))),c)}function checkIndexFieldsMatch(t,c,u){if(c){let d=oneArrayIsStrictSubArrayOfOther(c,t),m=oneArrayIsSubArrayOfOther(u,t);return d&&m}return oneSetIsSubArrayOfOther(u,t)}function isNonLogicalMatcher(t){return logicalMatchers.indexOf(t)===-1}function checkFieldsLogicallySound(t,c){let u=c[t[0]];return u===void 0?!0:!(Object.keys(u).length===1&&getKey(u)===`$ne`)}function checkIndexMatches(t,c,u,d){let m=t.def.fields.map(getKey);return checkIndexFieldsMatch(m,c,u)?checkFieldsLogicallySound(m,d):!1}function findMatchingIndexes(t,c,u,d){return d.filter(function(d){return checkIndexMatches(d,u,c,t)})}function findBestMatchingIndex(t,c,u,d,m){let g=findMatchingIndexes(t,c,u,d);if(g.length===0){if(m)throw{error:`no_usable_index`,message:`There is no index available for this selector.`};let t=d[0];return t.defaultUsed=!0,t}if(g.length===1&&!m)return g[0];let b=arrayToObject(c);function scoreIndex(t){let c=t.def.fields.map(getKey),u=0;for(let t of c)b[t]&&u++;return u}if(m){let t=`_design/`+m[0],c=m.length===2?m[1]:!1,u=g.find(function(u){return!!(c&&u.ddoc===t&&c===u.name||u.ddoc===t)});if(!u)throw{error:`unknown_error`,message:`Could not find that index or could not use that index for the query`};return u}return max(g,scoreIndex)}function getSingleFieldQueryOptsFor(t,c){switch(t){case`$eq`:return{key:c};case`$lte`:return{endkey:c};case`$gte`:return{startkey:c};case`$lt`:return{endkey:c,inclusive_end:!1};case`$gt`:return{startkey:c,inclusive_start:!1}}return{startkey:COLLATE_LO}}function getSingleFieldCoreQueryPlan(t,c){let u=getKey(c.def.fields[0]),d=t[u]||{},m=[],g=Object.keys(d),b;for(let t of g){isNonLogicalMatcher(t)&&m.push(u);let c=d[t],g=getSingleFieldQueryOptsFor(t,c);b=b?mergeObjects([b,g]):g}return{queryOpts:b,inMemoryFields:m}}function getMultiFieldCoreQueryPlan(t,c){switch(t){case`$eq`:return{startkey:c,endkey:c};case`$lte`:return{endkey:c};case`$gte`:return{startkey:c};case`$lt`:return{endkey:c,inclusive_end:!1};case`$gt`:return{startkey:c,inclusive_start:!1}}}function getMultiFieldQueryOpts(t,c){let u=c.def.fields.map(getKey),d=[],m=[],g=[],b,S;function finish(t){b!==!1&&m.push(COLLATE_LO),S!==!1&&g.push(COLLATE_HI),d=u.slice(t)}for(let c=0,d=u.length;c<d;c++){let d=t[u[c]];if(!d||!Object.keys(d).length){finish(c);break}else if(Object.keys(d).some(isNonLogicalMatcher)){finish(c);break}else if(c>0){let m=`$gt`in d||`$gte`in d||`$lt`in d||`$lte`in d,g=Object.keys(t[u[c-1]]),b=arrayEquals(g,[`$eq`]),S=arrayEquals(g,Object.keys(d));if(m&&!b&&!S){finish(c);break}}let C=Object.keys(d),w=null;for(let t of C){let c=d[t],u=getMultiFieldCoreQueryPlan(t,c);w=w?mergeObjects([w,u]):u}m.push(`startkey`in w?w.startkey:COLLATE_LO),g.push(`endkey`in w?w.endkey:COLLATE_HI),`inclusive_start`in w&&(b=w.inclusive_start),`inclusive_end`in w&&(S=w.inclusive_end)}let C={startkey:m,endkey:g};return b!==void 0&&(C.inclusive_start=b),S!==void 0&&(C.inclusive_end=S),{queryOpts:C,inMemoryFields:d}}function shouldShortCircuit(t){return Object.keys(t).map(function(c){return t[c]}).some(function(t){return typeof t==`object`&&Object.keys(t).length===0})}function getDefaultQueryPlan(t){return{queryOpts:{startkey:null},inMemoryFields:[Object.keys(t)]}}function getCoreQueryPlan(t,c){return c.defaultUsed?getDefaultQueryPlan(t,c):c.def.fields.length===1?getSingleFieldCoreQueryPlan(t,c):getMultiFieldQueryOpts(t,c)}function planQuery(t,c){let u=t.selector,d=t.sort;if(shouldShortCircuit(u))return Object.assign({},SHORT_CIRCUIT_QUERY,{index:c[0]});let m=getUserFields(u,d),g=m.fields,b=m.sortOrder,S=findBestMatchingIndex(u,g,b,c,t.use_index),C=getCoreQueryPlan(u,S),w=C.queryOpts,T=C.inMemoryFields;return{queryOpts:w,index:S,inMemoryFields:getInMemoryFields(T,S,u,g)}}function indexToSignature(t){return t.ddoc.substring(8)+`/`+t.name}async function doAllDocs(t,c){let u=clone$1(c);u.descending?(`endkey`in u&&typeof u.endkey!=`string`&&(u.endkey=``),`startkey`in u&&typeof u.startkey!=`string`&&(u.limit=0)):(`startkey`in u&&typeof u.startkey!=`string`&&(u.startkey=``),`endkey`in u&&typeof u.endkey!=`string`&&(u.limit=0)),`key`in u&&typeof u.key!=`string`&&(u.limit=0),u.limit>0&&u.indexes_count&&(u.original_limit=u.limit,u.limit+=u.indexes_count);let d=await t.allDocs(u);return d.rows=d.rows.filter(function(t){return!/^_design\//.test(t.id)}),u.original_limit&&(u.limit=u.original_limit),d.rows=d.rows.slice(0,u.limit),d}async function queryAllOrIndex(t,c,u){return u.name===`_all_docs`?doAllDocs(t,c):abstractMapper$1(t).query.call(t,indexToSignature(u),c)}async function find$1$1(t,c,u){c.selector&&(validateSelector(c.selector,!1),c.selector=massageSelector(c.selector)),c.sort&&(c.sort=massageSort(c.sort)),c.use_index&&(c.use_index=massageUseIndex(c.use_index)),`limit`in c||(c.limit=25),validateFindRequest(c);let d=await getIndexes$1(t);t.constructor.emit(`debug`,[`find`,`planning query`,c]);let m=planQuery(c,d.indexes);t.constructor.emit(`debug`,[`find`,`query plan`,m]);let g=m.index;validateSort(c,g);let b=Object.assign({include_docs:!0,reduce:!1,indexes_count:d.total_rows},m.queryOpts);if(`startkey`in b&&`endkey`in b&&collate(b.startkey,b.endkey)>0)return{docs:[]};if(c.sort&&typeof c.sort[0]!=`string`&&getValue(c.sort[0])===`desc`&&(b.descending=!0,b=reverseOptions(b)),m.inMemoryFields.length||(b.limit=c.limit,`skip`in c&&(b.skip=c.skip)),u)return Promise.resolve(m,b);let S=await queryAllOrIndex(t,b,g);b.inclusive_start===!1&&(S.rows=filterInclusiveStart(S.rows,b.startkey,g)),m.inMemoryFields.length&&(S.rows=filterInMemoryFields(S.rows,c,m.inMemoryFields));let C={docs:S.rows.map(function(t){let u=t.doc;return c.fields?pick(u,c.fields):u})};return g.defaultUsed&&(C.warning=`No matching index found, create an index to optimize query time.`),C}async function explain$1(t,c){let u=await find$1$1(t,c,!0);return{dbname:t.name,index:u.index,selector:c.selector,range:{start_key:u.queryOpts.startkey,end_key:u.queryOpts.endkey},opts:{use_index:c.use_index||[],bookmark:`nil`,limit:c.limit,skip:c.skip,sort:c.sort||{},fields:c.fields,conflicts:!1,r:[49]},limit:c.limit,skip:c.skip||0,fields:c.fields}}async function deleteIndex$1(t,c){if(!c.ddoc)throw Error(`you must supply an index.ddoc when deleting`);if(!c.name)throw Error(`you must supply an index.name when deleting`);let u=c.ddoc,d=c.name;function deltaFun(t){return Object.keys(t.views).length===1&&t.views[d]?{_id:u,_deleted:!0}:(delete t.views[d],t)}return await upsert(t,u,deltaFun),await abstractMapper$1(t).viewCleanup.apply(t),{ok:!0}}var nativeFlat,polyFlat,flatten,requireValidation,arrayTypeComparisonOperators,equalityOperators,abstractMapper,ddocIdPrefix,COLLATE_LO,COLLATE_HI,SHORT_CIRCUIT_QUERY,logicalMatchers,plugin$1,init_index_browser_es=__esmMin((()=>{init_index_es$5(),init_index_browser_es$4(),init_index_es$2(),init_index_browser_es$2(),init_index_es$4(),init_index_es$1(),init_index_browser_es$1(),nativeFlat=(...t)=>t.flat(1/0),polyFlat=(...t)=>{let c=[];for(let u of t)Array.isArray(u)?c=c.concat(polyFlat(...u)):c.push(u);return c},flatten=typeof Array.prototype.flat==`function`?nativeFlat:polyFlat,requireValidation=[`$all`,`$allMatch`,`$and`,`$elemMatch`,`$exists`,`$in`,`$mod`,`$nin`,`$nor`,`$not`,`$or`,`$regex`,`$size`,`$type`],arrayTypeComparisonOperators=[`$in`,`$nin`,`$mod`,`$all`],equalityOperators=[`$eq`,`$gt`,`$gte`,`$lt`,`$lte`],__name$2(find$1,`find`),abstractMapper=createAbstractMapReduce(`indexes`,mapper,reducer,ddocValidator),ddocIdPrefix=/^_design\//,COLLATE_LO=null,COLLATE_HI={"":{}},SHORT_CIRCUIT_QUERY={queryOpts:{limit:0,startkey:COLLATE_HI,endkey:COLLATE_LO},inMemoryFields:[]},logicalMatchers=[`$eq`,`$gt`,`$gte`,`$lt`,`$lte`],__name$2(find$1$1,`find$1`),plugin$1={},plugin$1.createIndex=resolveToCallback(async function(t){if(typeof t!=`object`)throw Error(`you must provide an index to create`);return(isRemote(this)?createIndex:createIndex$1)(this,t)}),plugin$1.find=resolveToCallback(async function(t){if(typeof t!=`object`)throw Error(`you must provide search parameters to find()`);return(isRemote(this)?find$1:find$1$1)(this,t)}),plugin$1.explain=resolveToCallback(async function(t){if(typeof t!=`object`)throw Error(`you must provide search parameters to explain()`);return(isRemote(this)?explain:explain$1)(this,t)}),plugin$1.getIndexes=resolveToCallback(async function(){return(isRemote(this)?getIndexes:getIndexes$1)(this)}),plugin$1.deleteIndex=resolveToCallback(async function(t){if(typeof t!=`object`)throw Error(`you must provide an index to delete`);return(isRemote(this)?deleteIndex:deleteIndex$1)(this,t)})}));function getConfigUrl(t){return(t?`/_node/`+t:``)+`/_config`}function wrapError(t){throw t.name===`unknown_error`&&(t.message=(t.message||``)+` Unknown error! Did you remember to enable CORS?`),t}function fetchJSON(t,c,u){return u=u||{},u.body&&(u.body=JSON.stringify(u.body)),u.headers=u.headers||new h,u.headers.set(`Content-Type`,`application/json`),u.headers.set(`Accept`,`application/json`),t(c,u).then(function(t){return t.ok?t.json():t.json().then(function(t){throw t})}).catch(wrapError)}function toCallback(t){return function(){for(var c=[],u=arguments.length;u--;)c[u]=arguments[u];if(typeof c[-1]==`function`){var d=c[-1];return t.apply(this,c.slice(0,-2)).then(function(t){return d(null,t)},function(t){return d(t)})}else return t.apply(this,c)}}function updateUser(t,c,u){var d=[`_id`,`_rev`,`name`,`type`,`roles`,`password`,`password_scheme`,`iterations`,`derived_key`,`salt`];if(u.metadata){for(var m in u.metadata)if(u.metadata.hasOwnProperty(m)&&d.indexOf(m)!==-1)return Promise.reject(new AuthError(`cannot use reserved word in metadata: "`+m+`"`));c=Object.assign(c,u.metadata)}u.roles&&(c=Object.assign(c,{roles:u.roles}));var g=usersPath+`/`+encodeURIComponent(c._id),b=Object.assign({method:`PUT`,body:c},u.ajax||{});return fetchJSON(t.fetch,g,b)}var AuthError,getMembership,getNodeName,signUpAdmin,deleteAdmin,sessionPath,logIn,logOut,getSession,usersPath,signUp,getUser,putUser,deleteUser,changePassword,changeUsername,plugin,init_index_es=__esmMin((()=>{init_index_browser_es$4(),init_index_browser_es$1(),AuthError=function(t){function AuthError(c){t.call(this,c),this.name=`authentication_error`,this.status=400,this.error=!0,Object.setPrototypeOf(this,AuthError.prototype)}return t&&(AuthError.__proto__=t),AuthError.prototype=Object.create(t&&t.prototype),AuthError.prototype.constructor=AuthError,AuthError}(Error),getMembership=toCallback(function(t){var c=this;t===void 0&&(t={});var u=`/_membership`,d=Object.assign({method:`GET`},t.ajax||{});return fetchJSON(c.fetch,u,d)}),getNodeName=function(t,c){return t.getMembership(c).then(function(t){return t.all_nodes[0]},function(t){if(t.error!==`illegal_database_name`)throw t})},signUpAdmin=toCallback(function(t,c,u){var d=this;return u===void 0&&(u={}),[`http`,`https`].indexOf(d.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):t?c?getNodeName(d,u).then(function(m){var g=getConfigUrl(m),b=(u.configUrl||g)+`/admins/`+encodeURIComponent(t),S=Object.assign({method:`PUT`,body:c},u.ajax||{});return fetchJSON(d.fetch,b,S)}):Promise.reject(new AuthError(`You must provide a password`)):Promise.reject(new AuthError(`You must provide a username`))}),deleteAdmin=toCallback(function(t,c){var u=this;return c===void 0&&(c={}),[`http`,`https`].indexOf(u.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):t?getNodeName(u,c).then(function(d){var m=getConfigUrl(d),g=(c.configUrl||m)+`/admins/`+encodeURIComponent(t),b=Object.assign({method:`DELETE`,processData:!1},c.ajax||{});return fetchJSON(u.fetch,g,b)}):Promise.reject(new AuthError(`You must provide a username`))}),sessionPath=`/_session`,logIn=toCallback(function(t,c,u){var d=this;if(u===void 0&&(u={}),[`http`,`https`].indexOf(d.type())===-1)return Promise.reject(new AuthError(`this plugin only works for the http/https adapter`));if(!t)return Promise.reject(new AuthError(`you must provide a username`));if(!c)return Promise.reject(new AuthError(`you must provide a password`));var m=sessionPath,g=Object.assign({method:`POST`,body:{name:t,password:c}},u.ajax||{});return fetchJSON(d.fetch,m,g)}),logOut=toCallback(function(t){var c=this;t===void 0&&(t={});var u=sessionPath,d=Object.assign({method:`DELETE`},t.ajax||{});return fetchJSON(c.fetch,u,d)}),getSession=toCallback(function(t){var c=this;t===void 0&&(t={});var u=sessionPath,d=Object.assign({method:`GET`},t.ajax||{});return fetchJSON(c.fetch,u,d)}),usersPath=`/_users`,signUp=toCallback(function(t,c,u){var d=this;return u===void 0&&(u={}),[`http`,`https`].indexOf(d.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):t?c?updateUser(d,{name:t,password:c,roles:[],type:`user`,_id:`org.couchdb.user:`+t},u):Promise.reject(new AuthError(`You must provide a password`)):Promise.reject(new AuthError(`You must provide a username`))}),getUser=toCallback(function(t,c){var u=this;if(c===void 0&&(c={}),!t)return Promise.reject(new AuthError(`you must provide a username`));var d=usersPath+`/`+encodeURIComponent(`org.couchdb.user:`+t),m=Object.assign({method:`GET`},c.ajax||{});return fetchJSON(u.fetch,d,m).then(function(t){return console.log(t),t})}),putUser=toCallback(function(t,c){var u=this;return c===void 0&&(c={}),[`http`,`https`].indexOf(u.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):t?u.getUser(t,c).then(function(t){return updateUser(u,t,c)}):Promise.reject(new AuthError(`You must provide a username`))}),deleteUser=toCallback(function(t,c){var u=this;return c===void 0&&(c={}),[`http`,`https`].indexOf(u.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):t?u.getUser(t,c).then(function(t){var d=usersPath+`/`+encodeURIComponent(t._id)+`?rev=`+t._rev,m=Object.assign({method:`DELETE`},c.ajax||{});return fetchJSON(u.fetch,d,m)}):Promise.reject(new AuthError(`You must provide a username`))}),changePassword=toCallback(function(t,c,u){var d=this;return u===void 0&&(u={}),[`http`,`https`].indexOf(d.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):t?c?d.getUser(t,u).then(function(t){t.password=c;var m=usersPath+`/`+encodeURIComponent(t._id),g=Object.assign({method:`PUT`,body:t},u.ajax||{});return fetchJSON(d.fetch,m,g)}):Promise.reject(new AuthError(`You must provide a password`)):Promise.reject(new AuthError(`You must provide a username`))}),changeUsername=toCallback(function(t,c,u){var d=this,m=`org.couchdb.user:`,updateUser=function(t,c){var u=usersPath+`/`+encodeURIComponent(t._id),m=Object.assign({method:`PUT`,body:t},c.ajax);return fetchJSON(d.fetch,u,m)};return u===void 0&&(u={}),u.ajax=u.ajax||{},[`http`,`https`].indexOf(d.type())===-1?Promise.reject(new AuthError(`This plugin only works for the http/https adapter. So you should use new PouchDB("http://mysite.com:5984/mydb") instead.`)):c?t?d.getUser(c,u).then(function(){var t=new AuthError(`user already exists`);throw t.taken=!0,t},function(){return d.getUser(t,u)}).then(function(t){var d=clone$1(t);return delete d._rev,d._id=m+c,d.name=c,d.roles=u.roles||t.roles||{},updateUser(d,u).then(function(){return t._deleted=!0,updateUser(t,u)})}):Promise.reject(new AuthError(`You must provide a username to rename`)):Promise.reject(new AuthError(`You must provide a new username`))}),plugin={},plugin.login=logIn,plugin.logIn=logIn,plugin.logout=logOut,plugin.logOut=logOut,plugin.getSession=getSession,plugin.getMembership=getMembership,plugin.signUpAdmin=signUpAdmin,plugin.deleteAdmin=deleteAdmin,plugin.signup=signUp,plugin.signUp=signUp,plugin.getUser=getUser,plugin.putUser=putUser,plugin.deleteUser=deleteUser,plugin.changePassword=changePassword,plugin.changeUsername=changeUsername,typeof window<`u`&&window.PouchDB&&window.PouchDB.plugin(plugin)}));function unsafeStringify(t,c=0){return(byteToHex[t[c+0]]+byteToHex[t[c+1]]+byteToHex[t[c+2]]+byteToHex[t[c+3]]+`-`+byteToHex[t[c+4]]+byteToHex[t[c+5]]+`-`+byteToHex[t[c+6]]+byteToHex[t[c+7]]+`-`+byteToHex[t[c+8]]+byteToHex[t[c+9]]+`-`+byteToHex[t[c+10]]+byteToHex[t[c+11]]+byteToHex[t[c+12]]+byteToHex[t[c+13]]+byteToHex[t[c+14]]+byteToHex[t[c+15]]).toLowerCase()}var byteToHex,init_stringify=__esmMin((()=>{byteToHex=[];for(let t=0;t<256;++t)byteToHex.push((t+256).toString(16).slice(1))}));function rng(){if(!getRandomValues){if(typeof crypto>`u`||!crypto.getRandomValues)throw Error(`crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported`);getRandomValues=crypto.getRandomValues.bind(crypto)}return getRandomValues(rnds8)}var getRandomValues,rnds8,init_rng=__esmMin((()=>{rnds8=new Uint8Array(16)})),randomUUID,native_default,init_native=__esmMin((()=>{randomUUID=typeof crypto<`u`&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),native_default={randomUUID}}));function v4(t,c,u){if(native_default.randomUUID&&!c&&!t)return native_default.randomUUID();t=t||{};let d=t.random??t.rng?.()??rng();if(d.length<16)throw Error(`Random bytes length must be >= 16`);if(d[6]=d[6]&15|64,d[8]=d[8]&63|128,c){if(u=u||0,u<0||u+16>c.length)throw RangeError(`UUID byte range ${u}:${u+15} is out of buffer bounds`);for(let t=0;t<16;++t)c[u+t]=d[t];return c}return unsafeStringify(d)}var init_v4=__esmMin((()=>{init_native(),init_rng(),init_stringify()})),init_esm_browser=__esmMin((()=>{init_v4()})),require_browser_ponyfill=__commonJSMin$2(((t,c)=>{var u=typeof globalThis<`u`&&globalThis||typeof self<`u`&&self||typeof window<`u`&&window,d=(function(){function F(){this.fetch=!1,this.DOMException=u.DOMException}return F.prototype=u,new F})();(function(t){(function(c){var u=t!==void 0&&t||typeof self<`u`&&self||typeof window<`u`&&window||{},d={searchParams:`URLSearchParams`in u,iterable:`Symbol`in u&&`iterator`in Symbol,blob:`FileReader`in u&&`Blob`in u&&(function(){try{return new Blob,!0}catch{return!1}})(),formData:`FormData`in u,arrayBuffer:`ArrayBuffer`in u};function isDataView(t){return t&&DataView.prototype.isPrototypeOf(t)}if(d.arrayBuffer)var m=[`[object Int8Array]`,`[object Uint8Array]`,`[object Uint8ClampedArray]`,`[object Int16Array]`,`[object Uint16Array]`,`[object Int32Array]`,`[object Uint32Array]`,`[object Float32Array]`,`[object Float64Array]`],g=ArrayBuffer.isView||function(t){return t&&m.indexOf(Object.prototype.toString.call(t))>-1};function normalizeName(t){if(typeof t!=`string`&&(t=String(t)),/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(t)||t===``)throw TypeError(`Invalid character in header field name: "`+t+`"`);return t.toLowerCase()}function normalizeValue(t){return typeof t!=`string`&&(t=String(t)),t}function iteratorFor(t){var c={next:function(){var c=t.shift();return{done:c===void 0,value:c}}};return d.iterable&&(c[Symbol.iterator]=function(){return c}),c}function Headers(t){this.map={},t instanceof Headers?t.forEach(function(t,c){this.append(c,t)},this):Array.isArray(t)?t.forEach(function(t){if(t.length!=2)throw TypeError(`Headers constructor: expected name/value pair to be length 2, found`+t.length);this.append(t[0],t[1])},this):t&&Object.getOwnPropertyNames(t).forEach(function(c){this.append(c,t[c])},this)}Headers.prototype.append=function(t,c){t=normalizeName(t),c=normalizeValue(c);var u=this.map[t];this.map[t]=u?u+`, `+c:c},Headers.prototype.delete=function(t){delete this.map[normalizeName(t)]},Headers.prototype.get=function(t){return t=normalizeName(t),this.has(t)?this.map[t]:null},Headers.prototype.has=function(t){return this.map.hasOwnProperty(normalizeName(t))},Headers.prototype.set=function(t,c){this.map[normalizeName(t)]=normalizeValue(c)},Headers.prototype.forEach=function(t,c){for(var u in this.map)this.map.hasOwnProperty(u)&&t.call(c,this.map[u],u,this)},Headers.prototype.keys=function(){var t=[];return this.forEach(function(c,u){t.push(u)}),iteratorFor(t)},Headers.prototype.values=function(){var t=[];return this.forEach(function(c){t.push(c)}),iteratorFor(t)},Headers.prototype.entries=function(){var t=[];return this.forEach(function(c,u){t.push([u,c])}),iteratorFor(t)},d.iterable&&(Headers.prototype[Symbol.iterator]=Headers.prototype.entries);function consumed(t){if(!t._noBody){if(t.bodyUsed)return Promise.reject(TypeError(`Already read`));t.bodyUsed=!0}}function fileReaderReady(t){return new Promise(function(c,u){t.onload=function(){c(t.result)},t.onerror=function(){u(t.error)}})}function readBlobAsArrayBuffer(t){var c=new FileReader,u=fileReaderReady(c);return c.readAsArrayBuffer(t),u}function readBlobAsText(t){var c=new FileReader,u=fileReaderReady(c),d=/charset=([A-Za-z0-9_-]+)/.exec(t.type),m=d?d[1]:`utf-8`;return c.readAsText(t,m),u}function readArrayBufferAsText(t){for(var c=new Uint8Array(t),u=Array(c.length),d=0;d<c.length;d++)u[d]=String.fromCharCode(c[d]);return u.join(``)}function bufferClone(t){if(t.slice)return t.slice(0);var c=new Uint8Array(t.byteLength);return c.set(new Uint8Array(t)),c.buffer}function Body(){return this.bodyUsed=!1,this._initBody=function(t){this.bodyUsed=this.bodyUsed,this._bodyInit=t,t?typeof t==`string`?this._bodyText=t:d.blob&&Blob.prototype.isPrototypeOf(t)?this._bodyBlob=t:d.formData&&FormData.prototype.isPrototypeOf(t)?this._bodyFormData=t:d.searchParams&&URLSearchParams.prototype.isPrototypeOf(t)?this._bodyText=t.toString():d.arrayBuffer&&d.blob&&isDataView(t)?(this._bodyArrayBuffer=bufferClone(t.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):d.arrayBuffer&&(ArrayBuffer.prototype.isPrototypeOf(t)||g(t))?this._bodyArrayBuffer=bufferClone(t):this._bodyText=t=Object.prototype.toString.call(t):(this._noBody=!0,this._bodyText=``),this.headers.get(`content-type`)||(typeof t==`string`?this.headers.set(`content-type`,`text/plain;charset=UTF-8`):this._bodyBlob&&this._bodyBlob.type?this.headers.set(`content-type`,this._bodyBlob.type):d.searchParams&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set(`content-type`,`application/x-www-form-urlencoded;charset=UTF-8`))},d.blob&&(this.blob=function(){var t=consumed(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw Error(`could not read FormData body as blob`);return Promise.resolve(new Blob([this._bodyText]))}),this.arrayBuffer=function(){if(this._bodyArrayBuffer)return consumed(this)||(ArrayBuffer.isView(this._bodyArrayBuffer)?Promise.resolve(this._bodyArrayBuffer.buffer.slice(this._bodyArrayBuffer.byteOffset,this._bodyArrayBuffer.byteOffset+this._bodyArrayBuffer.byteLength)):Promise.resolve(this._bodyArrayBuffer));if(d.blob)return this.blob().then(readBlobAsArrayBuffer);throw Error(`could not read as ArrayBuffer`)},this.text=function(){var t=consumed(this);if(t)return t;if(this._bodyBlob)return readBlobAsText(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer));if(this._bodyFormData)throw Error(`could not read FormData body as text`);return Promise.resolve(this._bodyText)},d.formData&&(this.formData=function(){return this.text().then(decode)}),this.json=function(){return this.text().then(JSON.parse)},this}var b=[`CONNECT`,`DELETE`,`GET`,`HEAD`,`OPTIONS`,`PATCH`,`POST`,`PUT`,`TRACE`];function normalizeMethod(t){var c=t.toUpperCase();return b.indexOf(c)>-1?c:t}function Request(t,c){if(!(this instanceof Request))throw TypeError(`Please use the "new" operator, this DOM object constructor cannot be called as a function.`);c=c||{};var d=c.body;if(t instanceof Request){if(t.bodyUsed)throw TypeError(`Already read`);this.url=t.url,this.credentials=t.credentials,c.headers||(this.headers=new Headers(t.headers)),this.method=t.method,this.mode=t.mode,this.signal=t.signal,!d&&t._bodyInit!=null&&(d=t._bodyInit,t.bodyUsed=!0)}else this.url=String(t);if(this.credentials=c.credentials||this.credentials||`same-origin`,(c.headers||!this.headers)&&(this.headers=new Headers(c.headers)),this.method=normalizeMethod(c.method||this.method||`GET`),this.mode=c.mode||this.mode||null,this.signal=c.signal||this.signal||function(){if(`AbortController`in u)return new AbortController().signal}(),this.referrer=null,(this.method===`GET`||this.method===`HEAD`)&&d)throw TypeError(`Body not allowed for GET or HEAD requests`);if(this._initBody(d),(this.method===`GET`||this.method===`HEAD`)&&(c.cache===`no-store`||c.cache===`no-cache`)){var m=/([?&])_=[^&]*/;m.test(this.url)?this.url=this.url.replace(m,`$1_=`+new Date().getTime()):this.url+=(/\?/.test(this.url)?`&`:`?`)+`_=`+new Date().getTime()}}Request.prototype.clone=function(){return new Request(this,{body:this._bodyInit})};function decode(t){var c=new FormData;return t.trim().split(`&`).forEach(function(t){if(t){var u=t.split(`=`),d=u.shift().replace(/\+/g,` `),m=u.join(`=`).replace(/\+/g,` `);c.append(decodeURIComponent(d),decodeURIComponent(m))}}),c}function parseHeaders(t){var c=new Headers;return t.replace(/\r?\n[\t ]+/g,` `).split(`\r`).map(function(t){return t.indexOf(`
|
|
94
|
-
`)===0?t.substr(1,t.length):t}).forEach(function(t){var u=t.split(`:`),d=u.shift().trim();if(d){var m=u.join(`:`).trim();try{c.append(d,m)}catch(t){console.warn(`Response `+t.message)}}}),c}Body.call(Request.prototype);function Response(t,c){if(!(this instanceof Response))throw TypeError(`Please use the "new" operator, this DOM object constructor cannot be called as a function.`);if(c||(c={}),this.type=`default`,this.status=c.status===void 0?200:c.status,this.status<200||this.status>599)throw RangeError(`Failed to construct 'Response': The status provided (0) is outside the range [200, 599].`);this.ok=this.status>=200&&this.status<300,this.statusText=c.statusText===void 0?``:``+c.statusText,this.headers=new Headers(c.headers),this.url=c.url||``,this._initBody(t)}Body.call(Response.prototype),Response.prototype.clone=function(){return new Response(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new Headers(this.headers),url:this.url})},Response.error=function(){var t=new Response(null,{status:200,statusText:``});return t.ok=!1,t.status=0,t.type=`error`,t};var S=[301,302,303,307,308];Response.redirect=function(t,c){if(S.indexOf(c)===-1)throw RangeError(`Invalid status code`);return new Response(null,{status:c,headers:{location:t}})},c.DOMException=u.DOMException;try{new c.DOMException}catch{c.DOMException=function(t,c){this.message=t,this.name=c,this.stack=Error(t).stack},c.DOMException.prototype=Object.create(Error.prototype),c.DOMException.prototype.constructor=c.DOMException}function fetch(t,m){return new Promise(function(g,b){var S=new Request(t,m);if(S.signal&&S.signal.aborted)return b(new c.DOMException(`Aborted`,`AbortError`));var C=new XMLHttpRequest;function abortXhr(){C.abort()}C.onload=function(){var t={statusText:C.statusText,headers:parseHeaders(C.getAllResponseHeaders()||``)};S.url.indexOf(`file://`)===0&&(C.status<200||C.status>599)?t.status=200:t.status=C.status,t.url=`responseURL`in C?C.responseURL:t.headers.get(`X-Request-URL`);var c=`response`in C?C.response:C.responseText;setTimeout(function(){g(new Response(c,t))},0)},C.onerror=function(){setTimeout(function(){b(TypeError(`Network request failed`))},0)},C.ontimeout=function(){setTimeout(function(){b(TypeError(`Network request timed out`))},0)},C.onabort=function(){setTimeout(function(){b(new c.DOMException(`Aborted`,`AbortError`))},0)};function fixUrl(t){try{return t===``&&u.location.href?u.location.href:t}catch{return t}}if(C.open(S.method,fixUrl(S.url),!0),S.credentials===`include`?C.withCredentials=!0:S.credentials===`omit`&&(C.withCredentials=!1),`responseType`in C&&(d.blob?C.responseType=`blob`:d.arrayBuffer&&(C.responseType=`arraybuffer`)),m&&typeof m.headers==`object`&&!(m.headers instanceof Headers||u.Headers&&m.headers instanceof u.Headers)){var w=[];Object.getOwnPropertyNames(m.headers).forEach(function(t){w.push(normalizeName(t)),C.setRequestHeader(t,normalizeValue(m.headers[t]))}),S.headers.forEach(function(t,c){w.indexOf(c)===-1&&C.setRequestHeader(c,t)})}else S.headers.forEach(function(t,c){C.setRequestHeader(c,t)});S.signal&&(S.signal.addEventListener(`abort`,abortXhr),C.onreadystatechange=function(){C.readyState===4&&S.signal.removeEventListener(`abort`,abortXhr)}),C.send(S._bodyInit===void 0?null:S._bodyInit)})}return fetch.polyfill=!0,u.fetch||(u.fetch=fetch,u.Headers=Headers,u.Request=Request,u.Response=Response),c.Headers=Headers,c.Request=Request,c.Response=Response,c.fetch=fetch,c})({})})(d),d.fetch.ponyfill=!0,delete d.fetch.polyfill;var m=u.fetch?u:d;t=m.fetch,t.default=m.fetch,t.fetch=m.fetch,t.Headers=m.Headers,t.Request=m.Request,t.Response=m.Response,c.exports=t})),require_browser=__commonJSMin$2(((t,c)=>{var u=c.exports={},d,m;function defaultSetTimout(){throw Error(`setTimeout has not been defined`)}function defaultClearTimeout(){throw Error(`clearTimeout has not been defined`)}(function(){try{d=typeof setTimeout==`function`?setTimeout:defaultSetTimout}catch{d=defaultSetTimout}try{m=typeof clearTimeout==`function`?clearTimeout:defaultClearTimeout}catch{m=defaultClearTimeout}})();function runTimeout(t){if(d===setTimeout)return setTimeout(t,0);if((d===defaultSetTimout||!d)&&setTimeout)return d=setTimeout,setTimeout(t,0);try{return d(t,0)}catch{try{return d.call(null,t,0)}catch{return d.call(this,t,0)}}}function runClearTimeout(t){if(m===clearTimeout)return clearTimeout(t);if((m===defaultClearTimeout||!m)&&clearTimeout)return m=clearTimeout,clearTimeout(t);try{return m(t)}catch{try{return m.call(null,t)}catch{return m.call(this,t)}}}var g=[],b=!1,S,C=-1;function cleanUpNextTick(){!b||!S||(b=!1,S.length?g=S.concat(g):C=-1,g.length&&drainQueue())}function drainQueue(){if(!b){var t=runTimeout(cleanUpNextTick);b=!0;for(var c=g.length;c;){for(S=g,g=[];++C<c;)S&&S[C].run();C=-1,c=g.length}S=null,b=!1,runClearTimeout(t)}}u.nextTick=function(t){var c=Array(arguments.length-1);if(arguments.length>1)for(var u=1;u<arguments.length;u++)c[u-1]=arguments[u];g.push(new Item(t,c)),g.length===1&&!b&&runTimeout(drainQueue)};function Item(t,c){this.fun=t,this.array=c}Item.prototype.run=function(){this.fun.apply(null,this.array)},u.title=`browser`,u.browser=!0,u.env={},u.argv=[],u.version=``,u.versions={};function noop(){}u.on=noop,u.addListener=noop,u.once=noop,u.off=noop,u.removeListener=noop,u.removeAllListeners=noop,u.emit=noop,u.prependListener=noop,u.prependOnceListener=noop,u.listeners=function(t){return[]},u.binding=function(t){throw Error(`process.binding is not supported`)},u.cwd=function(){return`/`},u.chdir=function(t){throw Error(`process.chdir is not supported`)},u.umask=function(){return 0}})),dist_exports=__exportAll$1({ContentNavigator:()=>ContentNavigator,CouchDBToStaticPacker:()=>CouchDBToStaticPacker,CourseLookup:()=>CourseLookup,DocType:()=>DocType,DocTypePrefixes:()=>DocTypePrefixes,ENV:()=>ENV,FileSystemError:()=>FileSystemError,GuestUsername:()=>GuestUsername,Loggable:()=>Loggable,NOT_SET:()=>NOT_SET,NavigatorRole:()=>NavigatorRole,NavigatorRoles:()=>NavigatorRoles,Navigators:()=>Navigators,QuotaRoundRobinMixer:()=>QuotaRoundRobinMixer,SessionController:()=>SessionController,StaticToCouchDBMigrator:()=>StaticToCouchDBMigrator,TagFilteredContentSource:()=>TagFilteredContentSource,_resetDataLayer:()=>_resetDataLayer,aggregateOutcomesForGradient:()=>aggregateOutcomesForGradient,areQuestionRecords:()=>areQuestionRecords,buildStrategyStateId:()=>buildStrategyStateId,captureMixerRun:()=>captureMixerRun,computeDeviation:()=>computeDeviation,computeEffectiveWeight:()=>computeEffectiveWeight,computeOutcomeSignal:()=>computeOutcomeSignal,computeSpread:()=>computeSpread,computeStrategyGradient:()=>computeStrategyGradient,createOrchestrationContext:()=>createOrchestrationContext,docIsDeleted:()=>docIsDeleted,endSessionTracking:()=>endSessionTracking,ensureAppDataDirectory:()=>ensureAppDataDirectory,getAppDataDirectory:()=>getAppDataDirectory,getCardHistoryID:()=>getCardHistoryID,getCardOrigin:()=>getCardOrigin,getDataLayer:()=>getDataLayer,getDbPath:()=>getDbPath,getDefaultLearnableWeight:()=>getDefaultLearnableWeight,getRegisteredNavigator:()=>getRegisteredNavigator,getRegisteredNavigatorNames:()=>getRegisteredNavigatorNames,getRegisteredNavigatorRole:()=>getRegisteredNavigatorRole,getStudySource:()=>getStudySource,hasRegisteredNavigator:()=>hasRegisteredNavigator,importParsedCards:()=>importParsedCards,initializeDataDirectory:()=>initializeDataDirectory,initializeDataLayer:()=>initializeDataLayer,initializeNavigatorRegistry:()=>initializeNavigatorRegistry,isDataShapeRegistered:()=>isDataShapeRegistered,isDataShapeSchemaAvailable:()=>isDataShapeSchemaAvailable,isFilter:()=>isFilter,isGenerator:()=>isGenerator,isQuestionRecord:()=>isQuestionRecord,isQuestionTypeRegistered:()=>isQuestionTypeRegistered,isReview:()=>isReview,log:()=>log,mixerDebugAPI:()=>mixerDebugAPI,mountMixerDebugger:()=>mountMixerDebugger,mountPipelineDebugger:()=>mountPipelineDebugger,mountSessionDebugger:()=>mountSessionDebugger,mountUserDBDebugger:()=>mountUserDBDebugger,newInterval:()=>newInterval,parseCardHistoryID:()=>parseCardHistoryID,pipelineDebugAPI:()=>pipelineDebugAPI,processCustomQuestionsData:()=>processCustomQuestionsData,recordCardPresentation:()=>recordCardPresentation,recordUserOutcome:()=>recordUserOutcome,registerBlanksCard:()=>registerBlanksCard,registerCustomQuestionTypes:()=>registerCustomQuestionTypes,registerDataShape:()=>registerDataShape,registerNavigator:()=>registerNavigator,registerQuestionType:()=>registerQuestionType,registerSeedData:()=>registerSeedData,removeCustomQuestionTypes:()=>removeCustomQuestionTypes,removeDataShape:()=>removeDataShape,removeQuestionType:()=>removeQuestionType,runPeriodUpdate:()=>runPeriodUpdate,scoreAccuracyInZone:()=>scoreAccuracyInZone,sessionDebugAPI:()=>sessionDebugAPI,snapshotQueues:()=>snapshotQueues,startSessionTracking:()=>startSessionTracking,updateLearningState:()=>updateLearningState,updateStrategyWeight:()=>updateStrategyWeight,userDBDebugAPI:()=>userDBDebugAPI,validateMigration:()=>validateMigration,validateProcessorConfig:()=>validateProcessorConfig,validateStaticCourse:()=>validateStaticCourse});function areQuestionRecords(t){return isQuestionRecord(t.records[0])}function isQuestionRecord(t){return t.userAnswer!==void 0}function getCardHistoryID(t,c){return`${DocTypePrefixes.CARDRECORD}-${t}-${c}`}function parseCardHistoryID(t){let c=t.split(`-`),u=``;if(u+=c.length===3?``:`
|
|
94
|
+
`)===0?t.substr(1,t.length):t}).forEach(function(t){var u=t.split(`:`),d=u.shift().trim();if(d){var m=u.join(`:`).trim();try{c.append(d,m)}catch(t){console.warn(`Response `+t.message)}}}),c}Body.call(Request.prototype);function Response(t,c){if(!(this instanceof Response))throw TypeError(`Please use the "new" operator, this DOM object constructor cannot be called as a function.`);if(c||(c={}),this.type=`default`,this.status=c.status===void 0?200:c.status,this.status<200||this.status>599)throw RangeError(`Failed to construct 'Response': The status provided (0) is outside the range [200, 599].`);this.ok=this.status>=200&&this.status<300,this.statusText=c.statusText===void 0?``:``+c.statusText,this.headers=new Headers(c.headers),this.url=c.url||``,this._initBody(t)}Body.call(Response.prototype),Response.prototype.clone=function(){return new Response(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new Headers(this.headers),url:this.url})},Response.error=function(){var t=new Response(null,{status:200,statusText:``});return t.ok=!1,t.status=0,t.type=`error`,t};var S=[301,302,303,307,308];Response.redirect=function(t,c){if(S.indexOf(c)===-1)throw RangeError(`Invalid status code`);return new Response(null,{status:c,headers:{location:t}})},c.DOMException=u.DOMException;try{new c.DOMException}catch{c.DOMException=function(t,c){this.message=t,this.name=c,this.stack=Error(t).stack},c.DOMException.prototype=Object.create(Error.prototype),c.DOMException.prototype.constructor=c.DOMException}function fetch(t,m){return new Promise(function(g,b){var S=new Request(t,m);if(S.signal&&S.signal.aborted)return b(new c.DOMException(`Aborted`,`AbortError`));var C=new XMLHttpRequest;function abortXhr(){C.abort()}C.onload=function(){var t={statusText:C.statusText,headers:parseHeaders(C.getAllResponseHeaders()||``)};S.url.indexOf(`file://`)===0&&(C.status<200||C.status>599)?t.status=200:t.status=C.status,t.url=`responseURL`in C?C.responseURL:t.headers.get(`X-Request-URL`);var c=`response`in C?C.response:C.responseText;setTimeout(function(){g(new Response(c,t))},0)},C.onerror=function(){setTimeout(function(){b(TypeError(`Network request failed`))},0)},C.ontimeout=function(){setTimeout(function(){b(TypeError(`Network request timed out`))},0)},C.onabort=function(){setTimeout(function(){b(new c.DOMException(`Aborted`,`AbortError`))},0)};function fixUrl(t){try{return t===``&&u.location.href?u.location.href:t}catch{return t}}if(C.open(S.method,fixUrl(S.url),!0),S.credentials===`include`?C.withCredentials=!0:S.credentials===`omit`&&(C.withCredentials=!1),`responseType`in C&&(d.blob?C.responseType=`blob`:d.arrayBuffer&&(C.responseType=`arraybuffer`)),m&&typeof m.headers==`object`&&!(m.headers instanceof Headers||u.Headers&&m.headers instanceof u.Headers)){var w=[];Object.getOwnPropertyNames(m.headers).forEach(function(t){w.push(normalizeName(t)),C.setRequestHeader(t,normalizeValue(m.headers[t]))}),S.headers.forEach(function(t,c){w.indexOf(c)===-1&&C.setRequestHeader(c,t)})}else S.headers.forEach(function(t,c){C.setRequestHeader(c,t)});S.signal&&(S.signal.addEventListener(`abort`,abortXhr),C.onreadystatechange=function(){C.readyState===4&&S.signal.removeEventListener(`abort`,abortXhr)}),C.send(S._bodyInit===void 0?null:S._bodyInit)})}return fetch.polyfill=!0,u.fetch||(u.fetch=fetch,u.Headers=Headers,u.Request=Request,u.Response=Response),c.Headers=Headers,c.Request=Request,c.Response=Response,c.fetch=fetch,c})({})})(d),d.fetch.ponyfill=!0,delete d.fetch.polyfill;var m=u.fetch?u:d;t=m.fetch,t.default=m.fetch,t.fetch=m.fetch,t.Headers=m.Headers,t.Request=m.Request,t.Response=m.Response,c.exports=t})),require_browser=__commonJSMin$2(((t,c)=>{var u=c.exports={},d,m;function defaultSetTimout(){throw Error(`setTimeout has not been defined`)}function defaultClearTimeout(){throw Error(`clearTimeout has not been defined`)}(function(){try{d=typeof setTimeout==`function`?setTimeout:defaultSetTimout}catch{d=defaultSetTimout}try{m=typeof clearTimeout==`function`?clearTimeout:defaultClearTimeout}catch{m=defaultClearTimeout}})();function runTimeout(t){if(d===setTimeout)return setTimeout(t,0);if((d===defaultSetTimout||!d)&&setTimeout)return d=setTimeout,setTimeout(t,0);try{return d(t,0)}catch{try{return d.call(null,t,0)}catch{return d.call(this,t,0)}}}function runClearTimeout(t){if(m===clearTimeout)return clearTimeout(t);if((m===defaultClearTimeout||!m)&&clearTimeout)return m=clearTimeout,clearTimeout(t);try{return m(t)}catch{try{return m.call(null,t)}catch{return m.call(this,t)}}}var g=[],b=!1,S,C=-1;function cleanUpNextTick(){!b||!S||(b=!1,S.length?g=S.concat(g):C=-1,g.length&&drainQueue())}function drainQueue(){if(!b){var t=runTimeout(cleanUpNextTick);b=!0;for(var c=g.length;c;){for(S=g,g=[];++C<c;)S&&S[C].run();C=-1,c=g.length}S=null,b=!1,runClearTimeout(t)}}u.nextTick=function(t){var c=Array(arguments.length-1);if(arguments.length>1)for(var u=1;u<arguments.length;u++)c[u-1]=arguments[u];g.push(new Item(t,c)),g.length===1&&!b&&runTimeout(drainQueue)};function Item(t,c){this.fun=t,this.array=c}Item.prototype.run=function(){this.fun.apply(null,this.array)},u.title=`browser`,u.browser=!0,u.env={},u.argv=[],u.version=``,u.versions={};function noop(){}u.on=noop,u.addListener=noop,u.once=noop,u.off=noop,u.removeListener=noop,u.removeAllListeners=noop,u.emit=noop,u.prependListener=noop,u.prependOnceListener=noop,u.listeners=function(t){return[]},u.binding=function(t){throw Error(`process.binding is not supported`)},u.cwd=function(){return`/`},u.chdir=function(t){throw Error(`process.chdir is not supported`)},u.umask=function(){return 0}})),dist_exports=__exportAll$1({ContentNavigator:()=>ContentNavigator,CouchDBToStaticPacker:()=>CouchDBToStaticPacker,CourseLookup:()=>CourseLookup,DIVERSITY_FLOOR:()=>DIVERSITY_FLOOR,DIVERSITY_STRENGTH:()=>DIVERSITY_STRENGTH,DocType:()=>DocType,DocTypePrefixes:()=>DocTypePrefixes,ENV:()=>ENV,FileSystemError:()=>FileSystemError,GuestUsername:()=>GuestUsername,Loggable:()=>Loggable,NOT_SET:()=>NOT_SET,NavigatorRole:()=>NavigatorRole,NavigatorRoles:()=>NavigatorRoles,Navigators:()=>Navigators,QuotaRoundRobinMixer:()=>QuotaRoundRobinMixer,SessionController:()=>SessionController,StaticToCouchDBMigrator:()=>StaticToCouchDBMigrator,TagFilteredContentSource:()=>TagFilteredContentSource,_resetDataLayer:()=>_resetDataLayer,aggregateOutcomesForGradient:()=>aggregateOutcomesForGradient,areQuestionRecords:()=>areQuestionRecords,buildStrategyStateId:()=>buildStrategyStateId,captureMixerRun:()=>captureMixerRun,computeDeviation:()=>computeDeviation,computeEffectiveWeight:()=>computeEffectiveWeight,computeOutcomeSignal:()=>computeOutcomeSignal,computeSpread:()=>computeSpread,computeStrategyGradient:()=>computeStrategyGradient,createOrchestrationContext:()=>createOrchestrationContext,diversityRerank:()=>diversityRerank,docIsDeleted:()=>docIsDeleted,endSessionTracking:()=>endSessionTracking,ensureAppDataDirectory:()=>ensureAppDataDirectory,getActivePipeline:()=>getActivePipeline,getAppDataDirectory:()=>getAppDataDirectory,getCardHistoryID:()=>getCardHistoryID,getCardOrigin:()=>getCardOrigin,getDataLayer:()=>getDataLayer,getDbPath:()=>getDbPath,getDefaultLearnableWeight:()=>getDefaultLearnableWeight,getRegisteredNavigator:()=>getRegisteredNavigator,getRegisteredNavigatorNames:()=>getRegisteredNavigatorNames,getRegisteredNavigatorRole:()=>getRegisteredNavigatorRole,getStudySource:()=>getStudySource,hasRegisteredNavigator:()=>hasRegisteredNavigator,importParsedCards:()=>importParsedCards,initializeDataDirectory:()=>initializeDataDirectory,initializeDataLayer:()=>initializeDataLayer,initializeNavigatorRegistry:()=>initializeNavigatorRegistry,isDataShapeRegistered:()=>isDataShapeRegistered,isDataShapeSchemaAvailable:()=>isDataShapeSchemaAvailable,isFilter:()=>isFilter,isGenerator:()=>isGenerator,isQuestionRecord:()=>isQuestionRecord,isQuestionTypeRegistered:()=>isQuestionTypeRegistered,isReview:()=>isReview,log:()=>log,mixerDebugAPI:()=>mixerDebugAPI,mountMixerDebugger:()=>mountMixerDebugger,mountPipelineDebugger:()=>mountPipelineDebugger,mountSessionDebugger:()=>mountSessionDebugger,mountUserDBDebugger:()=>mountUserDBDebugger,newInterval:()=>newInterval,parseCardHistoryID:()=>parseCardHistoryID,pipelineDebugAPI:()=>pipelineDebugAPI,processCustomQuestionsData:()=>processCustomQuestionsData,recordCardPresentation:()=>recordCardPresentation,recordUserOutcome:()=>recordUserOutcome,registerBlanksCard:()=>registerBlanksCard,registerCustomQuestionTypes:()=>registerCustomQuestionTypes,registerDataShape:()=>registerDataShape,registerNavigator:()=>registerNavigator,registerQuestionType:()=>registerQuestionType,registerSeedData:()=>registerSeedData,removeCustomQuestionTypes:()=>removeCustomQuestionTypes,removeDataShape:()=>removeDataShape,removeQuestionType:()=>removeQuestionType,runPeriodUpdate:()=>runPeriodUpdate,scoreAccuracyInZone:()=>scoreAccuracyInZone,sessionDebugAPI:()=>sessionDebugAPI,snapshotQueues:()=>snapshotQueues,startSessionTracking:()=>startSessionTracking,updateLearningState:()=>updateLearningState,updateStrategyWeight:()=>updateStrategyWeight,userDBDebugAPI:()=>userDBDebugAPI,validateMigration:()=>validateMigration,validateProcessorConfig:()=>validateProcessorConfig,validateStaticCourse:()=>validateStaticCourse});function areQuestionRecords(t){return isQuestionRecord(t.records[0])}function isQuestionRecord(t){return t.userAnswer!==void 0}function getCardHistoryID(t,c){return`${DocTypePrefixes.CARDRECORD}-${t}-${c}`}function parseCardHistoryID(t){let c=t.split(`-`),u=``;if(u+=c.length===3?``:`
|
|
95
95
|
given ID has incorrect number of '-' characters`,u+=c[0]===DocTypePrefixes.CARDRECORD?``:`
|
|
96
96
|
given ID does not start with ${DocTypePrefixes.CARDRECORD}`,c.length===3&&c[0]===DocTypePrefixes.CARDRECORD)return{courseID:c[1],cardID:c[2]};throw Error(`parseCardHistory Error:`+u)}function docIsDeleted(t){return t?.error===`not_found`&&t?.reason===`deleted`}function getAppDataDirectory(){return ENV.LOCAL_STORAGE_PREFIX?import___vite_browser_external$1.join(import___vite_browser_external$2.homedir(),`.tuilder`,ENV.LOCAL_STORAGE_PREFIX):import___vite_browser_external$1.join(import___vite_browser_external$2.homedir(),`.tuilder`)}async function ensureAppDataDirectory(){let t=getAppDataDirectory();try{await import___vite_browser_external.promises.mkdir(t,{recursive:!0})}catch(c){if(c.code!==`EEXIST`)throw Error(`Failed to create app data directory ${t}: ${c.message}`)}return t}function getDbPath(t){return import___vite_browser_external$1.join(getAppDataDirectory(),t)}async function initializeDataDirectory(){await ensureAppDataDirectory(),logger.info(`PouchDB data directory initialized: ${getAppDataDirectory()}`)}function hexEncode(t){let c,u=``;for(let d=0;d<t.length;d++)c=t.charCodeAt(d).toString(16),u+=(`000`+c).slice(3);return u}function filterAllDocsByPrefix(t,c,u){let d={startkey:c,endkey:c+``,include_docs:!0};return u&&Object.assign(d,u),t.allDocs(d)}function getStartAndEndKeys(t){return{startkey:t,endkey:t+``}}function updateGuestAccountExpirationDate(t){let c=hooks.utc().add(2,`months`).toISOString(),u=`GuestAccountExpirationDate`;t.get(u).then(d=>t.put({_id:u,_rev:d._rev,date:c})).catch(()=>t.put({_id:u,date:c}))}function getLocalUserDB(t){let c=`userdb-${t}`;return typeof window>`u`?new pouchdb_setup_default(getDbPath(c),{}):new pouchdb_setup_default(c,{})}function scheduleCardReviewLocal(t,c){let u=hooks.utc();logger.info(`Scheduling for review in: ${c.time.diff(u,`h`)/24} days`),t.put({_id:DocTypePrefixes.SCHEDULED_CARD+c.time.format(REVIEW_TIME_FORMAT),cardId:c.card_id,reviewTime:c.time.toISOString(),courseId:c.course_id,scheduledAt:u.toISOString(),scheduledFor:c.scheduledFor,schedulingAgentId:c.schedulingAgentId})}async function removeScheduledCardReviewLocal(t,c){let u=await t.get(c);t.remove(u).then(t=>{t.ok&&log2(`Removed Review Doc: ${c}`)}).catch(t=>{log2(`Failed to remove Review Doc: ${c},
|
|
97
|
-
${JSON.stringify(t)}`)})}async function GET_CACHED(t,c){return CLIENT_CACHE[t]?CLIENT_CACHE[t]:(CLIENT_CACHE[t]=c?await c(t):await GET_ITEM(t),GET_CACHED(t))}async function GET_ITEM(t){throw Error(`No implementation found for GET_CACHED(${t})`)}async function addNote55(t,c,u,d,m,g,b,S=blankCourseElo()){let C=getCourseDB(t),w=prepareNote55(t,c,u,d,m,g,b),T=`${DocTypePrefixes.DISPLAYABLE_DATA}-${v4()}`,E=await C.put({...w,_id:T}),D=NameSpacer.getDataShapeString({course:c,dataShape:u.name});if(E.ok)try{await createCards(t,D,E.id,g,S,m)}catch(t){let c=`Unknown error`;c=t instanceof Error?t.message:t&&typeof t==`object`&&`reason`in t?t.reason:t&&typeof t==`object`&&`message`in t?t.message:String(t),logger.error(`[addNote55] Failed to create cards for note ${E.id}: ${c}`),E.cardCreationFailed=!0,E.cardCreationError=c}else logger.error(`[addNote55] Error adding note. Result: ${JSON.stringify(E)}`);return E}async function createCards(t,c,u,d,m=blankCourseElo(),g){let b=await getCredentialledCourseConfig(t),S=NameSpacer.getDataShapeDescriptor(c),C=[];for(let t of b.dataShapes)t.name===c&&(C=t.questionTypes);if(C.length===0){let t=`No questionViewTypes found for datashapeID: ${c} in course config. Cards cannot be created.`;throw logger.error(t),Error(t)}for(let c of C)await createCard(c,t,S,u,d,m,g)}async function createCard(t,c,u,d,m,g=blankCourseElo(),b){let S=NameSpacer.getQuestionDescriptor(t),C=await getCredentialledCourseConfig(c);for(let w of C.questionTypes)if(w.name===t)for(let t of w.viewList)await addCard(c,u.course,[d],NameSpacer.getViewString({course:S.course,questionType:S.questionType,view:t}),g,m,b)}async function addCard(t,c,u,d,m,g,b){let S=getCourseDB(t),C=`${DocTypePrefixes.CARD}-${v4()}`,w=await S.put({_id:C,course:c,id_displayable_data:u,id_view:d,docType:`CARD`,elo:m||toCourseElo(990+Math.round(20*Math.random())),author:b});for(let c of g)logger.info(`adding tag: ${c} to card ${w.id}`),await addTagToCard(t,w.id,c,b,!1);return w}async function getCredentialledCourseConfig(t){try{let c=await getCourseDB(t).get(`CourseConfig`);return c.courseID=t,logger.info(`Returning course config: ${JSON.stringify(c)}`),c}catch(c){throw logger.error(`Error fetching config for ${t}:`,c),c}}async function addTagToCard(t,c,u,d,m=!0){let g=getTagID(u),b=getCourseDB(t),S=new CourseDB(t,async()=>BaseUser.Dummy({setupRemoteDB:()=>null,startSync:()=>{},canCreateAccount:()=>!1,canAuthenticate:()=>!1,getCurrentUsername:async()=>`DummyUser`}));try{logger.info(`Applying tag ${u} to card ${t+`-`+c}...`);let d=await b.get(g);if(d.taggedCards.includes(c))throw new AlreadyTaggedErr(`Card ${c} is already tagged with ${u}`);if(d.taggedCards.push(c),m)try{let d=(await S.getCardEloData([c]))[0];d.tags[u]={count:0,score:d.global.score},await updateCardElo(t,c,d)}catch(t){logger.error(`Failed to update ELO data for card:`,c,t)}return b.put(d)}catch(g){if(g instanceof AlreadyTaggedErr)throw g;return await createTag(t,u,d),addTagToCard(t,c,u,d,m)}}async function updateCardElo(t,c,u){if(u){let d=getCourseDB(t),m=await d.get(c);return logger.debug(`Replacing ${JSON.stringify(m.elo)} with ${JSON.stringify(u)}`),m.elo=u,d.put(m)}}function getTagID(t){let c=`TAG`.valueOf()+`-`;return t.indexOf(c)===0?t:c+t}function getCourseDB(t){let c=`coursedb-${t}`;return new pouchdb_setup_default(ENV.COUCHDB_SERVER_PROTOCOL+`://`+ENV.COUCHDB_SERVER_URL+c,createPouchDBConfig())}function registerPipelineForDebug(t){_activePipeline=t}function clearRunHistory(){runHistory.length=0}function getOrigin(t){let c=t.provenance[0];if(!c)return`unknown`;let u=c.reason?.toLowerCase()||``,d=c.strategy?.toLowerCase()||``;return u.includes(`new card`)||d.includes(`elo`)?`new`:u.includes(`review`)||d.includes(`srs`)?`review`:`unknown`}function captureRun(t){let c={...t,runId:`run-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,timestamp:new Date};runHistory.unshift(c),runHistory.length>MAX_RUNS&&runHistory.pop()}function parseCardElo(t){let c=t.find(t=>t.strategy===`elo`);if(!c?.reason)return;let u=c.reason.match(/card:\s*(\d+)/);return u?parseInt(u[1],10):void 0}function buildRunReport(t,c,u,d,m,g,b,S,C,w){let T=new Set(S.map(t=>t.cardId)),toReport=t=>({cardId:t.cardId,courseId:t.courseId,origin:getOrigin(t),generator:t.provenance[0]?.strategyName||t.provenance[0]?.strategy,finalScore:t.score,cardElo:parseCardElo(t.provenance),provenance:t.provenance,tags:t.tags,selected:T.has(t.cardId)}),E=[],D=[],O=[],Or=0;for(let t of b)T.has(t.cardId)?E.push(toReport(t)):Or<DISCARDED_KEEP_TOP?(D.push(toReport(t)),Or++):O.push(t);let kr=[...E,...D],Ar;if(O.length>0){let t=1/0,c=-1/0,u=1/0,d=-1/0,m=!1;for(let g of O){g.score<t&&(t=g.score),g.score>c&&(c=g.score);let b=parseCardElo(g.provenance);b!==void 0&&(m=!0,b<u&&(u=b),b>d&&(d=b))}let g=m?`, ELO ${u}\u2013${d}`:``;Ar={count:O.length,scoreRange:[t,c],eloRange:m?[u,d]:void 0,note:`${O.length} additional candidate(s) scored below the top ${DISCARDED_KEEP_TOP} near-misses and were not retained (score ${t.toExponential(2)}\u2013${c.toExponential(2)}${g}). Likely ELO-window pull remnants filtered out by hierarchy/lesson/priority gates.`}}let jr=S.filter(t=>getOrigin(t)===`review`).length,Mr=S.filter(t=>getOrigin(t)===`new`).length;return{courseId:t,courseName:c,userElo:C,generatorName:u,generators:d,generatedCount:m,filters:g,hints:w,finalCount:S.length,reviewsSelected:jr,newSelected:Mr,cards:kr,discardedTail:Ar}}function formatProvenance(t){return t.map(t=>` ${t.action===`generated`?`🎲`:t.action===`boosted`?`⬆️`:t.action===`penalized`?`⬇️`:`➡️`} ${t.strategyName}: ${t.score.toFixed(3)} - ${t.reason}`).join(`
|
|
97
|
+
${JSON.stringify(t)}`)})}async function GET_CACHED(t,c){return CLIENT_CACHE[t]?CLIENT_CACHE[t]:(CLIENT_CACHE[t]=c?await c(t):await GET_ITEM(t),GET_CACHED(t))}async function GET_ITEM(t){throw Error(`No implementation found for GET_CACHED(${t})`)}async function addNote55(t,c,u,d,m,g,b,S=blankCourseElo()){let C=getCourseDB(t),w=prepareNote55(t,c,u,d,m,g,b),T=`${DocTypePrefixes.DISPLAYABLE_DATA}-${v4()}`,E=await C.put({...w,_id:T}),D=NameSpacer.getDataShapeString({course:c,dataShape:u.name});if(E.ok)try{await createCards(t,D,E.id,g,S,m)}catch(t){let c=`Unknown error`;c=t instanceof Error?t.message:t&&typeof t==`object`&&`reason`in t?t.reason:t&&typeof t==`object`&&`message`in t?t.message:String(t),logger.error(`[addNote55] Failed to create cards for note ${E.id}: ${c}`),E.cardCreationFailed=!0,E.cardCreationError=c}else logger.error(`[addNote55] Error adding note. Result: ${JSON.stringify(E)}`);return E}async function createCards(t,c,u,d,m=blankCourseElo(),g){let b=await getCredentialledCourseConfig(t),S=NameSpacer.getDataShapeDescriptor(c),C=[];for(let t of b.dataShapes)t.name===c&&(C=t.questionTypes);if(C.length===0){let t=`No questionViewTypes found for datashapeID: ${c} in course config. Cards cannot be created.`;throw logger.error(t),Error(t)}for(let c of C)await createCard(c,t,S,u,d,m,g)}async function createCard(t,c,u,d,m,g=blankCourseElo(),b){let S=NameSpacer.getQuestionDescriptor(t),C=await getCredentialledCourseConfig(c);for(let w of C.questionTypes)if(w.name===t)for(let t of w.viewList)await addCard(c,u.course,[d],NameSpacer.getViewString({course:S.course,questionType:S.questionType,view:t}),g,m,b)}async function addCard(t,c,u,d,m,g,b){let S=getCourseDB(t),C=`${DocTypePrefixes.CARD}-${v4()}`,w=await S.put({_id:C,course:c,id_displayable_data:u,id_view:d,docType:`CARD`,elo:m||toCourseElo(990+Math.round(20*Math.random())),author:b});for(let c of g)logger.info(`adding tag: ${c} to card ${w.id}`),await addTagToCard(t,w.id,c,b,!1);return w}async function getCredentialledCourseConfig(t){try{let c=await getCourseDB(t).get(`CourseConfig`);return c.courseID=t,logger.info(`Returning course config: ${JSON.stringify(c)}`),c}catch(c){throw logger.error(`Error fetching config for ${t}:`,c),c}}async function addTagToCard(t,c,u,d,m=!0){let g=getTagID(u),b=getCourseDB(t),S=new CourseDB(t,async()=>BaseUser.Dummy({setupRemoteDB:()=>null,startSync:()=>{},canCreateAccount:()=>!1,canAuthenticate:()=>!1,getCurrentUsername:async()=>`DummyUser`}));try{logger.info(`Applying tag ${u} to card ${t+`-`+c}...`);let d=await b.get(g);if(d.taggedCards.includes(c))throw new AlreadyTaggedErr(`Card ${c} is already tagged with ${u}`);if(d.taggedCards.push(c),m)try{let d=(await S.getCardEloData([c]))[0];d.tags[u]={count:0,score:d.global.score},await updateCardElo(t,c,d)}catch(t){logger.error(`Failed to update ELO data for card:`,c,t)}return b.put(d)}catch(g){if(g instanceof AlreadyTaggedErr)throw g;return await createTag(t,u,d),addTagToCard(t,c,u,d,m)}}async function updateCardElo(t,c,u){if(u){let d=getCourseDB(t),m=await d.get(c);return logger.debug(`Replacing ${JSON.stringify(m.elo)} with ${JSON.stringify(u)}`),m.elo=u,d.put(m)}}function getTagID(t){let c=`TAG`.valueOf()+`-`;return t.indexOf(c)===0?t:c+t}function getCourseDB(t){let c=`coursedb-${t}`;return new pouchdb_setup_default(ENV.COUCHDB_SERVER_PROTOCOL+`://`+ENV.COUCHDB_SERVER_URL+c,createPouchDBConfig())}function diversityRerank(t,c={}){let u=c.strength??DIVERSITY_STRENGTH,d=c.floor??DIVERSITY_FLOOR,m=t.length;if(m<=1)return t;let g=new Map;for(let c of t)for(let t of c.tags??[])g.set(t,(g.get(t)??0)+1);let b=new Map;for(let[t,c]of g)b.set(t,Math.log(m/c));let S=[...t],C=new Map,w=[],repetitionLoad=t=>{let c=0;for(let u of t.tags??[]){let t=C.get(u);t&&(c+=(b.get(u)??0)*t)}return c};for(;S.length>0;){let t=0,c=-1/0,m=1,g=0;for(let b=0;b<S.length;b++){let C=S[b],w=repetitionLoad(C),T=w>0?Math.max(d,1/(1+u*w)):1,E=C.score*T;E>c&&(c=E,t=b,m=T,g=w)}let[b]=S.splice(t,1);if(Number.isFinite(b.score)&&m<1){let t=b.score*m;w.push({...b,score:t,provenance:[...b.provenance,{strategy:STRATEGY,strategyId:STRATEGY_ID,strategyName:STRATEGY_NAME,action:`penalized`,score:t,reason:`repeated tags (load ${g.toFixed(2)}) \u2192 \xD7${m.toFixed(2)}`}]})}else w.push(b);for(let t of b.tags??[])C.set(t,(C.get(t)??0)+1)}return w}function registerPipelineForDebug(t){_activePipeline=t}function getActivePipeline(){return _activePipeline}function clearRunHistory(){runHistory.length=0}function getOrigin(t){let c=t.provenance[0];if(!c)return`unknown`;let u=c.reason?.toLowerCase()||``,d=c.strategy?.toLowerCase()||``;return u.includes(`new card`)||d.includes(`elo`)?`new`:u.includes(`review`)||d.includes(`srs`)?`review`:`unknown`}function captureRun(t){let c={...t,runId:`run-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,timestamp:new Date};runHistory.unshift(c),runHistory.length>MAX_RUNS&&runHistory.pop()}function parseCardElo(t){let c=t.find(t=>t.strategy===`elo`);if(!c?.reason)return;let u=c.reason.match(/card:\s*(\d+)/);return u?parseInt(u[1],10):void 0}function buildRunReport(t,c,u,d,m,g,b,S,C,w){let T=new Set(S.map(t=>t.cardId)),toReport=t=>({cardId:t.cardId,courseId:t.courseId,origin:getOrigin(t),generator:t.provenance[0]?.strategyName||t.provenance[0]?.strategy,finalScore:t.score,cardElo:parseCardElo(t.provenance),provenance:t.provenance,tags:t.tags,selected:T.has(t.cardId)}),E=[],D=[],O=[],Or=0;for(let t of b)T.has(t.cardId)?E.push(toReport(t)):Or<DISCARDED_KEEP_TOP?(D.push(toReport(t)),Or++):O.push(t);let kr=[...E,...D],Ar;if(O.length>0){let t=1/0,c=-1/0,u=1/0,d=-1/0,m=!1;for(let g of O){g.score<t&&(t=g.score),g.score>c&&(c=g.score);let b=parseCardElo(g.provenance);b!==void 0&&(m=!0,b<u&&(u=b),b>d&&(d=b))}let g=m?`, ELO ${u}\u2013${d}`:``;Ar={count:O.length,scoreRange:[t,c],eloRange:m?[u,d]:void 0,note:`${O.length} additional candidate(s) scored below the top ${DISCARDED_KEEP_TOP} near-misses and were not retained (score ${t.toExponential(2)}\u2013${c.toExponential(2)}${g}). Likely ELO-window pull remnants filtered out by hierarchy/lesson/priority gates.`}}let jr=S.filter(t=>getOrigin(t)===`review`).length,Mr=S.filter(t=>getOrigin(t)===`new`).length;return{courseId:t,courseName:c,userElo:C,generatorName:u,generators:d,generatedCount:m,filters:g,hints:w,finalCount:S.length,reviewsSelected:jr,newSelected:Mr,cards:kr,discardedTail:Ar}}function formatProvenance(t){return t.map(t=>` ${t.action===`generated`?`🎲`:t.action===`boosted`?`⬆️`:t.action===`penalized`?`⬇️`:`➡️`} ${t.strategyName}: ${t.score.toFixed(3)} - ${t.reason}`).join(`
|
|
98
98
|
`)}function printRunSummary(t){if(console.group(`\u{1F50D} Pipeline Run: ${t.courseId} (${t.courseName||`unnamed`})`),logger.info(`Run ID: ${t.runId}`),logger.info(`Time: ${t.timestamp.toISOString()}`),logger.info(`User ELO: ${t.userElo??`unknown`}`),logger.info(`Generator: ${t.generatorName} \u2192 ${t.generatedCount} candidates`),t.generators&&t.generators.length>0){console.group(`Generator breakdown:`);for(let c of t.generators)logger.info(` ${c.name}: ${c.cardCount} cards (${c.newCount} new, ${c.reviewCount} reviews, top: ${c.topScore.toFixed(2)})`);console.groupEnd()}if(t.filters.length>0){console.group(`Filter impact:`);for(let c of t.filters)logger.info(` ${c.name}: \u2191${c.boosted} \u2193${c.penalized} =${c.passed} \u2715${c.removed}`);console.groupEnd()}logger.info(`Result: ${t.finalCount} cards selected (${t.newSelected} new, ${t.reviewsSelected} reviews)`),console.groupEnd()}function escapeHtml(t){return t.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`)}function escapeAttr(t){return escapeHtml(t).replace(/"/g,`"`)}function copyTextToClipboard(t,c){let done=()=>{if(!c)return;let t=c.textContent??`Copy`;c.textContent=`Copied!`,c.classList.add(`copied`),setTimeout(()=>{c.textContent=t,c.classList.remove(`copied`)},1200)},fallback=()=>{let c=document.createElement(`textarea`);c.value=t,c.style.position=`fixed`,c.style.opacity=`0`,document.body.appendChild(c),c.select();try{document.execCommand(`copy`)}catch(t){logger.warn(`[Pipeline Debug] Copy failed: ${t}`)}document.body.removeChild(c),done()};navigator.clipboard?.writeText?navigator.clipboard.writeText(t).then(done).catch(fallback):fallback()}function renderUI(){if(!_uiContainer)return;let t=runHistory,c=_selectedRunIndex===null?null:t[_selectedRunIndex],u=`
|
|
99
99
|
#sk-pipeline-debugger {
|
|
100
100
|
position: fixed;
|
|
@@ -310,7 +310,7 @@ ${JSON.stringify(t)}`)})}async function GET_CACHED(t,c){return CLIENT_CACHE[t]?C
|
|
|
310
310
|
Generator: ${t.name}
|
|
311
311
|
Filters:${u}`)}function logTagHydration(t,c){let u=Array.from(c.values()).reduce((t,c)=>t+c.length,0),d=Array.from(c.values()).filter(t=>t.length>0).length;logger.debug(`[Pipeline] Tag hydration: ${t.length} cards, ${d} have tags (${u} total tags) - single batch query`)}function logExecutionSummary(t,c,u,d,m,g){let b=m.length>0?m.map(t=>t.toFixed(2)).join(`, `):`none`,S=``;g.length>0&&(S=`
|
|
312
312
|
Filter impact: ${g.map(t=>{let c=[];return t.boosted>0&&c.push(`+${t.boosted}`),t.penalized>0&&c.push(`-${t.penalized}`),t.passed>0&&c.push(`=${t.passed}`),`${t.name}: ${c.join(`/`)}`}).join(`, `)}`),logger.info(`[Pipeline] Execution: ${t} produced ${c} \u2192 ${u} filters \u2192 ${d} results (top scores: ${b})`+S+`
|
|
313
|
-
💡 Inspect: window.skuilder.pipeline`)}function logResultCards(t){if(!(!VERBOSE_RESULTS||t.length===0)){logger.info(`[Pipeline] Results (${t.length} cards):`);for(let c=0;c<t.length;c++){let u=t[c],d=u.tags?.slice(0,3).join(`, `)||``,m=u.provenance.filter(t=>t.strategy===`hierarchyDefinition`||t.strategy===`priorityDefinition`||t.strategy===`interferenceFilter`||t.strategy===`letterGating`||t.strategy===`ephemeralHint`).map(t=>{let c=t.action===`boosted`?`↑`:t.action===`penalized`?`↓`:`=`;return`${t.strategyName}${c}${t.score.toFixed(2)}`}).join(` | `);logger.info(`[Pipeline] ${String(c+1).padStart(2)}. ${u.score.toFixed(4)} ${u.cardId} [${d}]${m?` {${m}}`:``}`)}}}function logCardProvenance(t,c=3){let u=t.slice(0,c);logger.debug(`[Pipeline] Provenance for top ${u.length} cards:`);for(let t of u){logger.debug(`[Pipeline] ${t.cardId} (final score: ${t.score.toFixed(3)}):`);for(let c of t.provenance){let t=c.score.toFixed(3),u=c.action.padEnd(9);logger.debug(`[Pipeline] ${u} ${t} - ${c.strategyName}: ${c.reason}`)}}}function createDefaultEloStrategy(t){return{_id:`NAVIGATION_STRATEGY-ELO-default`,docType:`NAVIGATION_STRATEGY`,name:`ELO (default)`,description:`Default ELO-based navigation strategy for new cards`,implementingClass:`elo`,course:t,serializedData:``}}function createDefaultSrsStrategy(t){return{_id:`NAVIGATION_STRATEGY-SRS-default`,docType:`NAVIGATION_STRATEGY`,name:`SRS (default)`,description:`Default SRS-based navigation strategy for reviews`,implementingClass:`srs`,course:t,serializedData:``}}function createDefaultPipeline(t,c){let u=c.getCourseID(),d=new ELONavigator(t,c,createDefaultEloStrategy(u)),m=new SRSNavigator(t,c,createDefaultSrsStrategy(u)),g=new CompositeGenerator([d,m]),b=createEloDistanceFilter();return new Pipeline(g,[b],t,c)}function registerNavigator(t,c,u){navigatorRegistry.set(t,{constructor:c,role:u}),logger.debug(`[NavigatorRegistry] Registered: ${t}${u?` (${u})`:``}`)}function getRegisteredNavigator(t){return navigatorRegistry.get(t)?.constructor}function hasRegisteredNavigator(t){return navigatorRegistry.has(t)}function getRegisteredNavigatorRole(t){return navigatorRegistry.get(t)?.role}function getRegisteredNavigatorNames(){return Array.from(navigatorRegistry.keys())}async function initializeNavigatorRegistry(){logger.debug(`[NavigatorRegistry] Initializing built-in navigators...`);let[t,c]=await Promise.all([Promise.resolve().then(()=>(init_elo(),elo_exports)),Promise.resolve().then(()=>(init_srs(),srs_exports))]),u=await Promise.resolve().then(()=>(init_prescribed(),prescribed_exports));registerNavigator(`elo`,t.default),registerNavigator(`srs`,c.default),registerNavigator(`prescribed`,u.default);let[d,m,g,b]=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))]);registerNavigator(`hierarchyDefinition`,d.default),registerNavigator(`interferenceMitigator`,m.default),registerNavigator(`relativePriority`,g.default),registerNavigator(`userTagPreference`,b.default),logger.debug(`[NavigatorRegistry] Initialized ${navigatorRegistry.size} navigators: ${getRegisteredNavigatorNames().join(`, `)}`)}function getCardOrigin(t){if(t.provenance.length===0)throw Error(`Card has no provenance - cannot determine origin`);let c=t.provenance[0].reason.toLowerCase();return c.includes(`failed`)?`failed`:c.includes(`review`)?`review`:`new`}function isGenerator(t){return NavigatorRoles[t]===`generator`?!0:getRegisteredNavigatorRole(t)===`generator`}function isFilter(t){return NavigatorRoles[t]===`filter`?!0:getRegisteredNavigatorRole(t)===`filter`}function randIntWeightedTowardZero(t){return Math.floor(Math.random()*Math.random()*Math.random()*t)}async function getCourseTagStubs(t){logger.debug(`Getting tag stubs for course: ${t}`);let c=await filterAllDocsByPrefix2(getCourseDB2(t),`TAG`.valueOf()+`-`);return c.rows.forEach(t=>{logger.debug(` Tag stub for doc: ${t.id}`)}),c}async function createTag(t,c,u){logger.debug(`Creating tag: ${c}...`);let d=getTagID(c);return await getCourseDB2(t).put({course:t,docType:`TAG`,name:c,snippet:``,taggedCards:[],wiki:``,author:u,_id:d})}async function updateTag(t){let c=await getTag(t.course,t.name);return await getCourseDB2(t.course).put({...t,_rev:c._rev})}async function getTag(t,c){let u=getTagID(c);return getCourseDB2(t).get(u)}async function removeTagFromCard(t,c,u){u=getTagID(u);let d=getCourseDB2(t),m=await d.get(u);return m.taggedCards=m.taggedCards.filter(t=>c!==t),d.put(m)}async function getAppliedTags(t,c){return await getCourseDB2(t).query(`getTags`,{startkey:c,endkey:c})}async function updateCredentialledCourseConfig(t,c){logger.debug(`Updating course config:
|
|
313
|
+
💡 Inspect: window.skuilder.pipeline`)}function logResultCards(t){if(!(!VERBOSE_RESULTS||t.length===0)){logger.info(`[Pipeline] Results (${t.length} cards):`);for(let c=0;c<t.length;c++){let u=t[c],d=u.tags?.slice(0,3).join(`, `)||``,m=u.provenance.filter(t=>t.strategy===`hierarchyDefinition`||t.strategy===`priorityDefinition`||t.strategy===`interferenceFilter`||t.strategy===`letterGating`||t.strategy===`ephemeralHint`||t.strategy===`diversityRerank`).map(t=>{let c=t.action===`boosted`?`↑`:t.action===`penalized`?`↓`:`=`;return`${t.strategyName}${c}${t.score.toFixed(2)}`}).join(` | `);logger.info(`[Pipeline] ${String(c+1).padStart(2)}. ${u.score.toFixed(4)} ${u.cardId} [${d}]${m?` {${m}}`:``}`)}}}function logCardProvenance(t,c=3){let u=t.slice(0,c);logger.debug(`[Pipeline] Provenance for top ${u.length} cards:`);for(let t of u){logger.debug(`[Pipeline] ${t.cardId} (final score: ${t.score.toFixed(3)}):`);for(let c of t.provenance){let t=c.score.toFixed(3),u=c.action.padEnd(9);logger.debug(`[Pipeline] ${u} ${t} - ${c.strategyName}: ${c.reason}`)}}}function createDefaultEloStrategy(t){return{_id:`NAVIGATION_STRATEGY-ELO-default`,docType:`NAVIGATION_STRATEGY`,name:`ELO (default)`,description:`Default ELO-based navigation strategy for new cards`,implementingClass:`elo`,course:t,serializedData:``}}function createDefaultSrsStrategy(t){return{_id:`NAVIGATION_STRATEGY-SRS-default`,docType:`NAVIGATION_STRATEGY`,name:`SRS (default)`,description:`Default SRS-based navigation strategy for reviews`,implementingClass:`srs`,course:t,serializedData:``}}function createDefaultPipeline(t,c){let u=c.getCourseID(),d=new ELONavigator(t,c,createDefaultEloStrategy(u)),m=new SRSNavigator(t,c,createDefaultSrsStrategy(u)),g=new CompositeGenerator([d,m]),b=createEloDistanceFilter();return new Pipeline(g,[b],t,c)}function registerNavigator(t,c,u){navigatorRegistry.set(t,{constructor:c,role:u}),logger.debug(`[NavigatorRegistry] Registered: ${t}${u?` (${u})`:``}`)}function getRegisteredNavigator(t){return navigatorRegistry.get(t)?.constructor}function hasRegisteredNavigator(t){return navigatorRegistry.has(t)}function getRegisteredNavigatorRole(t){return navigatorRegistry.get(t)?.role}function getRegisteredNavigatorNames(){return Array.from(navigatorRegistry.keys())}async function initializeNavigatorRegistry(){logger.debug(`[NavigatorRegistry] Initializing built-in navigators...`);let[t,c]=await Promise.all([Promise.resolve().then(()=>(init_elo(),elo_exports)),Promise.resolve().then(()=>(init_srs(),srs_exports))]),u=await Promise.resolve().then(()=>(init_prescribed(),prescribed_exports));registerNavigator(`elo`,t.default),registerNavigator(`srs`,c.default),registerNavigator(`prescribed`,u.default);let[d,m,g,b]=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))]);registerNavigator(`hierarchyDefinition`,d.default),registerNavigator(`interferenceMitigator`,m.default),registerNavigator(`relativePriority`,g.default),registerNavigator(`userTagPreference`,b.default),logger.debug(`[NavigatorRegistry] Initialized ${navigatorRegistry.size} navigators: ${getRegisteredNavigatorNames().join(`, `)}`)}function getCardOrigin(t){if(t.provenance.length===0)throw Error(`Card has no provenance - cannot determine origin`);let c=t.provenance[0].reason.toLowerCase();return c.includes(`failed`)?`failed`:c.includes(`review`)?`review`:`new`}function isGenerator(t){return NavigatorRoles[t]===`generator`?!0:getRegisteredNavigatorRole(t)===`generator`}function isFilter(t){return NavigatorRoles[t]===`filter`?!0:getRegisteredNavigatorRole(t)===`filter`}function randIntWeightedTowardZero(t){return Math.floor(Math.random()*Math.random()*Math.random()*t)}async function getCourseTagStubs(t){logger.debug(`Getting tag stubs for course: ${t}`);let c=await filterAllDocsByPrefix2(getCourseDB2(t),`TAG`.valueOf()+`-`);return c.rows.forEach(t=>{logger.debug(` Tag stub for doc: ${t.id}`)}),c}async function createTag(t,c,u){logger.debug(`Creating tag: ${c}...`);let d=getTagID(c);return await getCourseDB2(t).put({course:t,docType:`TAG`,name:c,snippet:``,taggedCards:[],wiki:``,author:u,_id:d})}async function updateTag(t){let c=await getTag(t.course,t.name);return await getCourseDB2(t.course).put({...t,_rev:c._rev})}async function getTag(t,c){let u=getTagID(c);return getCourseDB2(t).get(u)}async function removeTagFromCard(t,c,u){u=getTagID(u);let d=getCourseDB2(t),m=await d.get(u);return m.taggedCards=m.taggedCards.filter(t=>c!==t),d.put(m)}async function getAppliedTags(t,c){return await getCourseDB2(t).query(`getTags`,{startkey:c,endkey:c})}async function updateCredentialledCourseConfig(t,c){logger.debug(`Updating course config:
|
|
314
314
|
|
|
315
315
|
${JSON.stringify(c)}
|
|
316
316
|
`);let u=getCourseDB2(t),d=await getCredentialledCourseConfig(t);return await u.put({...c,_rev:d._rev})}function isSuccessRow(t){return`doc`in t&&t.doc!==null&&t.doc!==void 0}async function getCurrentSession(){try{if(ENV.COUCHDB_SERVER_URL===NOT_SET||ENV.COUCHDB_SERVER_PROTOCOL===NOT_SET)throw Error(`CouchDB server configuration not properly initialized. Protocol: "${ENV.COUCHDB_SERVER_PROTOCOL}", URL: "${ENV.COUCHDB_SERVER_URL}"`);let t=ENV.COUCHDB_SERVER_URL.endsWith(`/`)?ENV.COUCHDB_SERVER_URL.slice(0,-1):ENV.COUCHDB_SERVER_URL,c=`${ENV.COUCHDB_SERVER_PROTOCOL}://${t}/_session`;logger.debug(`Attempting session check at: ${c}`);let u=await(0,import_browser_ponyfill.default)(c,{method:`GET`,credentials:`include`});if(!u.ok)throw Error(`Session check failed: ${u.status}`);return await u.json()}catch(t){let c=ENV.COUCHDB_SERVER_URL.endsWith(`/`)?ENV.COUCHDB_SERVER_URL.slice(0,-1):ENV.COUCHDB_SERVER_URL,u=`${ENV.COUCHDB_SERVER_PROTOCOL}://${c}/_session`;throw logger.error(`Session check error attempting to connect to: ${u} - ${t}`),Error(`Session check failed connecting to ${u}: ${t}`)}}async function getLoggedInUsername(){let t=await getCurrentSession();if(t.userCtx.name&&t.userCtx.name!==``)return t.userCtx.name;throw Error(`No logged in user`)}function createPouchDBConfig(){return ENV.COUCHDB_USERNAME&&ENV.COUCHDB_PASSWORD&&typeof window>`u`?{fetch(t,c={}){let u=btoa(`${ENV.COUCHDB_USERNAME}:${ENV.COUCHDB_PASSWORD}`),d=new Headers(c.headers||{});d.set(`Authorization`,`Basic ${u}`);let m={...c,headers:d};return pouchdb_setup_default.fetch(t,m)}}:pouchDBincludeCredentialsConfig}function getCourseDB2(t){return new pouchdb_setup_default(ENV.COUCHDB_SERVER_PROTOCOL+`://`+ENV.COUCHDB_SERVER_URL+`coursedb-`+t,createPouchDBConfig())}function filterAllDocsByPrefix2(t,c,u){let d={startkey:c,endkey:c+``,include_docs:!0};return u&&Object.assign(d,u),t.allDocs(d)}function getStartAndEndKeys2(t){return{startkey:t,endkey:t+``}}function accomodateGuest(){if(logger.log(`[funnel] accomodateGuest() called`),typeof localStorage>`u`)return logger.log(`[funnel] localStorage not available (Node.js environment), returning default guest`),{username:GuestUsername+`nodejs-test`,firstVisit:!0};let t=`sk-guest-uuid`,c,u=localStorage.getItem(t);if(logger.log(`[funnel] Checking localStorage for key:`,t),logger.log(`[funnel] Existing UUID value:`,u),logger.log(`[funnel] existingUUID !== null:`,u!==null),u!==null)c=!1,logger.log(`[funnel] Returning guest ${u} "logging in".`);else{c=!0,logger.log(`[funnel] No existing UUID, generating new one...`);let u=generateUUID();logger.log(`[funnel] Generated UUID:`,u),logger.log(`[funnel] UUID length:`,u.length);try{localStorage.setItem(t,u),logger.log(`[funnel] Successfully stored UUID in localStorage`);let c=localStorage.getItem(t);logger.log(`[funnel] Verification read from localStorage:`,c)}catch(t){logger.error(`[funnel] ERROR storing UUID:`,t)}logger.log(`[funnel] Accommodating a new guest with account: ${u}`)}let d=localStorage.getItem(t),m=GuestUsername+d;return logger.log(`[funnel] Final UUID from localStorage:`,d),logger.log(`[funnel] GuestUsername constant:`,GuestUsername),logger.log(`[funnel] Final username to return:`,m),{username:m,firstVisit:c};function generateUUID(){if(logger.log(`[funnel] Inside generateUUID()`),typeof crypto<`u`&&typeof crypto.randomUUID==`function`){let t=crypto.randomUUID();return logger.log(`[funnel] Generated UUID using crypto.randomUUID():`,t),t}if(typeof crypto<`u`&&typeof crypto.getRandomValues==`function`){let t=new Uint8Array(16);crypto.getRandomValues(t),t[6]=t[6]&15|64,t[8]=t[8]&63|128;let c=[Array.from(t.slice(0,4)).map(t=>t.toString(16).padStart(2,`0`)).join(``),Array.from(t.slice(4,6)).map(t=>t.toString(16).padStart(2,`0`)).join(``),Array.from(t.slice(6,8)).map(t=>t.toString(16).padStart(2,`0`)).join(``),Array.from(t.slice(8,10)).map(t=>t.toString(16).padStart(2,`0`)).join(``),Array.from(t.slice(10,16)).map(t=>t.toString(16).padStart(2,`0`)).join(``)].join(`-`);return logger.log(`[funnel] Generated UUID using crypto.getRandomValues():`,c),c}logger.warn(`[funnel] crypto API not available, using timestamp-based UUID (NOT SECURE)`);let t=new Date().getTime();typeof performance<`u`&&typeof performance.now==`function`&&(t+=performance.now());let c=`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`.replace(/[xy]/g,c=>{let u=(t+Math.random()*16)%16|0;return t=Math.floor(t/16),(c===`x`?u:u&3|8).toString(16)});return logger.log(`[funnel] Generated UUID (fallback):`,c),c}}async function getOrCreateClassroomRegistrationsDoc(t){let c;try{c=await getLocalUserDB(t).get(userClassroomsDoc)}catch(u){let d=u;if(d.status===404)await getLocalUserDB(t).put({_id:userClassroomsDoc,registrations:[]}),c=await getOrCreateClassroomRegistrationsDoc(t);else{let t={name:d.name,status:d.status,message:d.message,reason:d.reason,error:d.error};throw logger.error(`Database error in getOrCreateClassroomRegistrationsDoc (standalone function):`,t),Error(`Database error accessing classroom registrations: ${d.message||d.name||`Unknown error`} (status: ${d.status})`)}}return c}async function getOrCreateCourseRegistrationsDoc(t){let c;try{c=await getLocalUserDB(t).get(userCoursesDoc)}catch(u){if(u.status===404)await getLocalUserDB(t).put({_id:userCoursesDoc,courses:[],studyWeight:{}}),c=await getOrCreateCourseRegistrationsDoc(t);else throw Error(`Unexpected error ${JSON.stringify(u)} in getOrCreateCourseRegistrationDoc...`)}return c}async function updateUserElo(t,c,u){let d=await getOrCreateCourseRegistrationsDoc(t),m=d.courses.find(t=>t.courseID===c);return m.elo=u,getLocalUserDB(t).put(d)}async function registerUserForClassroom(t,c,u){return log4(`Registering user: ${t} in course: ${c}`),getOrCreateClassroomRegistrationsDoc(t).then(d=>{let m={classID:c,registeredAs:u};return d.registrations.filter(t=>t.classID===m.classID&&t.registeredAs===m.registeredAs).length===0?d.registrations.push(m):log4(`User ${t} is already registered for class ${c}`),getLocalUserDB(t).put(d)})}async function dropUserFromClassroom(t,c){return getOrCreateClassroomRegistrationsDoc(t).then(u=>{let d=-1;for(let t=0;t<u.registrations.length;t++)u.registrations[t].classID===c&&(d=t);return d!==-1&&u.registrations.splice(d,1),getLocalUserDB(t).put(u)})}async function getUserClassrooms(t){return getOrCreateClassroomRegistrationsDoc(t)}async function initializeDataLayer(t){if(dataLayerInstance)return logger.warn(`Data layer already initialized. Returning existing instance.`),dataLayerInstance;if(await initializeNavigatorRegistry(),t.options.localStoragePrefix&&(ENV.LOCAL_STORAGE_PREFIX=t.options.localStoragePrefix),t.type===`couch`){if(!t.options.COUCHDB_SERVER_URL||!t.options.COUCHDB_SERVER_PROTOCOL)throw Error(`Missing CouchDB server URL or protocol`);if(ENV.COUCHDB_SERVER_PROTOCOL=t.options.COUCHDB_SERVER_PROTOCOL,ENV.COUCHDB_SERVER_URL=t.options.COUCHDB_SERVER_URL,ENV.COUCHDB_USERNAME=t.options.COUCHDB_USERNAME,ENV.COUCHDB_PASSWORD=t.options.COUCHDB_PASSWORD,t.options.courseSync){let{CourseSyncService:c}=await Promise.resolve().then(()=>(init_CourseSyncService(),CourseSyncService_exports));c.getInstance().configure(t.options.courseSync)}if(t.options.COUCHDB_PASSWORD&&t.options.COUCHDB_USERNAME&&typeof window<`u`){let{CouchDBSyncStrategy:c}=await Promise.resolve().then(()=>(init_CouchDBSyncStrategy(),CouchDBSyncStrategy_exports)),u=new c,d=await(await BaseUser.instance(u,t.options.COUCHDB_USERNAME)).login(t.options.COUCHDB_USERNAME,t.options.COUCHDB_PASSWORD);d.ok?logger.info(`Successfully authenticated as ${t.options.COUCHDB_USERNAME}`):logger.warn(`Authentication failed: ${d.error}`)}let{CouchDataLayerProvider:c}=await Promise.resolve().then(()=>(init_PouchDataLayerProvider(),PouchDataLayerProvider_exports));dataLayerInstance=new c(t.options.COURSE_IDS)}else if(t.type===`static`){let{StaticDataLayerProvider:c}=await Promise.resolve().then(()=>(init_StaticDataLayerProvider(),StaticDataLayerProvider_exports));dataLayerInstance=new c(t.options)}else throw Error(`Unknown data layer type: ${t.type}`);return await dataLayerInstance.initialize(),dataLayerInstance}function getDataLayer(){if(!dataLayerInstance)throw Error(`Data layer not initialized. Call initializeDataLayer first.`);return dataLayerInstance}async function _resetDataLayer(){dataLayerInstance&&await dataLayerInstance.teardown(),dataLayerInstance=null}function isReview(t){return t.status===`review`||t.status===`failed-review`||`reviewID`in t}async function getStudySource(t,c){return t.type===`classroom`?await StudentClassroomDB.factory(t.id,c):hasActiveFilter(t.tagFilter)?new TagFilteredContentSource(t.id,t.tagFilter,c):getDataLayer().getCourseDB(t.id)}function buildStrategyStateId(t,c){return`STRATEGY_STATE::${t}::${c}`}async function importParsedCards(t,c,u){let d=[];for(let m of t)try{let t=await processCard(m,c,u);d.push(t)}catch(t){logger.error(`Error processing card:`,t);let c=m.markdown;m.tags&&m.tags.length>0&&(c+=`
|
|
@@ -324,7 +324,7 @@ ${t}`)}function headerHtml(){let t=Date.now()<copyFlashUntil;return`<div style="
|
|
|
324
324
|
`)}function formatTime(t){let c=Math.max(0,Math.round(t));return`${Math.floor(c/60)}:${(c%60).toString().padStart(2,`0`)}`}function esc(t){return t.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`)}function startSessionTracking(t,c,u){clearRunHistory();let d=`session-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;activeSession={sessionId:d,startTime:new Date,initialQueues:{timestamp:new Date,reviewQLength:t,newQLength:c,failedQLength:u},presentations:[],queueSnapshots:[]},logger.debug(`[SessionDebugger] Started tracking session: ${d}`)}function recordCardPresentation(t,c,u,d,m,g){if(!activeSession){logger.warn(`[SessionDebugger] No active session to record presentation`);return}activeSession.presentations.push({timestamp:new Date,sequenceNumber:activeSession.presentations.length+1,cardId:t,courseId:c,courseName:u,origin:d,queueSource:m,score:g})}function snapshotQueues(t,c,u,d,m){activeSession&&activeSession.queueSnapshots.push({timestamp:new Date,reviewQLength:t,newQLength:c,failedQLength:u,reviewQNext3:d,newQNext3:m})}function endSessionTracking(){activeSession&&(activeSession.endTime=new Date,sessionHistory.unshift(activeSession),sessionHistory.length>MAX_HISTORY&&sessionHistory.pop(),logger.debug(`[SessionDebugger] Ended session: ${activeSession.sessionId}`),activeSession=null)}function showCurrentQueue(){if(!activeSession){logger.info(`[Session Debug] No active session.`);return}let t=activeSession.queueSnapshots[activeSession.queueSnapshots.length-1]||activeSession.initialQueues;console.group(`📊 Current Queue State`),logger.info(`Review Queue: ${t.reviewQLength} cards`),t.reviewQNext3&&t.reviewQNext3.length>0&&logger.info(` Next: ${t.reviewQNext3.join(`, `)}`),logger.info(`New Queue: ${t.newQLength} cards`),t.newQNext3&&t.newQNext3.length>0&&logger.info(` Next: ${t.newQNext3.join(`, `)}`),logger.info(`Failed Queue: ${t.failedQLength} cards`),console.groupEnd()}function showPresentationHistory(t=0){let c=t===0&&activeSession?activeSession:sessionHistory[t];if(!c){logger.info(`[Session Debug] No session found at index ${t}`);return}console.group(`\u{1F4DC} Session History: ${c.sessionId}`),logger.info(`Started: ${c.startTime.toLocaleTimeString()}`),c.endTime&&logger.info(`Ended: ${c.endTime.toLocaleTimeString()}`),logger.info(`Cards presented: ${c.presentations.length}`),c.presentations.length>0&&console.table(c.presentations.map(t=>({"#":t.sequenceNumber,course:t.courseName||t.courseId.slice(0,8),origin:t.origin,queue:t.queueSource,score:t.score?.toFixed(3)||`-`,time:t.timestamp.toLocaleTimeString()}))),console.groupEnd()}function showInterleaving(t=0){let c=t===0&&activeSession?activeSession:sessionHistory[t];if(!c){logger.info(`[Session Debug] No session found at index ${t}`);return}console.group(`🔀 Interleaving Analysis`);let u=new Map,d=new Map;if(c.presentations.forEach(t=>{let c=t.courseName||t.courseId;u.set(c,(u.get(c)||0)+1),d.has(c)||d.set(c,{review:0,new:0,failed:0});let m=d.get(c);m[t.origin]++}),logger.info(`Course distribution:`),console.table(Array.from(u.entries()).map(([t,u])=>{let m=d.get(t);return{course:t,total:u,reviews:m.review,new:m.new,failed:m.failed,percentage:(u/c.presentations.length*100).toFixed(1)+`%`}})),c.presentations.length>0){logger.info(`
|
|
325
325
|
Presentation sequence (first 20):`);let t=c.presentations.slice(0,20).map((t,c)=>`${c+1}. ${t.courseName||t.courseId.slice(0,8)} (${t.origin})`).join(`
|
|
326
326
|
`);logger.info(t)}let m=0,g=1,b=c.presentations[0]?.courseId;for(let t=1;t<c.presentations.length;t++)c.presentations[t].courseId===b?(g++,m=Math.max(m,g)):(b=c.presentations[t].courseId,g=1);m>3&&(logger.info(`
|
|
327
|
-
\u26A0\uFE0F Detected clustering: max ${m} cards from same course in a row`),logger.info(`This suggests cards are sorted by score rather than round-robin by course.`)),console.groupEnd()}function mountSessionDebugger(){if(typeof window>`u`)return;let t=window;t.skuilder=t.skuilder||{},t.skuilder.session=sessionDebugAPI}var import___vite_browser_external,import___vite_browser_external$1,import___vite_browser_external$2,import_browser_ponyfill,import_browser_ponyfill$1,import_browser,_SessionController2,__defProp,__getOwnPropNames,__glob,__esm,__export,init_adminDB,init_classroomDB,init_SyncStrategy,isDevelopment,logger,init_logger,GuestUsername,log,DocType,DocTypePrefixes,init_types_legacy,init_util,pouchdb_setup_default,init_pouchdb_setup,init_dataDirectory,REVIEW_TIME_FORMAT,log2,init_userDBHelpers,Loggable,init_Loggable,UpdateQueue,init_updateQueue,UsrCrsData,init_user_course_relDB,CLIENT_CACHE,init_clientCache,AlreadyTaggedErr,init_courseAPI,courseLookupDBTitle,CourseLookup,init_courseLookupDB,PipelineDebugger_exports,_activePipeline,MAX_RUNS,runHistory,DISCARDED_KEEP_TOP,_uiContainer,_selectedRunIndex,_cardSearchQuery,pipelineDebugAPI,init_PipelineDebugger,CompositeGenerator_exports,AggregationMode,DEFAULT_AGGREGATION_MODE,FREQUENCY_BOOST_FACTOR,CompositeGenerator,init_CompositeGenerator,elo_exports,ELO_RELEVANCE_SIGMA,ELONavigator,init_elo,generators_exports,init_generators,prescribed_exports,DEFAULT_FRESHNESS_WINDOW,DEFAULT_MAX_DIRECT_PER_RUN,DEFAULT_MAX_SUPPORT_PER_RUN,DEFAULT_HIERARCHY_DEPTH,DEFAULT_MIN_COUNT,BASE_TARGET_SCORE,BASE_SUPPORT_SCORE,DISCOVERED_SUPPORT_SCORE,MAX_TARGET_MULTIPLIER,MAX_SUPPORT_MULTIPLIER,PRESCRIBED_DEBUG_VERSION,PrescribedCardsGenerator,init_prescribed,srs_exports,DEFAULT_HEALTHY_BACKLOG,MAX_BACKLOG_PRESSURE,SRSNavigator,init_srs,types_exports,init_types,globImport_generators,init_,DEFAULT_LEARNABLE_WEIGHT,init_contentNavigationStrategy,WeightedFilter_exports,WeightedFilter,init_WeightedFilter,eloDistance_exports,DEFAULT_HALF_LIFE,DEFAULT_MIN_MULTIPLIER,DEFAULT_MAX_MULTIPLIER,init_eloDistance,hierarchyDefinition_exports,DEFAULT_MIN_COUNT2,HierarchyDefinitionNavigator,init_hierarchyDefinition,userTagPreference_exports,UserTagPreferenceFilter,init_userTagPreference,filters_exports,init_filters,inferredPreferenceStub_exports,INFERRED_PREFERENCE_NAVIGATOR_STUB,init_inferredPreferenceStub,interferenceMitigator_exports,DEFAULT_MIN_COUNT3,DEFAULT_MIN_ELAPSED_DAYS,DEFAULT_INTERFERENCE_DECAY,InterferenceMitigatorNavigator,init_interferenceMitigator,relativePriority_exports,DEFAULT_PRIORITY,DEFAULT_PRIORITY_INFLUENCE,DEFAULT_COMBINE_MODE,RelativePriorityNavigator,init_relativePriority,types_exports2,init_types2,userGoalStub_exports,USER_GOAL_NAVIGATOR_STUB,init_userGoalStub,globImport_filters,init_2,init_gradient,MIN_OBSERVATIONS_FOR_UPDATE,LEARNING_RATE,MAX_WEIGHT_DELTA,MIN_R_SQUARED_FOR_GRADIENT,FLAT_GRADIENT_THRESHOLD,MAX_HISTORY_LENGTH,init_learning,init_signal,init_recording,MIN_SPREAD,MAX_SPREAD,MIN_WEIGHT,MAX_WEIGHT,init_orchestration,Pipeline_exports,VERBOSE_RESULTS,Pipeline,init_Pipeline,defaults_exports,init_defaults,PipelineAssembler_exports,PipelineAssembler,init_PipelineAssembler,globImport,init_3,navigators_exports,navigatorRegistry,Navigators,NavigatorRole,NavigatorRoles,ContentNavigator,init_navigators,CoursesDB,CourseDB,init_courseDB,classroomLookupDBTitle,CLASSROOM_CONFIG,ClassroomDBBase,StudentClassroomDB,TeacherClassroomDB,ClassroomLookupDB,init_classroomDB2,AdminDB,init_adminDB2,CourseSyncService_exports,DEFAULT_REPLICATION,CourseSyncService,init_CourseSyncService,init_auth,CouchDBSyncStrategy_exports,log3,CouchDBSyncStrategy,init_CouchDBSyncStrategy,isBrowser,GUEST_LOCAL_DB,localUserDB,pouchDBincludeCredentialsConfig,REVIEW_TIME_FORMAT2,init_couch,log4,BaseUser,userCoursesDoc,userClassroomsDoc,init_BaseUserDB,init_common,PouchDataLayerProvider_exports,CouchDataLayerProvider,init_PouchDataLayerProvider,pathUtils,nodeFS,StaticDataUnpacker,init_StaticDataUnpacker,StaticCourseDB,init_courseDB2,StaticCoursesDB,init_coursesDB,NoOpSyncStrategy,init_NoOpSyncStrategy,StaticDataLayerProvider_exports,StaticDataLayerProvider,init_StaticDataLayerProvider,NOT_SET,ENV,dataLayerInstance,init_factory,TagFilteredContentSource,init_TagFilteredContentSource,init_contentSource,init_courseDB3,init_dataLayerProvider,init_userDB,init_interfaces,init_user,init_strategyState,init_userOutcome,init_cardProcessor,init_types3,init_bulkImport,userDBDebugAPI,init_UserDBDebugger,init_core,duration,SrsService,EloService,ResponseProcessor,CardHydrationService,ItemQueue,CouchDBToStaticPacker,DEFAULT_MIGRATION_OPTIONS,FileSystemError,nodeFS2,nodeFS3,nodePath,StaticToCouchDBMigrator,QuotaRoundRobinMixer,MAX_RUNS2,runHistory2,mixerDebugAPI,activeController,OVERLAY_ID,POLL_MS,INLINE_THRESHOLD,SPINNER_FRAMES,spinnerFrame,overlayEl,pollHandle,lastSnapshot,copyFlashUntil,minified,expanded,activeSession,sessionHistory,MAX_HISTORY,sessionDebugAPI,SessionController,init_dist=__esmMin((()=>{init_defineProperty(),init_index_browser_es$5(),init_index_browser_es(),init_index_es(),import___vite_browser_external=__toESM$2(require___vite_browser_external(),1),import___vite_browser_external$1=__toESM$2(require___vite_browser_external(),1),import___vite_browser_external$2=__toESM$2(require___vite_browser_external(),1),init_moment(),init_dist$1(),init_esm_browser(),import_browser_ponyfill=__toESM$2(require_browser_ponyfill(),1),import_browser_ponyfill$1=__toESM$2(require_browser_ponyfill(),1),import_browser=__toESM$2(require_browser(),1),__defProp=Object.defineProperty,__getOwnPropNames=Object.getOwnPropertyNames,__glob=t=>c=>{var u=t[c];if(u)return u();throw Error(`Module not found in bundle: `+c)},__esm=(t,c)=>function __init(){return t&&(c=(0,t[__getOwnPropNames(t)[0]])(t=0)),c},__export=(t,c)=>{for(var u in c)__defProp(t,u,{get:c[u],enumerable:!0})},init_adminDB=__esm({"src/core/interfaces/adminDB.ts"(){"use strict";}}),init_classroomDB=__esm({"src/core/interfaces/classroomDB.ts"(){"use strict";}}),init_SyncStrategy=__esm({"src/impl/common/SyncStrategy.ts"(){"use strict";}}),init_logger=__esm({"src/util/logger.ts"(){"use strict";isDevelopment=typeof process<`u`&&process.env.NODE_ENV===`development`,logger={debug:(t,...c)=>{isDevelopment&&console.debug(`[DB:DEBUG] ${t}`,...c)},info:(t,...c)=>{console.info(`[DB:INFO] ${t}`,...c)},warn:(t,...c)=>{console.warn(`[DB:WARN] ${t}`,...c)},error:(t,...c)=>{console.error(`[DB:ERROR] ${t}`,...c)},log:(t,...c)=>{isDevelopment&&console.log(`[DB:LOG] ${t}`,...c)}}}}),init_types_legacy=__esm({"src/core/types/types-legacy.ts"(){"use strict";init_logger(),GuestUsername=`sk-guest-`,log=t=>{logger.log(t)},DocType=(t=>(t.DISPLAYABLE_DATA=`DISPLAYABLE_DATA`,t.CARD=`CARD`,t.DATASHAPE=`DATASHAPE`,t.QUESTIONTYPE=`QUESTION`,t.VIEW=`VIEW`,t.PEDAGOGY=`PEDAGOGY`,t.CARDRECORD=`CARDRECORD`,t.SCHEDULED_CARD=`SCHEDULED_CARD`,t.TAG=`TAG`,t.NAVIGATION_STRATEGY=`NAVIGATION_STRATEGY`,t.STRATEGY_STATE=`STRATEGY_STATE`,t.USER_OUTCOME=`USER_OUTCOME`,t.STRATEGY_LEARNING_STATE=`STRATEGY_LEARNING_STATE`,t))(DocType||{}),DocTypePrefixes={CARD:`c`,DISPLAYABLE_DATA:`dd`,TAG:`TAG`,CARDRECORD:`cardH`,SCHEDULED_CARD:`card_review_`,DATASHAPE:`DATASHAPE`,QUESTION:`QUESTION`,VIEW:`VIEW`,PEDAGOGY:`PEDAGOGY`,NAVIGATION_STRATEGY:`NAVIGATION_STRATEGY`,STRATEGY_STATE:`STRATEGY_STATE`,USER_OUTCOME:`USER_OUTCOME`,STRATEGY_LEARNING_STATE:`STRATEGY_LEARNING_STATE`}}}),init_util=__esm({"src/core/util/index.ts"(){"use strict";init_types_legacy()}}),init_pouchdb_setup=__esm({"src/impl/couch/pouchdb-setup.ts"(){"use strict";PouchDB.plugin(plugin$1),PouchDB.plugin(plugin),PouchDB.debug!==void 0&&PouchDB.debug.disable(),PouchDB.defaults({}),pouchdb_setup_default=PouchDB}}),init_dataDirectory=__esm({"src/util/dataDirectory.ts"(){"use strict";init_logger(),init_factory()}}),init_userDBHelpers=__esm({"src/impl/common/userDBHelpers.ts"(){"use strict";init_core(),init_logger(),init_pouchdb_setup(),init_dataDirectory(),REVIEW_TIME_FORMAT=`YYYY-MM-DD--kk:mm:ss-SSS`,log2=t=>{logger.info(t)}}}),init_Loggable=__esm({"src/util/Loggable.ts"(){"use strict";Loggable=class{log(...t){console.log(`LOG-${this._className}@${new Date}:`,...t)}error(...t){console.error(`ERROR-${this._className}@${new Date}:`,...t)}}}}),init_updateQueue=__esm({"src/impl/couch/updateQueue.ts"(){"use strict";init_Loggable(),init_logger(),UpdateQueue=class extends Loggable{update(t,c){return logger.debug(`Update requested on doc: ${t}`),this.pendingUpdates[t]?this.pendingUpdates[t].push(c):this.pendingUpdates[t]=[c],this.applyUpdates(t)}constructor(t,c){super(),_defineProperty$2(this,`_className`,`UpdateQueue`),_defineProperty$2(this,`pendingUpdates`,{}),_defineProperty$2(this,`inprogressUpdates`,{}),_defineProperty$2(this,`readDB`,void 0),_defineProperty$2(this,`writeDB`,void 0),this.readDB=t,this.writeDB=c||t,logger.debug(`UpdateQ initialized...`),this.readDB.info().then(t=>{logger.debug(`db info: ${JSON.stringify(t)}`)})}async applyUpdates(t){if(logger.debug(`Applying updates on doc: ${t}`),this.inprogressUpdates[t]){for(;this.inprogressUpdates[t];)await new Promise(t=>setTimeout(t,Math.random()*50));return this.applyUpdates(t)}else if(this.pendingUpdates[t]&&this.pendingUpdates[t].length>0){this.inprogressUpdates[t]=!0;let c=5;for(let c=0;c<5;c++)try{let c={...await this.readDB.get(t)},u=[...this.pendingUpdates[t]];for(let t of u)c=typeof t==`function`?{...c,...t(c)}:{...c,...t};if(await this.writeDB.put(c),this.pendingUpdates[t].splice(0,u.length),this.pendingUpdates[t].length===0)this.inprogressUpdates[t]=!1,delete this.inprogressUpdates[t];else return this.applyUpdates(t);return c}catch(u){if(u.name===`conflict`&&c<4)logger.warn(`Conflict on update for doc ${t}, retry #${c+1}`),await new Promise(t=>setTimeout(t,50*Math.random()));else if(u.name===`not_found`&&c===0)throw logger.warn(`Update failed for ${t} - does not exist. Throwing to caller.`),delete this.inprogressUpdates[t],u;else throw delete this.inprogressUpdates[t],this.pendingUpdates[t]&&delete this.pendingUpdates[t],logger.error(`Error on attemped update (retry ${c}): ${JSON.stringify(u)}`),u}throw Error(`UpdateQueue failed for doc ${t} after 5 retries.`)}else throw Error(`Empty Updates Queue Triggered`)}}}}),init_user_course_relDB=__esm({"src/impl/couch/user-course-relDB.ts"(){"use strict";init_logger(),UsrCrsData=class{constructor(t,c){_defineProperty$2(this,`user`,void 0),_defineProperty$2(this,`_courseId`,void 0),this.user=t,this._courseId=c}async getReviewsForcast(t){let c=hooks.utc().add(t,`days`);return this.getReviewstoDate(c)}async getPendingReviews(){let t=hooks.utc();return this.getReviewstoDate(t)}async getScheduledReviewCount(){return(await this.getPendingReviews()).length}async getCourseSettings(){let t=(await this.user.getCourseRegistrationsDoc()).courses.find(t=>t.courseID===this._courseId);return t&&t.settings?t.settings:(logger.warn(`no settings found during lookup on course ${this._courseId}`),{})}updateCourseSettings(t){`updateCourseSettings`in this.user&&this.user.updateCourseSettings(this._courseId,t)}async getStrategyState(t){return this.user.getStrategyState(this._courseId,t)}async putStrategyState(t,c){return this.user.putStrategyState(this._courseId,t,c)}async deleteStrategyState(t){return this.user.deleteStrategyState(this._courseId,t)}async getReviewstoDate(t){let c=await this.user.getPendingReviews(this._courseId);return logger.debug(`Fetching ${this.user.getUsername()}'s scheduled reviews for course ${this._courseId}.`),c.filter(c=>{let u=hooks.utc(c.reviewTime);return t.isAfter(u)})}}}}),init_clientCache=__esm({"src/impl/couch/clientCache.ts"(){"use strict";CLIENT_CACHE={}}}),init_courseAPI=__esm({"src/impl/couch/courseAPI.ts"(){"use strict";init_pouchdb_setup(),init_couch(),init_factory(),init_courseDB(),init_types_legacy(),init_common(),init_logger(),AlreadyTaggedErr=class extends Error{constructor(t){super(t),this.name=`AlreadyTaggedErr`}}}}),init_courseLookupDB=__esm({"src/impl/couch/courseLookupDB.ts"(){"use strict";var t;init_pouchdb_setup(),init_factory(),init_logger(),courseLookupDBTitle=`coursedb-lookup`,logger.debug(`COURSELOOKUP FILE RUNNING`),CourseLookup=(t=class _CourseLookup{static get _db(){if(this._dbInstance)return this._dbInstance;if(ENV.COUCHDB_SERVER_URL===`NOT_SET`||!ENV.COUCHDB_SERVER_URL)throw Error(`CourseLookup.db: COUCHDB_SERVER_URL is not set. Ensure initializeDataLayer has been called with valid configuration.`);if(ENV.COUCHDB_SERVER_PROTOCOL===`NOT_SET`||!ENV.COUCHDB_SERVER_PROTOCOL)throw Error(`CourseLookup.db: COUCHDB_SERVER_PROTOCOL is not set. Ensure initializeDataLayer has been called with valid configuration.`);let t=`${ENV.COUCHDB_SERVER_PROTOCOL}://${ENV.COUCHDB_SERVER_URL}/${courseLookupDBTitle}`,c={};ENV.COUCHDB_USERNAME&&ENV.COUCHDB_PASSWORD?(c.auth={username:ENV.COUCHDB_USERNAME,password:ENV.COUCHDB_PASSWORD},logger.info(`CourseLookup: Connecting to ${t} with authentication.`)):logger.info(`CourseLookup: Connecting to ${t} without authentication.`);try{return this._dbInstance=new pouchdb_setup_default(t,c),logger.info(`CourseLookup: Database instance created for ${courseLookupDBTitle}.`),this._dbInstance}catch(c){throw logger.error(`CourseLookup: Failed to create PouchDB instance for ${t}`,c),this._dbInstance=null,Error(`CourseLookup: Failed to initialize database connection: ${c instanceof Error?c.message:String(c)}`)}}static async add(t){return(await _CourseLookup._db.post({name:t})).id}static async addWithId(t,c,u){let d={_id:t,name:c};u&&(d.disambiguator=u),await _CourseLookup._db.put(d)}static async delete(t){let c=await _CourseLookup._db.get(t);return await _CourseLookup._db.remove(c)}static async allCourseWare(){return(await _CourseLookup._db.allDocs({include_docs:!0})).rows.map(t=>t.doc)}static async updateDisambiguator(t,c){let u=await _CourseLookup._db.get(t);return u.disambiguator=c,await _CourseLookup._db.put(u)}static async isCourse(t){try{return await _CourseLookup._db.get(t),!0}catch(t){return logger.info(`Courselookup failed:`,t),!1}}},_defineProperty$2(t,`_dbInstance`,null),t)}}),PipelineDebugger_exports={},__export(PipelineDebugger_exports,{buildRunReport:()=>buildRunReport,captureRun:()=>captureRun,clearRunHistory:()=>clearRunHistory,mountPipelineDebugger:()=>mountPipelineDebugger,pipelineDebugAPI:()=>pipelineDebugAPI,registerPipelineForDebug:()=>registerPipelineForDebug}),init_PipelineDebugger=__esm({"src/core/navigators/PipelineDebugger.ts"(){"use strict";init_navigators(),init_logger(),_activePipeline=null,MAX_RUNS=10,runHistory=[],DISCARDED_KEEP_TOP=25,_uiContainer=null,_selectedRunIndex=null,_cardSearchQuery=``,pipelineDebugAPI={get runs(){return[...runHistory]},showRun(t=0){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}let c;if(typeof t==`number`){if(c=runHistory[t],!c){logger.info(`[Pipeline Debug] No run found at index ${t}. History length: ${runHistory.length}`);return}}else if(c=runHistory.find(c=>c.runId.endsWith(t)),!c){logger.info(`[Pipeline Debug] No run found matching ID '${t}'.`);return}printRunSummary(c)},showLastRun(){this.showRun(0)},showCard(t){for(let c of runHistory){let u=c.cards.find(c=>c.cardId===t);if(u){console.group(`\u{1F3B4} Card: ${t}`),logger.info(`Course: ${u.courseId}`),logger.info(`Origin: ${u.origin}`),logger.info(`Card ELO: ${u.cardElo??`unknown`} | User ELO: ${c.userElo??`unknown`}`),logger.info(`Final score: ${u.finalScore.toFixed(3)}`),logger.info(`Selected: ${u.selected?`Yes ✅`:`No ❌`}`),u.tags&&u.tags.length>0&&logger.info(`Tags (${u.tags.length}): ${u.tags.join(`, `)}`),logger.info(`Provenance:`),logger.info(formatProvenance(u.provenance)),console.groupEnd();return}}let c=runHistory.filter(t=>t.discardedTail&&t.discardedTail.count>0);c.length>0?logger.info(`[Pipeline Debug] Card '${t}' not found in retained cards. ${c.length} run(s) have discarded tails that were not retained \u2014 the card may have been a low-score candidate. See run.discardedTail for ranges.`):logger.info(`[Pipeline Debug] Card '${t}' not found in recent runs.`)},explainReviews(){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}console.group(`📋 Review Selection Analysis`);for(let t of runHistory){console.group(`Run: ${t.courseId} @ ${t.timestamp.toLocaleTimeString()}`);let c=t.cards.filter(t=>t.origin===`review`),u=c.filter(t=>t.selected);if(c.length===0)logger.info(`❌ No reviews were generated. Check SRS logs for why.`);else if(u.length===0){logger.info(`\u26A0\uFE0F ${c.length} reviews generated but none selected.`),logger.info(`Possible reasons:`);let u=Math.max(...t.cards.filter(t=>t.origin===`new`&&t.selected).map(t=>t.finalScore),0),d=Math.max(...c.map(t=>t.finalScore),0);d<u&&logger.info(` - New cards scored higher (top new: ${u.toFixed(2)}, top review: ${d.toFixed(2)})`);let m=c.sort((t,c)=>c.finalScore-t.finalScore)[0];m&&(logger.info(` - Top review score: ${m.finalScore.toFixed(3)}`),logger.info(` - Its provenance:`),logger.info(formatProvenance(m.provenance)))}else{logger.info(`\u2705 ${u.length}/${c.length} reviews selected.`),logger.info(`Top selected review:`);let t=u.sort((t,c)=>c.finalScore-t.finalScore)[0];logger.info(formatProvenance(t.provenance))}console.groupEnd()}console.groupEnd()},showPrescribed(t){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}let c=runHistory[0],u=c.cards.filter(t=>t.provenance.some(t=>t.strategy===`prescribed`));if(console.group(`\u{1F9ED} Prescribed Debug (${c.courseId})`),u.length===0){logger.info(`No prescribed-generated cards were present in the most recent run.`),console.groupEnd();return}let d=u.map(t=>{let c=t.provenance.find(t=>t.strategy===`prescribed`)?.reason??``,u=c.match(/group=([^;]+)/)?.[1]??`unknown`,d=c.match(/mode=([^;]+)/)?.[1]??`unknown`,m=c.match(/blocked=([^;]+)/)?.[1]??`unknown`,g=c.match(/blockedTargets=([^;]+)/)?.[1]??`none`,b=c.match(/supportCard=([^;]+)/)?.[1]??`none`,S=c.match(/supportTags=([^;]+)/)?.[1]??`none`,C=c.match(/multiplier=([^;]+)/)?.[1]??`unknown`;return{group:u,mode:d,supportSource:d===`discovered-support`?`discovered`:d===`support`?`authored`:`n/a`,cardId:t.cardId,selected:t.selected?`yes`:`no`,finalScore:t.finalScore.toFixed(3),blocked:m,blockedTargets:g,supportCard:b,supportTags:S,multiplier:C}}).filter(c=>!t||c.group===t).sort((t,c)=>Number(c.finalScore)-Number(t.finalScore));if(d.length===0){logger.info(`[Pipeline Debug] No prescribed cards matched group '${t}' in the most recent run.`),console.groupEnd();return}console.table(d);let m=d.filter(t=>t.selected===`yes`),g=new Set,b=new Set,S=new Set,C=new Set;for(let t of d)t.blockedTargets&&t.blockedTargets!==`none`&&t.blockedTargets.split(`|`).filter(Boolean).forEach(t=>g.add(t)),t.supportTags&&t.supportTags!==`none`&&t.supportTags.split(`|`).filter(Boolean).forEach(t=>b.add(t)),t.supportCard&&t.supportCard!==`none`&&(t.supportSource===`discovered`?C.add(t.supportCard):t.supportSource===`authored`&&S.add(t.supportCard));logger.info(`Prescribed cards in run: ${d.length}`),logger.info(`Selected prescribed cards: ${m.length}`),logger.info(`Blocked prescribed targets referenced: ${g.size>0?[...g].join(`, `):`none`}`),logger.info(`Resolved support tags referenced: ${b.size>0?[...b].join(`, `):`none`}`),logger.info(`Authored support cards emitted: ${S.size>0?[...S].join(`, `):`none`}`),logger.info(`Discovered support cards emitted: ${C.size>0?[...C].join(`, `):`none`}`),console.groupEnd()},listRuns(){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}console.table(runHistory.map(t=>({id:t.runId.slice(-8),time:t.timestamp.toLocaleTimeString(),course:t.courseName||t.courseId.slice(0,8),generated:t.generatedCount,selected:t.finalCount,new:t.newSelected,reviews:t.reviewsSelected})))},export(){let t=JSON.stringify(runHistory,null,2);return logger.info(`[Pipeline Debug] Run history exported. Copy the returned string or use:`),logger.info(` copy(window.skuilder.pipeline.export())`),t},clear(){runHistory.length=0,logger.info(`[Pipeline Debug] Run history cleared.`)},showRegistry(){let t=getRegisteredNavigatorNames();if(t.length===0){logger.info(`[Pipeline Debug] Navigator registry is empty.`);return}console.group(`📦 Navigator Registry`),console.table(t.map(t=>{let c=getRegisteredNavigatorRole(t),u=NavigatorRoles[t];return{name:t,role:u||c||`⚠️ NONE`,source:u?`built-in`:c?`consumer`:`unclassified`,isGenerator:isGenerator(t),isFilter:isFilter(t)}})),console.groupEnd()},showStrategies(){if(this.showRegistry(),runHistory.length===0){logger.info(`[Pipeline Debug] No pipeline runs captured yet — cannot show strategy doc mapping.`);return}let t=runHistory[0];if(console.group(`🔌 Pipeline Strategy Mapping (last run)`),logger.info(`Generator: ${t.generatorName}`),t.generators&&t.generators.length>0)for(let c of t.generators)logger.info(` \u{1F4E5} ${c.name}: ${c.cardCount} cards (${c.newCount} new, ${c.reviewCount} reviews)`);if(t.filters.length>0){logger.info(`Filters:`);for(let c of t.filters)logger.info(` \u{1F538} ${c.name}: \u2191${c.boosted} \u2193${c.penalized} =${c.passed} \u2715${c.removed}`)}else logger.info(`Filters: (none)`);console.groupEnd()},async diagnoseCardSpace(t){return _activePipeline?_activePipeline.diagnoseCardSpace({threshold:t}):(logger.info(`[Pipeline Debug] No active pipeline. Run a session first.`),null)},async showTagElo(t){if(!_activePipeline){logger.info(`[Pipeline Debug] No active pipeline. Run a session first.`);return}let c=await _activePipeline.getTagEloStatus(t),u=Object.entries(c).sort(([t],[c])=>t.localeCompare(c));if(u.length===0){logger.info(`[Pipeline Debug] No tag ELO data found${t?` for pattern: ${t}`:``}.`);return}console.table(Object.fromEntries(u.map(([t,c])=>[t,{score:Math.round(c.score),count:c.count}])))},ui(){if(_uiContainer){document.body.removeChild(_uiContainer),_uiContainer=null;return}_uiContainer=document.createElement(`div`),_uiContainer.id=`sk-pipeline-debugger`,document.body.appendChild(_uiContainer),_selectedRunIndex===null&&runHistory.length>0&&(_selectedRunIndex=0),renderUI()},_selectRun(t){_selectedRunIndex=t,renderUI()},_setSearch(t){_cardSearchQuery=t,renderUI()},_copyConfig(t,c){let u=runHistory.find(c=>c.runId===t);if(!u)return;let d={runId:u.runId,timestamp:u.timestamp.toISOString(),courseId:u.courseId,courseName:u.courseName,hints:u.hints??null};copyTextToClipboard(JSON.stringify(d,null,2),c)},_copyResults(t,c){let u=runHistory.find(c=>c.runId===t);if(!u)return;let d=u.cards.filter(t=>t.selected).sort((t,c)=>c.finalScore-t.finalScore).map(t=>({cardId:t.cardId,generator:t.generator,origin:t.origin,score:Number(t.finalScore.toFixed(3)),topReason:t.provenance[0]?.reason??``})),m={runId:u.runId,label:u.hints?._label??null,finalCount:u.finalCount,newSelected:u.newSelected,reviewsSelected:u.reviewsSelected,selected:d};copyTextToClipboard(JSON.stringify(m,null,2),c)},help(){logger.info(`
|
|
327
|
+
\u26A0\uFE0F Detected clustering: max ${m} cards from same course in a row`),logger.info(`This suggests cards are sorted by score rather than round-robin by course.`)),console.groupEnd()}function mountSessionDebugger(){if(typeof window>`u`)return;let t=window;t.skuilder=t.skuilder||{},t.skuilder.session=sessionDebugAPI}var import___vite_browser_external,import___vite_browser_external$1,import___vite_browser_external$2,import_browser_ponyfill,import_browser_ponyfill$1,import_browser,_SessionController2,__defProp,__getOwnPropNames,__glob,__esm,__export,init_adminDB,init_classroomDB,init_SyncStrategy,isDevelopment,logger,init_logger,GuestUsername,log,DocType,DocTypePrefixes,init_types_legacy,init_util,pouchdb_setup_default,init_pouchdb_setup,init_dataDirectory,REVIEW_TIME_FORMAT,log2,init_userDBHelpers,Loggable,init_Loggable,UpdateQueue,init_updateQueue,UsrCrsData,init_user_course_relDB,CLIENT_CACHE,init_clientCache,AlreadyTaggedErr,init_courseAPI,courseLookupDBTitle,CourseLookup,init_courseLookupDB,diversityRerank_exports,DIVERSITY_STRENGTH,DIVERSITY_FLOOR,STRATEGY,STRATEGY_ID,STRATEGY_NAME,init_diversityRerank,PipelineDebugger_exports,_activePipeline,MAX_RUNS,runHistory,DISCARDED_KEEP_TOP,_uiContainer,_selectedRunIndex,_cardSearchQuery,pipelineDebugAPI,init_PipelineDebugger,CompositeGenerator_exports,AggregationMode,DEFAULT_AGGREGATION_MODE,FREQUENCY_BOOST_FACTOR,CompositeGenerator,init_CompositeGenerator,elo_exports,ELO_RELEVANCE_SIGMA,ELONavigator,init_elo,generators_exports,init_generators,prescribed_exports,DEFAULT_FRESHNESS_WINDOW,DEFAULT_MAX_DIRECT_PER_RUN,DEFAULT_MAX_SUPPORT_PER_RUN,DEFAULT_HIERARCHY_DEPTH,DEFAULT_MIN_COUNT,DEFAULT_PRACTICE_MIN_COUNT,DEFAULT_MAX_PRACTICE_PER_RUN,BASE_TARGET_SCORE,BASE_SUPPORT_SCORE,DISCOVERED_SUPPORT_SCORE,BASE_PRACTICE_SCORE,MAX_TARGET_MULTIPLIER,MAX_SUPPORT_MULTIPLIER,PRESCRIBED_DEBUG_VERSION,PrescribedCardsGenerator,init_prescribed,srs_exports,DEFAULT_HEALTHY_BACKLOG,MAX_BACKLOG_PRESSURE,SRSNavigator,init_srs,types_exports,init_types,globImport_generators,init_,DEFAULT_LEARNABLE_WEIGHT,init_contentNavigationStrategy,WeightedFilter_exports,WeightedFilter,init_WeightedFilter,eloDistance_exports,DEFAULT_HALF_LIFE,DEFAULT_MIN_MULTIPLIER,DEFAULT_MAX_MULTIPLIER,init_eloDistance,hierarchyDefinition_exports,DEFAULT_MIN_COUNT2,HierarchyDefinitionNavigator,init_hierarchyDefinition,userTagPreference_exports,UserTagPreferenceFilter,init_userTagPreference,filters_exports,init_filters,inferredPreferenceStub_exports,INFERRED_PREFERENCE_NAVIGATOR_STUB,init_inferredPreferenceStub,interferenceMitigator_exports,DEFAULT_MIN_COUNT3,DEFAULT_MIN_ELAPSED_DAYS,DEFAULT_INTERFERENCE_DECAY,InterferenceMitigatorNavigator,init_interferenceMitigator,relativePriority_exports,DEFAULT_PRIORITY,DEFAULT_PRIORITY_INFLUENCE,DEFAULT_COMBINE_MODE,RelativePriorityNavigator,init_relativePriority,types_exports2,init_types2,userGoalStub_exports,USER_GOAL_NAVIGATOR_STUB,init_userGoalStub,globImport_filters,init_2,init_gradient,MIN_OBSERVATIONS_FOR_UPDATE,LEARNING_RATE,MAX_WEIGHT_DELTA,MIN_R_SQUARED_FOR_GRADIENT,FLAT_GRADIENT_THRESHOLD,MAX_HISTORY_LENGTH,init_learning,init_signal,init_recording,MIN_SPREAD,MAX_SPREAD,MIN_WEIGHT,MAX_WEIGHT,init_orchestration,Pipeline_exports,VERBOSE_RESULTS,Pipeline,init_Pipeline,defaults_exports,init_defaults,PipelineAssembler_exports,PipelineAssembler,init_PipelineAssembler,globImport,init_3,navigators_exports,navigatorRegistry,Navigators,NavigatorRole,NavigatorRoles,ContentNavigator,init_navigators,CoursesDB,CourseDB,init_courseDB,classroomLookupDBTitle,CLASSROOM_CONFIG,ClassroomDBBase,StudentClassroomDB,TeacherClassroomDB,ClassroomLookupDB,init_classroomDB2,AdminDB,init_adminDB2,CourseSyncService_exports,DEFAULT_REPLICATION,CourseSyncService,init_CourseSyncService,init_auth,CouchDBSyncStrategy_exports,log3,CouchDBSyncStrategy,init_CouchDBSyncStrategy,isBrowser,GUEST_LOCAL_DB,localUserDB,pouchDBincludeCredentialsConfig,REVIEW_TIME_FORMAT2,init_couch,log4,BaseUser,userCoursesDoc,userClassroomsDoc,init_BaseUserDB,init_common,PouchDataLayerProvider_exports,CouchDataLayerProvider,init_PouchDataLayerProvider,pathUtils,nodeFS,StaticDataUnpacker,init_StaticDataUnpacker,StaticCourseDB,init_courseDB2,StaticCoursesDB,init_coursesDB,NoOpSyncStrategy,init_NoOpSyncStrategy,StaticDataLayerProvider_exports,StaticDataLayerProvider,init_StaticDataLayerProvider,NOT_SET,ENV,dataLayerInstance,init_factory,TagFilteredContentSource,init_TagFilteredContentSource,init_contentSource,init_courseDB3,init_dataLayerProvider,init_userDB,init_interfaces,init_user,init_strategyState,init_userOutcome,init_cardProcessor,init_types3,init_bulkImport,userDBDebugAPI,init_UserDBDebugger,init_core,duration,SrsService,EloService,ResponseProcessor,CardHydrationService,ItemQueue,CouchDBToStaticPacker,DEFAULT_MIGRATION_OPTIONS,FileSystemError,nodeFS2,nodeFS3,nodePath,StaticToCouchDBMigrator,QuotaRoundRobinMixer,MAX_RUNS2,runHistory2,mixerDebugAPI,activeController,OVERLAY_ID,POLL_MS,INLINE_THRESHOLD,SPINNER_FRAMES,spinnerFrame,overlayEl,pollHandle,lastSnapshot,copyFlashUntil,minified,expanded,activeSession,sessionHistory,MAX_HISTORY,sessionDebugAPI,SessionController,init_dist=__esmMin((()=>{init_defineProperty(),init_index_browser_es$5(),init_index_browser_es(),init_index_es(),import___vite_browser_external=__toESM$2(require___vite_browser_external(),1),import___vite_browser_external$1=__toESM$2(require___vite_browser_external(),1),import___vite_browser_external$2=__toESM$2(require___vite_browser_external(),1),init_moment(),init_dist$1(),init_esm_browser(),import_browser_ponyfill=__toESM$2(require_browser_ponyfill(),1),import_browser_ponyfill$1=__toESM$2(require_browser_ponyfill(),1),import_browser=__toESM$2(require_browser(),1),__defProp=Object.defineProperty,__getOwnPropNames=Object.getOwnPropertyNames,__glob=t=>c=>{var u=t[c];if(u)return u();throw Error(`Module not found in bundle: `+c)},__esm=(t,c)=>function __init(){return t&&(c=(0,t[__getOwnPropNames(t)[0]])(t=0)),c},__export=(t,c)=>{for(var u in c)__defProp(t,u,{get:c[u],enumerable:!0})},init_adminDB=__esm({"src/core/interfaces/adminDB.ts"(){"use strict";}}),init_classroomDB=__esm({"src/core/interfaces/classroomDB.ts"(){"use strict";}}),init_SyncStrategy=__esm({"src/impl/common/SyncStrategy.ts"(){"use strict";}}),init_logger=__esm({"src/util/logger.ts"(){"use strict";isDevelopment=typeof process<`u`&&process.env.NODE_ENV===`development`,logger={debug:(t,...c)=>{isDevelopment&&console.debug(`[DB:DEBUG] ${t}`,...c)},info:(t,...c)=>{console.info(`[DB:INFO] ${t}`,...c)},warn:(t,...c)=>{console.warn(`[DB:WARN] ${t}`,...c)},error:(t,...c)=>{console.error(`[DB:ERROR] ${t}`,...c)},log:(t,...c)=>{isDevelopment&&console.log(`[DB:LOG] ${t}`,...c)}}}}),init_types_legacy=__esm({"src/core/types/types-legacy.ts"(){"use strict";init_logger(),GuestUsername=`sk-guest-`,log=t=>{logger.log(t)},DocType=(t=>(t.DISPLAYABLE_DATA=`DISPLAYABLE_DATA`,t.CARD=`CARD`,t.DATASHAPE=`DATASHAPE`,t.QUESTIONTYPE=`QUESTION`,t.VIEW=`VIEW`,t.PEDAGOGY=`PEDAGOGY`,t.CARDRECORD=`CARDRECORD`,t.SCHEDULED_CARD=`SCHEDULED_CARD`,t.TAG=`TAG`,t.NAVIGATION_STRATEGY=`NAVIGATION_STRATEGY`,t.STRATEGY_STATE=`STRATEGY_STATE`,t.USER_OUTCOME=`USER_OUTCOME`,t.STRATEGY_LEARNING_STATE=`STRATEGY_LEARNING_STATE`,t))(DocType||{}),DocTypePrefixes={CARD:`c`,DISPLAYABLE_DATA:`dd`,TAG:`TAG`,CARDRECORD:`cardH`,SCHEDULED_CARD:`card_review_`,DATASHAPE:`DATASHAPE`,QUESTION:`QUESTION`,VIEW:`VIEW`,PEDAGOGY:`PEDAGOGY`,NAVIGATION_STRATEGY:`NAVIGATION_STRATEGY`,STRATEGY_STATE:`STRATEGY_STATE`,USER_OUTCOME:`USER_OUTCOME`,STRATEGY_LEARNING_STATE:`STRATEGY_LEARNING_STATE`}}}),init_util=__esm({"src/core/util/index.ts"(){"use strict";init_types_legacy()}}),init_pouchdb_setup=__esm({"src/impl/couch/pouchdb-setup.ts"(){"use strict";PouchDB.plugin(plugin$1),PouchDB.plugin(plugin),PouchDB.debug!==void 0&&PouchDB.debug.disable(),PouchDB.defaults({}),pouchdb_setup_default=PouchDB}}),init_dataDirectory=__esm({"src/util/dataDirectory.ts"(){"use strict";init_logger(),init_factory()}}),init_userDBHelpers=__esm({"src/impl/common/userDBHelpers.ts"(){"use strict";init_core(),init_logger(),init_pouchdb_setup(),init_dataDirectory(),REVIEW_TIME_FORMAT=`YYYY-MM-DD--kk:mm:ss-SSS`,log2=t=>{logger.info(t)}}}),init_Loggable=__esm({"src/util/Loggable.ts"(){"use strict";Loggable=class{log(...t){console.log(`LOG-${this._className}@${new Date}:`,...t)}error(...t){console.error(`ERROR-${this._className}@${new Date}:`,...t)}}}}),init_updateQueue=__esm({"src/impl/couch/updateQueue.ts"(){"use strict";init_Loggable(),init_logger(),UpdateQueue=class extends Loggable{update(t,c){return logger.debug(`Update requested on doc: ${t}`),this.pendingUpdates[t]?this.pendingUpdates[t].push(c):this.pendingUpdates[t]=[c],this.applyUpdates(t)}constructor(t,c){super(),_defineProperty$2(this,`_className`,`UpdateQueue`),_defineProperty$2(this,`pendingUpdates`,{}),_defineProperty$2(this,`inprogressUpdates`,{}),_defineProperty$2(this,`readDB`,void 0),_defineProperty$2(this,`writeDB`,void 0),this.readDB=t,this.writeDB=c||t,logger.debug(`UpdateQ initialized...`),this.readDB.info().then(t=>{logger.debug(`db info: ${JSON.stringify(t)}`)})}async applyUpdates(t){if(logger.debug(`Applying updates on doc: ${t}`),this.inprogressUpdates[t]){for(;this.inprogressUpdates[t];)await new Promise(t=>setTimeout(t,Math.random()*50));return this.applyUpdates(t)}else if(this.pendingUpdates[t]&&this.pendingUpdates[t].length>0){this.inprogressUpdates[t]=!0;let c=5;for(let c=0;c<5;c++)try{let c={...await this.readDB.get(t)},u=[...this.pendingUpdates[t]];for(let t of u)c=typeof t==`function`?{...c,...t(c)}:{...c,...t};if(await this.writeDB.put(c),this.pendingUpdates[t].splice(0,u.length),this.pendingUpdates[t].length===0)this.inprogressUpdates[t]=!1,delete this.inprogressUpdates[t];else return this.applyUpdates(t);return c}catch(u){if(u.name===`conflict`&&c<4)logger.warn(`Conflict on update for doc ${t}, retry #${c+1}`),await new Promise(t=>setTimeout(t,50*Math.random()));else if(u.name===`not_found`&&c===0)throw logger.warn(`Update failed for ${t} - does not exist. Throwing to caller.`),delete this.inprogressUpdates[t],u;else throw delete this.inprogressUpdates[t],this.pendingUpdates[t]&&delete this.pendingUpdates[t],logger.error(`Error on attemped update (retry ${c}): ${JSON.stringify(u)}`),u}throw Error(`UpdateQueue failed for doc ${t} after 5 retries.`)}else throw Error(`Empty Updates Queue Triggered`)}}}}),init_user_course_relDB=__esm({"src/impl/couch/user-course-relDB.ts"(){"use strict";init_logger(),UsrCrsData=class{constructor(t,c){_defineProperty$2(this,`user`,void 0),_defineProperty$2(this,`_courseId`,void 0),this.user=t,this._courseId=c}async getReviewsForcast(t){let c=hooks.utc().add(t,`days`);return this.getReviewstoDate(c)}async getPendingReviews(){let t=hooks.utc();return this.getReviewstoDate(t)}async getScheduledReviewCount(){return(await this.getPendingReviews()).length}async getCourseSettings(){let t=(await this.user.getCourseRegistrationsDoc()).courses.find(t=>t.courseID===this._courseId);return t&&t.settings?t.settings:(logger.warn(`no settings found during lookup on course ${this._courseId}`),{})}updateCourseSettings(t){`updateCourseSettings`in this.user&&this.user.updateCourseSettings(this._courseId,t)}async getStrategyState(t){return this.user.getStrategyState(this._courseId,t)}async putStrategyState(t,c){return this.user.putStrategyState(this._courseId,t,c)}async deleteStrategyState(t){return this.user.deleteStrategyState(this._courseId,t)}async getReviewstoDate(t){let c=await this.user.getPendingReviews(this._courseId);return logger.debug(`Fetching ${this.user.getUsername()}'s scheduled reviews for course ${this._courseId}.`),c.filter(c=>{let u=hooks.utc(c.reviewTime);return t.isAfter(u)})}}}}),init_clientCache=__esm({"src/impl/couch/clientCache.ts"(){"use strict";CLIENT_CACHE={}}}),init_courseAPI=__esm({"src/impl/couch/courseAPI.ts"(){"use strict";init_pouchdb_setup(),init_couch(),init_factory(),init_courseDB(),init_types_legacy(),init_common(),init_logger(),AlreadyTaggedErr=class extends Error{constructor(t){super(t),this.name=`AlreadyTaggedErr`}}}}),init_courseLookupDB=__esm({"src/impl/couch/courseLookupDB.ts"(){"use strict";var t;init_pouchdb_setup(),init_factory(),init_logger(),courseLookupDBTitle=`coursedb-lookup`,logger.debug(`COURSELOOKUP FILE RUNNING`),CourseLookup=(t=class _CourseLookup{static get _db(){if(this._dbInstance)return this._dbInstance;if(ENV.COUCHDB_SERVER_URL===`NOT_SET`||!ENV.COUCHDB_SERVER_URL)throw Error(`CourseLookup.db: COUCHDB_SERVER_URL is not set. Ensure initializeDataLayer has been called with valid configuration.`);if(ENV.COUCHDB_SERVER_PROTOCOL===`NOT_SET`||!ENV.COUCHDB_SERVER_PROTOCOL)throw Error(`CourseLookup.db: COUCHDB_SERVER_PROTOCOL is not set. Ensure initializeDataLayer has been called with valid configuration.`);let t=`${ENV.COUCHDB_SERVER_PROTOCOL}://${ENV.COUCHDB_SERVER_URL}/${courseLookupDBTitle}`,c={};ENV.COUCHDB_USERNAME&&ENV.COUCHDB_PASSWORD?(c.auth={username:ENV.COUCHDB_USERNAME,password:ENV.COUCHDB_PASSWORD},logger.info(`CourseLookup: Connecting to ${t} with authentication.`)):logger.info(`CourseLookup: Connecting to ${t} without authentication.`);try{return this._dbInstance=new pouchdb_setup_default(t,c),logger.info(`CourseLookup: Database instance created for ${courseLookupDBTitle}.`),this._dbInstance}catch(c){throw logger.error(`CourseLookup: Failed to create PouchDB instance for ${t}`,c),this._dbInstance=null,Error(`CourseLookup: Failed to initialize database connection: ${c instanceof Error?c.message:String(c)}`)}}static async add(t){return(await _CourseLookup._db.post({name:t})).id}static async addWithId(t,c,u){let d={_id:t,name:c};u&&(d.disambiguator=u),await _CourseLookup._db.put(d)}static async delete(t){let c=await _CourseLookup._db.get(t);return await _CourseLookup._db.remove(c)}static async allCourseWare(){return(await _CourseLookup._db.allDocs({include_docs:!0})).rows.map(t=>t.doc)}static async updateDisambiguator(t,c){let u=await _CourseLookup._db.get(t);return u.disambiguator=c,await _CourseLookup._db.put(u)}static async isCourse(t){try{return await _CourseLookup._db.get(t),!0}catch(t){return logger.info(`Courselookup failed:`,t),!1}}},_defineProperty$2(t,`_dbInstance`,null),t)}}),diversityRerank_exports={},__export(diversityRerank_exports,{DIVERSITY_FLOOR:()=>DIVERSITY_FLOOR,DIVERSITY_STRENGTH:()=>DIVERSITY_STRENGTH,diversityRerank:()=>diversityRerank}),init_diversityRerank=__esm({"src/core/navigators/diversityRerank.ts"(){"use strict";DIVERSITY_STRENGTH=.6,DIVERSITY_FLOOR=.3,STRATEGY=`diversityRerank`,STRATEGY_ID=`DIVERSITY_RERANK`,STRATEGY_NAME=`Diversity Re-rank`}}),PipelineDebugger_exports={},__export(PipelineDebugger_exports,{buildRunReport:()=>buildRunReport,captureRun:()=>captureRun,clearRunHistory:()=>clearRunHistory,getActivePipeline:()=>getActivePipeline,mountPipelineDebugger:()=>mountPipelineDebugger,pipelineDebugAPI:()=>pipelineDebugAPI,registerPipelineForDebug:()=>registerPipelineForDebug}),init_PipelineDebugger=__esm({"src/core/navigators/PipelineDebugger.ts"(){"use strict";init_navigators(),init_logger(),_activePipeline=null,MAX_RUNS=10,runHistory=[],DISCARDED_KEEP_TOP=25,_uiContainer=null,_selectedRunIndex=null,_cardSearchQuery=``,pipelineDebugAPI={get runs(){return[...runHistory]},showRun(t=0){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}let c;if(typeof t==`number`){if(c=runHistory[t],!c){logger.info(`[Pipeline Debug] No run found at index ${t}. History length: ${runHistory.length}`);return}}else if(c=runHistory.find(c=>c.runId.endsWith(t)),!c){logger.info(`[Pipeline Debug] No run found matching ID '${t}'.`);return}printRunSummary(c)},showLastRun(){this.showRun(0)},showCard(t){for(let c of runHistory){let u=c.cards.find(c=>c.cardId===t);if(u){console.group(`\u{1F3B4} Card: ${t}`),logger.info(`Course: ${u.courseId}`),logger.info(`Origin: ${u.origin}`),logger.info(`Card ELO: ${u.cardElo??`unknown`} | User ELO: ${c.userElo??`unknown`}`),logger.info(`Final score: ${u.finalScore.toFixed(3)}`),logger.info(`Selected: ${u.selected?`Yes ✅`:`No ❌`}`),u.tags&&u.tags.length>0&&logger.info(`Tags (${u.tags.length}): ${u.tags.join(`, `)}`),logger.info(`Provenance:`),logger.info(formatProvenance(u.provenance)),console.groupEnd();return}}let c=runHistory.filter(t=>t.discardedTail&&t.discardedTail.count>0);c.length>0?logger.info(`[Pipeline Debug] Card '${t}' not found in retained cards. ${c.length} run(s) have discarded tails that were not retained \u2014 the card may have been a low-score candidate. See run.discardedTail for ranges.`):logger.info(`[Pipeline Debug] Card '${t}' not found in recent runs.`)},explainReviews(){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}console.group(`📋 Review Selection Analysis`);for(let t of runHistory){console.group(`Run: ${t.courseId} @ ${t.timestamp.toLocaleTimeString()}`);let c=t.cards.filter(t=>t.origin===`review`),u=c.filter(t=>t.selected);if(c.length===0)logger.info(`❌ No reviews were generated. Check SRS logs for why.`);else if(u.length===0){logger.info(`\u26A0\uFE0F ${c.length} reviews generated but none selected.`),logger.info(`Possible reasons:`);let u=Math.max(...t.cards.filter(t=>t.origin===`new`&&t.selected).map(t=>t.finalScore),0),d=Math.max(...c.map(t=>t.finalScore),0);d<u&&logger.info(` - New cards scored higher (top new: ${u.toFixed(2)}, top review: ${d.toFixed(2)})`);let m=c.sort((t,c)=>c.finalScore-t.finalScore)[0];m&&(logger.info(` - Top review score: ${m.finalScore.toFixed(3)}`),logger.info(` - Its provenance:`),logger.info(formatProvenance(m.provenance)))}else{logger.info(`\u2705 ${u.length}/${c.length} reviews selected.`),logger.info(`Top selected review:`);let t=u.sort((t,c)=>c.finalScore-t.finalScore)[0];logger.info(formatProvenance(t.provenance))}console.groupEnd()}console.groupEnd()},showPrescribed(t){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}let c=runHistory[0],u=c.cards.filter(t=>t.provenance.some(t=>t.strategy===`prescribed`));if(console.group(`\u{1F9ED} Prescribed Debug (${c.courseId})`),u.length===0){logger.info(`No prescribed-generated cards were present in the most recent run.`),console.groupEnd();return}let d=u.map(t=>{let c=t.provenance.find(t=>t.strategy===`prescribed`)?.reason??``,u=c.match(/group=([^;]+)/)?.[1]??`unknown`,d=c.match(/mode=([^;]+)/)?.[1]??`unknown`,m=c.match(/blocked=([^;]+)/)?.[1]??`unknown`,g=c.match(/blockedTargets=([^;]+)/)?.[1]??`none`,b=c.match(/supportCard=([^;]+)/)?.[1]??`none`,S=c.match(/supportTags=([^;]+)/)?.[1]??`none`,C=c.match(/multiplier=([^;]+)/)?.[1]??`unknown`;return{group:u,mode:d,supportSource:d===`discovered-support`?`discovered`:d===`support`?`authored`:`n/a`,cardId:t.cardId,selected:t.selected?`yes`:`no`,finalScore:t.finalScore.toFixed(3),blocked:m,blockedTargets:g,supportCard:b,supportTags:S,multiplier:C}}).filter(c=>!t||c.group===t).sort((t,c)=>Number(c.finalScore)-Number(t.finalScore));if(d.length===0){logger.info(`[Pipeline Debug] No prescribed cards matched group '${t}' in the most recent run.`),console.groupEnd();return}console.table(d);let m=d.filter(t=>t.selected===`yes`),g=new Set,b=new Set,S=new Set,C=new Set;for(let t of d)t.blockedTargets&&t.blockedTargets!==`none`&&t.blockedTargets.split(`|`).filter(Boolean).forEach(t=>g.add(t)),t.supportTags&&t.supportTags!==`none`&&t.supportTags.split(`|`).filter(Boolean).forEach(t=>b.add(t)),t.supportCard&&t.supportCard!==`none`&&(t.supportSource===`discovered`?C.add(t.supportCard):t.supportSource===`authored`&&S.add(t.supportCard));logger.info(`Prescribed cards in run: ${d.length}`),logger.info(`Selected prescribed cards: ${m.length}`),logger.info(`Blocked prescribed targets referenced: ${g.size>0?[...g].join(`, `):`none`}`),logger.info(`Resolved support tags referenced: ${b.size>0?[...b].join(`, `):`none`}`),logger.info(`Authored support cards emitted: ${S.size>0?[...S].join(`, `):`none`}`),logger.info(`Discovered support cards emitted: ${C.size>0?[...C].join(`, `):`none`}`),console.groupEnd()},listRuns(){if(runHistory.length===0){logger.info(`[Pipeline Debug] No runs captured yet.`);return}console.table(runHistory.map(t=>({id:t.runId.slice(-8),time:t.timestamp.toLocaleTimeString(),course:t.courseName||t.courseId.slice(0,8),generated:t.generatedCount,selected:t.finalCount,new:t.newSelected,reviews:t.reviewsSelected})))},export(){let t=JSON.stringify(runHistory,null,2);return logger.info(`[Pipeline Debug] Run history exported. Copy the returned string or use:`),logger.info(` copy(window.skuilder.pipeline.export())`),t},clear(){runHistory.length=0,logger.info(`[Pipeline Debug] Run history cleared.`)},showRegistry(){let t=getRegisteredNavigatorNames();if(t.length===0){logger.info(`[Pipeline Debug] Navigator registry is empty.`);return}console.group(`📦 Navigator Registry`),console.table(t.map(t=>{let c=getRegisteredNavigatorRole(t),u=NavigatorRoles[t];return{name:t,role:u||c||`⚠️ NONE`,source:u?`built-in`:c?`consumer`:`unclassified`,isGenerator:isGenerator(t),isFilter:isFilter(t)}})),console.groupEnd()},showStrategies(){if(this.showRegistry(),runHistory.length===0){logger.info(`[Pipeline Debug] No pipeline runs captured yet — cannot show strategy doc mapping.`);return}let t=runHistory[0];if(console.group(`🔌 Pipeline Strategy Mapping (last run)`),logger.info(`Generator: ${t.generatorName}`),t.generators&&t.generators.length>0)for(let c of t.generators)logger.info(` \u{1F4E5} ${c.name}: ${c.cardCount} cards (${c.newCount} new, ${c.reviewCount} reviews)`);if(t.filters.length>0){logger.info(`Filters:`);for(let c of t.filters)logger.info(` \u{1F538} ${c.name}: \u2191${c.boosted} \u2193${c.penalized} =${c.passed} \u2715${c.removed}`)}else logger.info(`Filters: (none)`);console.groupEnd()},async diagnoseCardSpace(t){return _activePipeline?_activePipeline.diagnoseCardSpace({threshold:t}):(logger.info(`[Pipeline Debug] No active pipeline. Run a session first.`),null)},async showTagElo(t){if(!_activePipeline){logger.info(`[Pipeline Debug] No active pipeline. Run a session first.`);return}let c=await _activePipeline.getTagEloStatus(t),u=Object.entries(c).sort(([t],[c])=>t.localeCompare(c));if(u.length===0){logger.info(`[Pipeline Debug] No tag ELO data found${t?` for pattern: ${t}`:``}.`);return}console.table(Object.fromEntries(u.map(([t,c])=>[t,{score:Math.round(c.score),count:c.count}])))},ui(){if(_uiContainer){document.body.removeChild(_uiContainer),_uiContainer=null;return}_uiContainer=document.createElement(`div`),_uiContainer.id=`sk-pipeline-debugger`,document.body.appendChild(_uiContainer),_selectedRunIndex===null&&runHistory.length>0&&(_selectedRunIndex=0),renderUI()},_selectRun(t){_selectedRunIndex=t,renderUI()},_setSearch(t){_cardSearchQuery=t,renderUI()},_copyConfig(t,c){let u=runHistory.find(c=>c.runId===t);if(!u)return;let d={runId:u.runId,timestamp:u.timestamp.toISOString(),courseId:u.courseId,courseName:u.courseName,hints:u.hints??null};copyTextToClipboard(JSON.stringify(d,null,2),c)},_copyResults(t,c){let u=runHistory.find(c=>c.runId===t);if(!u)return;let d=u.cards.filter(t=>t.selected).sort((t,c)=>c.finalScore-t.finalScore).map(t=>({cardId:t.cardId,generator:t.generator,origin:t.origin,score:Number(t.finalScore.toFixed(3)),topReason:t.provenance[0]?.reason??``})),m={runId:u.runId,label:u.hints?._label??null,finalCount:u.finalCount,newSelected:u.newSelected,reviewsSelected:u.reviewsSelected,selected:d};copyTextToClipboard(JSON.stringify(m,null,2),c)},help(){logger.info(`
|
|
328
328
|
🔧 Pipeline Debug API
|
|
329
329
|
|
|
330
330
|
Commands:
|
|
@@ -349,7 +349,7 @@ Example:
|
|
|
349
349
|
window.skuilder.pipeline.showLastRun()
|
|
350
350
|
window.skuilder.pipeline.showRun(1)
|
|
351
351
|
await window.skuilder.pipeline.diagnoseCardSpace()
|
|
352
|
-
`)}},mountPipelineDebugger()}}),CompositeGenerator_exports={},__export(CompositeGenerator_exports,{AggregationMode:()=>AggregationMode,default:()=>CompositeGenerator}),init_CompositeGenerator=__esm({"src/core/navigators/generators/CompositeGenerator.ts"(){"use strict";init_navigators(),init_logger(),AggregationMode=(t=>(t.MAX=`max`,t.AVERAGE=`average`,t.FREQUENCY_BOOST=`frequencyBoost`,t))(AggregationMode||{}),DEFAULT_AGGREGATION_MODE=`frequencyBoost`,FREQUENCY_BOOST_FACTOR=.1,CompositeGenerator=class _CompositeGenerator extends ContentNavigator{constructor(t,c=DEFAULT_AGGREGATION_MODE){if(super(),_defineProperty$2(this,`name`,`Composite Generator`),_defineProperty$2(this,`generators`,void 0),_defineProperty$2(this,`aggregationMode`,void 0),this.generators=t,this.aggregationMode=c,t.length===0)throw Error(`CompositeGenerator requires at least one generator`);logger.debug(`[CompositeGenerator] Created with ${t.length} generators, mode: ${c}`)}static async fromStrategies(t,c,u,d=DEFAULT_AGGREGATION_MODE){return new _CompositeGenerator(await Promise.all(u.map(u=>ContentNavigator.create(t,c,u))),d)}async getWeightedCards(t,c){if(!c)throw Error(`CompositeGenerator.getWeightedCards requires a GeneratorContext. It should be called via Pipeline, not directly.`);let u=await Promise.all(this.generators.map(u=>u.getWeightedCards(t,c))),d=[];u.forEach((t,c)=>{let u=t.cards,m=this.generators[c].name||`Generator ${c}`,g=u.filter(t=>t.provenance[0]?.reason?.includes(`new card`)),b=u.filter(t=>t.provenance[0]?.reason?.includes(`review`));if(u.length>0){let t=Math.max(...u.map(t=>t.score)).toFixed(2),c=[];g.length>0&&c.push(`${g.length} new`),b.length>0&&c.push(`${b.length} reviews`);let S=c.length>0?c.join(`, `):`${u.length} cards`;d.push(`${m}: ${S} (top: ${t})`)}else d.push(`${m}: 0 cards`)}),logger.info(`[Composite] Generator breakdown: ${d.join(` | `)}`);let m=new Map;u.forEach((t,u)=>{let d=t.cards,g=this.generators[u],b=g.learnable?.weight??1,S;if(g.learnable&&!g.staticWeight&&c.orchestration){let t=g.strategyId;t&&(b=c.orchestration.getEffectiveWeight(t,g.learnable),S=c.orchestration.getDeviation(t))}for(let t of d){t.provenance.length>0&&(t.provenance[0].effectiveWeight=b,t.provenance[0].deviation=S);let c=m.get(t.cardId)||[];c.push({card:t,weight:b}),m.set(t.cardId,c)}});let g=[];for(let[,t]of m){let c=t.map(t=>t.card),u=this.aggregateScores(t),d=Math.max(0,u),m=c.flatMap(t=>t.provenance),b=c[0].score,S=d>b?`boosted`:d<b?`penalized`:`passed`,C=this.buildAggregationReason(t,d);g.push({...c[0],score:d,provenance:[...m,{strategy:`composite`,strategyName:`Composite Generator`,strategyId:`COMPOSITE_GENERATOR`,action:S,score:d,reason:C}]})}return{cards:g.sort((t,c)=>c.score-t.score).slice(0,t),hints:mergeHints(u.map(t=>t.hints))}}buildAggregationReason(t,c){let u=t.map(t=>t.card),d=u.length,m=u.map(t=>t.score.toFixed(2)).join(`, `);if(d===1){let u=Math.abs(t[0].weight-1)>.001?` (w=${t[0].weight.toFixed(2)})`:``;return`Single generator, score ${c.toFixed(2)}${u}`}let g=u.map(t=>t.provenance[0]?.strategy||`unknown`).join(`, `);switch(this.aggregationMode){case`max`:return`Max of ${d} generators (${g}): scores [${m}] \u2192 ${c.toFixed(2)}`;case`average`:return`Weighted Avg of ${d} generators (${g}): scores [${m}] \u2192 ${c.toFixed(2)}`;case`frequencyBoost`:{let u=t.reduce((t,c)=>t+c.weight,0),m=t.reduce((t,c)=>t+c.card.score*c.weight,0),b=u>0?m/u:0,S=1+FREQUENCY_BOOST_FACTOR*(d-1);return`Frequency boost from ${d} generators (${g}): w-avg ${b.toFixed(2)} \xD7 ${S.toFixed(2)} \u2192 ${c.toFixed(2)}`}default:return`Aggregated from ${d} generators: ${c.toFixed(2)}`}}aggregateScores(t){let c=t.map(t=>t.card.score);switch(this.aggregationMode){case`max`:return Math.max(...c);case`average`:{let c=t.reduce((t,c)=>t+c.weight,0);return c===0?0:t.reduce((t,c)=>t+c.card.score*c.weight,0)/c}case`frequencyBoost`:{let c=t.reduce((t,c)=>t+c.weight,0),u=t.reduce((t,c)=>t+c.card.score*c.weight,0);return(c>0?u/c:0)*(1+FREQUENCY_BOOST_FACTOR*(t.length-1))}default:return c[0]}}}}}),elo_exports={},__export(elo_exports,{default:()=>ELONavigator}),init_elo=__esm({"src/core/navigators/generators/elo.ts"(){"use strict";init_navigators(),init_logger(),ELO_RELEVANCE_SIGMA=300,ELONavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`name`,void 0),this.name=u?.name||`ELO`}async getWeightedCards(t,c){let u;u=c?.userElo===void 0?toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo).global.score:c.userElo;let d=await this.user.getActiveCards(),m=(await this.course.getCardsCenteredAtELO({limit:t,elo:`user`},t=>!d.some(c=>t.cardID===c.cardID))).map(t=>({...t,status:`new`})).map(t=>{let c=t.elo??1e3,d=Math.abs(c-u),m=Math.exp(-((d/ELO_RELEVANCE_SIGMA)**2)),g=m*(.5+.5*Math.random());return{cardId:t.cardID,courseId:t.courseID,score:g,provenance:[{strategy:`elo`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-ELO-default`,action:`generated`,score:g,reason:`ELO distance ${Math.round(d)} (card: ${Math.round(c)}, user: ${Math.round(u)}), relevance ${m.toFixed(3)}, key ${g.toFixed(3)}`}]}});m.sort((t,c)=>c.score-t.score);let g=m.slice(0,t);if(g.length>0){let t=g.slice(0,3).map(t=>t.score.toFixed(2)).join(`, `);logger.info(`[ELO] Course ${this.course.getCourseID()}: ${g.length} new cards (top scores: ${t})`)}else logger.info(`[ELO] Course ${this.course.getCourseID()}: No new cards available`);return{cards:g}}}}}),generators_exports={},init_generators=__esm({"src/core/navigators/generators/index.ts"(){"use strict";}}),prescribed_exports={},__export(prescribed_exports,{default:()=>PrescribedCardsGenerator}),init_prescribed=__esm({"src/core/navigators/generators/prescribed.ts"(){"use strict";init_navigators(),init_logger(),DEFAULT_FRESHNESS_WINDOW=3,DEFAULT_MAX_DIRECT_PER_RUN=3,DEFAULT_MAX_SUPPORT_PER_RUN=3,DEFAULT_HIERARCHY_DEPTH=2,DEFAULT_MIN_COUNT=3,BASE_TARGET_SCORE=1,BASE_SUPPORT_SCORE=.8,DISCOVERED_SUPPORT_SCORE=12,MAX_TARGET_MULTIPLIER=8,MAX_SUPPORT_MULTIPLIER=4,PRESCRIBED_DEBUG_VERSION=`testversion-prescribed-v3`,PrescribedCardsGenerator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`config`,void 0),this.name=u.name||`Prescribed Cards`,this.config=this.parseConfig(u.serializedData),logger.debug(`[Prescribed] Initialized with ${this.config.groups.length} groups and ${this.config.groups.reduce((t,c)=>t+c.targetCardIds.length,0)} targets`)}get strategyKey(){return`PrescribedProgress`}async getWeightedCards(t,c){if(this.config.groups.length===0||t<=0)return{cards:[]};let u=this.course.getCourseID(),d=await this.user.getActiveCards(),m=new Set(d.map(t=>t.cardID)),g=await this.user.getSeenCards(u).catch(()=>[]),b=new Set(g),S=await this.getStrategyState()??{updatedAt:isoNow(),groups:{}},C=await this.loadHierarchyConfigs(),w=await this.user.getCourseRegDoc(u).catch(()=>null),T=typeof w?.elo==`number`?w.elo:w?.elo?.global?.score??c?.userElo??1e3,E=typeof w?.elo==`number`?{}:w?.elo?.tags??{},D=dedupe(this.config.groups.flatMap(t=>t.targetCardIds)),O=dedupe(this.config.groups.flatMap(t=>t.supportCardIds??[])),Or=dedupe([...D,...O]),kr=Or.length>0?await this.course.getAppliedTagsBatch(Or):new Map,Ar=await this.course.getCourseTagStubs().catch(()=>({rows:[],offset:0,total_rows:0})),jr=new Map;for(let t of Ar.rows??[]){let c=t.doc;c?.name&&Array.isArray(c.taggedCards)&&jr.set(c.name,[...c.taggedCards])}let Mr={updatedAt:isoNow(),groups:{}},Nr=[],Pr=new Set,Fr=[];for(let t of this.config.groups){let c=this.buildGroupRuntimeState({group:t,priorState:S.groups[t.id],activeIds:m,seenIds:b,tagsByCard:kr,cardsByTag:jr,hierarchyConfigs:C,userTagElo:E,userGlobalElo:T});Fr.push(c),logger.info(`[Prescribed] Group '${t.id}': ${t.targetCardIds.length} targets total, ${c.encounteredTargets.size} encountered, ${c.pendingTargets.length} pending (${c.surfaceableTargets.length} surfaceable, ${c.blockedTargets.length} blocked), ${c.supportCandidates.length} authored support candidates, ${c.discoveredSupportCandidates.length} discovered support candidates, pressure=${c.pressureMultiplier.toFixed(2)}`),c.blockedTargets.length>0&&(logger.info(`[Prescribed] Group '${t.id}' blocked targets: ${c.blockedTargets.join(`, `)}`),logger.info(`[Prescribed] Group '${t.id}' support tags needed: ${c.supportTags.join(`, `)||`(none)`}`),logger.info(`[Prescribed] Group '${t.id}' escalation mode: `+(c.supportCandidates.length>0?`direct-support`:c.discoveredSupportCandidates.length>0?`inserted-support-candidates`:`boost-only`)),c.discoveredSupportCandidates.length>0&&logger.info(`[Prescribed] Group '${t.id}' discovered support candidates: ${c.discoveredSupportCandidates.join(`, `)}`)),Mr.groups[t.id]=this.buildNextGroupState(c,S.groups[t.id]);let d=this.buildDirectTargetCards(c,u,Pr),g=this.buildSupportCards(c,u,Pr),w=this.buildDiscoveredSupportCards(c,u,Pr);Nr.push(...d,...g,...w)}let Ir=this.buildSupportHintSummary(Fr),Lr=Object.keys(Ir.boostTags).length>0?{boostTags:Ir.boostTags,_label:`prescribed-support (${Ir.supportTags.length} tags; blocked=${Ir.blockedTargetIds.length}; testversion=${PRESCRIBED_DEBUG_VERSION})`}:void 0;if(Lr){let t=Object.entries(Lr.boostTags??{});logger.info(`[Prescribed] Emitting ${t.length} boost hint(s): `+t.map(([t,c])=>`${t}\xD7${c.toFixed(1)}`).join(`, `))}else logger.info(`[Prescribed] No hints to emit (no blocked targets or no support tags)`);if(Nr.length===0)return logger.info(`[Prescribed] 0 cards emitted (all targets blocked, authored/discovered support candidates exhausted)`+(Lr?` — boost hints emitted but may not survive filters`:``)),await this.putStrategyState(Mr).catch(t=>{logger.debug(`[Prescribed] Failed to persist empty-state update: ${t}`)}),Lr?{cards:[],hints:Lr}:{cards:[]};let Rr=pickTopByScore(Nr,t),zr=new Map;for(let t of Rr){let c=t.provenance[0],u=c?.reason.match(/group=([^;]+)/)?.[1],d=c?.reason.includes(`mode=support`)?`supportIds`:`targetIds`;u&&(zr.has(u)||zr.set(u,{targetIds:[],supportIds:[]}),zr.get(u)[d].push(t.cardId))}for(let t of this.config.groups){let c=Mr.groups[t.id],u=zr.get(t.id);u&&(u.targetIds.length>0||u.supportIds.length>0)&&(c.lastSurfacedAt=isoNow(),c.sessionsSinceSurfaced=0,u.supportIds.length>0&&(c.lastSupportAt=isoNow()))}return await this.putStrategyState(Mr).catch(t=>{logger.debug(`[Prescribed] Failed to persist prescribed progress: ${t}`)}),logger.info(`[Prescribed] Emitting ${Rr.length} cards (${Rr.filter(t=>t.provenance[0]?.reason.includes(`mode=target`)).length} target, ${Rr.filter(t=>t.provenance[0]?.reason.includes(`mode=support`)).length} support, ${Rr.filter(t=>t.provenance[0]?.reason.includes(`mode=discovered-support`)).length} discovered support)`),Lr?{cards:Rr,hints:Lr}:{cards:Rr}}buildSupportHintSummary(t){let c={},u=new Set,d=new Set;for(let m of t)if(!(m.blockedTargets.length===0||m.supportTags.length===0)){m.blockedTargets.forEach(t=>u.add(t));for(let t of m.supportTags)d.add(t),c[t]=(c[t]??1)*m.supportMultiplier}return{boostTags:c,blockedTargetIds:[...u].sort(),supportTags:[...d].sort()}}parseConfig(t){try{let c=JSON.parse(t);return{groups:(Array.isArray(c.groups)?c.groups:[]).map((t,c)=>({id:typeof t.id==`string`&&t.id.trim().length>0?t.id:`group-${c+1}`,targetCardIds:dedupe(Array.isArray(t.targetCardIds)?t.targetCardIds.filter(t=>typeof t==`string`):[]),supportCardIds:dedupe(Array.isArray(t.supportCardIds)?t.supportCardIds.filter(t=>typeof t==`string`):[]),supportTagPatterns:dedupe(Array.isArray(t.supportTagPatterns)?t.supportTagPatterns.filter(t=>typeof t==`string`):[]),freshnessWindowSessions:typeof t.freshnessWindowSessions==`number`?t.freshnessWindowSessions:DEFAULT_FRESHNESS_WINDOW,maxDirectTargetsPerRun:typeof t.maxDirectTargetsPerRun==`number`?t.maxDirectTargetsPerRun:DEFAULT_MAX_DIRECT_PER_RUN,maxSupportCardsPerRun:typeof t.maxSupportCardsPerRun==`number`?t.maxSupportCardsPerRun:DEFAULT_MAX_SUPPORT_PER_RUN,hierarchyWalk:{enabled:t.hierarchyWalk?.enabled!==!1,maxDepth:typeof t.hierarchyWalk?.maxDepth==`number`?t.hierarchyWalk.maxDepth:DEFAULT_HIERARCHY_DEPTH},retireOnEncounter:t.retireOnEncounter!==!1})).filter(t=>t.targetCardIds.length>0)}}catch{return{groups:[]}}}async loadHierarchyConfigs(){try{return(await this.course.getAllNavigationStrategies()).filter(t=>t.implementingClass===`hierarchyDefinition`).map(t=>{try{return{prerequisites:JSON.parse(t.serializedData).prerequisites||{}}}catch{return{prerequisites:{}}}})}catch(t){return logger.debug(`[Prescribed] Failed to load hierarchy configs: ${t}`),[]}}buildGroupRuntimeState(t){let{group:c,priorState:u,activeIds:d,seenIds:m,tagsByCard:g,cardsByTag:b,hierarchyConfigs:S,userTagElo:C,userGlobalElo:w}=t,T=new Set;for(let t of c.targetCardIds)(d.has(t)||m.has(t))&&T.add(t);if(u?.encounteredCardIds?.length)for(let t of u.encounteredCardIds)T.add(t);let E=c.targetCardIds.filter(t=>!T.has(t)),D=new Map;for(let t of E)D.set(t,g.get(t)??[]);let O=[],Or=[],kr=new Set;for(let t of E){let u=D.get(t)??[],d=this.resolveBlockedSupportTags(u,S,C,w,c.hierarchyWalk?.enabled!==!1,c.hierarchyWalk?.maxDepth??DEFAULT_HIERARCHY_DEPTH),m=u.filter(t=>t.startsWith(`gpc:intro:`)),g=new Set(u.filter(t=>t.startsWith(`gpc:expose:`)));for(let t of m){let c=t.slice(10);c&&g.add(`gpc:expose:${c}`)}let b=[...g].filter(t=>{let c=C[t];return!c||c.count<DEFAULT_MIN_COUNT});b.length>0&&b.forEach(t=>kr.add(t)),d.blocked||b.length>0?(O.push(t),d.supportTags.forEach(t=>kr.add(t))):Or.push(t)}let Ar=dedupe([...c.supportCardIds??[],...this.findSupportCardsByTags(c,g,[...kr])]).filter(t=>!d.has(t)&&!m.has(t)),jr=O.length>0&&kr.size>0&&Ar.length===0?this.findDiscoveredSupportCards({supportTags:[...kr],cardsByTag:b,activeIds:d,seenIds:m,excludedIds:new Set([...c.targetCardIds,...c.supportCardIds??[]]),limit:c.maxSupportCardsPerRun??DEFAULT_MAX_SUPPORT_PER_RUN}):[];O.length>0&&kr.size>0&&jr.length===0&&logger.info(`[Prescribed] Group '${c.id}' discovered 0 broader support candidates (blocked=${O.length}; authoredSupport=${Ar.length})`);let Mr=u?.sessionsSinceSurfaced??0,Nr=c.freshnessWindowSessions??DEFAULT_FRESHNESS_WINDOW,Pr=Math.max(0,Mr-Nr),Fr=E.length===0?1:clamp(1+Pr*.75+Math.min(2,E.length*.1),1,MAX_TARGET_MULTIPLIER),Ir=O.length===0?1:clamp(1+Pr*.5+Math.min(1.5,O.length*.15),1,MAX_SUPPORT_MULTIPLIER);return{group:c,encounteredTargets:T,pendingTargets:E,blockedTargets:O,surfaceableTargets:Or,targetTags:D,supportCandidates:Ar,discoveredSupportCandidates:jr,supportTags:[...kr],pressureMultiplier:Fr,supportMultiplier:Ir,debugVersion:PRESCRIBED_DEBUG_VERSION}}buildNextGroupState(t,c){let u=c?.sessionsSinceSurfaced??0,d=!1;return{encounteredCardIds:[...t.encounteredTargets].sort(),pendingTargetIds:[...t.pendingTargets].sort(),lastSurfacedAt:c?.lastSurfacedAt??null,sessionsSinceSurfaced:u+1,lastSupportAt:c?.lastSupportAt??null,blockedTargetIds:[...t.blockedTargets].sort(),lastResolvedSupportTags:[...t.supportTags].sort()}}buildDirectTargetCards(t,c,u){let d=t.group.maxDirectTargetsPerRun??DEFAULT_MAX_DIRECT_PER_RUN,m=t.surfaceableTargets.filter(t=>!u.has(t)).slice(0,d),g=[];for(let d of m)u.add(d),g.push({cardId:d,courseId:c,score:BASE_TARGET_SCORE*t.pressureMultiplier,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:BASE_TARGET_SCORE*t.pressureMultiplier,reason:`mode=target;group=${t.group.id};pending=${t.pendingTargets.length};surfaceable=${t.surfaceableTargets.length};blocked=${t.blockedTargets.length};blockedTargets=${t.blockedTargets.join(`|`)||`none`};supportTags=${t.supportTags.join(`|`)||`none`};multiplier=${t.pressureMultiplier.toFixed(2)};testversion=${t.debugVersion}`}]});return g}buildSupportCards(t,c,u){if(t.blockedTargets.length===0||t.supportCandidates.length===0)return[];let d=t.group.maxSupportCardsPerRun??DEFAULT_MAX_SUPPORT_PER_RUN,m=t.supportCandidates.filter(t=>!u.has(t)).slice(0,d),g=[];for(let d of m)u.add(d),g.push({cardId:d,courseId:c,score:BASE_SUPPORT_SCORE*t.supportMultiplier,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:BASE_SUPPORT_SCORE*t.supportMultiplier,reason:`mode=support;group=${t.group.id};pending=${t.pendingTargets.length};blocked=${t.blockedTargets.length};blockedTargets=${t.blockedTargets.join(`|`)||`none`};supportCard=${d};supportTags=${t.supportTags.join(`|`)||`none`};multiplier=${t.supportMultiplier.toFixed(2)};testversion=${t.debugVersion}`}]});return g}buildDiscoveredSupportCards(t,c,u){if(t.blockedTargets.length===0||t.discoveredSupportCandidates.length===0)return[];let d=t.group.maxSupportCardsPerRun??DEFAULT_MAX_SUPPORT_PER_RUN,m=t.discoveredSupportCandidates.filter(t=>!u.has(t)).slice(0,d),g=[];for(let d of m)u.add(d),g.push({cardId:d,courseId:c,score:DISCOVERED_SUPPORT_SCORE*t.supportMultiplier,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:DISCOVERED_SUPPORT_SCORE*t.supportMultiplier,reason:`mode=discovered-support;group=${t.group.id};pending=${t.pendingTargets.length};blocked=${t.blockedTargets.length};blockedTargets=${t.blockedTargets.join(`|`)||`none`};supportCard=${d};supportTags=${t.supportTags.join(`|`)||`none`};multiplier=${t.supportMultiplier.toFixed(2)};testversion=${t.debugVersion}`}]});return g}findSupportCardsByTags(t,c,u){if(u.length===0)return[];let d=t.supportCardIds??[],m=t.supportTagPatterns??[];if(d.length===0&&m.length===0)return[];let g=new Set;for(let t of d){let d=c.get(t)??[],b=u.some(t=>d.includes(t)),S=m.some(t=>d.some(c=>matchesTagPattern(c,t)));(b||S)&&g.add(t)}return[...g]}findDiscoveredSupportCards(t){let{supportTags:c,cardsByTag:u,activeIds:d,seenIds:m,excludedIds:g,limit:b}=t,S=new Map;for(let t of c){let c=u.get(t)??[];for(let t of c){if(d.has(t)||m.has(t)||g.has(t))continue;let c=S.get(t);c?c.matches+=1:S.set(t,{cardId:t,matches:1})}}let C=[...S.values()].sort((t,c)=>c.matches-t.matches||t.cardId.localeCompare(c.cardId)),w=new Set,T=[],E=[];for(let t of C){let c=extractWordStem(t.cardId);w.has(c)?E.push(t):(w.add(c),T.push(t))}return shuffleInPlace(T),shuffleInPlace(E),[...T,...E].slice(0,b).map(t=>t.cardId)}resolveBlockedSupportTags(t,c,u,d,m,g){let b=new Set,S=!1;for(let C of t){let t=c.map(t=>t.prerequisites[C]).filter(t=>Array.isArray(t)&&t.length>0);if(t.length!==0&&t.some(t=>t.some(t=>!this.isPrerequisiteMet(t,u[t.tag],d)))){if(S=!0,!m){for(let c of t)for(let t of c)this.isPrerequisiteMet(t,u[t.tag],d)||b.add(t.tag);continue}for(let m of t)for(let t of m)this.isPrerequisiteMet(t,u[t.tag],d)||this.collectSupportTagsRecursive(t.tag,c,u,d,g,new Set,b)}}return{blocked:S,supportTags:[...b]}}collectSupportTagsRecursive(t,c,u,d,m,g,b){if(m<0||g.has(t))return;g.add(t);let S=!1;for(let C of c){let w=C.prerequisites[t];if(!w||w.length===0)continue;let T=w.filter(t=>!this.isPrerequisiteMet(t,u[t.tag],d));if(T.length>0&&m>0){S=!0;for(let t of T)this.collectSupportTagsRecursive(t.tag,c,u,d,m-1,g,b)}}S||b.add(t)}isPrerequisiteMet(t,c,u){if(!c)return!1;let d=t.masteryThreshold?.minCount??DEFAULT_MIN_COUNT;return c.count<d?!1:t.masteryThreshold?.minElo===void 0?t.masteryThreshold?.minCount===void 0?c.score>=u:!0:c.score>=t.masteryThreshold.minElo}}}}),srs_exports={},__export(srs_exports,{default:()=>SRSNavigator}),init_srs=__esm({"src/core/navigators/generators/srs.ts"(){"use strict";init_navigators(),init_logger(),DEFAULT_HEALTHY_BACKLOG=20,MAX_BACKLOG_PRESSURE=.5,SRSNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`healthyBacklog`,void 0),this.name=u?.name||`SRS`,this.healthyBacklog=this.parseConfig(u?.serializedData).healthyBacklog??DEFAULT_HEALTHY_BACKLOG}parseConfig(t){if(!t)return{};try{return JSON.parse(t)}catch{return logger.warn(`[SRS] Failed to parse strategy config, using defaults`),{}}}async getWeightedCards(t,c){if(!this.user||!this.course)throw Error(`SRSNavigator requires user and course to be set`);let u=this.course.getCourseID(),d=await this.user.getPendingReviews(u),m=hooks.utc(),g=d.filter(t=>m.isAfter(hooks.utc(t.reviewTime)));if(g.length>0){let t=[...new Set(g.map(t=>t.cardId))],c=await this.course.getAppliedTagsBatch(t),u=[];if(g=g.filter(t=>(c.get(t.cardId)??[]).includes(`srs:skip`)?(u.push(t._id),!1):!0),u.length>0){logger.info(`[SRS] Removing ${u.length} scheduled reviews for srs:skip cards`);for(let t of u)this.user.removeScheduledCardReview(t)}}let b=this.computeBacklogPressure(g.length);if(g.length>0){let t=b>0?` [backlog pressure: +${b.toFixed(2)}]`:` [healthy backlog]`;logger.info(`[SRS] Course ${u}: ${g.length} reviews due now (of ${d.length} scheduled)${t}`)}else if(d.length>0){let t=[...d].sort((t,c)=>hooks.utc(t.reviewTime).diff(hooks.utc(c.reviewTime)))[0],c=hooks.utc(t.reviewTime),g=hooks.duration(c.diff(m)),b=g.asHours()<1?`${Math.round(g.asMinutes())}m`:g.asHours()<24?`${Math.round(g.asHours())}h`:`${Math.round(g.asDays())}d`;logger.info(`[SRS] Course ${u}: 0 reviews due now (${d.length} scheduled, next in ${b})`)}else logger.info(`[SRS] Course ${u}: No reviews scheduled`);return{cards:g.map(t=>{let{score:c,reason:u}=this.computeUrgencyScore(t,m,b);return{cardId:t.cardId,courseId:t.courseId,score:c,reviewID:t._id,provenance:[{strategy:`srs`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-SRS-default`,action:`generated`,score:c,reason:u}]}}).sort((t,c)=>c.score-t.score).slice(0,t)}}computeBacklogPressure(t){if(t<=this.healthyBacklog)return 0;let c=(t-this.healthyBacklog)/this.healthyBacklog*(MAX_BACKLOG_PRESSURE/2);return Math.min(MAX_BACKLOG_PRESSURE,c)}computeUrgencyScore(t,c,u){let d=hooks.utc(t.scheduledAt),m=hooks.utc(t.reviewTime),g=Math.max(1,m.diff(d,`hours`)),b=c.diff(m,`hours`),S=b/g,C=.3+.7*Math.exp(-g/720),w=.5+(Math.min(1,Math.max(0,S))*.5+C*.5)*.45,T=Math.min(1,w+u),E=[`${Math.round(b)}h overdue`,`interval: ${Math.round(g)}h`,`relative: ${S.toFixed(2)}`,`recency: ${C.toFixed(2)}`];return u>0&&E.push(`backlog: +${u.toFixed(2)}`),E.push(`review`),{score:T,reason:E.join(`, `)}}}}}),types_exports={},init_types=__esm({"src/core/navigators/generators/types.ts"(){"use strict";}}),init_=__esm({'import("./generators/**/*") in src/core/navigators/index.ts'(){globImport_generators=__glob({"./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))})}}),init_contentNavigationStrategy=__esm({"src/core/types/contentNavigationStrategy.ts"(){"use strict";DEFAULT_LEARNABLE_WEIGHT={weight:1,confidence:.1,sampleSize:0}}}),WeightedFilter_exports={},__export(WeightedFilter_exports,{WeightedFilter:()=>WeightedFilter}),init_WeightedFilter=__esm({"src/core/navigators/filters/WeightedFilter.ts"(){"use strict";init_contentNavigationStrategy(),WeightedFilter=class{constructor(t,c=DEFAULT_LEARNABLE_WEIGHT,u=!1,d){_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`inner`,void 0),_defineProperty$2(this,`learnable`,void 0),_defineProperty$2(this,`staticWeight`,void 0),_defineProperty$2(this,`strategyId`,void 0),this.inner=t,this.name=t.name,this.learnable=c,this.staticWeight=u,this.strategyId=d}async transform(t,c){let u=this.learnable.weight,d;if(!this.staticWeight&&c.orchestration){let t=this.strategyId||this.inner.strategyId||this.name;u=c.orchestration.getEffectiveWeight(t,this.learnable),d=c.orchestration.getDeviation(t)}if(Math.abs(u-1)<.001)return this.inner.transform(t,c);let m=new Map;for(let c of t)m.set(c.cardId,c.score);return(await this.inner.transform(t,c)).map(t=>{let c=m.get(t.cardId);if(c===void 0||c===0||t.score===0)return t;let g=t.score/c;if(Math.abs(g-1)<1e-4)return t;let b=c*g**+u,S=t.provenance.length-1,C=t.provenance[S];if(C){let c=[...t.provenance];return c[S]={...C,score:b,effectiveWeight:u,deviation:d},{...t,score:b,provenance:c}}return{...t,score:b}})}}}}),eloDistance_exports={},__export(eloDistance_exports,{DEFAULT_HALF_LIFE:()=>DEFAULT_HALF_LIFE,DEFAULT_MAX_MULTIPLIER:()=>DEFAULT_MAX_MULTIPLIER,DEFAULT_MIN_MULTIPLIER:()=>DEFAULT_MIN_MULTIPLIER,createEloDistanceFilter:()=>createEloDistanceFilter}),init_eloDistance=__esm({"src/core/navigators/filters/eloDistance.ts"(){"use strict";DEFAULT_HALF_LIFE=200,DEFAULT_MIN_MULTIPLIER=.3,DEFAULT_MAX_MULTIPLIER=1}}),hierarchyDefinition_exports={},__export(hierarchyDefinition_exports,{default:()=>HierarchyDefinitionNavigator}),init_hierarchyDefinition=__esm({"src/core/navigators/filters/hierarchyDefinition.ts"(){"use strict";init_navigators(),init_logger(),DEFAULT_MIN_COUNT2=3,HierarchyDefinitionNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`name`,void 0),this.config=this.parseConfig(u.serializedData),this.name=u.name||`Hierarchy Definition`}parseConfig(t){try{return{prerequisites:JSON.parse(t).prerequisites||{}}}catch{return{prerequisites:{}}}}isPrerequisiteMet(t,c,u){if(!c)return!1;let d=t.masteryThreshold?.minCount??DEFAULT_MIN_COUNT2;return c.count<d?!1:t.masteryThreshold?.minElo===void 0?t.masteryThreshold?.minCount===void 0?c.score>=u:!0:c.score>=t.masteryThreshold.minElo}async getMasteredTags(t){let c=new Set;try{let u=toCourseElo((await t.user.getCourseRegDoc(t.course.getCourseID())).elo);for(let t of Object.values(this.config.prerequisites))for(let d of t){let t=u.tags[d.tag];this.isPrerequisiteMet(d,t,u.global.score)&&c.add(d.tag)}}catch{}return c}getUnlockedTags(t){let c=new Set;for(let[u,d]of Object.entries(this.config.prerequisites))d.every(c=>t.has(c.tag))&&c.add(u);return c}hasPrerequisites(t){return t in this.config.prerequisites}async checkCardUnlock(t,c,u,d){try{let c=t.tags??[],m=c.filter(t=>this.hasPrerequisites(t)&&!u.has(t));return m.length===0?{isUnlocked:!0,reason:`Prerequisites met, tags: ${c.length>0?c.join(`, `):`none`}`}:{isUnlocked:!1,reason:`Blocked: missing prerequisites ${m.flatMap(t=>(this.config.prerequisites[t]||[]).filter(t=>!d.has(t.tag)).map(t=>t.tag)).join(`, `)} for tags ${m.join(`, `)}`}}catch{return{isUnlocked:!0,reason:`Prerequisites check skipped (tag lookup failed)`}}}getPreReqBoosts(t,c){let u=new Map;for(let[d,m]of Object.entries(this.config.prerequisites))if(!t.has(d))for(let t of m){if(!t.preReqBoost||t.preReqBoost<=1||c.has(t.tag))continue;let d=u.get(t.tag)??1;u.set(t.tag,Math.max(d,t.preReqBoost))}return u}getTargetBoosts(t){let c=new Map,u=Object.keys(this.config.prerequisites),d=[...t];logger.info(`[HierarchyDefinition:targetBoost:trace] ${this.name} | configKeys=${u.length}, unlocked=${d.length} (${d.slice(0,5).join(`, `)}${d.length>5?`...`:``})`);for(let[u,d]of Object.entries(this.config.prerequisites))if(t.has(u)){logger.info(`[HierarchyDefinition:targetBoost:trace] UNLOCKED ${u}: ${d.length} prereqs, raw=${JSON.stringify(d.map(t=>({tag:t.tag,tb:t.targetBoost})))}`);for(let t of d){if(!t.targetBoost||t.targetBoost<=1)continue;let d=c.get(u)??1;c.set(u,Math.max(d,t.targetBoost))}}return c.size>0?logger.info(`[HierarchyDefinition] targetBoosts active: ${[...c.entries()].map(([t,c])=>`${t}=\xD7${c}`).join(`, `)}`):logger.info(`[HierarchyDefinition:targetBoost:trace] no targetBoosts found despite ${d.length} unlocked tags`),c}async transform(t,c){let u=await this.getMasteredTags(c),d=this.getUnlockedTags(u),m=this.getPreReqBoosts(d,u),g=this.getTargetBoosts(d),b=[];for(let S of t){let{isUnlocked:t,reason:C}=await this.checkCardUnlock(S,c.course,d,u),w=t?S.score:S.score*.02,T=t?`passed`:`penalized`,E=C;if(t&&m.size>0){let t=S.tags??[],c=1,u=[];for(let d of t){let t=m.get(d);t&&t>c&&(c=t,u.push(d))}c>1&&(w*=c,T=`boosted`,E=`${C} | preReqBoost \xD7${c.toFixed(2)} for ${u.join(`, `)}`,logger.info(`[HierarchyDefinition] preReqBoost \xD7${c.toFixed(2)} applied to card ${S.cardId} via tags [${u.join(`, `)}] (score: ${S.score.toFixed(3)} \u2192 ${w.toFixed(3)})`))}if(t&&g.size>0){let t=S.tags??[],c=1,u=[];for(let d of t){let t=g.get(d);t&&t>c&&(c=t,u.push(d))}c>1&&(w*=c,T=`boosted`,E=`${E} | targetBoost \xD7${c.toFixed(2)} for ${u.join(`, `)}`,logger.info(`[HierarchyDefinition] targetBoost \xD7${c.toFixed(2)} applied to card ${S.cardId} via tags [${u.join(`, `)}] (score: ${S.score.toFixed(3)} \u2192 ${w.toFixed(3)})`))}b.push({...S,score:w,provenance:[...S.provenance,{strategy:`hierarchyDefinition`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-hierarchy`,action:T,score:w,reason:E}]})}return b}async getWeightedCards(t){throw Error(`HierarchyDefinitionNavigator is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),userTagPreference_exports={},__export(userTagPreference_exports,{default:()=>UserTagPreferenceFilter}),init_userTagPreference=__esm({"src/core/navigators/filters/userTagPreference.ts"(){"use strict";init_navigators(),UserTagPreferenceFilter=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`_strategyData`,void 0),_defineProperty$2(this,`name`,void 0),this._strategyData=u,this.name=u.name||`User Tag Preferences`}computeMultiplier(t,c){let u=t.map(t=>c[t]).filter(t=>t!==void 0);return u.length===0?1:Math.max(...u)}buildReason(t,c,u){let d=t.filter(t=>c[t]===u);return u===0?`Excluded by user preference: ${d.join(`, `)} (${u}x)`:u<1?`Penalized by user preference: ${d.join(`, `)} (${u.toFixed(2)}x)`:u>1?`Boosted by user preference: ${d.join(`, `)} (${u.toFixed(2)}x)`:`No matching user preferences`}async transform(t,c){let u=await this.getStrategyState();return!u||Object.keys(u.boost).length===0?t.map(t=>({...t,provenance:[...t.provenance,{strategy:`userTagPreference`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||this._strategyData._id,action:`passed`,score:t.score,reason:`No user tag preferences configured`}]})):await Promise.all(t.map(async t=>{let c=t.tags??[],d=this.computeMultiplier(c,u.boost),m=Math.min(1,t.score*d),g;return g=d===0||d<1?`penalized`:d>1?`boosted`:`passed`,{...t,score:m,provenance:[...t.provenance,{strategy:`userTagPreference`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||this._strategyData._id,action:g,score:m,reason:this.buildReason(c,u.boost,d)}]}}))}async getWeightedCards(t){throw Error(`UserTagPreferenceFilter is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),filters_exports={},__export(filters_exports,{UserTagPreferenceFilter:()=>UserTagPreferenceFilter,createEloDistanceFilter:()=>createEloDistanceFilter}),init_filters=__esm({"src/core/navigators/filters/index.ts"(){"use strict";init_eloDistance(),init_userTagPreference()}}),inferredPreferenceStub_exports={},__export(inferredPreferenceStub_exports,{INFERRED_PREFERENCE_NAVIGATOR_STUB:()=>INFERRED_PREFERENCE_NAVIGATOR_STUB}),init_inferredPreferenceStub=__esm({"src/core/navigators/filters/inferredPreferenceStub.ts"(){"use strict";INFERRED_PREFERENCE_NAVIGATOR_STUB=!0}}),interferenceMitigator_exports={},__export(interferenceMitigator_exports,{default:()=>InterferenceMitigatorNavigator}),init_interferenceMitigator=__esm({"src/core/navigators/filters/interferenceMitigator.ts"(){"use strict";init_navigators(),DEFAULT_MIN_COUNT3=10,DEFAULT_MIN_ELAPSED_DAYS=3,DEFAULT_INTERFERENCE_DECAY=.8,InterferenceMitigatorNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`interferenceMap`,void 0),this.config=this.parseConfig(u.serializedData),this.interferenceMap=this.buildInterferenceMap(),this.name=u.name||`Interference Mitigator`}parseConfig(t){try{let c=JSON.parse(t),u=c.interferenceSets||[];return u.length>0&&Array.isArray(u[0])&&(u=u.map(t=>({tags:t}))),{interferenceSets:u,maturityThreshold:{minCount:c.maturityThreshold?.minCount??DEFAULT_MIN_COUNT3,minElo:c.maturityThreshold?.minElo,minElapsedDays:c.maturityThreshold?.minElapsedDays??DEFAULT_MIN_ELAPSED_DAYS},defaultDecay:c.defaultDecay??DEFAULT_INTERFERENCE_DECAY}}catch{return{interferenceSets:[],maturityThreshold:{minCount:DEFAULT_MIN_COUNT3,minElapsedDays:DEFAULT_MIN_ELAPSED_DAYS},defaultDecay:DEFAULT_INTERFERENCE_DECAY}}}buildInterferenceMap(){let t=new Map;for(let c of this.config.interferenceSets){let u=c.decay??this.config.defaultDecay??DEFAULT_INTERFERENCE_DECAY;for(let d of c.tags){t.has(d)||t.set(d,[]);let m=t.get(d);for(let t of c.tags)if(t!==d){let c=m.find(c=>c.partner===t);c?c.decay=Math.max(c.decay,u):m.push({partner:t,decay:u})}}}return t}async getImmatureTags(t){let c=new Set;try{let u=toCourseElo((await t.user.getCourseRegDoc(t.course.getCourseID())).elo),d=this.config.maturityThreshold?.minCount??DEFAULT_MIN_COUNT3,m=this.config.maturityThreshold?.minElo,g=(this.config.maturityThreshold?.minElapsedDays??DEFAULT_MIN_ELAPSED_DAYS)*2;for(let[t,b]of Object.entries(u.tags)){if(b.count===0)continue;let u=b.count<d,S=m!==void 0&&b.score<m,C=b.count<g;(u||S||C)&&c.add(t)}}catch{}return c}getTagsToAvoid(t){let c=new Map;for(let u of t){let d=this.interferenceMap.get(u);if(d){for(let{partner:u,decay:m}of d)if(!t.has(u)){let t=c.get(u)??0;c.set(u,Math.max(t,m))}}}return c}computeInterferenceEffect(t,c,u){if(c.size===0)return{multiplier:1,interferingTags:[],reason:`No interference detected`};let d=1,m=[];for(let u of t){let t=c.get(u);t!==void 0&&(m.push(u),d*=1-t)}if(m.length===0)return{multiplier:1,interferingTags:[],reason:`No interference detected`};let g=new Set;for(let t of m)for(let c of u)this.interferenceMap.get(c)?.some(c=>c.partner===t)&&g.add(c);let b=`Interferes with immature tags ${Array.from(g).join(`, `)} (tags: ${m.join(`, `)}, multiplier: ${d.toFixed(2)})`;return{multiplier:d,interferingTags:m,reason:b}}async transform(t,c){let u=await this.getImmatureTags(c),d=this.getTagsToAvoid(u),m=[];for(let c of t){let t=c.tags??[],{multiplier:g,reason:b}=this.computeInterferenceEffect(t,d,u),S=c.score*g,C=g<1?`penalized`:g>1?`boosted`:`passed`;m.push({...c,score:S,provenance:[...c.provenance,{strategy:`interferenceMitigator`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-interference`,action:C,score:S,reason:b}]})}return m}async getWeightedCards(t){throw Error(`InterferenceMitigatorNavigator is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),relativePriority_exports={},__export(relativePriority_exports,{default:()=>RelativePriorityNavigator}),init_relativePriority=__esm({"src/core/navigators/filters/relativePriority.ts"(){"use strict";init_navigators(),DEFAULT_PRIORITY=.5,DEFAULT_PRIORITY_INFLUENCE=.5,DEFAULT_COMBINE_MODE=`max`,RelativePriorityNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`name`,void 0),this.config=this.parseConfig(u.serializedData),this.name=u.name||`Relative Priority`}parseConfig(t){try{let c=JSON.parse(t);return{tagPriorities:c.tagPriorities||{},defaultPriority:c.defaultPriority??DEFAULT_PRIORITY,combineMode:c.combineMode??DEFAULT_COMBINE_MODE,priorityInfluence:c.priorityInfluence??DEFAULT_PRIORITY_INFLUENCE}}catch{return{tagPriorities:{},defaultPriority:DEFAULT_PRIORITY,combineMode:DEFAULT_COMBINE_MODE,priorityInfluence:DEFAULT_PRIORITY_INFLUENCE}}}getTagPriority(t){return this.config.tagPriorities[t]??this.config.defaultPriority??DEFAULT_PRIORITY}computeCardPriority(t){if(t.length===0)return this.config.defaultPriority??DEFAULT_PRIORITY;let c=t.map(t=>this.getTagPriority(t));switch(this.config.combineMode){case`max`:return Math.max(...c);case`min`:return Math.min(...c);case`average`:return c.reduce((t,c)=>t+c,0)/c.length;default:return Math.max(...c)}}computeBoostFactor(t){let c=this.config.priorityInfluence??DEFAULT_PRIORITY_INFLUENCE;return 1+(t-.5)*c}buildPriorityReason(t,c,u,d){if(t.length===0)return`No tags, neutral priority (${c.toFixed(2)})`;let m=t.slice(0,3).join(`, `),g=t.length>3?` (+${t.length-3} more)`:``;return u===1?`Neutral priority (${c.toFixed(2)}) for tags: ${m}${g}`:u>1?`High-priority tags: ${m}${g} (priority ${c.toFixed(2)} \u2192 boost ${u.toFixed(2)}x \u2192 ${d.toFixed(2)})`:`Low-priority tags: ${m}${g} (priority ${c.toFixed(2)} \u2192 reduce ${u.toFixed(2)}x \u2192 ${d.toFixed(2)})`}async transform(t,c){return await Promise.all(t.map(async t=>{let c=t.tags??[],u=this.computeCardPriority(c),d=this.computeBoostFactor(u),m=Math.max(0,t.score*d),g=d>1?`boosted`:d<1?`penalized`:`passed`,b=this.buildPriorityReason(c,u,d,m);return{...t,score:m,provenance:[...t.provenance,{strategy:`relativePriority`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-priority`,action:g,score:m,reason:b}]}}))}async getWeightedCards(t){throw Error(`RelativePriorityNavigator is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),types_exports2={},init_types2=__esm({"src/core/navigators/filters/types.ts"(){"use strict";}}),userGoalStub_exports={},__export(userGoalStub_exports,{USER_GOAL_NAVIGATOR_STUB:()=>USER_GOAL_NAVIGATOR_STUB}),init_userGoalStub=__esm({"src/core/navigators/filters/userGoalStub.ts"(){"use strict";USER_GOAL_NAVIGATOR_STUB=!0}}),init_2=__esm({'import("./filters/**/*") in src/core/navigators/index.ts'(){globImport_filters=__glob({"./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))})}}),init_gradient=__esm({"src/core/orchestration/gradient.ts"(){"use strict";init_logger()}}),init_learning=__esm({"src/core/orchestration/learning.ts"(){"use strict";init_contentNavigationStrategy(),init_types_legacy(),init_logger(),MIN_OBSERVATIONS_FOR_UPDATE=10,LEARNING_RATE=.1,MAX_WEIGHT_DELTA=.3,MIN_R_SQUARED_FOR_GRADIENT=.05,FLAT_GRADIENT_THRESHOLD=.02,MAX_HISTORY_LENGTH=100}}),init_signal=__esm({"src/core/orchestration/signal.ts"(){"use strict";}}),init_recording=__esm({"src/core/orchestration/recording.ts"(){"use strict";init_signal(),init_types_legacy(),init_logger()}}),init_orchestration=__esm({"src/core/orchestration/index.ts"(){"use strict";init_logger(),init_gradient(),init_learning(),init_signal(),init_recording(),MIN_SPREAD=.1,MAX_SPREAD=.5,MIN_WEIGHT=.1,MAX_WEIGHT=3}}),Pipeline_exports={},__export(Pipeline_exports,{Pipeline:()=>Pipeline,mergeHints:()=>mergeHints2}),init_Pipeline=__esm({"src/core/navigators/Pipeline.ts"(){"use strict";init_navigators(),init_logger(),init_orchestration(),init_PipelineDebugger(),VERBOSE_RESULTS=!0,Pipeline=class extends ContentNavigator{constructor(t,c,u,d){super(),_defineProperty$2(this,`generator`,void 0),_defineProperty$2(this,`filters`,void 0),_defineProperty$2(this,`_cachedOrchestration`,null),_defineProperty$2(this,`_tagCache`,new Map),_defineProperty$2(this,`_ephemeralHints`,null),this.generator=t,this.filters=c,this.user=u,this.course=d,d.getCourseConfig().then(t=>{logger.debug(`[pipeline] Crated pipeline for ${t.name}`)}).catch(t=>{logger.error(`[pipeline] Failed to lookup courseCfg: ${t}`)}),logPipelineConfig(t,c),registerPipelineForDebug(this)}setEphemeralHints(t){this._ephemeralHints=t,logger.info(`[Pipeline] Ephemeral hints set: ${JSON.stringify(t)}`)}async getWeightedCards(t){let c=performance.now(),u=await this.buildContext(),d=performance.now(),m=500;logger.debug(`[Pipeline] Fetching 500 candidates from generator '${this.generator.name}'`);let g=await this.generator.getWeightedCards(500,u),b=g.cards,S=performance.now(),C=b.length;this._ephemeralHints=mergeHints2([this._ephemeralHints,g.hints])??null;let w;if(this.generator.generators){let t=new Map;for(let c of b){let u=c.provenance[0];if(u){let d=u.strategyName;t.has(d)||t.set(d,{cards:[]}),t.get(d).cards.push(c)}}w=Array.from(t.entries()).map(([t,c])=>{let u=c.cards.filter(t=>t.provenance[0]?.reason?.includes(`new card`)),d=c.cards.filter(t=>t.provenance[0]?.reason?.includes(`review`));return{name:t,cardCount:c.cards.length,newCount:u.length,reviewCount:d.length,topScore:Math.max(...c.cards.map(t=>t.score),0)}})}logger.debug(`[Pipeline] Generator returned ${C} candidates`),b=await this.hydrateTags(b);let T=performance.now(),E=[...b],D=this._ephemeralHints;if(D?.requireCards?.length){let t=new Set(E.map(t=>t.cardId)),c=D.requireCards.filter(c=>!c.includes(`*`)&&!t.has(c));if(c.length>0){let t=await this.course.getAppliedTagsBatch(c),u=this.course.getCourseID();for(let d of c)E.push({cardId:d,courseId:u,score:1,tags:t.get(d)??[],provenance:[]});logger.info(`[Pipeline] Pre-fetched ${c.length} required card(s) into pool: ${c.join(`, `)}`)}}let O=new Set(b.filter(t=>t.provenance.some(t=>t.strategy===`prescribed`)).map(t=>t.cardId)),Or=[];for(let t of this.filters){let c=b.length,d=new Map(b.map(t=>[t.cardId,t.score]));b=await t.transform(b,u);let m=0,g=0,S=0,C=c-b.length;for(let t of b){let c=d.get(t.cardId)??0;t.score>c?m++:t.score<c?g++:S++}if(Or.push({name:t.name,boosted:m,penalized:g,passed:S,removed:C}),O.size>0){let c=new Set(b.map(t=>t.cardId)),u=[...O].filter(t=>!c.has(t)),d=b.filter(t=>O.has(t.cardId)&&t.score===0).map(t=>t.cardId);(u.length>0||d.length>0)&&(logger.info(`[Pipeline] Filter '${t.name}' impact on prescribed cards: `+(u.length>0?`removed=[${u.join(`, `)}] `:``)+(d.length>0?`zeroed=[${d.join(`, `)}]`:``)),u.forEach(t=>O.delete(t)))}logger.debug(`[Pipeline] Filter '${t.name}': ${d.size} \u2192 ${b.length} cards (\u2191${m} \u2193${g} =${S})`)}b=b.filter(t=>t.score>0);let kr=this._ephemeralHints;kr&&(this._ephemeralHints=null,b=this.applyHints(b,kr,E)),b.sort((t,c)=>c.score-t.score);let Ar=performance.now(),jr=b.slice(0,t);logger.info(`[Pipeline:timing] total=${(Ar-c).toFixed(0)}ms (context=${(d-c).toFixed(0)} generate=${(S-d).toFixed(0)} hydrate=${(T-S).toFixed(0)} filter=${(Ar-T).toFixed(0)})`);let Mr=jr.slice(0,3).map(t=>t.score);logExecutionSummary(this.generator.name,C,this.filters.length,jr.length,Mr,Or),logResultCards(jr),logCardProvenance(jr,3);try{let t=await this.course?.getCourseConfig().then(t=>t.name).catch(()=>void 0);captureRun(buildRunReport(this.course?.getCourseID()||`unknown`,t,this.generator.name,w,C,Or,b,jr,u.userElo,kr??void 0))}catch(t){logger.debug(`[Pipeline] Failed to capture debug run: ${t}`)}return{cards:jr}}async hydrateTags(t){if(t.length===0)return t;let c=[];for(let u of t)this._tagCache.has(u.cardId)||c.push(u.cardId);if(c.length>0){let t=await this.course.getAppliedTagsBatch(c);for(let[c,u]of t)this._tagCache.set(c,u)}let u=new Map;for(let c of t)u.set(c.cardId,this._tagCache.get(c.cardId)??[]);return logTagHydration(t,u),t.map(t=>({...t,tags:this._tagCache.get(t.cardId)??[]}))}applyHints(t,c,u){let d=t.length;if(c.excludeCards?.length&&(t=t.filter(t=>!c.excludeCards.some(c=>globMatch(t.cardId,c)))),c.excludeTags?.length&&(t=t.filter(t=>!c.excludeTags.some(c=>cardMatchesTagPattern(t,c)))),c.boostTags)for(let[u,d]of Object.entries(c.boostTags))for(let m of t)cardMatchesTagPattern(m,u)&&(m.score*=d,m.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:c._label?`Replan Hint (${c._label})`:`Replan Hint`,action:`boosted`,score:m.score,reason:`boostTag ${u} \xD7${d}`}));if(c.boostCards)for(let[u,d]of Object.entries(c.boostCards))for(let m of t)globMatch(m.cardId,u)&&(m.score*=d,m.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:c._label?`Replan Hint (${c._label})`:`Replan Hint`,action:`boosted`,score:m.score,reason:`boostCard ${u} \xD7${d}`}));let m=new Set(t.map(t=>t.cardId)),g=new Map(t.map(t=>[t.cardId,t])),b=c._label?`Replan Hint (${c._label})`:`Replan Hint`,applyRequirement=(c,u)=>{let d=1/0,S=g.get(c.cardId);S?S.score<d&&(S.score=d,S.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:b,action:`boosted`,score:d,reason:`${u} (upgrade to mandatory score)`})):(t.push({...c,score:d,provenance:[...c.provenance,{strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:b,action:`boosted`,score:d,reason:u}]}),m.add(c.cardId),g.set(c.cardId,t[t.length-1]))};if(c.requireCards?.length)for(let t of c.requireCards){for(let c of m)globMatch(c,t)&&applyRequirement(g.get(c),`requireCard ${t}`);for(let c of u)globMatch(c.cardId,t)&&applyRequirement(c,`requireCard ${t}`)}if(c.requireTags?.length)for(let t of c.requireTags){for(let c of m){let u=g.get(c);cardMatchesTagPattern(u,t)&&applyRequirement(u,`requireTag ${t}`)}for(let c of u)cardMatchesTagPattern(c,t)&&applyRequirement(c,`requireTag ${t}`)}return logger.info(`[Pipeline] Hints applied: ${d} \u2192 ${t.length} cards`),t}async buildContext(){let t=1e3;try{t=toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo).global.score}catch(t){logger.debug(`[Pipeline] Could not get user ELO, using default: ${t}`)}this._cachedOrchestration||(this._cachedOrchestration=await createOrchestrationContext(this.user,this.course));let c=this._cachedOrchestration;return{user:this.user,course:this.course,userElo:t,orchestration:c}}getCourseID(){return this.course.getCourseID()}async getOrchestrationContext(){return createOrchestrationContext(this.user,this.course)}getStrategyIds(){let t=[],extractId=t=>t.strategyId?t.strategyId:null,c=extractId(this.generator);c&&t.push(c),this.generator.generators&&Array.isArray(this.generator.generators)&&this.generator.generators.forEach(c=>{let u=extractId(c);u&&t.push(u)});for(let c of this.filters){let u=extractId(c);u&&t.push(u)}return[...new Set(t)]}async getTagEloStatus(t){let c=toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo),u={};if(t){let d=Array.isArray(t)?t:[t];for(let t of d){let d=globToRegex(t);for(let[t,m]of Object.entries(c.tags))d.test(t)&&(u[t]={score:m.score,count:m.count})}}else for(let[t,d]of Object.entries(c.tags))u[t]={score:d.score,count:d.count};return u}async diagnoseCardSpace(t){let c=t?.threshold??.1,u=performance.now(),d=await this.course.getAllCardIds(),m=d.map(t=>({cardId:t,courseId:this.course.getCourseID(),score:1,provenance:[]}));m=await this.hydrateTags(m);let g=await this.buildContext(),b=[];for(let t of this.filters){m=await t.transform(m,g);let u=m.filter(t=>t.score>=c).length;b.push({name:t.name,wellIndicated:u})}let S=m.filter(t=>t.score>=c),C=new Set(S.map(t=>t.cardId)),w;try{let t=this.course.getCourseID(),c=await this.user.getSeenCards(t);w=new Set(c)}catch{w=new Set}let T=S.filter(t=>!w.has(t.cardId)),E=new Map;for(let t of m){let u=t.cardId.split(`-`)[1]||`unknown`;E.has(u)||E.set(u,{total:0,wellIndicated:0,new:0});let d=E.get(u);d.total++,t.score>=c&&(d.wellIndicated++,w.has(t.cardId)||d.new++)}let D=performance.now()-u,O={totalCards:d.length,threshold:c,wellIndicated:C.size,encountered:w.size,wellIndicatedNew:T.length,byType:Object.fromEntries(E),filterBreakdown:b,elapsedMs:Math.round(D)};logger.info(`[Pipeline:diagnose] Card space scan (${O.elapsedMs}ms):`),logger.info(`[Pipeline:diagnose] Total cards: ${O.totalCards}`),logger.info(`[Pipeline:diagnose] Well-indicated (score >= ${c}): ${O.wellIndicated}`),logger.info(`[Pipeline:diagnose] Encountered: ${O.encountered}`),logger.info(`[Pipeline:diagnose] Well-indicated & new: ${O.wellIndicatedNew}`),logger.info(`[Pipeline:diagnose] By type:`);for(let[t,c]of E)logger.info(`[Pipeline:diagnose] ${t}: ${c.wellIndicated}/${c.total} well-indicated, ${c.new} new`);logger.info(`[Pipeline:diagnose] After each filter:`);for(let t of b)logger.info(`[Pipeline:diagnose] ${t.name}: ${t.wellIndicated} well-indicated`);return O}}}}),defaults_exports={},__export(defaults_exports,{createDefaultEloStrategy:()=>createDefaultEloStrategy,createDefaultPipeline:()=>createDefaultPipeline,createDefaultSrsStrategy:()=>createDefaultSrsStrategy}),init_defaults=__esm({"src/core/navigators/defaults.ts"(){"use strict";init_navigators(),init_Pipeline(),init_CompositeGenerator(),init_elo(),init_srs(),init_eloDistance(),init_types_legacy()}}),PipelineAssembler_exports={},__export(PipelineAssembler_exports,{PipelineAssembler:()=>PipelineAssembler}),init_PipelineAssembler=__esm({"src/core/navigators/PipelineAssembler.ts"(){"use strict";init_navigators(),init_WeightedFilter(),init_Pipeline(),init_logger(),init_CompositeGenerator(),init_defaults(),PipelineAssembler=class{async assemble(t){let{strategies:c,user:u,course:d}=t,m=[];if(c.length===0)return{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:m};let g=[],b=[];for(let t of c)isGenerator(t.implementingClass)?g.push(t):isFilter(t.implementingClass)?b.push(t):m.push(`Unknown strategy type '${t.implementingClass}', skipping: ${t.name}`);let S=d.getCourseID(),C=g.some(t=>t.implementingClass===`elo`),w=g.some(t=>t.implementingClass===`srs`);if(C||(logger.debug(`[PipelineAssembler] No ELO generator configured, adding default`),g.push(createDefaultEloStrategy(S))),w||(logger.debug(`[PipelineAssembler] No SRS generator configured, adding default`),g.push(createDefaultSrsStrategy(S))),g.length===0)return m.push(`No generator strategy found`),{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:m};let T;g.length===1?(T=await ContentNavigator.create(u,d,g[0]),logger.debug(`[PipelineAssembler] Using single generator: ${g[0].name}`)):(logger.debug(`[PipelineAssembler] Using CompositeGenerator for ${g.length} generators: ${g.map(t=>t.name).join(`, `)}`),T=await CompositeGenerator.fromStrategies(u,d,g));let E=[],D=[...b].sort((t,c)=>t.name.localeCompare(c.name));for(let t of D)try{let c=await ContentNavigator.create(u,d,t);if(`transform`in c&&typeof c.transform==`function`){let u=c;t.learnable&&(u=new WeightedFilter(u,t.learnable,t.staticWeight,t._id)),E.push(u),logger.debug(`[PipelineAssembler] Added filter: ${t.name}`)}else m.push(`Filter '${t.name}' does not implement CardFilter.transform(), skipping`)}catch(c){m.push(`Failed to instantiate filter '${t.name}': ${c}`)}let O=new Pipeline(T,E,u,d);return logger.debug(`[PipelineAssembler] Assembled pipeline with ${g.length} generator(s) and ${E.length} filter(s)`),{pipeline:O,generatorStrategies:g,filterStrategies:D,warnings:m}}}}}),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)),"./defaults.ts":()=>Promise.resolve().then(()=>(init_defaults(),defaults_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))})}}),navigators_exports={},__export(navigators_exports,{ContentNavigator:()=>ContentNavigator,NavigatorRole:()=>NavigatorRole,NavigatorRoles:()=>NavigatorRoles,Navigators:()=>Navigators,getCardOrigin:()=>getCardOrigin,getRegisteredNavigator:()=>getRegisteredNavigator,getRegisteredNavigatorNames:()=>getRegisteredNavigatorNames,getRegisteredNavigatorRole:()=>getRegisteredNavigatorRole,hasRegisteredNavigator:()=>hasRegisteredNavigator,initializeNavigatorRegistry:()=>initializeNavigatorRegistry,isFilter:()=>isFilter,isGenerator:()=>isGenerator,mountPipelineDebugger:()=>mountPipelineDebugger,pipelineDebugAPI:()=>pipelineDebugAPI,registerNavigator:()=>registerNavigator}),init_navigators=__esm({"src/core/navigators/index.ts"(){"use strict";init_PipelineDebugger(),init_logger(),init_(),init_2(),init_3(),navigatorRegistry=new Map,Navigators=(t=>(t.ELO=`elo`,t.SRS=`srs`,t.PRESCRIBED=`prescribed`,t.HIERARCHY=`hierarchyDefinition`,t.INTERFERENCE=`interferenceMitigator`,t.RELATIVE_PRIORITY=`relativePriority`,t.USER_TAG_PREFERENCE=`userTagPreference`,t))(Navigators||{}),NavigatorRole=(t=>(t.GENERATOR=`generator`,t.FILTER=`filter`,t))(NavigatorRole||{}),NavigatorRoles={elo:`generator`,srs:`generator`,prescribed:`generator`,hierarchyDefinition:`filter`,interferenceMitigator:`filter`,relativePriority:`filter`,userTagPreference:`filter`},ContentNavigator=class{constructor(t,c,u){_defineProperty$2(this,`user`,void 0),_defineProperty$2(this,`course`,void 0),_defineProperty$2(this,`strategyName`,void 0),_defineProperty$2(this,`strategyId`,void 0),_defineProperty$2(this,`learnable`,void 0),_defineProperty$2(this,`staticWeight`,void 0),this.user=t,this.course=c,u&&(this.strategyName=u.name,this.strategyId=u._id,this.learnable=u.learnable,this.staticWeight=u.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(t){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,t)}static async create(t,c,u){let d=u.implementingClass,m=getRegisteredNavigator(d);if(m)return logger.debug(`[ContentNavigator.create] Using registered navigator: ${d}`),new m(t,c,u);logger.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${d}`);let g;for(let t of[`.ts`,`.js`,``]){try{if(g=(await globImport_generators(`./generators/${d}${t}`)).default,g)break}catch(c){logger.debug(`Failed to load generator ${d}${t}:`,c)}try{if(g=(await globImport_filters(`./filters/${d}${t}`)).default,g)break}catch(c){logger.debug(`Failed to load filter ${d}${t}:`,c)}try{if(g=(await globImport(`./${d}${t}`)).default,g)break}catch(c){logger.debug(`Failed to load legacy ${d}${t}:`,c)}if(g)break}if(!g)throw Error(`Could not load navigator implementation for: ${d}`);return new g(t,c,u)}async getWeightedCards(t){throw Error(`${this.constructor.name} must implement getWeightedCards(). `)}setEphemeralHints(t){}}}}),init_courseDB=__esm({"src/impl/couch/courseDB.ts"(){"use strict";init_couch(),init_updateQueue(),init_types_legacy(),init_logger(),init_clientCache(),init_courseAPI(),init_courseLookupDB(),init_navigators(),init_PipelineAssembler(),init_defaults(),CoursesDB=class{constructor(t){_defineProperty$2(this,`_courseIDs`,void 0),t&&t.length>0?this._courseIDs=t:this._courseIDs=void 0}async getCourseList(){let t=await CourseLookup.allCourseWare();return logger.debug(`AllCourses: ${t.map(t=>t.name+`, `+t._id+`
|
|
352
|
+
`)}},mountPipelineDebugger()}}),CompositeGenerator_exports={},__export(CompositeGenerator_exports,{AggregationMode:()=>AggregationMode,default:()=>CompositeGenerator}),init_CompositeGenerator=__esm({"src/core/navigators/generators/CompositeGenerator.ts"(){"use strict";init_navigators(),init_logger(),AggregationMode=(t=>(t.MAX=`max`,t.AVERAGE=`average`,t.FREQUENCY_BOOST=`frequencyBoost`,t))(AggregationMode||{}),DEFAULT_AGGREGATION_MODE=`frequencyBoost`,FREQUENCY_BOOST_FACTOR=.1,CompositeGenerator=class _CompositeGenerator extends ContentNavigator{constructor(t,c=DEFAULT_AGGREGATION_MODE){if(super(),_defineProperty$2(this,`name`,`Composite Generator`),_defineProperty$2(this,`generators`,void 0),_defineProperty$2(this,`aggregationMode`,void 0),this.generators=t,this.aggregationMode=c,t.length===0)throw Error(`CompositeGenerator requires at least one generator`);logger.debug(`[CompositeGenerator] Created with ${t.length} generators, mode: ${c}`)}static async fromStrategies(t,c,u,d=DEFAULT_AGGREGATION_MODE){return new _CompositeGenerator(await Promise.all(u.map(u=>ContentNavigator.create(t,c,u))),d)}async getWeightedCards(t,c){if(!c)throw Error(`CompositeGenerator.getWeightedCards requires a GeneratorContext. It should be called via Pipeline, not directly.`);let u=await Promise.all(this.generators.map(u=>u.getWeightedCards(t,c))),d=[];u.forEach((t,c)=>{let u=t.cards,m=this.generators[c].name||`Generator ${c}`,g=u.filter(t=>t.provenance[0]?.reason?.includes(`new card`)),b=u.filter(t=>t.provenance[0]?.reason?.includes(`review`));if(u.length>0){let t=Math.max(...u.map(t=>t.score)).toFixed(2),c=[];g.length>0&&c.push(`${g.length} new`),b.length>0&&c.push(`${b.length} reviews`);let S=c.length>0?c.join(`, `):`${u.length} cards`;d.push(`${m}: ${S} (top: ${t})`)}else d.push(`${m}: 0 cards`)}),logger.info(`[Composite] Generator breakdown: ${d.join(` | `)}`);let m=new Map;u.forEach((t,u)=>{let d=t.cards,g=this.generators[u],b=g.learnable?.weight??1,S;if(g.learnable&&!g.staticWeight&&c.orchestration){let t=g.strategyId;t&&(b=c.orchestration.getEffectiveWeight(t,g.learnable),S=c.orchestration.getDeviation(t))}for(let t of d){t.provenance.length>0&&(t.provenance[0].effectiveWeight=b,t.provenance[0].deviation=S);let c=m.get(t.cardId)||[];c.push({card:t,weight:b}),m.set(t.cardId,c)}});let g=[];for(let[,t]of m){let c=t.map(t=>t.card),u=this.aggregateScores(t),d=Math.max(0,u),m=c.flatMap(t=>t.provenance),b=c[0].score,S=d>b?`boosted`:d<b?`penalized`:`passed`,C=this.buildAggregationReason(t,d);g.push({...c[0],score:d,provenance:[...m,{strategy:`composite`,strategyName:`Composite Generator`,strategyId:`COMPOSITE_GENERATOR`,action:S,score:d,reason:C}]})}return{cards:g.sort((t,c)=>c.score-t.score).slice(0,t),hints:mergeHints(u.map(t=>t.hints))}}buildAggregationReason(t,c){let u=t.map(t=>t.card),d=u.length,m=u.map(t=>t.score.toFixed(2)).join(`, `);if(d===1){let u=Math.abs(t[0].weight-1)>.001?` (w=${t[0].weight.toFixed(2)})`:``;return`Single generator, score ${c.toFixed(2)}${u}`}let g=u.map(t=>t.provenance[0]?.strategy||`unknown`).join(`, `);switch(this.aggregationMode){case`max`:return`Max of ${d} generators (${g}): scores [${m}] \u2192 ${c.toFixed(2)}`;case`average`:return`Weighted Avg of ${d} generators (${g}): scores [${m}] \u2192 ${c.toFixed(2)}`;case`frequencyBoost`:{let u=t.reduce((t,c)=>t+c.weight,0),m=t.reduce((t,c)=>t+c.card.score*c.weight,0),b=u>0?m/u:0,S=1+FREQUENCY_BOOST_FACTOR*(d-1);return`Frequency boost from ${d} generators (${g}): w-avg ${b.toFixed(2)} \xD7 ${S.toFixed(2)} \u2192 ${c.toFixed(2)}`}default:return`Aggregated from ${d} generators: ${c.toFixed(2)}`}}aggregateScores(t){let c=t.map(t=>t.card.score);switch(this.aggregationMode){case`max`:return Math.max(...c);case`average`:{let c=t.reduce((t,c)=>t+c.weight,0);return c===0?0:t.reduce((t,c)=>t+c.card.score*c.weight,0)/c}case`frequencyBoost`:{let c=t.reduce((t,c)=>t+c.weight,0),u=t.reduce((t,c)=>t+c.card.score*c.weight,0);return(c>0?u/c:0)*(1+FREQUENCY_BOOST_FACTOR*(t.length-1))}default:return c[0]}}}}}),elo_exports={},__export(elo_exports,{default:()=>ELONavigator}),init_elo=__esm({"src/core/navigators/generators/elo.ts"(){"use strict";init_navigators(),init_logger(),ELO_RELEVANCE_SIGMA=300,ELONavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`name`,void 0),this.name=u?.name||`ELO`}async getWeightedCards(t,c){let u;u=c?.userElo===void 0?toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo).global.score:c.userElo;let d=await this.user.getActiveCards(),m=(await this.course.getCardsCenteredAtELO({limit:t,elo:`user`},t=>!d.some(c=>t.cardID===c.cardID))).map(t=>({...t,status:`new`})).map(t=>{let c=t.elo??1e3,d=Math.abs(c-u),m=Math.exp(-((d/ELO_RELEVANCE_SIGMA)**2)),g=m*(.5+.5*Math.random());return{cardId:t.cardID,courseId:t.courseID,score:g,provenance:[{strategy:`elo`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-ELO-default`,action:`generated`,score:g,reason:`ELO distance ${Math.round(d)} (card: ${Math.round(c)}, user: ${Math.round(u)}), relevance ${m.toFixed(3)}, key ${g.toFixed(3)}`}]}});m.sort((t,c)=>c.score-t.score);let g=m.slice(0,t);if(g.length>0){let t=g.slice(0,3).map(t=>t.score.toFixed(2)).join(`, `);logger.info(`[ELO] Course ${this.course.getCourseID()}: ${g.length} new cards (top scores: ${t})`)}else logger.info(`[ELO] Course ${this.course.getCourseID()}: No new cards available`);return{cards:g}}}}}),generators_exports={},init_generators=__esm({"src/core/navigators/generators/index.ts"(){"use strict";}}),prescribed_exports={},__export(prescribed_exports,{default:()=>PrescribedCardsGenerator}),init_prescribed=__esm({"src/core/navigators/generators/prescribed.ts"(){"use strict";init_navigators(),init_logger(),DEFAULT_FRESHNESS_WINDOW=3,DEFAULT_MAX_DIRECT_PER_RUN=3,DEFAULT_MAX_SUPPORT_PER_RUN=3,DEFAULT_HIERARCHY_DEPTH=2,DEFAULT_MIN_COUNT=3,DEFAULT_PRACTICE_MIN_COUNT=3,DEFAULT_MAX_PRACTICE_PER_RUN=4,BASE_TARGET_SCORE=1,BASE_SUPPORT_SCORE=.8,DISCOVERED_SUPPORT_SCORE=12,BASE_PRACTICE_SCORE=1,MAX_TARGET_MULTIPLIER=8,MAX_SUPPORT_MULTIPLIER=4,PRESCRIBED_DEBUG_VERSION=`testversion-prescribed-v3`,PrescribedCardsGenerator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`config`,void 0),this.name=u.name||`Prescribed Cards`,this.config=this.parseConfig(u.serializedData),logger.debug(`[Prescribed] Initialized with ${this.config.groups.length} groups and ${this.config.groups.reduce((t,c)=>t+c.targetCardIds.length,0)} targets`)}get strategyKey(){return`PrescribedProgress`}async getWeightedCards(t,c){if(this.config.groups.length===0||t<=0)return{cards:[]};let u=this.course.getCourseID(),d=await this.user.getActiveCards(),m=new Set(d.map(t=>t.cardID)),g=await this.user.getSeenCards(u).catch(()=>[]),b=new Set(g),S=await this.getStrategyState()??{updatedAt:isoNow(),groups:{}},C=await this.loadHierarchyConfigs(),w=await this.user.getCourseRegDoc(u).catch(()=>null),T=typeof w?.elo==`number`?w.elo:w?.elo?.global?.score??c?.userElo??1e3,E=typeof w?.elo==`number`?{}:w?.elo?.tags??{},D=dedupe(this.config.groups.flatMap(t=>t.targetCardIds)),O=dedupe(this.config.groups.flatMap(t=>t.supportCardIds??[])),Or=dedupe([...D,...O]),kr=Or.length>0?await this.course.getAppliedTagsBatch(Or):new Map,Ar=await this.course.getCourseTagStubs().catch(()=>({rows:[],offset:0,total_rows:0})),jr=new Map;for(let t of Ar.rows??[]){let c=t.doc;c?.name&&Array.isArray(c.taggedCards)&&jr.set(c.name,[...c.taggedCards])}let Mr={updatedAt:isoNow(),groups:{}},Nr=[],Pr=new Set,Fr=[];for(let t of this.config.groups){let c=this.buildGroupRuntimeState({group:t,priorState:S.groups[t.id],activeIds:m,seenIds:b,tagsByCard:kr,cardsByTag:jr,hierarchyConfigs:C,userTagElo:E,userGlobalElo:T});Fr.push(c),logger.info(`[Prescribed] Group '${t.id}': ${t.targetCardIds.length} targets total, ${c.encounteredTargets.size} encountered, ${c.pendingTargets.length} pending (${c.surfaceableTargets.length} surfaceable, ${c.blockedTargets.length} blocked), ${c.supportCandidates.length} authored support candidates, ${c.discoveredSupportCandidates.length} discovered support candidates, pressure=${c.pressureMultiplier.toFixed(2)}`),c.blockedTargets.length>0&&(logger.info(`[Prescribed] Group '${t.id}' blocked targets: ${c.blockedTargets.join(`, `)}`),logger.info(`[Prescribed] Group '${t.id}' support tags needed: ${c.supportTags.join(`, `)||`(none)`}`),logger.info(`[Prescribed] Group '${t.id}' escalation mode: `+(c.supportCandidates.length>0?`direct-support`:c.discoveredSupportCandidates.length>0?`inserted-support-candidates`:`boost-only`)),c.discoveredSupportCandidates.length>0&&logger.info(`[Prescribed] Group '${t.id}' discovered support candidates: ${c.discoveredSupportCandidates.join(`, `)}`)),Mr.groups[t.id]=this.buildNextGroupState(c,S.groups[t.id]);let d=this.buildDirectTargetCards(c,u,Pr),g=this.buildSupportCards(c,u,Pr),w=this.buildDiscoveredSupportCards(c,u,Pr),D=this.buildPracticeCards({group:t,courseId:u,emittedIds:Pr,cardsByTag:jr,hierarchyConfigs:C,userTagElo:E,userGlobalElo:T,activeIds:m,seenIds:b});Nr.push(...d,...g,...w,...D)}let Ir=this.buildSupportHintSummary(Fr),Lr=Object.keys(Ir.boostTags).length>0?{boostTags:Ir.boostTags,_label:`prescribed-support (${Ir.supportTags.length} tags; blocked=${Ir.blockedTargetIds.length}; testversion=${PRESCRIBED_DEBUG_VERSION})`}:void 0;if(Lr){let t=Object.entries(Lr.boostTags??{});logger.info(`[Prescribed] Emitting ${t.length} boost hint(s): `+t.map(([t,c])=>`${t}\xD7${c.toFixed(1)}`).join(`, `))}else logger.info(`[Prescribed] No hints to emit (no blocked targets or no support tags)`);if(Nr.length===0)return logger.info(`[Prescribed] 0 cards emitted (all targets blocked, authored/discovered support candidates exhausted)`+(Lr?` — boost hints emitted but may not survive filters`:``)),await this.putStrategyState(Mr).catch(t=>{logger.debug(`[Prescribed] Failed to persist empty-state update: ${t}`)}),Lr?{cards:[],hints:Lr}:{cards:[]};let Rr=pickTopByScore(Nr,t),zr=new Map;for(let t of Rr){let c=t.provenance[0];if(c?.reason.includes(`mode=practice`))continue;let u=c?.reason.match(/group=([^;]+)/)?.[1],d=c?.reason.includes(`mode=support`)?`supportIds`:`targetIds`;u&&(zr.has(u)||zr.set(u,{targetIds:[],supportIds:[]}),zr.get(u)[d].push(t.cardId))}for(let t of this.config.groups){let c=Mr.groups[t.id],u=zr.get(t.id);u&&(u.targetIds.length>0||u.supportIds.length>0)&&(c.lastSurfacedAt=isoNow(),c.sessionsSinceSurfaced=0,u.supportIds.length>0&&(c.lastSupportAt=isoNow()))}return await this.putStrategyState(Mr).catch(t=>{logger.debug(`[Prescribed] Failed to persist prescribed progress: ${t}`)}),logger.info(`[Prescribed] Emitting ${Rr.length} cards (${Rr.filter(t=>t.provenance[0]?.reason.includes(`mode=target`)).length} target, ${Rr.filter(t=>t.provenance[0]?.reason.includes(`mode=support`)).length} support, ${Rr.filter(t=>t.provenance[0]?.reason.includes(`mode=discovered-support`)).length} discovered support)`),Lr?{cards:Rr,hints:Lr}:{cards:Rr}}buildSupportHintSummary(t){let c={},u=new Set,d=new Set;for(let m of t)if(!(m.blockedTargets.length===0||m.supportTags.length===0)){m.blockedTargets.forEach(t=>u.add(t));for(let t of m.supportTags)d.add(t),c[t]=(c[t]??1)*m.supportMultiplier}return{boostTags:c,blockedTargetIds:[...u].sort(),supportTags:[...d].sort()}}parseConfig(t){try{let c=JSON.parse(t);return{groups:(Array.isArray(c.groups)?c.groups:[]).map((t,c)=>({id:typeof t.id==`string`&&t.id.trim().length>0?t.id:`group-${c+1}`,targetCardIds:dedupe(Array.isArray(t.targetCardIds)?t.targetCardIds.filter(t=>typeof t==`string`):[]),supportCardIds:dedupe(Array.isArray(t.supportCardIds)?t.supportCardIds.filter(t=>typeof t==`string`):[]),supportTagPatterns:dedupe(Array.isArray(t.supportTagPatterns)?t.supportTagPatterns.filter(t=>typeof t==`string`):[]),freshnessWindowSessions:typeof t.freshnessWindowSessions==`number`?t.freshnessWindowSessions:DEFAULT_FRESHNESS_WINDOW,maxDirectTargetsPerRun:typeof t.maxDirectTargetsPerRun==`number`?t.maxDirectTargetsPerRun:DEFAULT_MAX_DIRECT_PER_RUN,maxSupportCardsPerRun:typeof t.maxSupportCardsPerRun==`number`?t.maxSupportCardsPerRun:DEFAULT_MAX_SUPPORT_PER_RUN,hierarchyWalk:{enabled:t.hierarchyWalk?.enabled!==!1,maxDepth:typeof t.hierarchyWalk?.maxDepth==`number`?t.hierarchyWalk.maxDepth:DEFAULT_HIERARCHY_DEPTH},retireOnEncounter:t.retireOnEncounter!==!1,practiceTagPatterns:dedupe(Array.isArray(t.practiceTagPatterns)?t.practiceTagPatterns.filter(t=>typeof t==`string`):[]),practiceMinCount:typeof t.practiceMinCount==`number`?t.practiceMinCount:DEFAULT_PRACTICE_MIN_COUNT,maxPracticeCardsPerRun:typeof t.maxPracticeCardsPerRun==`number`?t.maxPracticeCardsPerRun:DEFAULT_MAX_PRACTICE_PER_RUN})).filter(t=>t.targetCardIds.length>0)}}catch{return{groups:[]}}}async loadHierarchyConfigs(){try{return(await this.course.getAllNavigationStrategies()).filter(t=>t.implementingClass===`hierarchyDefinition`).map(t=>{try{return{prerequisites:JSON.parse(t.serializedData).prerequisites||{}}}catch{return{prerequisites:{}}}})}catch(t){return logger.debug(`[Prescribed] Failed to load hierarchy configs: ${t}`),[]}}buildGroupRuntimeState(t){let{group:c,priorState:u,activeIds:d,seenIds:m,tagsByCard:g,cardsByTag:b,hierarchyConfigs:S,userTagElo:C,userGlobalElo:w}=t,T=new Set;for(let t of c.targetCardIds)(d.has(t)||m.has(t))&&T.add(t);if(u?.encounteredCardIds?.length)for(let t of u.encounteredCardIds)T.add(t);let E=c.targetCardIds.filter(t=>!T.has(t)),D=new Map;for(let t of E)D.set(t,g.get(t)??[]);let O=[],Or=[],kr=new Set;for(let t of E){let u=D.get(t)??[],d=this.resolveBlockedSupportTags(u,S,C,w,c.hierarchyWalk?.enabled!==!1,c.hierarchyWalk?.maxDepth??DEFAULT_HIERARCHY_DEPTH),m=u.filter(t=>t.startsWith(`gpc:intro:`)),g=new Set(u.filter(t=>t.startsWith(`gpc:expose:`)));for(let t of m){let c=t.slice(10);c&&g.add(`gpc:expose:${c}`)}let b=[...g].filter(t=>{let c=C[t];return!c||c.count<DEFAULT_MIN_COUNT});b.length>0&&b.forEach(t=>kr.add(t)),d.blocked||b.length>0?(O.push(t),d.supportTags.forEach(t=>kr.add(t))):Or.push(t)}let Ar=dedupe([...c.supportCardIds??[],...this.findSupportCardsByTags(c,g,[...kr])]).filter(t=>!d.has(t)&&!m.has(t)),jr=O.length>0&&kr.size>0&&Ar.length===0?this.findDiscoveredSupportCards({supportTags:[...kr],cardsByTag:b,activeIds:d,seenIds:m,excludedIds:new Set([...c.targetCardIds,...c.supportCardIds??[]]),limit:c.maxSupportCardsPerRun??DEFAULT_MAX_SUPPORT_PER_RUN}):[];O.length>0&&kr.size>0&&jr.length===0&&logger.info(`[Prescribed] Group '${c.id}' discovered 0 broader support candidates (blocked=${O.length}; authoredSupport=${Ar.length})`);let Mr=u?.sessionsSinceSurfaced??0,Nr=c.freshnessWindowSessions??DEFAULT_FRESHNESS_WINDOW,Pr=Math.max(0,Mr-Nr),Fr=E.length===0?1:clamp(1+Pr*.75+Math.min(2,E.length*.1),1,MAX_TARGET_MULTIPLIER),Ir=O.length===0?1:clamp(1+Pr*.5+Math.min(1.5,O.length*.15),1,MAX_SUPPORT_MULTIPLIER);return{group:c,encounteredTargets:T,pendingTargets:E,blockedTargets:O,surfaceableTargets:Or,targetTags:D,supportCandidates:Ar,discoveredSupportCandidates:jr,supportTags:[...kr],pressureMultiplier:Fr,supportMultiplier:Ir,debugVersion:PRESCRIBED_DEBUG_VERSION}}buildNextGroupState(t,c){let u=c?.sessionsSinceSurfaced??0,d=!1;return{encounteredCardIds:[...t.encounteredTargets].sort(),pendingTargetIds:[...t.pendingTargets].sort(),lastSurfacedAt:c?.lastSurfacedAt??null,sessionsSinceSurfaced:u+1,lastSupportAt:c?.lastSupportAt??null,blockedTargetIds:[...t.blockedTargets].sort(),lastResolvedSupportTags:[...t.supportTags].sort()}}buildDirectTargetCards(t,c,u){let d=t.group.maxDirectTargetsPerRun??DEFAULT_MAX_DIRECT_PER_RUN,m=t.surfaceableTargets.filter(t=>!u.has(t)).slice(0,d),g=[];for(let d of m)u.add(d),g.push({cardId:d,courseId:c,score:BASE_TARGET_SCORE*t.pressureMultiplier,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:BASE_TARGET_SCORE*t.pressureMultiplier,reason:`mode=target;group=${t.group.id};pending=${t.pendingTargets.length};surfaceable=${t.surfaceableTargets.length};blocked=${t.blockedTargets.length};blockedTargets=${t.blockedTargets.join(`|`)||`none`};supportTags=${t.supportTags.join(`|`)||`none`};multiplier=${t.pressureMultiplier.toFixed(2)};testversion=${t.debugVersion}`}]});return g}buildSupportCards(t,c,u){if(t.blockedTargets.length===0||t.supportCandidates.length===0)return[];let d=t.group.maxSupportCardsPerRun??DEFAULT_MAX_SUPPORT_PER_RUN,m=t.supportCandidates.filter(t=>!u.has(t)).slice(0,d),g=[];for(let d of m)u.add(d),g.push({cardId:d,courseId:c,score:BASE_SUPPORT_SCORE*t.supportMultiplier,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:BASE_SUPPORT_SCORE*t.supportMultiplier,reason:`mode=support;group=${t.group.id};pending=${t.pendingTargets.length};blocked=${t.blockedTargets.length};blockedTargets=${t.blockedTargets.join(`|`)||`none`};supportCard=${d};supportTags=${t.supportTags.join(`|`)||`none`};multiplier=${t.supportMultiplier.toFixed(2)};testversion=${t.debugVersion}`}]});return g}buildDiscoveredSupportCards(t,c,u){if(t.blockedTargets.length===0||t.discoveredSupportCandidates.length===0)return[];let d=t.group.maxSupportCardsPerRun??DEFAULT_MAX_SUPPORT_PER_RUN,m=t.discoveredSupportCandidates.filter(t=>!u.has(t)).slice(0,d),g=[];for(let d of m)u.add(d),g.push({cardId:d,courseId:c,score:DISCOVERED_SUPPORT_SCORE*t.supportMultiplier,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:DISCOVERED_SUPPORT_SCORE*t.supportMultiplier,reason:`mode=discovered-support;group=${t.group.id};pending=${t.pendingTargets.length};blocked=${t.blockedTargets.length};blockedTargets=${t.blockedTargets.join(`|`)||`none`};supportCard=${d};supportTags=${t.supportTags.join(`|`)||`none`};multiplier=${t.supportMultiplier.toFixed(2)};testversion=${t.debugVersion}`}]});return g}buildPracticeCards(t){let{group:c,courseId:u,emittedIds:d,cardsByTag:m,hierarchyConfigs:g,userTagElo:b,userGlobalElo:S,activeIds:C,seenIds:w}=t,T=c.practiceTagPatterns??[];if(T.length===0)return[];let E=c.practiceMinCount??DEFAULT_PRACTICE_MIN_COUNT,D=c.maxPracticeCardsPerRun??DEFAULT_MAX_PRACTICE_PER_RUN,O=[...m.keys()].filter(t=>T.some(c=>matchesTagPattern(t,c))&&this.isUnlockedGatedSkill(t,g,b,S)&&(b[t]?.count??0)<E);if(O.length===0)return[];let Or=this.findDiscoveredSupportCards({supportTags:O,cardsByTag:m,activeIds:C,seenIds:w,excludedIds:d,limit:D});if(Or.length===0)return[];logger.info(`[Prescribed] Group '${c.id}' practice: ${O.length} unlocked under-practiced skill(s), emitting ${Or.length} drill card(s)`);let kr=[];for(let t of Or)d.add(t),kr.push({cardId:t,courseId:u,score:BASE_PRACTICE_SCORE,provenance:[{strategy:`prescribed`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-prescribed`,action:`generated`,score:BASE_PRACTICE_SCORE,reason:`mode=practice;group=${c.id};underPracticedSkills=${O.length};practiceTags=${O.slice(0,8).join(`|`)}${O.length>8?`|…`:``};testversion=${PRESCRIBED_DEBUG_VERSION}`}]});return kr}isUnlockedGatedSkill(t,c,u,d){let m=c.map(c=>c.prerequisites[t]).filter(t=>Array.isArray(t)&&t.length>0);return m.length===0?!1:m.every(t=>t.every(t=>this.isPrerequisiteMet(t,u[t.tag],d)))}findSupportCardsByTags(t,c,u){if(u.length===0)return[];let d=t.supportCardIds??[],m=t.supportTagPatterns??[];if(d.length===0&&m.length===0)return[];let g=new Set;for(let t of d){let d=c.get(t)??[],b=u.some(t=>d.includes(t)),S=m.some(t=>d.some(c=>matchesTagPattern(c,t)));(b||S)&&g.add(t)}return[...g]}findDiscoveredSupportCards(t){let{supportTags:c,cardsByTag:u,activeIds:d,seenIds:m,excludedIds:g,limit:b}=t,S=new Map;for(let t of c){let c=u.get(t)??[];for(let t of c){if(d.has(t)||m.has(t)||g.has(t))continue;let c=S.get(t);c?c.matches+=1:S.set(t,{cardId:t,matches:1})}}let C=[...S.values()].sort((t,c)=>c.matches-t.matches||t.cardId.localeCompare(c.cardId)),w=new Set,T=[],E=[];for(let t of C){let c=extractWordStem(t.cardId);w.has(c)?E.push(t):(w.add(c),T.push(t))}return shuffleInPlace(T),shuffleInPlace(E),[...T,...E].slice(0,b).map(t=>t.cardId)}resolveBlockedSupportTags(t,c,u,d,m,g){let b=new Set,S=!1;for(let C of t){let t=c.map(t=>t.prerequisites[C]).filter(t=>Array.isArray(t)&&t.length>0);if(t.length!==0&&t.some(t=>t.some(t=>!this.isPrerequisiteMet(t,u[t.tag],d)))){if(S=!0,!m){for(let c of t)for(let t of c)this.isPrerequisiteMet(t,u[t.tag],d)||b.add(t.tag);continue}for(let m of t)for(let t of m)this.isPrerequisiteMet(t,u[t.tag],d)||this.collectSupportTagsRecursive(t.tag,c,u,d,g,new Set,b)}}return{blocked:S,supportTags:[...b]}}collectSupportTagsRecursive(t,c,u,d,m,g,b){if(m<0||g.has(t))return;g.add(t);let S=!1;for(let C of c){let w=C.prerequisites[t];if(!w||w.length===0)continue;let T=w.filter(t=>!this.isPrerequisiteMet(t,u[t.tag],d));if(T.length>0&&m>0){S=!0;for(let t of T)this.collectSupportTagsRecursive(t.tag,c,u,d,m-1,g,b)}}S||b.add(t)}isPrerequisiteMet(t,c,u){if(!c)return!1;let d=t.masteryThreshold?.minCount??DEFAULT_MIN_COUNT;return c.count<d?!1:t.masteryThreshold?.minElo===void 0?t.masteryThreshold?.minCount===void 0?c.score>=u:!0:c.score>=t.masteryThreshold.minElo}}}}),srs_exports={},__export(srs_exports,{default:()=>SRSNavigator}),init_srs=__esm({"src/core/navigators/generators/srs.ts"(){"use strict";init_navigators(),init_logger(),DEFAULT_HEALTHY_BACKLOG=20,MAX_BACKLOG_PRESSURE=.5,SRSNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`healthyBacklog`,void 0),this.name=u?.name||`SRS`,this.healthyBacklog=this.parseConfig(u?.serializedData).healthyBacklog??DEFAULT_HEALTHY_BACKLOG}parseConfig(t){if(!t)return{};try{return JSON.parse(t)}catch{return logger.warn(`[SRS] Failed to parse strategy config, using defaults`),{}}}async getWeightedCards(t,c){if(!this.user||!this.course)throw Error(`SRSNavigator requires user and course to be set`);let u=this.course.getCourseID(),d=await this.user.getPendingReviews(u),m=hooks.utc(),g=d.filter(t=>m.isAfter(hooks.utc(t.reviewTime)));if(g.length>0){let t=[...new Set(g.map(t=>t.cardId))],c=await this.course.getAppliedTagsBatch(t),u=[];if(g=g.filter(t=>(c.get(t.cardId)??[]).includes(`srs:skip`)?(u.push(t._id),!1):!0),u.length>0){logger.info(`[SRS] Removing ${u.length} scheduled reviews for srs:skip cards`);for(let t of u)this.user.removeScheduledCardReview(t)}}let b=this.computeBacklogPressure(g.length);if(g.length>0){let t=b>0?` [backlog pressure: +${b.toFixed(2)}]`:` [healthy backlog]`;logger.info(`[SRS] Course ${u}: ${g.length} reviews due now (of ${d.length} scheduled)${t}`)}else if(d.length>0){let t=[...d].sort((t,c)=>hooks.utc(t.reviewTime).diff(hooks.utc(c.reviewTime)))[0],c=hooks.utc(t.reviewTime),g=hooks.duration(c.diff(m)),b=g.asHours()<1?`${Math.round(g.asMinutes())}m`:g.asHours()<24?`${Math.round(g.asHours())}h`:`${Math.round(g.asDays())}d`;logger.info(`[SRS] Course ${u}: 0 reviews due now (${d.length} scheduled, next in ${b})`)}else logger.info(`[SRS] Course ${u}: No reviews scheduled`);return{cards:g.map(t=>{let{score:c,reason:u}=this.computeUrgencyScore(t,m,b);return{cardId:t.cardId,courseId:t.courseId,score:c,reviewID:t._id,provenance:[{strategy:`srs`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-SRS-default`,action:`generated`,score:c,reason:u}]}}).sort((t,c)=>c.score-t.score).slice(0,t)}}computeBacklogPressure(t){if(t<=this.healthyBacklog)return 0;let c=(t-this.healthyBacklog)/this.healthyBacklog*(MAX_BACKLOG_PRESSURE/2);return Math.min(MAX_BACKLOG_PRESSURE,c)}computeUrgencyScore(t,c,u){let d=hooks.utc(t.scheduledAt),m=hooks.utc(t.reviewTime),g=Math.max(1,m.diff(d,`hours`)),b=c.diff(m,`hours`),S=b/g,C=.3+.7*Math.exp(-g/720),w=.5+(Math.min(1,Math.max(0,S))*.5+C*.5)*.45,T=Math.min(1,w+u),E=[`${Math.round(b)}h overdue`,`interval: ${Math.round(g)}h`,`relative: ${S.toFixed(2)}`,`recency: ${C.toFixed(2)}`];return u>0&&E.push(`backlog: +${u.toFixed(2)}`),E.push(`review`),{score:T,reason:E.join(`, `)}}}}}),types_exports={},init_types=__esm({"src/core/navigators/generators/types.ts"(){"use strict";}}),init_=__esm({'import("./generators/**/*") in src/core/navigators/index.ts'(){globImport_generators=__glob({"./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))})}}),init_contentNavigationStrategy=__esm({"src/core/types/contentNavigationStrategy.ts"(){"use strict";DEFAULT_LEARNABLE_WEIGHT={weight:1,confidence:.1,sampleSize:0}}}),WeightedFilter_exports={},__export(WeightedFilter_exports,{WeightedFilter:()=>WeightedFilter}),init_WeightedFilter=__esm({"src/core/navigators/filters/WeightedFilter.ts"(){"use strict";init_contentNavigationStrategy(),WeightedFilter=class{constructor(t,c=DEFAULT_LEARNABLE_WEIGHT,u=!1,d){_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`inner`,void 0),_defineProperty$2(this,`learnable`,void 0),_defineProperty$2(this,`staticWeight`,void 0),_defineProperty$2(this,`strategyId`,void 0),this.inner=t,this.name=t.name,this.learnable=c,this.staticWeight=u,this.strategyId=d}async transform(t,c){let u=this.learnable.weight,d;if(!this.staticWeight&&c.orchestration){let t=this.strategyId||this.inner.strategyId||this.name;u=c.orchestration.getEffectiveWeight(t,this.learnable),d=c.orchestration.getDeviation(t)}if(Math.abs(u-1)<.001)return this.inner.transform(t,c);let m=new Map;for(let c of t)m.set(c.cardId,c.score);return(await this.inner.transform(t,c)).map(t=>{let c=m.get(t.cardId);if(c===void 0||c===0||t.score===0)return t;let g=t.score/c;if(Math.abs(g-1)<1e-4)return t;let b=c*g**+u,S=t.provenance.length-1,C=t.provenance[S];if(C){let c=[...t.provenance];return c[S]={...C,score:b,effectiveWeight:u,deviation:d},{...t,score:b,provenance:c}}return{...t,score:b}})}}}}),eloDistance_exports={},__export(eloDistance_exports,{DEFAULT_HALF_LIFE:()=>DEFAULT_HALF_LIFE,DEFAULT_MAX_MULTIPLIER:()=>DEFAULT_MAX_MULTIPLIER,DEFAULT_MIN_MULTIPLIER:()=>DEFAULT_MIN_MULTIPLIER,createEloDistanceFilter:()=>createEloDistanceFilter}),init_eloDistance=__esm({"src/core/navigators/filters/eloDistance.ts"(){"use strict";DEFAULT_HALF_LIFE=200,DEFAULT_MIN_MULTIPLIER=.3,DEFAULT_MAX_MULTIPLIER=1}}),hierarchyDefinition_exports={},__export(hierarchyDefinition_exports,{default:()=>HierarchyDefinitionNavigator}),init_hierarchyDefinition=__esm({"src/core/navigators/filters/hierarchyDefinition.ts"(){"use strict";init_navigators(),init_logger(),DEFAULT_MIN_COUNT2=3,HierarchyDefinitionNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`name`,void 0),this.config=this.parseConfig(u.serializedData),this.name=u.name||`Hierarchy Definition`}parseConfig(t){try{return{prerequisites:JSON.parse(t).prerequisites||{}}}catch{return{prerequisites:{}}}}isPrerequisiteMet(t,c,u){if(!c)return!1;let d=t.masteryThreshold?.minCount??DEFAULT_MIN_COUNT2;return c.count<d?!1:t.masteryThreshold?.minElo===void 0?t.masteryThreshold?.minCount===void 0?c.score>=u:!0:c.score>=t.masteryThreshold.minElo}async getMasteredTags(t){let c=new Set;try{let u=toCourseElo((await t.user.getCourseRegDoc(t.course.getCourseID())).elo);for(let t of Object.values(this.config.prerequisites))for(let d of t){let t=u.tags[d.tag];this.isPrerequisiteMet(d,t,u.global.score)&&c.add(d.tag)}}catch{}return c}getUnlockedTags(t){let c=new Set;for(let[u,d]of Object.entries(this.config.prerequisites))d.every(c=>t.has(c.tag))&&c.add(u);return c}hasPrerequisites(t){return t in this.config.prerequisites}async checkCardUnlock(t,c,u,d){try{let c=t.tags??[],m=c.filter(t=>this.hasPrerequisites(t)&&!u.has(t));return m.length===0?{isUnlocked:!0,reason:`Prerequisites met, tags: ${c.length>0?c.join(`, `):`none`}`}:{isUnlocked:!1,reason:`Blocked: missing prerequisites ${m.flatMap(t=>(this.config.prerequisites[t]||[]).filter(t=>!d.has(t.tag)).map(t=>t.tag)).join(`, `)} for tags ${m.join(`, `)}`}}catch{return{isUnlocked:!0,reason:`Prerequisites check skipped (tag lookup failed)`}}}getPreReqBoosts(t,c){let u=new Map;for(let[d,m]of Object.entries(this.config.prerequisites))if(!t.has(d))for(let t of m){if(!t.preReqBoost||t.preReqBoost<=1||c.has(t.tag))continue;let d=u.get(t.tag)??1;u.set(t.tag,Math.max(d,t.preReqBoost))}return u}getTargetBoosts(t){let c=new Map,u=Object.keys(this.config.prerequisites),d=[...t];logger.info(`[HierarchyDefinition:targetBoost:trace] ${this.name} | configKeys=${u.length}, unlocked=${d.length} (${d.slice(0,5).join(`, `)}${d.length>5?`...`:``})`);for(let[u,d]of Object.entries(this.config.prerequisites))if(t.has(u)){logger.info(`[HierarchyDefinition:targetBoost:trace] UNLOCKED ${u}: ${d.length} prereqs, raw=${JSON.stringify(d.map(t=>({tag:t.tag,tb:t.targetBoost})))}`);for(let t of d){if(!t.targetBoost||t.targetBoost<=1)continue;let d=c.get(u)??1;c.set(u,Math.max(d,t.targetBoost))}}return c.size>0?logger.info(`[HierarchyDefinition] targetBoosts active: ${[...c.entries()].map(([t,c])=>`${t}=\xD7${c}`).join(`, `)}`):logger.info(`[HierarchyDefinition:targetBoost:trace] no targetBoosts found despite ${d.length} unlocked tags`),c}async transform(t,c){let u=await this.getMasteredTags(c),d=this.getUnlockedTags(u),m=this.getPreReqBoosts(d,u),g=this.getTargetBoosts(d),b=[];for(let S of t){let{isUnlocked:t,reason:C}=await this.checkCardUnlock(S,c.course,d,u),w=t?S.score:S.score*.02,T=t?`passed`:`penalized`,E=C;if(t&&m.size>0){let t=S.tags??[],c=1,u=[];for(let d of t){let t=m.get(d);t&&t>c&&(c=t,u.push(d))}c>1&&(w*=c,T=`boosted`,E=`${C} | preReqBoost \xD7${c.toFixed(2)} for ${u.join(`, `)}`,logger.info(`[HierarchyDefinition] preReqBoost \xD7${c.toFixed(2)} applied to card ${S.cardId} via tags [${u.join(`, `)}] (score: ${S.score.toFixed(3)} \u2192 ${w.toFixed(3)})`))}if(t&&g.size>0){let t=S.tags??[],c=1,u=[];for(let d of t){let t=g.get(d);t&&t>c&&(c=t,u.push(d))}c>1&&(w*=c,T=`boosted`,E=`${E} | targetBoost \xD7${c.toFixed(2)} for ${u.join(`, `)}`,logger.info(`[HierarchyDefinition] targetBoost \xD7${c.toFixed(2)} applied to card ${S.cardId} via tags [${u.join(`, `)}] (score: ${S.score.toFixed(3)} \u2192 ${w.toFixed(3)})`))}b.push({...S,score:w,provenance:[...S.provenance,{strategy:`hierarchyDefinition`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-hierarchy`,action:T,score:w,reason:E}]})}return b}async getWeightedCards(t){throw Error(`HierarchyDefinitionNavigator is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),userTagPreference_exports={},__export(userTagPreference_exports,{default:()=>UserTagPreferenceFilter}),init_userTagPreference=__esm({"src/core/navigators/filters/userTagPreference.ts"(){"use strict";init_navigators(),UserTagPreferenceFilter=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`_strategyData`,void 0),_defineProperty$2(this,`name`,void 0),this._strategyData=u,this.name=u.name||`User Tag Preferences`}computeMultiplier(t,c){let u=t.map(t=>c[t]).filter(t=>t!==void 0);return u.length===0?1:Math.max(...u)}buildReason(t,c,u){let d=t.filter(t=>c[t]===u);return u===0?`Excluded by user preference: ${d.join(`, `)} (${u}x)`:u<1?`Penalized by user preference: ${d.join(`, `)} (${u.toFixed(2)}x)`:u>1?`Boosted by user preference: ${d.join(`, `)} (${u.toFixed(2)}x)`:`No matching user preferences`}async transform(t,c){let u=await this.getStrategyState();return!u||Object.keys(u.boost).length===0?t.map(t=>({...t,provenance:[...t.provenance,{strategy:`userTagPreference`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||this._strategyData._id,action:`passed`,score:t.score,reason:`No user tag preferences configured`}]})):await Promise.all(t.map(async t=>{let c=t.tags??[],d=this.computeMultiplier(c,u.boost),m=Math.min(1,t.score*d),g;return g=d===0||d<1?`penalized`:d>1?`boosted`:`passed`,{...t,score:m,provenance:[...t.provenance,{strategy:`userTagPreference`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||this._strategyData._id,action:g,score:m,reason:this.buildReason(c,u.boost,d)}]}}))}async getWeightedCards(t){throw Error(`UserTagPreferenceFilter is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),filters_exports={},__export(filters_exports,{UserTagPreferenceFilter:()=>UserTagPreferenceFilter,createEloDistanceFilter:()=>createEloDistanceFilter}),init_filters=__esm({"src/core/navigators/filters/index.ts"(){"use strict";init_eloDistance(),init_userTagPreference()}}),inferredPreferenceStub_exports={},__export(inferredPreferenceStub_exports,{INFERRED_PREFERENCE_NAVIGATOR_STUB:()=>INFERRED_PREFERENCE_NAVIGATOR_STUB}),init_inferredPreferenceStub=__esm({"src/core/navigators/filters/inferredPreferenceStub.ts"(){"use strict";INFERRED_PREFERENCE_NAVIGATOR_STUB=!0}}),interferenceMitigator_exports={},__export(interferenceMitigator_exports,{default:()=>InterferenceMitigatorNavigator}),init_interferenceMitigator=__esm({"src/core/navigators/filters/interferenceMitigator.ts"(){"use strict";init_navigators(),DEFAULT_MIN_COUNT3=10,DEFAULT_MIN_ELAPSED_DAYS=3,DEFAULT_INTERFERENCE_DECAY=.8,InterferenceMitigatorNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`name`,void 0),_defineProperty$2(this,`interferenceMap`,void 0),this.config=this.parseConfig(u.serializedData),this.interferenceMap=this.buildInterferenceMap(),this.name=u.name||`Interference Mitigator`}parseConfig(t){try{let c=JSON.parse(t),u=c.interferenceSets||[];return u.length>0&&Array.isArray(u[0])&&(u=u.map(t=>({tags:t}))),{interferenceSets:u,maturityThreshold:{minCount:c.maturityThreshold?.minCount??DEFAULT_MIN_COUNT3,minElo:c.maturityThreshold?.minElo,minElapsedDays:c.maturityThreshold?.minElapsedDays??DEFAULT_MIN_ELAPSED_DAYS},defaultDecay:c.defaultDecay??DEFAULT_INTERFERENCE_DECAY}}catch{return{interferenceSets:[],maturityThreshold:{minCount:DEFAULT_MIN_COUNT3,minElapsedDays:DEFAULT_MIN_ELAPSED_DAYS},defaultDecay:DEFAULT_INTERFERENCE_DECAY}}}buildInterferenceMap(){let t=new Map;for(let c of this.config.interferenceSets){let u=c.decay??this.config.defaultDecay??DEFAULT_INTERFERENCE_DECAY;for(let d of c.tags){t.has(d)||t.set(d,[]);let m=t.get(d);for(let t of c.tags)if(t!==d){let c=m.find(c=>c.partner===t);c?c.decay=Math.max(c.decay,u):m.push({partner:t,decay:u})}}}return t}async getImmatureTags(t){let c=new Set;try{let u=toCourseElo((await t.user.getCourseRegDoc(t.course.getCourseID())).elo),d=this.config.maturityThreshold?.minCount??DEFAULT_MIN_COUNT3,m=this.config.maturityThreshold?.minElo,g=(this.config.maturityThreshold?.minElapsedDays??DEFAULT_MIN_ELAPSED_DAYS)*2;for(let[t,b]of Object.entries(u.tags)){if(b.count===0)continue;let u=b.count<d,S=m!==void 0&&b.score<m,C=b.count<g;(u||S||C)&&c.add(t)}}catch{}return c}getTagsToAvoid(t){let c=new Map;for(let u of t){let d=this.interferenceMap.get(u);if(d){for(let{partner:u,decay:m}of d)if(!t.has(u)){let t=c.get(u)??0;c.set(u,Math.max(t,m))}}}return c}computeInterferenceEffect(t,c,u){if(c.size===0)return{multiplier:1,interferingTags:[],reason:`No interference detected`};let d=1,m=[];for(let u of t){let t=c.get(u);t!==void 0&&(m.push(u),d*=1-t)}if(m.length===0)return{multiplier:1,interferingTags:[],reason:`No interference detected`};let g=new Set;for(let t of m)for(let c of u)this.interferenceMap.get(c)?.some(c=>c.partner===t)&&g.add(c);let b=`Interferes with immature tags ${Array.from(g).join(`, `)} (tags: ${m.join(`, `)}, multiplier: ${d.toFixed(2)})`;return{multiplier:d,interferingTags:m,reason:b}}async transform(t,c){let u=await this.getImmatureTags(c),d=this.getTagsToAvoid(u),m=[];for(let c of t){let t=c.tags??[],{multiplier:g,reason:b}=this.computeInterferenceEffect(t,d,u),S=c.score*g,C=g<1?`penalized`:g>1?`boosted`:`passed`;m.push({...c,score:S,provenance:[...c.provenance,{strategy:`interferenceMitigator`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-interference`,action:C,score:S,reason:b}]})}return m}async getWeightedCards(t){throw Error(`InterferenceMitigatorNavigator is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),relativePriority_exports={},__export(relativePriority_exports,{default:()=>RelativePriorityNavigator}),init_relativePriority=__esm({"src/core/navigators/filters/relativePriority.ts"(){"use strict";init_navigators(),DEFAULT_PRIORITY=.5,DEFAULT_PRIORITY_INFLUENCE=.5,DEFAULT_COMBINE_MODE=`max`,RelativePriorityNavigator=class extends ContentNavigator{constructor(t,c,u){super(t,c,u),_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`name`,void 0),this.config=this.parseConfig(u.serializedData),this.name=u.name||`Relative Priority`}parseConfig(t){try{let c=JSON.parse(t);return{tagPriorities:c.tagPriorities||{},defaultPriority:c.defaultPriority??DEFAULT_PRIORITY,combineMode:c.combineMode??DEFAULT_COMBINE_MODE,priorityInfluence:c.priorityInfluence??DEFAULT_PRIORITY_INFLUENCE}}catch{return{tagPriorities:{},defaultPriority:DEFAULT_PRIORITY,combineMode:DEFAULT_COMBINE_MODE,priorityInfluence:DEFAULT_PRIORITY_INFLUENCE}}}getTagPriority(t){return this.config.tagPriorities[t]??this.config.defaultPriority??DEFAULT_PRIORITY}computeCardPriority(t){if(t.length===0)return this.config.defaultPriority??DEFAULT_PRIORITY;let c=t.map(t=>this.getTagPriority(t));switch(this.config.combineMode){case`max`:return Math.max(...c);case`min`:return Math.min(...c);case`average`:return c.reduce((t,c)=>t+c,0)/c.length;default:return Math.max(...c)}}computeBoostFactor(t){let c=this.config.priorityInfluence??DEFAULT_PRIORITY_INFLUENCE;return 1+(t-.5)*c}buildPriorityReason(t,c,u,d){if(t.length===0)return`No tags, neutral priority (${c.toFixed(2)})`;let m=t.slice(0,3).join(`, `),g=t.length>3?` (+${t.length-3} more)`:``;return u===1?`Neutral priority (${c.toFixed(2)}) for tags: ${m}${g}`:u>1?`High-priority tags: ${m}${g} (priority ${c.toFixed(2)} \u2192 boost ${u.toFixed(2)}x \u2192 ${d.toFixed(2)})`:`Low-priority tags: ${m}${g} (priority ${c.toFixed(2)} \u2192 reduce ${u.toFixed(2)}x \u2192 ${d.toFixed(2)})`}async transform(t,c){return await Promise.all(t.map(async t=>{let c=t.tags??[],u=this.computeCardPriority(c),d=this.computeBoostFactor(u),m=Math.max(0,t.score*d),g=d>1?`boosted`:d<1?`penalized`:`passed`,b=this.buildPriorityReason(c,u,d,m);return{...t,score:m,provenance:[...t.provenance,{strategy:`relativePriority`,strategyName:this.strategyName||this.name,strategyId:this.strategyId||`NAVIGATION_STRATEGY-priority`,action:g,score:m,reason:b}]}}))}async getWeightedCards(t){throw Error(`RelativePriorityNavigator is a filter and should not be used as a generator. Use Pipeline with a generator and this filter via transform().`)}}}}),types_exports2={},init_types2=__esm({"src/core/navigators/filters/types.ts"(){"use strict";}}),userGoalStub_exports={},__export(userGoalStub_exports,{USER_GOAL_NAVIGATOR_STUB:()=>USER_GOAL_NAVIGATOR_STUB}),init_userGoalStub=__esm({"src/core/navigators/filters/userGoalStub.ts"(){"use strict";USER_GOAL_NAVIGATOR_STUB=!0}}),init_2=__esm({'import("./filters/**/*") in src/core/navigators/index.ts'(){globImport_filters=__glob({"./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))})}}),init_gradient=__esm({"src/core/orchestration/gradient.ts"(){"use strict";init_logger()}}),init_learning=__esm({"src/core/orchestration/learning.ts"(){"use strict";init_contentNavigationStrategy(),init_types_legacy(),init_logger(),MIN_OBSERVATIONS_FOR_UPDATE=10,LEARNING_RATE=.1,MAX_WEIGHT_DELTA=.3,MIN_R_SQUARED_FOR_GRADIENT=.05,FLAT_GRADIENT_THRESHOLD=.02,MAX_HISTORY_LENGTH=100}}),init_signal=__esm({"src/core/orchestration/signal.ts"(){"use strict";}}),init_recording=__esm({"src/core/orchestration/recording.ts"(){"use strict";init_signal(),init_types_legacy(),init_logger()}}),init_orchestration=__esm({"src/core/orchestration/index.ts"(){"use strict";init_logger(),init_gradient(),init_learning(),init_signal(),init_recording(),MIN_SPREAD=.1,MAX_SPREAD=.5,MIN_WEIGHT=.1,MAX_WEIGHT=3}}),Pipeline_exports={},__export(Pipeline_exports,{Pipeline:()=>Pipeline,mergeHints:()=>mergeHints2}),init_Pipeline=__esm({"src/core/navigators/Pipeline.ts"(){"use strict";init_navigators(),init_logger(),init_orchestration(),init_PipelineDebugger(),init_diversityRerank(),VERBOSE_RESULTS=!0,Pipeline=class extends ContentNavigator{constructor(t,c,u,d){super(),_defineProperty$2(this,`generator`,void 0),_defineProperty$2(this,`filters`,void 0),_defineProperty$2(this,`_cachedOrchestration`,null),_defineProperty$2(this,`_tagCache`,new Map),_defineProperty$2(this,`_ephemeralHints`,null),this.generator=t,this.filters=c,this.user=u,this.course=d,d.getCourseConfig().then(t=>{logger.debug(`[pipeline] Crated pipeline for ${t.name}`)}).catch(t=>{logger.error(`[pipeline] Failed to lookup courseCfg: ${t}`)}),logPipelineConfig(t,c),registerPipelineForDebug(this)}setEphemeralHints(t){this._ephemeralHints=t,logger.info(`[Pipeline] Ephemeral hints set: ${JSON.stringify(t)}`)}async getWeightedCards(t){let c=performance.now(),u=await this.buildContext(),d=performance.now(),m=500;logger.debug(`[Pipeline] Fetching 500 candidates from generator '${this.generator.name}'`);let g=await this.generator.getWeightedCards(500,u),b=g.cards,S=performance.now(),C=b.length;this._ephemeralHints=mergeHints2([this._ephemeralHints,g.hints])??null;let w;if(this.generator.generators){let t=new Map;for(let c of b){let u=c.provenance[0];if(u){let d=u.strategyName;t.has(d)||t.set(d,{cards:[]}),t.get(d).cards.push(c)}}w=Array.from(t.entries()).map(([t,c])=>{let u=c.cards.filter(t=>t.provenance[0]?.reason?.includes(`new card`)),d=c.cards.filter(t=>t.provenance[0]?.reason?.includes(`review`));return{name:t,cardCount:c.cards.length,newCount:u.length,reviewCount:d.length,topScore:Math.max(...c.cards.map(t=>t.score),0)}})}logger.debug(`[Pipeline] Generator returned ${C} candidates`),b=await this.hydrateTags(b);let T=performance.now(),E=[...b],D=this._ephemeralHints;if(D?.requireCards?.length){let t=new Set(E.map(t=>t.cardId)),c=D.requireCards.filter(c=>!c.includes(`*`)&&!t.has(c));if(c.length>0){let t=await this.course.getAppliedTagsBatch(c),u=this.course.getCourseID();for(let d of c)E.push({cardId:d,courseId:u,score:1,tags:t.get(d)??[],provenance:[]});logger.info(`[Pipeline] Pre-fetched ${c.length} required card(s) into pool: ${c.join(`, `)}`)}}let O=new Set(b.filter(t=>t.provenance.some(t=>t.strategy===`prescribed`)).map(t=>t.cardId)),Or=[];for(let t of this.filters){let c=b.length,d=new Map(b.map(t=>[t.cardId,t.score]));b=await t.transform(b,u);let m=0,g=0,S=0,C=c-b.length;for(let t of b){let c=d.get(t.cardId)??0;t.score>c?m++:t.score<c?g++:S++}if(Or.push({name:t.name,boosted:m,penalized:g,passed:S,removed:C}),O.size>0){let c=new Set(b.map(t=>t.cardId)),u=[...O].filter(t=>!c.has(t)),d=b.filter(t=>O.has(t.cardId)&&t.score===0).map(t=>t.cardId);(u.length>0||d.length>0)&&(logger.info(`[Pipeline] Filter '${t.name}' impact on prescribed cards: `+(u.length>0?`removed=[${u.join(`, `)}] `:``)+(d.length>0?`zeroed=[${d.join(`, `)}]`:``)),u.forEach(t=>O.delete(t)))}logger.debug(`[Pipeline] Filter '${t.name}': ${d.size} \u2192 ${b.length} cards (\u2191${m} \u2193${g} =${S})`)}b=b.filter(t=>t.score>0);let kr=this._ephemeralHints;kr&&(this._ephemeralHints=null,b=this.applyHints(b,kr,E)),b=diversityRerank(b),b.sort((t,c)=>c.score-t.score);let Ar=performance.now(),jr=b.slice(0,t);logger.info(`[Pipeline:timing] total=${(Ar-c).toFixed(0)}ms (context=${(d-c).toFixed(0)} generate=${(S-d).toFixed(0)} hydrate=${(T-S).toFixed(0)} filter=${(Ar-T).toFixed(0)})`);let Mr=jr.slice(0,3).map(t=>t.score);logExecutionSummary(this.generator.name,C,this.filters.length,jr.length,Mr,Or),logResultCards(jr),logCardProvenance(jr,3);try{let t=await this.course?.getCourseConfig().then(t=>t.name).catch(()=>void 0);captureRun(buildRunReport(this.course?.getCourseID()||`unknown`,t,this.generator.name,w,C,Or,b,jr,u.userElo,kr??void 0))}catch(t){logger.debug(`[Pipeline] Failed to capture debug run: ${t}`)}return{cards:jr}}async hydrateTags(t){if(t.length===0)return t;let c=[];for(let u of t)this._tagCache.has(u.cardId)||c.push(u.cardId);if(c.length>0){let t=await this.course.getAppliedTagsBatch(c);for(let[c,u]of t)this._tagCache.set(c,u)}let u=new Map;for(let c of t)u.set(c.cardId,this._tagCache.get(c.cardId)??[]);return logTagHydration(t,u),t.map(t=>({...t,tags:this._tagCache.get(t.cardId)??[]}))}applyHints(t,c,u){let d=t.length;if(c.excludeCards?.length&&(t=t.filter(t=>!c.excludeCards.some(c=>globMatch(t.cardId,c)))),c.excludeTags?.length&&(t=t.filter(t=>!c.excludeTags.some(c=>cardMatchesTagPattern(t,c)))),c.boostTags)for(let[u,d]of Object.entries(c.boostTags))for(let m of t)cardMatchesTagPattern(m,u)&&(m.score*=d,m.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:c._label?`Replan Hint (${c._label})`:`Replan Hint`,action:`boosted`,score:m.score,reason:`boostTag ${u} \xD7${d}`}));if(c.boostCards)for(let[u,d]of Object.entries(c.boostCards))for(let m of t)globMatch(m.cardId,u)&&(m.score*=d,m.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:c._label?`Replan Hint (${c._label})`:`Replan Hint`,action:`boosted`,score:m.score,reason:`boostCard ${u} \xD7${d}`}));let m=new Set(t.map(t=>t.cardId)),g=new Map(t.map(t=>[t.cardId,t])),b=c._label?`Replan Hint (${c._label})`:`Replan Hint`,applyRequirement=(c,u)=>{let d=1/0,S=g.get(c.cardId);S?S.score<d&&(S.score=d,S.provenance.push({strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:b,action:`boosted`,score:d,reason:`${u} (upgrade to mandatory score)`})):(t.push({...c,score:d,provenance:[...c.provenance,{strategy:`ephemeralHint`,strategyId:`ephemeral-hint`,strategyName:b,action:`boosted`,score:d,reason:u}]}),m.add(c.cardId),g.set(c.cardId,t[t.length-1]))};if(c.requireCards?.length)for(let t of c.requireCards){for(let c of m)globMatch(c,t)&&applyRequirement(g.get(c),`requireCard ${t}`);for(let c of u)globMatch(c.cardId,t)&&applyRequirement(c,`requireCard ${t}`)}if(c.requireTags?.length)for(let t of c.requireTags){for(let c of m){let u=g.get(c);cardMatchesTagPattern(u,t)&&applyRequirement(u,`requireTag ${t}`)}for(let c of u)cardMatchesTagPattern(c,t)&&applyRequirement(c,`requireTag ${t}`)}return logger.info(`[Pipeline] Hints applied: ${d} \u2192 ${t.length} cards`),t}async buildContext(){let t=1e3;try{t=toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo).global.score}catch(t){logger.debug(`[Pipeline] Could not get user ELO, using default: ${t}`)}this._cachedOrchestration||(this._cachedOrchestration=await createOrchestrationContext(this.user,this.course));let c=this._cachedOrchestration;return{user:this.user,course:this.course,userElo:t,orchestration:c}}getCourseID(){return this.course.getCourseID()}async getOrchestrationContext(){return createOrchestrationContext(this.user,this.course)}getStrategyIds(){let t=[],extractId=t=>t.strategyId?t.strategyId:null,c=extractId(this.generator);c&&t.push(c),this.generator.generators&&Array.isArray(this.generator.generators)&&this.generator.generators.forEach(c=>{let u=extractId(c);u&&t.push(u)});for(let c of this.filters){let u=extractId(c);u&&t.push(u)}return[...new Set(t)]}async getTagEloStatus(t){let c=toCourseElo((await this.user.getCourseRegDoc(this.course.getCourseID())).elo),u={};if(t){let d=Array.isArray(t)?t:[t];for(let t of d){let d=globToRegex(t);for(let[t,m]of Object.entries(c.tags))d.test(t)&&(u[t]={score:m.score,count:m.count})}}else for(let[t,d]of Object.entries(c.tags))u[t]={score:d.score,count:d.count};return u}async forecast(t){let c=t?.threshold??.1,u=t?.unseenOnly??!0,d=this.course.getCourseID(),m=(await this.course.getAllCardIds()).map(t=>({cardId:t,courseId:d,score:1,provenance:[]}));m=await this.hydrateTags(m);let g=m.slice(),b=await this.buildContext();for(let t of this.filters)m=await t.transform(m,b);if(t?.hints&&(m=this.applyHints(m,t.hints,g)),m=m.filter(t=>t.score>=c),u){let t;try{t=new Set(await this.user.getSeenCards(d))}catch{t=new Set}m=m.filter(c=>!t.has(c.cardId))}return m.sort((t,c)=>c.score-t.score),t?.limit?m.slice(0,t.limit):m}async diagnoseCardSpace(t){let c=t?.threshold??.1,u=performance.now(),d=await this.course.getAllCardIds(),m=d.map(t=>({cardId:t,courseId:this.course.getCourseID(),score:1,provenance:[]}));m=await this.hydrateTags(m);let g=await this.buildContext(),b=[];for(let t of this.filters){m=await t.transform(m,g);let u=m.filter(t=>t.score>=c).length;b.push({name:t.name,wellIndicated:u})}let S=m.filter(t=>t.score>=c),C=new Set(S.map(t=>t.cardId)),w;try{let t=this.course.getCourseID(),c=await this.user.getSeenCards(t);w=new Set(c)}catch{w=new Set}let T=S.filter(t=>!w.has(t.cardId)),E=new Map;for(let t of m){let u=t.cardId.split(`-`)[1]||`unknown`;E.has(u)||E.set(u,{total:0,wellIndicated:0,new:0});let d=E.get(u);d.total++,t.score>=c&&(d.wellIndicated++,w.has(t.cardId)||d.new++)}let D=performance.now()-u,O={totalCards:d.length,threshold:c,wellIndicated:C.size,encountered:w.size,wellIndicatedNew:T.length,byType:Object.fromEntries(E),filterBreakdown:b,elapsedMs:Math.round(D)};logger.info(`[Pipeline:diagnose] Card space scan (${O.elapsedMs}ms):`),logger.info(`[Pipeline:diagnose] Total cards: ${O.totalCards}`),logger.info(`[Pipeline:diagnose] Well-indicated (score >= ${c}): ${O.wellIndicated}`),logger.info(`[Pipeline:diagnose] Encountered: ${O.encountered}`),logger.info(`[Pipeline:diagnose] Well-indicated & new: ${O.wellIndicatedNew}`),logger.info(`[Pipeline:diagnose] By type:`);for(let[t,c]of E)logger.info(`[Pipeline:diagnose] ${t}: ${c.wellIndicated}/${c.total} well-indicated, ${c.new} new`);logger.info(`[Pipeline:diagnose] After each filter:`);for(let t of b)logger.info(`[Pipeline:diagnose] ${t.name}: ${t.wellIndicated} well-indicated`);return O}}}}),defaults_exports={},__export(defaults_exports,{createDefaultEloStrategy:()=>createDefaultEloStrategy,createDefaultPipeline:()=>createDefaultPipeline,createDefaultSrsStrategy:()=>createDefaultSrsStrategy}),init_defaults=__esm({"src/core/navigators/defaults.ts"(){"use strict";init_navigators(),init_Pipeline(),init_CompositeGenerator(),init_elo(),init_srs(),init_eloDistance(),init_types_legacy()}}),PipelineAssembler_exports={},__export(PipelineAssembler_exports,{PipelineAssembler:()=>PipelineAssembler}),init_PipelineAssembler=__esm({"src/core/navigators/PipelineAssembler.ts"(){"use strict";init_navigators(),init_WeightedFilter(),init_Pipeline(),init_logger(),init_CompositeGenerator(),init_defaults(),PipelineAssembler=class{async assemble(t){let{strategies:c,user:u,course:d}=t,m=[];if(c.length===0)return{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:m};let g=[],b=[];for(let t of c)isGenerator(t.implementingClass)?g.push(t):isFilter(t.implementingClass)?b.push(t):m.push(`Unknown strategy type '${t.implementingClass}', skipping: ${t.name}`);let S=d.getCourseID(),C=g.some(t=>t.implementingClass===`elo`),w=g.some(t=>t.implementingClass===`srs`);if(C||(logger.debug(`[PipelineAssembler] No ELO generator configured, adding default`),g.push(createDefaultEloStrategy(S))),w||(logger.debug(`[PipelineAssembler] No SRS generator configured, adding default`),g.push(createDefaultSrsStrategy(S))),g.length===0)return m.push(`No generator strategy found`),{pipeline:null,generatorStrategies:[],filterStrategies:[],warnings:m};let T;g.length===1?(T=await ContentNavigator.create(u,d,g[0]),logger.debug(`[PipelineAssembler] Using single generator: ${g[0].name}`)):(logger.debug(`[PipelineAssembler] Using CompositeGenerator for ${g.length} generators: ${g.map(t=>t.name).join(`, `)}`),T=await CompositeGenerator.fromStrategies(u,d,g));let E=[],D=[...b].sort((t,c)=>t.name.localeCompare(c.name));for(let t of D)try{let c=await ContentNavigator.create(u,d,t);if(`transform`in c&&typeof c.transform==`function`){let u=c;t.learnable&&(u=new WeightedFilter(u,t.learnable,t.staticWeight,t._id)),E.push(u),logger.debug(`[PipelineAssembler] Added filter: ${t.name}`)}else m.push(`Filter '${t.name}' does not implement CardFilter.transform(), skipping`)}catch(c){m.push(`Failed to instantiate filter '${t.name}': ${c}`)}let O=new Pipeline(T,E,u,d);return logger.debug(`[PipelineAssembler] Assembled pipeline with ${g.length} generator(s) and ${E.length} filter(s)`),{pipeline:O,generatorStrategies:g,filterStrategies:D,warnings:m}}}}}),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)),"./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))})}}),navigators_exports={},__export(navigators_exports,{ContentNavigator:()=>ContentNavigator,DIVERSITY_FLOOR:()=>DIVERSITY_FLOOR,DIVERSITY_STRENGTH:()=>DIVERSITY_STRENGTH,NavigatorRole:()=>NavigatorRole,NavigatorRoles:()=>NavigatorRoles,Navigators:()=>Navigators,diversityRerank:()=>diversityRerank,getActivePipeline:()=>getActivePipeline,getCardOrigin:()=>getCardOrigin,getRegisteredNavigator:()=>getRegisteredNavigator,getRegisteredNavigatorNames:()=>getRegisteredNavigatorNames,getRegisteredNavigatorRole:()=>getRegisteredNavigatorRole,hasRegisteredNavigator:()=>hasRegisteredNavigator,initializeNavigatorRegistry:()=>initializeNavigatorRegistry,isFilter:()=>isFilter,isGenerator:()=>isGenerator,mountPipelineDebugger:()=>mountPipelineDebugger,pipelineDebugAPI:()=>pipelineDebugAPI,registerNavigator:()=>registerNavigator}),init_navigators=__esm({"src/core/navigators/index.ts"(){"use strict";init_diversityRerank(),init_PipelineDebugger(),init_logger(),init_(),init_2(),init_3(),navigatorRegistry=new Map,Navigators=(t=>(t.ELO=`elo`,t.SRS=`srs`,t.PRESCRIBED=`prescribed`,t.HIERARCHY=`hierarchyDefinition`,t.INTERFERENCE=`interferenceMitigator`,t.RELATIVE_PRIORITY=`relativePriority`,t.USER_TAG_PREFERENCE=`userTagPreference`,t))(Navigators||{}),NavigatorRole=(t=>(t.GENERATOR=`generator`,t.FILTER=`filter`,t))(NavigatorRole||{}),NavigatorRoles={elo:`generator`,srs:`generator`,prescribed:`generator`,hierarchyDefinition:`filter`,interferenceMitigator:`filter`,relativePriority:`filter`,userTagPreference:`filter`},ContentNavigator=class{constructor(t,c,u){_defineProperty$2(this,`user`,void 0),_defineProperty$2(this,`course`,void 0),_defineProperty$2(this,`strategyName`,void 0),_defineProperty$2(this,`strategyId`,void 0),_defineProperty$2(this,`learnable`,void 0),_defineProperty$2(this,`staticWeight`,void 0),this.user=t,this.course=c,u&&(this.strategyName=u.name,this.strategyId=u._id,this.learnable=u.learnable,this.staticWeight=u.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(t){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,t)}static async create(t,c,u){let d=u.implementingClass,m=getRegisteredNavigator(d);if(m)return logger.debug(`[ContentNavigator.create] Using registered navigator: ${d}`),new m(t,c,u);logger.debug(`[ContentNavigator.create] Navigator not in registry, attempting dynamic import: ${d}`);let g;for(let t of[`.ts`,`.js`,``]){try{if(g=(await globImport_generators(`./generators/${d}${t}`)).default,g)break}catch(c){logger.debug(`Failed to load generator ${d}${t}:`,c)}try{if(g=(await globImport_filters(`./filters/${d}${t}`)).default,g)break}catch(c){logger.debug(`Failed to load filter ${d}${t}:`,c)}try{if(g=(await globImport(`./${d}${t}`)).default,g)break}catch(c){logger.debug(`Failed to load legacy ${d}${t}:`,c)}if(g)break}if(!g)throw Error(`Could not load navigator implementation for: ${d}`);return new g(t,c,u)}async getWeightedCards(t){throw Error(`${this.constructor.name} must implement getWeightedCards(). `)}setEphemeralHints(t){}}}}),init_courseDB=__esm({"src/impl/couch/courseDB.ts"(){"use strict";init_couch(),init_updateQueue(),init_types_legacy(),init_logger(),init_clientCache(),init_courseAPI(),init_courseLookupDB(),init_navigators(),init_PipelineAssembler(),init_defaults(),CoursesDB=class{constructor(t){_defineProperty$2(this,`_courseIDs`,void 0),t&&t.length>0?this._courseIDs=t:this._courseIDs=void 0}async getCourseList(){let t=await CourseLookup.allCourseWare();return logger.debug(`AllCourses: ${t.map(t=>t.name+`, `+t._id+`
|
|
353
353
|
`)}`),this._courseIDs&&(t=t.filter(t=>this._courseIDs.includes(t._id))),logger.debug(`AllCourses.filtered: ${t.map(t=>t.name+`, `+t._id+`
|
|
354
354
|
`)}`),(await Promise.all(t.map(async t=>{try{let c=await getCredentialledCourseConfig(t._id);return logger.debug(`Found cfg: ${JSON.stringify(c)}`),c}catch(c){logger.warn(`Error fetching cfg for course ${t.name}, ${t._id}: ${c}`);return}}))).filter(t=>!!t)}async getCourseConfig(t){if(this._courseIDs&&this._courseIDs.length&&!this._courseIDs.includes(t))throw Error(`Course ${t} not in course list`);let c=await getCredentialledCourseConfig(t);if(c===void 0)throw Error(`Error fetching cfg for course ${t}`);return c}async disambiguateCourse(t,c){await CourseLookup.updateDisambiguator(t,c)}},CourseDB=class{constructor(t,c,u){_defineProperty$2(this,`db`,void 0),_defineProperty$2(this,`remoteDB`,void 0),_defineProperty$2(this,`id`,void 0),_defineProperty$2(this,`_getCurrentUser`,void 0),_defineProperty$2(this,`updateQueue`,void 0),_defineProperty$2(this,`_pendingHints`,null),_defineProperty$2(this,`_eloPoolCache`,null),_defineProperty$2(this,`_eloPoolTtlMs`,300*1e3),_defineProperty$2(this,`_cachedNavigator`,null),_defineProperty$2(this,`_navigatorTtlMs`,300*1e3),this.id=t;let d=getCourseDB2(this.id);this.remoteDB=d,this.db=u??d,this._getCurrentUser=c,this.updateQueue=new UpdateQueue(this.remoteDB,this.remoteDB)}getCourseID(){return this.id}async getCourseInfo(){return{cardCount:(await this.db.find({selector:{docType:`CARD`},limit:1e3})).docs.length,registeredUsers:0}}async getInexperiencedCards(t=2){return(await this.db.query(`cardsByInexperience`,{limit:t})).rows.map(t=>({courseId:this.id,cardId:t.id,count:t.key,elo:t.value}))}async getCardsByEloLimits(t={low:0,high:-(2**53-1),limit:25,page:0}){return(await this.db.query(`elo`,{startkey:t.low,endkey:t.high,limit:t.limit,skip:t.limit*t.page})).rows.map(t=>`${this.id}-${t.id}-${t.key}`)}async getCardEloData(t){let c=await this.db.allDocs({keys:t,include_docs:!0}),u=[];return c.rows.forEach(t=>{isSuccessRow(t)?t.doc&&t.doc.elo?u.push(toCourseElo(t.doc.elo)):(logger.warn(`no elo data for card: `+t.id),u.push(blankCourseElo())):(logger.warn(`no elo data for card: `+JSON.stringify(t)),u.push(blankCourseElo()))}),u}async getELOBounds(){let[t,c]=await Promise.all([(await this.db.query(`elo`,{startkey:0,limit:1,include_docs:!1})).rows[0].key,(await this.db.query(`elo`,{limit:1,descending:!0,startkey:1e5})).rows[0].key]);return{low:t,high:c}}async removeCard(t){let c=await this.remoteDB.get(t);if(!c.docType||c.docType!==`CARD`)throw Error(`failed to remove ${t} from course ${this.id}. id does not point to a card`);try{let c=await this.getAppliedTags(t);(await Promise.allSettled(c.rows.map(async c=>{let u=c.id;await this.removeTagFromCard(t,u)}))).forEach((u,d)=>{if(u.status===`rejected`){let m=c.rows[d].id;logger.error(`Failed to remove card ${t} from tag ${m}: ${u.reason}`)}})}catch(c){logger.error(`Error removing card ${t} from tags: ${c}`)}return this.remoteDB.remove(c)}async getCardDisplayableDataIDs(t){logger.debug(t.join(`, `));let c=await this.db.allDocs({keys:t,include_docs:!0}),u={};return c.rows.forEach(t=>{isSuccessRow(t)&&(u[t.id]=t.doc.id_displayable_data)}),u}async getCardsByELO(t,c){t=parseInt(t);let u=c||25,d=await this.db.query(`elo`,{limit:Math.ceil(u/2),startkey:t,descending:!0}),m=u-d.rows.length,g=await this.db.query(`elo`,{limit:m,startkey:t+1}),b=d.rows;b=b.concat(g.rows);let S=b.sort((c,u)=>{let d=Math.abs(c.key-t)-Math.abs(u.key-t);return d===0?Math.random()-.5:d}).map(t=>({courseID:this.id,cardID:t.id,elo:t.key})),C=`below:
|
|
355
355
|
${d.rows.map(t=>` ${t.id}-${t.key}
|
|
@@ -405,7 +405,7 @@ Examples:
|
|
|
405
405
|
Card: ${JSON.stringify(t.cardElo)})
|
|
406
406
|
`)}}else logger.warn(`[EloService] Partial ELO update (per-tag):
|
|
407
407
|
User ELO update: ${S?`SUCCESS`:`FAILED`}
|
|
408
|
-
Card ELO update: ${C?`SUCCESS`:`FAILED`}`),!S&&m[0].status===`rejected`&&logger.error(`[EloService] User ELO update error:`,m[0].reason),!C&&m[1].status===`rejected`&&logger.error(`[EloService] Card ELO update error:`,m[1].reason)}}},init_core(),init_logger(),ResponseProcessor=class{constructor(t,c){_defineProperty$2(this,`srsService`,void 0),_defineProperty$2(this,`eloService`,void 0),this.srsService=t,this.eloService=c}parsePerformance(t){return typeof t==`number`?{globalScore:t,taggedPerformance:null}:isTaggedPerformance(t)?{globalScore:t._global,taggedPerformance:t}:(logger.warn(`[ResponseProcessor] Unexpected performance structure, using neutral score`,{performance:t}),{globalScore:.5,taggedPerformance:null})}async processResponse(t,c,u,d,m,g,b,S,C,w){if(!isQuestionRecord(t))return{nextCardAction:`dismiss-success`,shouldLoadNextCard:!0,isCorrect:!0,shouldClearFeedbackShadow:!0};try{let T=await c,E;return E=t.isCorrect?this.processCorrectResponse(t,T,u,d,m,g,b):this.processIncorrectResponse(t,T,d,m,g,b,S,C,w),t.deferAdvance&&E.shouldLoadNextCard&&(logger.info(`[ResponseProcessor] deferAdvance requested — suppressing navigation, action stashed:`,{nextCardAction:E.nextCardAction}),E={...E,shouldLoadNextCard:!1,deferred:!0}),E}catch(t){throw logger.error(`[ResponseProcessor] Failed to load card history`,{e:t,cardId:b}),t}}processCorrectResponse(t,c,u,d,m,g,b){if(t.priorAttemps===0){m.card.tags.includes(`srs:skip`)||this.srsService.scheduleReview(c,u);let{globalScore:S,taggedPerformance:C}=this.parsePerformance(t.performance);if(C){let t=Object.keys(C).filter(t=>t!==`_global`),c=t.filter(t=>C[t]===null),u=t.filter(t=>C[t]!==null);logger.info(`[ResponseProcessor] per-tag ELO update for ${b}: scored=[${u.join(`, `)}] count-only=[${c.join(`, `)}]`),this.eloService.updateUserAndCardEloPerTag(C,g,b,d,m)}else{let t=.5+S/2;if(c.records.length===1)this.eloService.updateUserAndCardElo(t,g,b,d,m);else{let u=Math.ceil(32/c.records.length);this.eloService.updateUserAndCardElo(t,g,b,d,m,u)}logger.info(`[ResponseProcessor] Processed correct response with SRS scheduling and ELO update`)}return{nextCardAction:`dismiss-success`,shouldLoadNextCard:!0,isCorrect:!0,performanceScore:S,shouldClearFeedbackShadow:!0}}else{logger.info(`[ResponseProcessor] Processed correct response (retry attempt - no scheduling/ELO)`);let{globalScore:c}=this.parsePerformance(t.performance);return{nextCardAction:`marked-failed`,shouldLoadNextCard:!0,isCorrect:!0,performanceScore:c,shouldClearFeedbackShadow:!0}}}processIncorrectResponse(t,c,u,d,m,g,b,S,C){let{taggedPerformance:w}=this.parsePerformance(t.performance);return c.records.length!==1&&t.priorAttemps===0?w?(this.eloService.updateUserAndCardEloPerTag(w,m,g,u,d),logger.info(`[ResponseProcessor] Processed incorrect response with per-tag ELO update (${Object.keys(w).length-1} tags)`)):(this.eloService.updateUserAndCardElo(0,m,g,u,d),logger.info(`[ResponseProcessor] Processed incorrect response with ELO update`)):logger.info(`[ResponseProcessor] Processed incorrect response (no ELO update needed)`),d.records.length>=b?C>=S?(w?this.eloService.updateUserAndCardEloPerTag(w,m,g,u,d):this.eloService.updateUserAndCardElo(0,m,g,u,d),{nextCardAction:`dismiss-failed`,shouldLoadNextCard:!0,isCorrect:!1,shouldClearFeedbackShadow:!0}):{nextCardAction:`marked-failed`,shouldLoadNextCard:!0,isCorrect:!1,shouldClearFeedbackShadow:!0}:{nextCardAction:`none`,shouldLoadNextCard:!1,isCorrect:!1,shouldClearFeedbackShadow:!0}}},init_logger(),CardHydrationService=class{constructor(t,c,u){_defineProperty$2(this,`hydratedCards`,new Map),_defineProperty$2(this,`hydrationInFlight`,new Set),_defineProperty$2(this,`hydrationInProgress`,!1),this.getViewComponent=t,this.getCourseDB=c,this.getItemsToHydrate=u}getHydratedCard(t){return this.hydratedCards.get(t)??null}hasHydratedCard(t){return this.hydratedCards.has(t)}removeCard(t){this.hydratedCards.delete(t)}async ensureHydratedCards(){this.fillHydratedCards()}async waitForCard(t){if(this.hydratedCards.has(t))return this.hydratedCards.get(t);this.hydrationInProgress||this.fillHydratedCards();let c=1e4,u=25,d=0;for(;d<1e4;){if(this.hydratedCards.has(t))return this.hydratedCards.get(t);if(!this.hydrationInFlight.has(t)&&!this.hydrationInProgress)break;await new Promise(t=>setTimeout(t,25)),d+=25}return this.hydratedCards.get(t)??null}get hydratedCount(){return this.hydratedCards.size}getHydratedCardIds(){return Array.from(this.hydratedCards.keys())}async fillHydratedCards(){if(!this.hydrationInProgress){this.hydrationInProgress=!0;try{let t=this.getItemsToHydrate();for(let c of t)if(!(this.hydratedCards.has(c.cardID)||this.hydrationInFlight.has(c.cardID)))try{await this.hydrateCard(c)}catch(t){logger.error(`[CardHydrationService] Error hydrating card ${c.cardID}:`,t)}}finally{this.hydrationInProgress=!1}}}async hydrateCard(t){if(!(this.hydratedCards.has(t.cardID)||this.hydrationInFlight.has(t.cardID))){this.hydrationInFlight.add(t.cardID);try{let c=this.getCourseDB(t.courseID),[u,d]=await Promise.all([c.getCourseDoc(t.cardID),c.getAppliedTagsBatch([t.cardID])]);isCourseElo(u.elo)||(u.elo=toCourseElo(u.elo));let m=this.getViewComponent(u.id_view),g=await Promise.all(u.id_displayable_data.map(t=>c.getCourseDoc(t,{attachments:!0,binary:!0}))),b=[];g.forEach(t=>{t.data.forEach(t=>{b.push(...parseAudioURIs(t.data))})});let S=[...new Set(b)];S.length>0&&(logger.debug(`[CardHydrationService] Prefetching ${S.length} audio files for card ${t.cardID}`),await Promise.allSettled(S.map(prefetchAudio)));let C=g.map(displayableDataToViewData).reverse();this.hydratedCards.set(t.cardID,{item:t,view:m,data:C,tags:d.get(t.cardID)??[]}),logger.debug(`[CardHydrationService] Hydrated card ${t.cardID}`)}finally{this.hydrationInFlight.delete(t.cardID)}}}},ItemQueue=class{constructor(){_defineProperty$2(this,`q`,[]),_defineProperty$2(this,`seenCardIds`,[]),_defineProperty$2(this,`_dequeueCount`,0)}get dequeueCount(){return this._dequeueCount}add(t,c){this.seenCardIds.find(t=>t===c)||(this.seenCardIds.push(c),this.q.push(t))}addAll(t,c){t.forEach(t=>this.add(t,c(t)))}get length(){return this.q.length}peek(t){return this.q[t]}dequeue(t){if(this.q.length!==0){this._dequeueCount++;let c=this.q.splice(0,1)[0];if(t){let u=t(c),d=this.seenCardIds.indexOf(u);d>-1&&this.seenCardIds.splice(d,1)}return c}else return null}replaceAll(t,c){this.q=[],this.seenCardIds=[];for(let u of t){let t=c(u);this.seenCardIds.includes(t)||(this.seenCardIds.push(t),this.q.push(u))}}mergeToFront(t,c){let
|
|
408
|
+
Card ELO update: ${C?`SUCCESS`:`FAILED`}`),!S&&m[0].status===`rejected`&&logger.error(`[EloService] User ELO update error:`,m[0].reason),!C&&m[1].status===`rejected`&&logger.error(`[EloService] Card ELO update error:`,m[1].reason)}}},init_core(),init_logger(),ResponseProcessor=class{constructor(t,c){_defineProperty$2(this,`srsService`,void 0),_defineProperty$2(this,`eloService`,void 0),this.srsService=t,this.eloService=c}parsePerformance(t){return typeof t==`number`?{globalScore:t,taggedPerformance:null}:isTaggedPerformance(t)?{globalScore:t._global,taggedPerformance:t}:(logger.warn(`[ResponseProcessor] Unexpected performance structure, using neutral score`,{performance:t}),{globalScore:.5,taggedPerformance:null})}async processResponse(t,c,u,d,m,g,b,S,C,w){if(!isQuestionRecord(t))return{nextCardAction:`dismiss-success`,shouldLoadNextCard:!0,isCorrect:!0,shouldClearFeedbackShadow:!0};try{let T=await c,E;return E=t.isCorrect?this.processCorrectResponse(t,T,u,d,m,g,b):this.processIncorrectResponse(t,T,d,m,g,b,S,C,w),t.deferAdvance&&E.shouldLoadNextCard&&(logger.info(`[ResponseProcessor] deferAdvance requested — suppressing navigation, action stashed:`,{nextCardAction:E.nextCardAction}),E={...E,shouldLoadNextCard:!1,deferred:!0}),E}catch(t){throw logger.error(`[ResponseProcessor] Failed to load card history`,{e:t,cardId:b}),t}}processCorrectResponse(t,c,u,d,m,g,b){if(t.priorAttemps===0){m.card.tags.includes(`srs:skip`)||this.srsService.scheduleReview(c,u);let{globalScore:S,taggedPerformance:C}=this.parsePerformance(t.performance);if(C){let t=Object.keys(C).filter(t=>t!==`_global`),c=t.filter(t=>C[t]===null),u=t.filter(t=>C[t]!==null);logger.info(`[ResponseProcessor] per-tag ELO update for ${b}: scored=[${u.join(`, `)}] count-only=[${c.join(`, `)}]`),this.eloService.updateUserAndCardEloPerTag(C,g,b,d,m)}else{let t=.5+S/2;if(c.records.length===1)this.eloService.updateUserAndCardElo(t,g,b,d,m);else{let u=Math.ceil(32/c.records.length);this.eloService.updateUserAndCardElo(t,g,b,d,m,u)}logger.info(`[ResponseProcessor] Processed correct response with SRS scheduling and ELO update`)}return{nextCardAction:`dismiss-success`,shouldLoadNextCard:!0,isCorrect:!0,performanceScore:S,shouldClearFeedbackShadow:!0}}else{logger.info(`[ResponseProcessor] Processed correct response (retry attempt - no scheduling/ELO)`);let{globalScore:c}=this.parsePerformance(t.performance);return{nextCardAction:`marked-failed`,shouldLoadNextCard:!0,isCorrect:!0,performanceScore:c,shouldClearFeedbackShadow:!0}}}processIncorrectResponse(t,c,u,d,m,g,b,S,C){let{taggedPerformance:w}=this.parsePerformance(t.performance);return c.records.length!==1&&t.priorAttemps===0?w?(this.eloService.updateUserAndCardEloPerTag(w,m,g,u,d),logger.info(`[ResponseProcessor] Processed incorrect response with per-tag ELO update (${Object.keys(w).length-1} tags)`)):(this.eloService.updateUserAndCardElo(0,m,g,u,d),logger.info(`[ResponseProcessor] Processed incorrect response with ELO update`)):logger.info(`[ResponseProcessor] Processed incorrect response (no ELO update needed)`),d.records.length>=b?C>=S?(w?this.eloService.updateUserAndCardEloPerTag(w,m,g,u,d):this.eloService.updateUserAndCardElo(0,m,g,u,d),{nextCardAction:`dismiss-failed`,shouldLoadNextCard:!0,isCorrect:!1,shouldClearFeedbackShadow:!0}):{nextCardAction:`marked-failed`,shouldLoadNextCard:!0,isCorrect:!1,shouldClearFeedbackShadow:!0}:{nextCardAction:`none`,shouldLoadNextCard:!1,isCorrect:!1,shouldClearFeedbackShadow:!0}}},init_logger(),CardHydrationService=class{constructor(t,c,u){_defineProperty$2(this,`hydratedCards`,new Map),_defineProperty$2(this,`hydrationInFlight`,new Set),_defineProperty$2(this,`hydrationInProgress`,!1),this.getViewComponent=t,this.getCourseDB=c,this.getItemsToHydrate=u}getHydratedCard(t){return this.hydratedCards.get(t)??null}hasHydratedCard(t){return this.hydratedCards.has(t)}removeCard(t){this.hydratedCards.delete(t)}async ensureHydratedCards(){this.fillHydratedCards()}async waitForCard(t){if(this.hydratedCards.has(t))return this.hydratedCards.get(t);this.hydrationInProgress||this.fillHydratedCards();let c=1e4,u=25,d=0;for(;d<1e4;){if(this.hydratedCards.has(t))return this.hydratedCards.get(t);if(!this.hydrationInFlight.has(t)&&!this.hydrationInProgress)break;await new Promise(t=>setTimeout(t,25)),d+=25}return this.hydratedCards.get(t)??null}get hydratedCount(){return this.hydratedCards.size}getHydratedCardIds(){return Array.from(this.hydratedCards.keys())}async fillHydratedCards(){if(!this.hydrationInProgress){this.hydrationInProgress=!0;try{let t=this.getItemsToHydrate();for(let c of t)if(!(this.hydratedCards.has(c.cardID)||this.hydrationInFlight.has(c.cardID)))try{await this.hydrateCard(c)}catch(t){logger.error(`[CardHydrationService] Error hydrating card ${c.cardID}:`,t)}}finally{this.hydrationInProgress=!1}}}async hydrateCard(t){if(!(this.hydratedCards.has(t.cardID)||this.hydrationInFlight.has(t.cardID))){this.hydrationInFlight.add(t.cardID);try{let c=this.getCourseDB(t.courseID),[u,d]=await Promise.all([c.getCourseDoc(t.cardID),c.getAppliedTagsBatch([t.cardID])]);isCourseElo(u.elo)||(u.elo=toCourseElo(u.elo));let m=this.getViewComponent(u.id_view),g=await Promise.all(u.id_displayable_data.map(t=>c.getCourseDoc(t,{attachments:!0,binary:!0}))),b=[];g.forEach(t=>{t.data.forEach(t=>{b.push(...parseAudioURIs(t.data))})});let S=[...new Set(b)];S.length>0&&(logger.debug(`[CardHydrationService] Prefetching ${S.length} audio files for card ${t.cardID}`),await Promise.allSettled(S.map(prefetchAudio)));let C=g.map(displayableDataToViewData).reverse();this.hydratedCards.set(t.cardID,{item:t,view:m,data:C,tags:d.get(t.cardID)??[]}),logger.debug(`[CardHydrationService] Hydrated card ${t.cardID}`)}finally{this.hydrationInFlight.delete(t.cardID)}}}},ItemQueue=class{constructor(){_defineProperty$2(this,`q`,[]),_defineProperty$2(this,`seenCardIds`,[]),_defineProperty$2(this,`_dequeueCount`,0)}get dequeueCount(){return this._dequeueCount}add(t,c){this.seenCardIds.find(t=>t===c)||(this.seenCardIds.push(c),this.q.push(t))}addAll(t,c){t.forEach(t=>this.add(t,c(t)))}get length(){return this.q.length}peek(t){return this.q[t]}dequeue(t){if(this.q.length!==0){this._dequeueCount++;let c=this.q.splice(0,1)[0];if(t){let u=t(c),d=this.seenCardIds.indexOf(u);d>-1&&this.seenCardIds.splice(d,1)}return c}else return null}replaceAll(t,c){this.q=[],this.seenCardIds=[];for(let u of t){let t=c(u);this.seenCardIds.includes(t)||(this.seenCardIds.push(t),this.q.push(u))}}mergeToFront(t,c,u){let d=0,m=[];for(let g of t){let t=c(g);if(!this.seenCardIds.includes(t))this.seenCardIds.push(t),m.push(g),d++;else if(u?.has(t)){let u=this.q.findIndex(u=>c(u)===t);u>=0&&m.push(...this.q.splice(u,1))}}return this.q.unshift(...m),d}get toString(){return`${typeof this.q[0]}:
|
|
409
409
|
`+this.q.map(t=>` ${t.courseID}+${t.cardID}: ${t.status}`).join(`
|
|
410
410
|
`)}},init_couch(),init_core(),init_recording(),init_Loggable(),init_types_legacy(),init_logger(),CouchDBToStaticPacker=class{constructor(t={}){_defineProperty$2(this,`config`,void 0),_defineProperty$2(this,`sourceDB`,null),this.config={chunkSize:1e3,includeAttachments:!0,...t}}async packCourse(t,c){logger.info(`Starting static pack for course: ${c}`),this.sourceDB=t;let u={version:`1.0.0`,courseId:c,courseName:``,courseConfig:null,lastUpdated:new Date().toISOString(),documentCount:0,chunks:[],indices:[],designDocs:[]},d=await this.extractCourseConfig(t);u.courseName=d.name,u.courseConfig=d,u.designDocs=await this.extractDesignDocs(t);let m=await this.extractDocumentsByType(t),g=new Map;this.config.includeAttachments&&await this.extractAllAttachments(m,g);let b=new Map;for(let[t,c]of Object.entries(m)){let d=this.createChunks(c,t);u.chunks.push(...d),u.documentCount+=c.length,this.prepareChunkData(d,c,b)}let S=new Map;return u.indices=await this.buildIndices(m,u.designDocs,S),{manifest:u,chunks:b,indices:S,attachments:g}}async packCourseToFiles(t,c,u,d){logger.info(`Packing course ${c} to files in ${u}`);let m=await this.packCourse(t,c),g=await this.writePackedDataToFiles(m,u,d);return{manifest:m.manifest,filesWritten:g,attachmentsFound:m.attachments?m.attachments.size:0}}async writePackedDataToFiles(t,c,u){let d=0;await u.ensureDir(c);let m=u.joinPath(c,`manifest.json`);await u.writeJson(m,t.manifest,{spaces:2}),d++,logger.info(`Wrote manifest: ${m}`);let g=u.joinPath(c,`chunks`),b=u.joinPath(c,`indices`);await u.ensureDir(g),await u.ensureDir(b);for(let[c,m]of t.chunks){let t=u.joinPath(g,`${c}.json`);await u.writeJson(t,m),d++}logger.info(`Wrote ${t.chunks.size} chunk files`);for(let[c,m]of t.indices){let t=u.joinPath(b,`${c}.json`);await u.writeJson(t,m,{spaces:2}),d++}if(logger.info(`Wrote ${t.indices.size} index files`),t.attachments&&t.attachments.size>0){for(let[m,g]of t.attachments){let t=u.joinPath(c,m),b=u.dirname(t);await u.ensureDir(b),await u.writeFile(t,g.buffer),d++}logger.info(`Wrote ${t.attachments.size} attachment files`)}return d}async extractCourseConfig(t){try{return await t.get(`CourseConfig`)}catch(t){throw logger.error(`Failed to extract course config:`,t),Error(`Course config not found`)}}async extractDesignDocs(t){return(await t.allDocs({startkey:`_design/`,endkey:`_design/`,include_docs:!0})).rows.map(t=>({_id:t.id,views:t.doc.views||{}}))}async extractDocumentsByType(t){let c=await t.allDocs({include_docs:!0}),u={};for(let t of c.rows){if(t.id.startsWith(`_`))continue;let c=t.doc;c.docType&&(u[c.docType]||(u[c.docType]=[]),u[c.docType].push(c))}return u}createChunks(t,c){let u=[],d=t.sort((t,c)=>t._id.localeCompare(c._id));for(let t=0;t<d.length;t+=this.config.chunkSize){let m=d.slice(t,t+this.config.chunkSize),g=`${c}-${String(Math.floor(t/this.config.chunkSize)).padStart(4,`0`)}`;u.push({id:g,docType:c,startKey:m[0]._id,endKey:m[m.length-1]._id,documentCount:m.length,path:`chunks/${g}.json`})}return u}prepareChunkData(t,c,u){let d=c.sort((t,c)=>t._id.localeCompare(c._id));for(let c of t){let t=d.filter(t=>t._id>=c.startKey&&t._id<=c.endKey).map(t=>{let c={...t};return delete c._rev,this.config.includeAttachments&&c._attachments?c._attachments=this.transformAttachmentStubs(c._attachments,c._id):this.config.includeAttachments||delete c._attachments,c});u.set(c.id,t)}}async buildIndices(t,c,u){let d=[];if(t.CARD){let c=await this.buildEloIndex(t.CARD,u);d.push(c)}if(t.TAG){let c=await this.buildTagIndex(t.TAG,u);d.push(c)}for(let t of c)for(let[c,m]of Object.entries(t.views))if(m.map){logger.info(`Processing view: ${t._id}/${c}`);let m=await this.buildViewIndex(c,t,u);m?(d.push(m),logger.info(`Successfully built index: ${m.name}`)):logger.warn(`Skipped view index: ${t._id}/${c}`)}return d}async buildEloIndex(t,c){let u=[];for(let c of t)c.elo?.global?.score&&u.push({elo:c.elo.global.score,cardId:c._id});u.sort((t,c)=>t.elo-c.elo);let d={},m=50;for(let t of u){let c=Math.floor(t.elo/50)*50;d[c]||(d[c]=[]),d[c].push(t.cardId)}return c.set(`elo`,{sorted:u,buckets:d,stats:{min:u[0]?.elo||0,max:u[u.length-1]?.elo||0,count:u.length}}),{name:`elo`,type:`btree`,path:`indices/elo.json`}}async buildTagIndex(t,c){let u={};for(let c of t)u[c.name]={cardIds:c.taggedCards,snippet:c.snippet,count:c.taggedCards.length};let d={};for(let c of t)for(let t of c.taggedCards)d[t]||(d[t]=[]),d[t].push(c.name);return c.set(`tags`,{byTag:u,byCard:d}),{name:`tags`,type:`hash`,path:`indices/tags.json`}}async buildViewIndex(t,c,u){if(!this.sourceDB)return logger.error(`Source database not available for view querying`),null;try{let d=`${c._id.replace(`_design/`,``)}/${t}`;logger.info(`Querying CouchDB view: ${d}`);let m=await this.sourceDB.query(d,{include_docs:!1});if(!m.rows||m.rows.length===0)return logger.warn(`View ${d} returned no results`),null;logger.info(`Successfully queried view ${d}: ${m.rows.length} results`);let g=this.formatViewResults(t,m.rows,c),b=`view-${c._id.replace(`_design/`,``)}-${t}`;return u.set(b,g),{name:b,type:`view`,path:`indices/${b}.json`}}catch(u){return logger.error(`Failed to query view ${c._id}/${t}:`,u),null}}formatViewResults(t,c,u){let d={type:`couchdb-view`,viewName:t,designDoc:u._id,results:c,metadata:{resultCount:c.length,generatedAt:new Date().toISOString()}};switch(t){case`elo`:return this.formatEloViewIndex(c,d);case`getTags`:return this.formatTagsViewIndex(c,d);case`cardsByInexperience`:return this.formatInexperienceViewIndex(c,d);default:return this.formatGenericViewIndex(c,d)}}formatEloViewIndex(t,c){let u=t.sort((t,c)=>typeof t.key==`number`&&typeof c.key==`number`?t.key-c.key:0);return{...c,sorted:u,stats:{min:u[0]?.key||0,max:u[u.length-1]?.key||0,count:u.length}}}formatTagsViewIndex(t,c){let u={};for(let c of t){let t=c.key;typeof t==`string`&&(u[t]||(u[t]=[]),u[t].push(c.id))}return{...c,byTag:u,tagCount:Object.keys(u).length}}formatInexperienceViewIndex(t,c){let u=t.sort((t,c)=>typeof t.key==`number`&&typeof c.key==`number`?t.key-c.key:0);return{...c,sorted:u,stats:{minInexperience:u[0]?.key||0,maxInexperience:u[u.length-1]?.key||0,count:u.length}}}formatGenericViewIndex(t,c){return{...c}}async extractAllAttachments(t,c){logger.info(`Extracting attachments...`);let u=[];for(let c of Object.values(t))u.push(...c);let d=u.filter(t=>t._attachments&&Object.keys(t._attachments).length>0);if(d.length===0){logger.info(`No attachments found`);return}logger.info(`Found ${d.length} documents with attachments`);let m=d.map(t=>this.extractDocumentAttachments(t,c));await Promise.all(m),logger.info(`Extracted ${c.size} attachment files`)}async extractDocumentAttachments(t,c){if(!t._attachments||!this.sourceDB)return;let u=t._id;for(let[d,m]of Object.entries(t._attachments))try{let t=await this.sourceDB.getAttachment(u,d),g;if(t instanceof ArrayBuffer)g=Buffer.from(t);else if(Buffer.isBuffer(t))g=t;else{let c=t;g=Buffer.from(await c.arrayBuffer())}let b=`${d}${this.getFileExtension(m.content_type)}`,S=`attachments/${u}/${b}`;c.set(S,{docId:u,attachmentName:d,filename:b,path:S,contentType:m.content_type,length:m.length||g.length,digest:m.digest,buffer:g}),logger.debug(`Extracted attachment: ${S}`)}catch(t){throw logger.error(`Failed to extract attachment ${u}/${d}:`,t),Error(`Failed to extract attachment ${u}/${d}: ${t}`)}}transformAttachmentStubs(t,c){let u={};for(let[d,m]of Object.entries(t))u[d]={path:`attachments/${c}/${`${d}${this.getFileExtension(m.content_type)}`}`,content_type:m.content_type,length:m.length,digest:m.digest,stub:!1};return u}getFileExtension(t){return{"image/jpeg":`.jpg`,"image/jpg":`.jpg`,"image/png":`.png`,"image/gif":`.gif`,"image/webp":`.webp`,"audio/mpeg":`.mp3`,"audio/mp3":`.mp3`,"audio/wav":`.wav`,"audio/ogg":`.ogg`,"video/mp4":`.mp4`,"video/webm":`.webm`,"application/pdf":`.pdf`,"text/plain":`.txt`,"application/json":`.json`}[t]||``}},init_logger(),DEFAULT_MIGRATION_OPTIONS={chunkBatchSize:100,validateRoundTrip:!1,cleanupOnFailure:!0,timeout:3e5},init_logger(),FileSystemError=class extends Error{constructor(t,c,u,d){super(t),this.operation=c,this.filePath=u,this.cause=d,this.name=`FileSystemError`}},nodeFS2=null;try{typeof window>`u`&&typeof process<`u`&&process.versions?.node&&(nodeFS2=eval(`require`)(`fs`),nodeFS2.promises=nodeFS2.promises||eval(`require`)(`fs`).promises)}catch{}nodeFS3=null,nodePath=null;try{typeof window>`u`&&typeof process<`u`&&process.versions?.node&&(nodeFS3=eval(`require`)(`fs`),nodePath=eval(`require`)(`path`),nodeFS3.promises=nodeFS3.promises||eval(`require`)(`fs`).promises)}catch{}StaticToCouchDBMigrator=class{constructor(t={},c){_defineProperty$2(this,`options`,void 0),_defineProperty$2(this,`progressCallback`,void 0),_defineProperty$2(this,`fs`,void 0),this.options={...DEFAULT_MIGRATION_OPTIONS,...t},this.fs=c}setProgressCallback(t){this.progressCallback=t}async migrateCourse(t,c){let u=Date.now(),d={success:!1,documentsRestored:0,attachmentsRestored:0,designDocsRestored:0,courseConfigRestored:0,errors:[],warnings:[],migrationTime:0};try{logger.info(`Starting migration from ${t} to CouchDB`),this.reportProgress(`manifest`,0,1,`Validating static course...`);let m=await validateStaticCourse(t,this.fs);if(!m.valid)throw d.errors.push(...m.errors),Error(`Static course validation failed: ${m.errors.join(`, `)}`);d.warnings.push(...m.warnings),this.reportProgress(`manifest`,1,1,`Loading course manifest...`);let g=await this.loadManifest(t);logger.info(`Loaded manifest for course: ${g.courseId} (${g.courseName})`),this.reportProgress(`design_docs`,0,g.designDocs.length,`Restoring design documents...`);let b=await this.restoreDesignDocuments(g.designDocs,c);d.designDocsRestored=b.restored,d.errors.push(...b.errors),d.warnings.push(...b.warnings),this.reportProgress(`course_config`,0,1,`Restoring CourseConfig document...`);let S=await this.restoreCourseConfig(g,c);d.courseConfigRestored=S.restored,d.errors.push(...S.errors),d.warnings.push(...S.warnings),this.reportProgress(`course_config`,1,1,`CourseConfig document restored`);let C=this.calculateExpectedCounts(g);this.reportProgress(`documents`,0,g.documentCount,`Aggregating documents from chunks...`);let w=await this.aggregateDocuments(t,g),T=w.filter(t=>t._id!==`CourseConfig`);w.length!==T.length&&d.warnings.push(`Filtered out ${w.length-T.length} CourseConfig document(s) from chunks to prevent conflicts`),this.reportProgress(`documents`,T.length,g.documentCount,`Uploading documents to CouchDB...`);let E=await this.uploadDocuments(T,c);d.documentsRestored=E.restored,d.errors.push(...E.errors),d.warnings.push(...E.warnings);let D=w.filter(t=>t._attachments&&Object.keys(t._attachments).length>0);this.reportProgress(`attachments`,0,D.length,`Uploading attachments...`);let O=await this.uploadAttachments(t,D,c);if(d.attachmentsRestored=O.restored,d.errors.push(...O.errors),d.warnings.push(...O.warnings),this.options.validateRoundTrip){this.reportProgress(`validation`,0,1,`Validating migration...`);let t=await validateMigration(c,C,g);t.valid||(d.warnings.push(`Migration validation found issues`),t.issues.forEach(t=>{t.type===`error`?d.errors.push(`Validation: ${t.message}`):d.warnings.push(`Validation: ${t.message}`)})),this.reportProgress(`validation`,1,1,`Migration validation completed`)}d.success=d.errors.length===0,d.migrationTime=Date.now()-u,logger.info(`Migration completed in ${d.migrationTime}ms`),logger.info(`Documents restored: ${d.documentsRestored}`),logger.info(`Attachments restored: ${d.attachmentsRestored}`),logger.info(`Design docs restored: ${d.designDocsRestored}`),logger.info(`CourseConfig restored: ${d.courseConfigRestored}`),d.errors.length>0&&logger.error(`Migration completed with ${d.errors.length} errors`),d.warnings.length>0&&logger.warn(`Migration completed with ${d.warnings.length} warnings`)}catch(t){d.success=!1,d.migrationTime=Date.now()-u;let m=t instanceof Error?t.message:String(t);if(d.errors.push(`Migration failed: ${m}`),logger.error(`Migration failed:`,t),this.options.cleanupOnFailure)try{await this.cleanupFailedMigration(c)}catch(t){logger.error(`Failed to cleanup after migration failure:`,t),d.warnings.push(`Failed to cleanup after migration failure`)}}return d}async loadManifest(t){try{let c,u;if(this.fs)u=this.fs.joinPath(t,`manifest.json`),c=await this.fs.readFile(u);else if(u=nodeFS3&&nodePath?nodePath.join(t,`manifest.json`):`${t}/manifest.json`,nodeFS3&&this.isLocalPath(t))c=await nodeFS3.promises.readFile(u,`utf8`);else{let t=await fetch(u);if(!t.ok)throw Error(`Failed to fetch manifest: ${t.status} ${t.statusText}`);c=await t.text()}let d=JSON.parse(c);if(!d.version||!d.courseId||!d.chunks)throw Error(`Invalid manifest structure`);return d}catch(t){let c=t instanceof FileSystemError?t.message:`Failed to load manifest: ${t instanceof Error?t.message:String(t)}`;throw Error(c)}}async restoreDesignDocuments(t,c){let u={restored:0,errors:[],warnings:[]};for(let d=0;d<t.length;d++){let m=t[d];this.reportProgress(`design_docs`,d,t.length,`Restoring ${m._id}...`);try{let t;try{t=await c.get(m._id)}catch{}let d={_id:m._id,views:m.views};t?(d._rev=t._rev,logger.debug(`Updating existing design document: ${m._id}`)):logger.debug(`Creating new design document: ${m._id}`),await c.put(d),u.restored++}catch(t){let c=`Failed to restore design document ${m._id}: ${t instanceof Error?t.message:String(t)}`;u.errors.push(c),logger.error(c)}}return this.reportProgress(`design_docs`,t.length,t.length,`Restored ${u.restored} design documents`),u}async aggregateDocuments(t,c){let u=[],d=new Map;for(let m=0;m<c.chunks.length;m++){let g=c.chunks[m];this.reportProgress(`documents`,u.length,c.documentCount,`Loading chunk ${g.id}...`);try{let c=await this.loadChunk(t,g);for(let t of c){if(!t._id){logger.warn(`Document without _id found in chunk ${g.id}, skipping`);continue}d.has(t._id)&&logger.warn(`Duplicate document ID found: ${t._id}, using latest version`),d.set(t._id,t)}}catch(t){throw Error(`Failed to load chunk ${g.id}: ${t instanceof Error?t.message:String(t)}`)}}return u.push(...d.values()),logger.info(`Aggregated ${u.length} unique documents from ${c.chunks.length} chunks`),u}async loadChunk(t,c){try{let u,d;if(this.fs)d=this.fs.joinPath(t,c.path),u=await this.fs.readFile(d);else if(d=nodeFS3&&nodePath?nodePath.join(t,c.path):`${t}/${c.path}`,nodeFS3&&this.isLocalPath(t))u=await nodeFS3.promises.readFile(d,`utf8`);else{let t=await fetch(d);if(!t.ok)throw Error(`Failed to fetch chunk: ${t.status} ${t.statusText}`);u=await t.text()}let m=JSON.parse(u);if(!Array.isArray(m))throw Error(`Chunk file does not contain an array of documents`);return m}catch(t){let c=t instanceof FileSystemError?t.message:`Failed to load chunk: ${t instanceof Error?t.message:String(t)}`;throw Error(c)}}async uploadDocuments(t,c){let u={restored:0,errors:[],warnings:[]},d=this.options.chunkBatchSize;for(let m=0;m<t.length;m+=d){let g=t.slice(m,m+d);this.reportProgress(`documents`,m,t.length,`Uploading batch ${Math.floor(m/d)+1}...`);try{let t=g.map(t=>{let c={...t};return delete c._rev,delete c._attachments,c}),d=await c.bulkDocs(t);for(let t=0;t<d.length;t++){let c=d[t],m=g[t];if(`error`in c){let t=`Failed to upload document ${m._id}: ${c.error} - ${c.reason}`;u.errors.push(t),logger.error(t)}else u.restored++}}catch(t){let c;c=t instanceof Error||t&&typeof t==`object`&&`message`in t?`Failed to upload document batch starting at index ${m}: ${t.message}`:`Failed to upload document batch starting at index ${m}: ${JSON.stringify(t)}`,u.errors.push(c),logger.error(c)}}return this.reportProgress(`documents`,t.length,t.length,`Uploaded ${u.restored} documents`),u}async uploadAttachments(t,c,u){let d={restored:0,errors:[],warnings:[]},m=0;for(let g of c)if(this.reportProgress(`attachments`,m,c.length,`Processing attachments for ${g._id}...`),m++,g._attachments)for(let[c,m]of Object.entries(g._attachments))try{let b=await this.uploadSingleAttachment(t,g._id,c,m,u);b.success?d.restored++:d.errors.push(b.error||`Unknown attachment upload error`)}catch(t){let u=`Failed to upload attachment ${g._id}/${c}: ${t instanceof Error?t.message:String(t)}`;d.errors.push(u),logger.error(u)}return this.reportProgress(`attachments`,c.length,c.length,`Uploaded ${d.restored} attachments`),d}async uploadSingleAttachment(t,c,u,d,m){let g={success:!1,attachmentName:u,docId:c};try{if(!d.path)return g.error=`Attachment metadata missing file path`,g;let b,S;if(this.fs)S=this.fs.joinPath(t,d.path),b=await this.fs.readBinary(S);else if(S=nodeFS3&&nodePath?nodePath.join(t,d.path):`${t}/${d.path}`,nodeFS3&&this.isLocalPath(t))b=await nodeFS3.promises.readFile(S);else{let t=await fetch(S);if(!t.ok)return g.error=`Failed to fetch attachment: ${t.status} ${t.statusText}`,g;b=await t.arrayBuffer()}let C=await m.get(c);await m.putAttachment(c,u,C._rev,b,d.content_type),g.success=!0}catch(t){g.error=t instanceof Error?t.message:String(t)}return g}async restoreCourseConfig(t,c){let u={restored:0,errors:[],warnings:[]};try{if(!t.courseConfig)return u.warnings.push(`No courseConfig found in manifest, skipping CourseConfig document creation`),u;let d={_id:`CourseConfig`,...t.courseConfig,courseID:t.courseId};delete d._rev,await c.put(d),u.restored=1,logger.info(`CourseConfig document created for course: ${t.courseId}`)}catch(t){let c=t instanceof Error?t.message:JSON.stringify(t);u.errors.push(`Failed to restore CourseConfig: ${c}`),logger.error(`CourseConfig restoration failed:`,t)}return u}calculateExpectedCounts(t){let c={};for(let u of t.chunks)c[u.docType]=(c[u.docType]||0)+u.documentCount;return t.designDocs.length>0&&(c._design=t.designDocs.length),c}async cleanupFailedMigration(t){logger.info(`Cleaning up failed migration...`);try{let c=(await t.allDocs()).rows.map(t=>({_id:t.id,_rev:t.value.rev,_deleted:!0}));c.length>0&&(await t.bulkDocs(c),logger.info(`Cleaned up ${c.length} documents from failed migration`))}catch(t){throw logger.error(`Failed to cleanup documents:`,t),t}}reportProgress(t,c,u,d){this.progressCallback&&this.progressCallback({phase:t,current:c,total:u,message:d})}isLocalPath(t){return!t.startsWith(`http://`)&&!t.startsWith(`https://`)}},init_dataDirectory(),init_navigators(),init_Pipeline(),QuotaRoundRobinMixer=class{mix(t,c){if(t.length===0)return[];let u=Math.ceil(c/t.length),d=t.map(t=>[...t.weighted].sort((t,c)=>c.score-t.score).slice(0,u));for(let t=d.length-1;t>0;t--){let c=Math.floor(Math.random()*(t+1));[d[t],d[c]]=[d[c],d[t]]}let m=[],g=0,b=Array(d.length).fill(0);for(;m.length<c&&g<d.length;){g=0;for(let t=0;t<d.length&&!(m.length>=c);t++)b[t]<d[t].length?(m.push(d[t][b[t]]),b[t]++):g++}return m}},init_logger(),init_navigators(),MAX_RUNS2=10,runHistory2=[],mixerDebugAPI={get runs(){return[...runHistory2]},showRun(t=0){if(runHistory2.length===0){logger.info(`[Mixer Debug] No runs captured yet.`);return}let c;if(typeof t==`number`){if(c=runHistory2[t],!c){logger.info(`[Mixer Debug] No run found at index ${t}. History length: ${runHistory2.length}`);return}}else if(c=runHistory2.find(c=>c.runId.endsWith(t)),!c){logger.info(`[Mixer Debug] No run found matching ID '${t}'.`);return}printMixerSummary(c)},showLastMix(){this.showRun(0)},explainSourceBalance(){if(runHistory2.length===0){logger.info(`[Mixer Debug] No runs captured yet.`);return}let t=runHistory2[0];console.group(`⚖️ Source Balance Analysis`),logger.info(`Mixer: ${t.mixerType}`),logger.info(`Requested limit: ${t.requestedLimit}`),t.quotaPerSource&&logger.info(`Quota per source: ${t.quotaPerSource}`),console.group(`Input Distribution:`);for(let c of t.sourceSummaries){let t=c.sourceName||c.sourceId;logger.info(`${t}:`),logger.info(` Provided: ${c.totalCards} cards (${c.reviewCount} reviews, ${c.newCount} new)`),logger.info(` Score range: [${c.scoreRange[0].toFixed(2)}, ${c.scoreRange[1].toFixed(2)}]`)}console.groupEnd(),console.group(`Selection Results:`);for(let c of t.sourceBreakdowns){let t=c.sourceName||c.sourceId;logger.info(`${t}:`),logger.info(` Selected: ${c.totalSelected}/${c.reviewsProvided+c.newProvided} (${c.selectionRate.toFixed(1)}%)`),logger.info(` Reviews: ${c.reviewsSelected}/${c.reviewsProvided}`),logger.info(` New: ${c.newSelected}/${c.newProvided}`),c.reviewsProvided>0&&c.reviewsSelected===0&&logger.info(` ⚠️ Had reviews but none selected!`),c.totalSelected===0&&c.reviewsProvided+c.newProvided>0&&logger.info(` ⚠️ Had cards but none selected!`)}console.groupEnd();let c=t.sourceBreakdowns.map(t=>t.selectionRate),u=c.reduce((t,c)=>t+c,0)/c.length,d=Math.max(...c.map(t=>Math.abs(t-u)));d>20&&(logger.info(`
|
|
411
411
|
\u26A0\uFE0F Significant imbalance detected (max deviation: ${d.toFixed(1)}%)`),logger.info(`Possible causes:`),logger.info(` - Score range differences between sources`),logger.info(` - One source has much better quality cards`),logger.info(` - Different card availability (reviews vs new)`)),console.groupEnd()},compareScores(){if(runHistory2.length===0){logger.info(`[Mixer Debug] No runs captured yet.`);return}let t=runHistory2[0];console.group(`📊 Score Distribution Comparison`),console.table(t.sourceSummaries.map(t=>({source:t.sourceName||t.sourceId,cards:t.totalCards,min:t.bottomScore.toFixed(3),max:t.topScore.toFixed(3),avg:t.avgScore.toFixed(3),range:(t.topScore-t.bottomScore).toFixed(3)})));let c=t.sourceSummaries.map(t=>t.topScore-t.bottomScore),u=t.sourceSummaries.map(t=>t.avgScore),d=Math.max(...c)-Math.min(...c),m=Math.max(...u)-Math.min(...u);(d>.3||m>.2)&&(logger.info(`
|
|
@@ -454,12 +454,12 @@ Example:
|
|
|
454
454
|
startTime: ${this.startTime}
|
|
455
455
|
endTime: ${this.endTime}
|
|
456
456
|
defaultBatchLimit: ${this._defaultBatchLimit}
|
|
457
|
-
initialReviewCap: ${this._initialReviewCap}`),registerActiveController(this)}tick(){this._secondsRemaining=Math.floor((this.endTime.valueOf()-Date.now())/1e3),this._secondsRemaining<=0&&clearInterval(this._intervalHandle)}estimateCleanupTime(){let t=0;for(let c=0;c<this.failedQ.length;c++){let u=this.failedQ.peek(c),d=this._sessionRecord.find(t=>t.item.cardID===u.cardID),m=0;if(d){for(let t=0;t<d.records.length;t++)m+=d.records[t].timeSpent;m/=d.records.length,t+=m}}let c=t/1e3;return this.log(`Failed card cleanup estimate: ${Math.round(c)}`),c}estimateReviewTime(){let t=5*this.reviewQ.length;return this.log(`Review card time estimate: ${t}`),t}async prepareSession(){if(this.sources.some(t=>typeof t.getWeightedCards!=`function`))throw Error(`[SessionController] All content sources must implement getWeightedCards().`);let t=await this.getWeightedContent();this._wellIndicatedRemaining=t,t>=0&&t<_SessionController.MIN_WELL_INDICATED&&this.log(`[Init] Only ${t}/${_SessionController.MIN_WELL_INDICATED} well-indicated cards in initial load`),await this.hydrationService.ensureHydratedCards(),startSessionTracking(this.reviewQ.length,this.newQ.length,this.failedQ.length),this._intervalHandle=setInterval(()=>{this.tick()},1e3)}async requestReplan(t){let c=this.normalizeReplanOptions(t),u=this._replanHasIntent(c);if(this._replanPromise){if(!u)return this.log(`Replan already in progress, coalescing unhinted auto-replan`),this._replanPromise;let t=c.label?` [${c.label}]`:``;this.log(`Replan in progress; queueing hint-bearing replan${t} behind in-flight run`);let d=this._replanPromise.catch(()=>void 0).then(()=>this._runReplan(c)),m=d.finally(()=>{this._replanPromise===m&&(this._replanPromise=null,this._activeReplanLabel=null)});return this._replanPromise=m,d}let d=this._runReplan(c),m=d.finally(()=>{this._replanPromise===m&&(this._replanPromise=null,this._activeReplanLabel=null)});this._replanPromise=m,await d}_replanHasIntent(t){return!!(t.limit!==void 0||t.minFollowUpCards!==void 0||t.mode&&t.mode!==`replace`||t.hints&&Object.keys(t.hints).length>0||t.sessionHints!==void 0||t.mergeSessionHints!==void 0)}async _runReplan(t){this._activeReplanLabel=t.label??`(auto)`,t.hints||(t.hints={});let c=t.hints,u=new Set(c.excludeCards??[]);this._currentCard?.item.cardID&&u.add(this._currentCard.item.cardID);for(let t of this._sessionRecord)u.add(t.card.card_id);this.newQ.length>0&&u.add(this.newQ.peek(0).cardID),c.excludeCards=[...u],t.sessionHints!==void 0&&(this._sessionHints=t.sessionHints,this.log(`[Replan] Session hints ${t.sessionHints?`set`:`cleared`}: ${JSON.stringify(t.sessionHints)}`)),t.mergeSessionHints!==void 0&&(this._sessionHints=mergeHints2([this._sessionHints,t.mergeSessionHints])??null,this.log(`[Replan] Session hints merged: ${JSON.stringify(this._sessionHints)}`)),this._applyHintsToSources(t.hints,t.label);let d=t.label?` [${t.label}]`:``;this.log(`Mid-session replan requested${d} (limit: ${t.limit??`default`}, mode: ${t.mode??`replace`}${t.hints?`, with hints`:``})`),t.minFollowUpCards!==void 0&&t.minFollowUpCards>0&&(this._minCardsGuarantee=Math.max(this._minCardsGuarantee,t.minFollowUpCards),this.log(`[Replan] Card guarantee set to ${this._minCardsGuarantee}`)),await this._executeReplan(t)}setSessionHints(t){this._sessionHints=t,this.log(`Session hints ${t?`set`:`cleared`}: ${JSON.stringify(t)}`)}getSessionHints(){return this._sessionHints}getDebugSnapshot(){let describe=t=>{let c=[];for(let u=0;u<t.length;u++)c.push(t.peek(u).cardID);return{length:t.length,dequeueCount:t.dequeueCount,cards:c}},t=this._sessionRecord.map(t=>{let c=t.records[t.records.length-1];return{cardID:t.item.cardID,status:t.item.status,attempts:t.records.length,correct:c&&isQuestionRecord(c)?c.isCorrect:null,timeSpentMs:t.records.reduce((t,c)=>t+c.timeSpent,0)}});return{secondsRemaining:this.secondsRemaining,hasCardGuarantee:this.hasCardGuarantee,minCardsGuarantee:this._minCardsGuarantee,wellIndicatedRemaining:this._wellIndicatedRemaining,currentCard:this._currentCard?.item.cardID??null,sessionHints:this._sessionHints,replanActive:this._replanPromise!==null,replanLabel:this._activeReplanLabel,reviewQ:describe(this.reviewQ),newQ:describe(this.newQ),failedQ:describe(this.failedQ),drawnCards:t}}mergeSessionHints(t){this._sessionHints=mergeHints2([this._sessionHints,t])??null,this.log(`Session hints merged: ${JSON.stringify(this._sessionHints)}`)}_applyHintsToSources(t,c){let u=t&&c?{...t,_label:c}:t,d=mergeHints2([this._sessionHints,u]);if(d)for(let t of this.sources)t.setEphemeralHints?.(d)}_getSessionControls(){return this._sessionControls||(this._sessionControls={getSessionHints:()=>this.getSessionHints(),setSessionHints:t=>this.setSessionHints(t),mergeSessionHints:t=>this.mergeSessionHints(t),requestReplan:t=>this.requestReplan(t)}),this._sessionControls}async _notifyOutcomeObservers(t,c,u){if(this._outcomeObservers.length===0||!isQuestionRecord(t))return;let d={record:t,card:c.card,result:u},m=this._getSessionControls();for(let t of this._outcomeObservers)try{await t(d,m)}catch(t){this.error(`[OutcomeObserver] observer threw; ignoring`,t)}}async _replanUncoalesced(t){let c=this._runReplan(t),u=c.finally(()=>{this._replanPromise===u&&(this._replanPromise=null,this._activeReplanLabel=null)});this._replanPromise=u,await c}normalizeReplanOptions(t){if(!t)return{};let c=[`hints`,`sessionHints`,`limit`,`mode`,`label`,`minFollowUpCards`];return Object.keys(t).some(t=>c.includes(t))?t:{hints:t}}async _executeReplan(t={}){let c=t.limit,u=t.mode??`replace`,d=await this.getWeightedContent({replan:!0,additive:u===`merge`,limit:c});this._wellIndicatedRemaining=d,c!==void 0&&c<this._defaultBatchLimit?(this._suppressQualityReplan=!0,this.log(`[Replan] Burst mode (limit=${c}): suppressing quality-based auto-replan`)):this._suppressQualityReplan=!1,d>=0&&d<_SessionController.MIN_WELL_INDICATED&&this.log(`[Replan] Only ${d}/${_SessionController.MIN_WELL_INDICATED} well-indicated cards after replan`),await this.hydrationService.ensureHydratedCards();let m=t.label?` [${t.label}]`:``;this.log(`Replan complete${m}: newQ now has ${this.newQ.length} cards (mode=${u})`),snapshotQueues(this.reviewQ.length,this.newQ.length,this.failedQ.length)}addTime(t){this.endTime=new Date(this.endTime.valueOf()+1e3*t)}get failedCount(){return this.failedQ.length}toString(){return`Session: ${this.reviewQ.length} Reviews, ${this.newQ.length} New, ${this.failedQ.length} failed`}reportString(){return`${this.reviewQ.dequeueCount} Reviews, ${this.newQ.dequeueCount} New, ${this.failedQ.dequeueCount} failed`}getDebugInfo(){let t=this.sources.some(t=>typeof t.getWeightedCards==`function`),extractQueueItems=(t,c=10)=>{let u=[];for(let d=0;d<Math.min(t.length,c);d++){let c=t.peek(d);u.push({courseID:c.courseID||`unknown`,cardID:c.cardID||`unknown`,status:c.status||`unknown`})}return u};return{api:{mode:t?`weighted`:`legacy`,description:t?`Using getWeightedCards() API with scored candidates`:`ERROR: getWeightedCards() not a function.`},reviewQueue:{length:this.reviewQ.length,dequeueCount:this.reviewQ.dequeueCount,items:extractQueueItems(this.reviewQ)},newQueue:{length:this.newQ.length,dequeueCount:this.newQ.dequeueCount,items:extractQueueItems(this.newQ)},failedQueue:{length:this.failedQ.length,dequeueCount:this.failedQ.dequeueCount,items:extractQueueItems(this.failedQ)},hydratedCache:{count:this.hydrationService.hydratedCount,cardIds:this.hydrationService.getHydratedCardIds()},replan:{inProgress:this._replanPromise!==null,suppressQualityReplan:this._suppressQualityReplan,defaultBatchLimit:this._defaultBatchLimit,minCardsGuarantee:this._minCardsGuarantee}}}async getWeightedContent(t){let c=t?.replan??!1,u=t?.additive??!1,d=t?.limit??this._defaultBatchLimit,m=c?d:d+this._initialReviewCap;c||this._applyHintsToSources();let g=[];for(let t=0;t<this.sources.length;t++){let c=this.sources[t];try{let u=(await c.getWeightedCards(m)).cards;g.push({sourceIndex:t,weighted:u})}catch(c){if(this.error(`Failed to get content from source ${t}:`,c),this.sources.length===1)throw Error(`Cannot start session: failed to load content from source ${t}`)}}if(g.length===0){if(c)return this.log(`Replan: no content from any source, keeping existing newQ`),-1;throw Error(`Cannot start session: failed to load content from all ${this.sources.length} source(s). Check logs for details.`)}let b=this.mixer.mix(g,m*this.sources.length),S=g.map(t=>t.weighted[0]?.courseId||`source-${t.sourceIndex}`);await Promise.all(S.map(async t=>{if(!this.courseNameCache.has(t))try{let c=await this.dataLayer.getCoursesDB().getCourseConfig(t);this.courseNameCache.set(t,c.name)}catch{}}));let C=S.map(t=>this.courseNameCache.get(t)),w=this.mixer instanceof QuotaRoundRobinMixer?Math.ceil(m*this.sources.length/g.length):void 0;captureMixerRun(this.mixer.constructor.name,g,S,C,m*this.sources.length,w,b);let T=b.filter(t=>getCardOrigin(t)===`review`).slice(0,this._initialReviewCap),E=b.filter(t=>getCardOrigin(t)===`new`&&!this._servedCardIds.has(t.cardId)).slice(0,d);logger.debug(`[reviews] got ${T.length} reviews from mixer`);let
|
|
457
|
+
initialReviewCap: ${this._initialReviewCap}`),registerActiveController(this)}tick(){this._secondsRemaining=Math.floor((this.endTime.valueOf()-Date.now())/1e3),this._secondsRemaining<=0&&clearInterval(this._intervalHandle)}estimateCleanupTime(){let t=0;for(let c=0;c<this.failedQ.length;c++){let u=this.failedQ.peek(c),d=this._sessionRecord.find(t=>t.item.cardID===u.cardID),m=0;if(d){for(let t=0;t<d.records.length;t++)m+=d.records[t].timeSpent;m/=d.records.length,t+=m}}let c=t/1e3;return this.log(`Failed card cleanup estimate: ${Math.round(c)}`),c}estimateReviewTime(){let t=5*this.reviewQ.length;return this.log(`Review card time estimate: ${t}`),t}async prepareSession(){if(this.sources.some(t=>typeof t.getWeightedCards!=`function`))throw Error(`[SessionController] All content sources must implement getWeightedCards().`);let t=await this.getWeightedContent();this._wellIndicatedRemaining=t,t>=0&&t<_SessionController.MIN_WELL_INDICATED&&this.log(`[Init] Only ${t}/${_SessionController.MIN_WELL_INDICATED} well-indicated cards in initial load`),await this.hydrationService.ensureHydratedCards(),startSessionTracking(this.reviewQ.length,this.newQ.length,this.failedQ.length),this._intervalHandle=setInterval(()=>{this.tick()},1e3)}async requestReplan(t){let c=this.normalizeReplanOptions(t),u=this._replanHasIntent(c);if(this._replanPromise){if(!u)return this.log(`Replan already in progress, coalescing unhinted auto-replan`),this._replanPromise;let t=c.label?` [${c.label}]`:``;this.log(`Replan in progress; queueing hint-bearing replan${t} behind in-flight run`);let d=this._replanPromise.catch(()=>void 0).then(()=>this._runReplan(c)),m=d.finally(()=>{this._replanPromise===m&&(this._replanPromise=null,this._activeReplanLabel=null)});return this._replanPromise=m,d}let d=this._runReplan(c),m=d.finally(()=>{this._replanPromise===m&&(this._replanPromise=null,this._activeReplanLabel=null)});this._replanPromise=m,await d}_replanHasIntent(t){return!!(t.limit!==void 0||t.minFollowUpCards!==void 0||t.mode&&t.mode!==`replace`||t.hints&&Object.keys(t.hints).length>0||t.sessionHints!==void 0||t.mergeSessionHints!==void 0)}async _runReplan(t){this._activeReplanLabel=t.label??`(auto)`,t.hints||(t.hints={});let c=t.hints,u=new Set(c.excludeCards??[]);this._currentCard?.item.cardID&&u.add(this._currentCard.item.cardID);for(let t of this._sessionRecord)u.add(t.card.card_id);this.newQ.length>0&&u.add(this.newQ.peek(0).cardID),c.excludeCards=[...u],t.sessionHints!==void 0&&(this._sessionHints=t.sessionHints,this.log(`[Replan] Session hints ${t.sessionHints?`set`:`cleared`}: ${JSON.stringify(t.sessionHints)}`)),t.mergeSessionHints!==void 0&&(this._sessionHints=mergeHints2([this._sessionHints,t.mergeSessionHints])??null,this.log(`[Replan] Session hints merged: ${JSON.stringify(this._sessionHints)}`)),this._applyHintsToSources(t.hints,t.label);let d=t.label?` [${t.label}]`:``;this.log(`Mid-session replan requested${d} (limit: ${t.limit??`default`}, mode: ${t.mode??`replace`}${t.hints?`, with hints`:``})`),t.minFollowUpCards!==void 0&&t.minFollowUpCards>0&&(this._minCardsGuarantee=Math.max(this._minCardsGuarantee,t.minFollowUpCards),this.log(`[Replan] Card guarantee set to ${this._minCardsGuarantee}`)),await this._executeReplan(t)}setSessionHints(t){this._sessionHints=t,this.log(`Session hints ${t?`set`:`cleared`}: ${JSON.stringify(t)}`)}getSessionHints(){return this._sessionHints}getDebugSnapshot(){let describe=t=>{let c=[];for(let u=0;u<t.length;u++)c.push(t.peek(u).cardID);return{length:t.length,dequeueCount:t.dequeueCount,cards:c}},t=this._sessionRecord.map(t=>{let c=t.records[t.records.length-1];return{cardID:t.item.cardID,status:t.item.status,attempts:t.records.length,correct:c&&isQuestionRecord(c)?c.isCorrect:null,timeSpentMs:t.records.reduce((t,c)=>t+c.timeSpent,0)}});return{secondsRemaining:this.secondsRemaining,hasCardGuarantee:this.hasCardGuarantee,minCardsGuarantee:this._minCardsGuarantee,wellIndicatedRemaining:this._wellIndicatedRemaining,currentCard:this._currentCard?.item.cardID??null,sessionHints:this._sessionHints,replanActive:this._replanPromise!==null,replanLabel:this._activeReplanLabel,reviewQ:describe(this.reviewQ),newQ:describe(this.newQ),failedQ:describe(this.failedQ),drawnCards:t}}mergeSessionHints(t){this._sessionHints=mergeHints2([this._sessionHints,t])??null,this.log(`Session hints merged: ${JSON.stringify(this._sessionHints)}`)}_applyHintsToSources(t,c){let u=t&&c?{...t,_label:c}:t,d=mergeHints2([this._sessionHints,u]);if(d)for(let t of this.sources)t.setEphemeralHints?.(d)}_getSessionControls(){return this._sessionControls||(this._sessionControls={getSessionHints:()=>this.getSessionHints(),setSessionHints:t=>this.setSessionHints(t),mergeSessionHints:t=>this.mergeSessionHints(t),requestReplan:t=>this.requestReplan(t)}),this._sessionControls}async _notifyOutcomeObservers(t,c,u){if(this._outcomeObservers.length===0||!isQuestionRecord(t))return;let d={record:t,card:c.card,result:u},m=this._getSessionControls();for(let t of this._outcomeObservers)try{await t(d,m)}catch(t){this.error(`[OutcomeObserver] observer threw; ignoring`,t)}}async _replanUncoalesced(t){let c=this._runReplan(t),u=c.finally(()=>{this._replanPromise===u&&(this._replanPromise=null,this._activeReplanLabel=null)});this._replanPromise=u,await c}normalizeReplanOptions(t){if(!t)return{};let c=[`hints`,`sessionHints`,`limit`,`mode`,`label`,`minFollowUpCards`];return Object.keys(t).some(t=>c.includes(t))?t:{hints:t}}async _executeReplan(t={}){let c=t.limit,u=t.mode??`replace`,d=await this.getWeightedContent({replan:!0,additive:u===`merge`,limit:c});this._wellIndicatedRemaining=d,c!==void 0&&c<this._defaultBatchLimit?(this._suppressQualityReplan=!0,this.log(`[Replan] Burst mode (limit=${c}): suppressing quality-based auto-replan`)):this._suppressQualityReplan=!1,d>=0&&d<_SessionController.MIN_WELL_INDICATED&&this.log(`[Replan] Only ${d}/${_SessionController.MIN_WELL_INDICATED} well-indicated cards after replan`),await this.hydrationService.ensureHydratedCards();let m=t.label?` [${t.label}]`:``;this.log(`Replan complete${m}: newQ now has ${this.newQ.length} cards (mode=${u})`),snapshotQueues(this.reviewQ.length,this.newQ.length,this.failedQ.length)}addTime(t){this.endTime=new Date(this.endTime.valueOf()+1e3*t)}get failedCount(){return this.failedQ.length}toString(){return`Session: ${this.reviewQ.length} Reviews, ${this.newQ.length} New, ${this.failedQ.length} failed`}reportString(){return`${this.reviewQ.dequeueCount} Reviews, ${this.newQ.dequeueCount} New, ${this.failedQ.dequeueCount} failed`}getDebugInfo(){let t=this.sources.some(t=>typeof t.getWeightedCards==`function`),extractQueueItems=(t,c=10)=>{let u=[];for(let d=0;d<Math.min(t.length,c);d++){let c=t.peek(d);u.push({courseID:c.courseID||`unknown`,cardID:c.cardID||`unknown`,status:c.status||`unknown`})}return u};return{api:{mode:t?`weighted`:`legacy`,description:t?`Using getWeightedCards() API with scored candidates`:`ERROR: getWeightedCards() not a function.`},reviewQueue:{length:this.reviewQ.length,dequeueCount:this.reviewQ.dequeueCount,items:extractQueueItems(this.reviewQ)},newQueue:{length:this.newQ.length,dequeueCount:this.newQ.dequeueCount,items:extractQueueItems(this.newQ)},failedQueue:{length:this.failedQ.length,dequeueCount:this.failedQ.dequeueCount,items:extractQueueItems(this.failedQ)},hydratedCache:{count:this.hydrationService.hydratedCount,cardIds:this.hydrationService.getHydratedCardIds()},replan:{inProgress:this._replanPromise!==null,suppressQualityReplan:this._suppressQualityReplan,defaultBatchLimit:this._defaultBatchLimit,minCardsGuarantee:this._minCardsGuarantee}}}async getWeightedContent(t){let c=t?.replan??!1,u=t?.additive??!1,d=t?.limit??this._defaultBatchLimit,m=c?d:d+this._initialReviewCap;c||this._applyHintsToSources();let g=[];for(let t=0;t<this.sources.length;t++){let c=this.sources[t];try{let u=(await c.getWeightedCards(m)).cards;g.push({sourceIndex:t,weighted:u})}catch(c){if(this.error(`Failed to get content from source ${t}:`,c),this.sources.length===1)throw Error(`Cannot start session: failed to load content from source ${t}`)}}if(g.length===0){if(c)return this.log(`Replan: no content from any source, keeping existing newQ`),-1;throw Error(`Cannot start session: failed to load content from all ${this.sources.length} source(s). Check logs for details.`)}let b=this.mixer.mix(g,m*this.sources.length),S=g.map(t=>t.weighted[0]?.courseId||`source-${t.sourceIndex}`);await Promise.all(S.map(async t=>{if(!this.courseNameCache.has(t))try{let c=await this.dataLayer.getCoursesDB().getCourseConfig(t);this.courseNameCache.set(t,c.name)}catch{}}));let C=S.map(t=>this.courseNameCache.get(t)),w=this.mixer instanceof QuotaRoundRobinMixer?Math.ceil(m*this.sources.length/g.length):void 0;captureMixerRun(this.mixer.constructor.name,g,S,C,m*this.sources.length,w,b);let T=b.filter(t=>getCardOrigin(t)===`review`).slice(0,this._initialReviewCap),E=b.filter(t=>getCardOrigin(t)===`new`&&!this._servedCardIds.has(t.cardId)),D=E.filter(t=>t.score===1/0),O=E.filter(t=>t.score!==1/0),Or=[...D,...O.slice(0,Math.max(0,d-D.length))],kr=new Set(D.map(t=>t.cardId));logger.debug(`[reviews] got ${T.length} reviews from mixer`);let Ar=c?`Replan content:
|
|
458
458
|
`:`Mixed content session created with:
|
|
459
|
-
`;if(!c)for(let t of T){let c={cardID:t.cardId,courseID:t.courseId,contentSourceType:`course`,contentSourceID:t.courseId,reviewID:t.reviewID,status:`review`};this.reviewQ.add(c,c.cardID),
|
|
460
|
-
`}let
|
|
461
|
-
`}if(u){let t=this.newQ.mergeToFront(
|
|
462
|
-
`}else if(c)this.newQ.replaceAll(Or,t=>t.cardID);else for(let t of Or)this.newQ.add(t,t.cardID);return this.log(D),O}_getItemsToHydrate(){let t=[],c=2;for(let c=0;c<Math.min(2,this.reviewQ.length);c++)t.push(this.reviewQ.peek(c));for(let c=0;c<Math.min(2,this.newQ.length);c++)t.push(this.newQ.peek(c));for(let c=0;c<Math.min(2,this.failedQ.length);c++)t.push(this.failedQ.peek(c));return t}_selectNextItemToHydrate(){let t=Math.random(),c=.1,u=.75;if(this.reviewQ.length===0&&this.failedQ.length===0&&this.newQ.length===0||this._secondsRemaining<2&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return null;if(this._secondsRemaining<=0&&this._minCardsGuarantee<=0)return this.failedQ.length>0?this.failedQ.peek(0):null;if(this.newQ.dequeueCount<this.sources.length&&this.newQ.length)return this.newQ.peek(0);let d=this.estimateCleanupTime(),m=this.estimateReviewTime();return this._secondsRemaining-(d+m)>20?(c=.5,u=.9):this._secondsRemaining-d>20?(c=.05,u=.9):(c=.01,u=.1),this.failedQ.length===0&&(u=1),this.reviewQ.length===0&&(c=u),t<c&&this.newQ.length?this.newQ.peek(0):t<u&&this.reviewQ.length?this.reviewQ.peek(0):this.failedQ.length?this.failedQ.peek(0):(this.log(`No more cards available for the session!`),null)}async nextCard(t=`dismiss-success`){if(this.dismissCurrentCard(t),this._minCardsGuarantee>0&&(this._minCardsGuarantee--,this.log(`[CardGuarantee] ${this._minCardsGuarantee} guaranteed cards remaining`)),this._replanPromise&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0&&(this.log(`nextCard: queues empty, awaiting in-flight replan before drawing`),await this._replanPromise),this.newQ.length<=_SessionController.DEPLETION_PREFETCH_THRESHOLD&&this._secondsRemaining>0&&!this._replanPromise){this._suppressQualityReplan=!1;let t=this.reviewQ.length+this.failedQ.length;this.log(`[AutoReplan:depletion] newQ has ${this.newQ.length} card(s) (${t} in other queues) with ${this._secondsRemaining}s remaining. Triggering background replan.`),this.requestReplan({label:`auto:depletion`,mode:`merge`})}if(!this._suppressQualityReplan&&this._wellIndicatedRemaining<=3&&this.newQ.length>0&&!this._replanPromise&&(this.log(`[AutoReplan:quality] ${this._wellIndicatedRemaining} well-indicated cards remaining (newQ: ${this.newQ.length}). Triggering background replan.`),this.requestReplan({label:`auto:quality`})),this._secondsRemaining<=0&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return this._currentCard=null,endSessionTracking(),null;let c=3,u=250,d=0;for(;this._secondsRemaining>0&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0;)if(this.log(`[WedgeBreaker] All queues empty with ${this._secondsRemaining}s remaining. Running pipeline (attempt ${d+1}/3).`),await this._replanUncoalesced({label:`wedge-breaker`}),this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0){if(d++,d>=3){this.log(`[WedgeBreaker] Pipeline returned no content 3 consecutive times. Giving up; session will end.`);break}await new Promise(t=>setTimeout(t,250))}else d=0;let m=20;for(let t=0;t<20;t++){let t=this._selectNextItemToHydrate();if(!t)return this._currentCard=null,endSessionTracking(),null;let c=this.hydrationService.getHydratedCard(t.cardID);if(c||(c=await this.hydrationService.waitForCard(t.cardID)),this.removeItemFromQueue(t),c){await this.hydrationService.ensureHydratedCards(),this._currentCard=c;let u=t.status===`review`||t.status===`failed-review`?`review`:t.status===`new`||t.status===`failed-new`?`new`:`failed`,d=t.status.startsWith(`failed`)?`failedQ`:t.status===`review`?`reviewQ`:`newQ`;return recordCardPresentation(t.cardID,t.courseID,this.courseNameCache.get(t.courseID),u,d),snapshotQueues(this.reviewQ.length,this.newQ.length,this.failedQ.length),c}this.log(`Skipping card ${t.cardID}: hydration failed, trying next`),isReview(t)&&this.srsService.removeReview(t.reviewID)}return this.log(`Exhausted 20 skip attempts finding a hydratable card`),this._currentCard=null,endSessionTracking(),null}async submitResponse(t,c,u,d,m,g,b,S,C){let w={...d.item},T=await this.services.response.processResponse(t,c,w,u,d,m,g,b,S,C);return await this._notifyOutcomeObservers(t,d,T),T}dismissCurrentCard(t=`dismiss-success`){if(this._currentCard)if(t===`dismiss-success`)this.hydrationService.removeCard(this._currentCard.item.cardID);else if(t===`marked-failed`){let t;t=isReview(this._currentCard.item)?{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-review`,reviewID:this._currentCard.item.reviewID}:{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-new`},this.failedQ.add(t,t.cardID)}else (t===`dismiss-error`||t===`dismiss-failed`)&&this.hydrationService.removeCard(this._currentCard.item.cardID)}removeItemFromQueue(t){this._clearDurableRequirement(t.cardID),this._servedCardIds.add(t.cardID),this.reviewQ.peek(0)?.cardID===t.cardID?this.reviewQ.dequeue(t=>t.cardID):this.newQ.peek(0)?.cardID===t.cardID?(this.newQ.dequeue(t=>t.cardID),this._wellIndicatedRemaining>0&&this._wellIndicatedRemaining--):this.failedQ.peek(0)?.cardID===t.cardID&&this.failedQ.dequeue(t=>t.cardID)}_clearDurableRequirement(t){let c=this._sessionHints?.requireCards;if(!c||c.length===0)return;let u=c.filter(c=>c!==t);u.length!==c.length&&(this._sessionHints={...this._sessionHints,requireCards:u.length>0?u:void 0},this.log(`[Replan] Durable requirement satisfied & cleared on draw: ${t}`))}async endSession(){if(!this._sessionRecord||this._sessionRecord.length===0)return;let t=this._sessionRecord.flatMap(t=>t.records).filter(t=>t.userAnswer!==void 0);if(t.length===0)return;let c=null,u=[];for(let t of this.sources)if(t.getOrchestrationContext){try{c=await t.getOrchestrationContext(),t.getStrategyIds&&u.push(...t.getStrategyIds())}catch(t){logger.warn(`[SessionController] Failed to get orchestration context: ${t}`)}if(c)break}if(!c){logger.debug(`[SessionController] No orchestration context available, skipping outcome recording`);return}let d=new Date().toISOString(),m=new Date(this.startTime).toISOString();await recordUserOutcome(c,m,d,t,u)}},_defineProperty$2(_SessionController2,`MIN_WELL_INDICATED`,5),_defineProperty$2(_SessionController2,`WELL_INDICATED_SCORE`,.1),_defineProperty$2(_SessionController2,`DEPLETION_PREFETCH_THRESHOLD`,3),_SessionController2),init_TagFilteredContentSource(),init_factory()}));function useRouter(){return inject(routerKey)}function useRoute(t){return inject(routeLocationKey)}var isArray,NavigationType,NavigationDirection,NavigationFailureSymbol,NavigationFailureType,matchedRouteKey,viewDepthKey,routerKey,routeLocationKey,routerViewLocationKey,init_vue_router=__esmMin((()=>{init_vue_runtime_esm_bundler(),Array.isArray,(function(t){t.pop=`pop`,t.push=`push`})(NavigationType||(NavigationType={})),(function(t){t.back=`back`,t.forward=`forward`,t.unknown=``})(NavigationDirection||(NavigationDirection={})),Symbol(process.env.NODE_ENV===`production`?``:`navigation failure`),(function(t){t[t.aborted=4]=`aborted`,t[t.cancelled=8]=`cancelled`,t[t.duplicated=16]=`duplicated`})(NavigationFailureType||(NavigationFailureType={})),Symbol(process.env.NODE_ENV===`production`?``:`router view location matched`),Symbol(process.env.NODE_ENV===`production`?``:`router view depth`),routerKey=Symbol(process.env.NODE_ENV===`production`?``:`router`),routeLocationKey=Symbol(process.env.NODE_ENV===`production`?``:`route location`),Symbol(process.env.NODE_ENV===`production`?``:`router view location`)})),init_style=__esmMin((()=>{}));function registerRuntimeHelpers(t){Object.getOwnPropertySymbols(t).forEach(c=>{helperNameMap[c]=t[c]})}function createRoot(t,c=``){return{type:0,source:c,children:t,helpers:new Set,components:[],directives:[],hoists:[],imports:[],cached:[],temps:0,codegenNode:void 0,loc:locStub}}function createVNodeCall(t,c,u,d,m,g,b,S=!1,C=!1,w=!1,T=locStub){return t&&(S?(t.helper(OPEN_BLOCK),t.helper(getVNodeBlockHelper(t.inSSR,w))):t.helper(getVNodeHelper(t.inSSR,w)),b&&t.helper(WITH_DIRECTIVES)),{type:13,tag:c,props:u,children:d,patchFlag:m,dynamicProps:g,directives:b,isBlock:S,disableTracking:C,isComponent:w,loc:T}}function createArrayExpression(t,c=locStub){return{type:17,loc:c,elements:t}}function createObjectExpression(t,c=locStub){return{type:15,loc:c,properties:t}}function createObjectProperty(t,c){return{type:16,loc:locStub,key:isString$1(t)?createSimpleExpression(t,!0):t,value:c}}function createSimpleExpression(t,c=!1,u=locStub,d=0){return{type:4,loc:u,content:t,isStatic:c,constType:c?3:d}}function createInterpolation(t,c){return{type:5,loc:c,content:isString$1(t)?createSimpleExpression(t,!1,c):t}}function createCompoundExpression(t,c=locStub){return{type:8,loc:c,children:t}}function createCallExpression(t,c=[],u=locStub){return{type:14,loc:u,callee:t,arguments:c}}function createFunctionExpression(t,c=void 0,u=!1,d=!1,m=locStub){return{type:18,params:t,returns:c,newline:u,isSlot:d,loc:m}}function createConditionalExpression(t,c,u,d=!0){return{type:19,test:t,consequent:c,alternate:u,newline:d,loc:locStub}}function createCacheExpression(t,c,u=!1,d=!1){return{type:20,index:t,value:c,needPauseTracking:u,inVOnce:d,needArraySpread:!1,loc:locStub}}function createBlockStatement(t){return{type:21,body:t,loc:locStub}}function createTemplateLiteral(t){return{type:22,elements:t,loc:locStub}}function createIfStatement(t,c,u){return{type:23,test:t,consequent:c,alternate:u,loc:locStub}}function createAssignmentExpression(t,c){return{type:24,left:t,right:c,loc:locStub}}function createSequenceExpression(t){return{type:25,expressions:t,loc:locStub}}function createReturnStatement(t){return{type:26,returns:t,loc:locStub}}function getVNodeHelper(t,c){return t||c?CREATE_VNODE:CREATE_ELEMENT_VNODE}function getVNodeBlockHelper(t,c){return t||c?CREATE_BLOCK:CREATE_ELEMENT_BLOCK}function convertToBlock(t,{helper:c,removeHelper:u,inSSR:d}){t.isBlock||(t.isBlock=!0,u(getVNodeHelper(d,t.isComponent)),c(OPEN_BLOCK),c(getVNodeBlockHelper(d,t.isComponent)))}function isTagStartChar(t){return t>=97&&t<=122||t>=65&&t<=90}function isWhitespace(t){return t===32||t===10||t===9||t===12||t===13}function isEndOfTagSection(t){return t===47||t===62||isWhitespace(t)}function toCharCodes(t){let c=new Uint8Array(t.length);for(let u=0;u<t.length;u++)c[u]=t.charCodeAt(u);return c}function getCompatValue(t,{compatConfig:c}){let u=c&&c[t];return t===`MODE`?u||3:u}function isCompatEnabled(t,c){let u=getCompatValue(`MODE`,c),d=getCompatValue(t,c);return u===3?d===!0:d!==!1}function checkCompatEnabled(t,c,u,...d){let m=isCompatEnabled(t,c);return process.env.NODE_ENV!==`production`&&m&&warnDeprecation(t,c,u,...d),m}function warnDeprecation(t,c,u,...d){if(getCompatValue(t,c)===`suppress-warning`)return;let{message:m,link:g}=deprecationData[t],b=`(deprecation ${t}) ${typeof m==`function`?m(...d):m}${g?`
|
|
459
|
+
`;if(!c)for(let t of T){let c={cardID:t.cardId,courseID:t.courseId,contentSourceType:`course`,contentSourceID:t.courseId,reviewID:t.reviewID,status:`review`};this.reviewQ.add(c,c.cardID),Ar+=`Review: ${t.courseId}::${t.cardId} (score: ${t.score.toFixed(2)})
|
|
460
|
+
`}let jr=Or.filter(t=>t.score>=_SessionController.WELL_INDICATED_SCORE).length,Mr=[];for(let t of Or){let c={cardID:t.cardId,courseID:t.courseId,contentSourceType:`course`,contentSourceID:t.courseId,status:`new`};Mr.push(c),Ar+=`New: ${t.courseId}::${t.cardId} (score: ${t.score.toFixed(2)})
|
|
461
|
+
`}if(u){let t=this.newQ.mergeToFront(Mr,t=>t.cardID,kr);Ar+=`Additive merge: ${t} new cards added to front of newQ
|
|
462
|
+
`}else if(c)this.newQ.replaceAll(Mr,t=>t.cardID);else for(let t of Mr)this.newQ.add(t,t.cardID);return this.log(Ar),jr}_getItemsToHydrate(){let t=[],c=2;for(let c=0;c<Math.min(2,this.reviewQ.length);c++)t.push(this.reviewQ.peek(c));for(let c=0;c<Math.min(2,this.newQ.length);c++)t.push(this.newQ.peek(c));for(let c=0;c<Math.min(2,this.failedQ.length);c++)t.push(this.failedQ.peek(c));return t}_selectNextItemToHydrate(){let t=Math.random(),c=.1,u=.75;if(this.reviewQ.length===0&&this.failedQ.length===0&&this.newQ.length===0||this._secondsRemaining<2&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return null;if(this._secondsRemaining<=0&&this._minCardsGuarantee<=0)return this.failedQ.length>0?this.failedQ.peek(0):null;if(this.newQ.dequeueCount<this.sources.length&&this.newQ.length)return this.newQ.peek(0);let d=this.estimateCleanupTime(),m=this.estimateReviewTime();return this._secondsRemaining-(d+m)>20?(c=.5,u=.9):this._secondsRemaining-d>20?(c=.05,u=.9):(c=.01,u=.1),this.failedQ.length===0&&(u=1),this.reviewQ.length===0&&(c=u),t<c&&this.newQ.length?this.newQ.peek(0):t<u&&this.reviewQ.length?this.reviewQ.peek(0):this.failedQ.length?this.failedQ.peek(0):(this.log(`No more cards available for the session!`),null)}async nextCard(t=`dismiss-success`){if(this.dismissCurrentCard(t),this._minCardsGuarantee>0&&(this._minCardsGuarantee--,this.log(`[CardGuarantee] ${this._minCardsGuarantee} guaranteed cards remaining`)),this._replanPromise&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0&&(this.log(`nextCard: queues empty, awaiting in-flight replan before drawing`),await this._replanPromise),this.newQ.length<=_SessionController.DEPLETION_PREFETCH_THRESHOLD&&this._secondsRemaining>0&&!this._replanPromise){this._suppressQualityReplan=!1;let t=this.reviewQ.length+this.failedQ.length;this.log(`[AutoReplan:depletion] newQ has ${this.newQ.length} card(s) (${t} in other queues) with ${this._secondsRemaining}s remaining. Triggering background replan.`),this.requestReplan({label:`auto:depletion`,mode:`merge`})}if(!this._suppressQualityReplan&&this._wellIndicatedRemaining<=3&&this.newQ.length>0&&!this._replanPromise&&(this.log(`[AutoReplan:quality] ${this._wellIndicatedRemaining} well-indicated cards remaining (newQ: ${this.newQ.length}). Triggering background replan.`),this.requestReplan({label:`auto:quality`})),this._secondsRemaining<=0&&this.failedQ.length===0&&this._minCardsGuarantee<=0)return this._currentCard=null,endSessionTracking(),null;let c=3,u=250,d=0;for(;this._secondsRemaining>0&&this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0;)if(this.log(`[WedgeBreaker] All queues empty with ${this._secondsRemaining}s remaining. Running pipeline (attempt ${d+1}/3).`),await this._replanUncoalesced({label:`wedge-breaker`}),this.newQ.length===0&&this.reviewQ.length===0&&this.failedQ.length===0){if(d++,d>=3){this.log(`[WedgeBreaker] Pipeline returned no content 3 consecutive times. Giving up; session will end.`);break}await new Promise(t=>setTimeout(t,250))}else d=0;let m=20;for(let t=0;t<20;t++){let t=this._selectNextItemToHydrate();if(!t)return this._currentCard=null,endSessionTracking(),null;let c=this.hydrationService.getHydratedCard(t.cardID);if(c||(c=await this.hydrationService.waitForCard(t.cardID)),this.removeItemFromQueue(t),c){await this.hydrationService.ensureHydratedCards(),this._currentCard=c;let u=t.status===`review`||t.status===`failed-review`?`review`:t.status===`new`||t.status===`failed-new`?`new`:`failed`,d=t.status.startsWith(`failed`)?`failedQ`:t.status===`review`?`reviewQ`:`newQ`;return recordCardPresentation(t.cardID,t.courseID,this.courseNameCache.get(t.courseID),u,d),snapshotQueues(this.reviewQ.length,this.newQ.length,this.failedQ.length),c}this.log(`Skipping card ${t.cardID}: hydration failed, trying next`),isReview(t)&&this.srsService.removeReview(t.reviewID)}return this.log(`Exhausted 20 skip attempts finding a hydratable card`),this._currentCard=null,endSessionTracking(),null}async submitResponse(t,c,u,d,m,g,b,S,C){let w={...d.item},T=await this.services.response.processResponse(t,c,w,u,d,m,g,b,S,C);return await this._notifyOutcomeObservers(t,d,T),T}dismissCurrentCard(t=`dismiss-success`){if(this._currentCard)if(t===`dismiss-success`)this.hydrationService.removeCard(this._currentCard.item.cardID);else if(t===`marked-failed`){let t;t=isReview(this._currentCard.item)?{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-review`,reviewID:this._currentCard.item.reviewID}:{cardID:this._currentCard.item.cardID,courseID:this._currentCard.item.courseID,contentSourceID:this._currentCard.item.contentSourceID,contentSourceType:this._currentCard.item.contentSourceType,status:`failed-new`},this.failedQ.add(t,t.cardID)}else (t===`dismiss-error`||t===`dismiss-failed`)&&this.hydrationService.removeCard(this._currentCard.item.cardID)}removeItemFromQueue(t){this._clearDurableRequirement(t.cardID),this._servedCardIds.add(t.cardID),this.reviewQ.peek(0)?.cardID===t.cardID?this.reviewQ.dequeue(t=>t.cardID):this.newQ.peek(0)?.cardID===t.cardID?(this.newQ.dequeue(t=>t.cardID),this._wellIndicatedRemaining>0&&this._wellIndicatedRemaining--):this.failedQ.peek(0)?.cardID===t.cardID&&this.failedQ.dequeue(t=>t.cardID)}_clearDurableRequirement(t){let c=this._sessionHints?.requireCards;if(!c||c.length===0)return;let u=c.filter(c=>c!==t);u.length!==c.length&&(this._sessionHints={...this._sessionHints,requireCards:u.length>0?u:void 0},this.log(`[Replan] Durable requirement satisfied & cleared on draw: ${t}`))}async endSession(){if(!this._sessionRecord||this._sessionRecord.length===0)return;let t=this._sessionRecord.flatMap(t=>t.records).filter(t=>t.userAnswer!==void 0);if(t.length===0)return;let c=null,u=[];for(let t of this.sources)if(t.getOrchestrationContext){try{c=await t.getOrchestrationContext(),t.getStrategyIds&&u.push(...t.getStrategyIds())}catch(t){logger.warn(`[SessionController] Failed to get orchestration context: ${t}`)}if(c)break}if(!c){logger.debug(`[SessionController] No orchestration context available, skipping outcome recording`);return}let d=new Date().toISOString(),m=new Date(this.startTime).toISOString();await recordUserOutcome(c,m,d,t,u)}},_defineProperty$2(_SessionController2,`MIN_WELL_INDICATED`,5),_defineProperty$2(_SessionController2,`WELL_INDICATED_SCORE`,.1),_defineProperty$2(_SessionController2,`DEPLETION_PREFETCH_THRESHOLD`,3),_SessionController2),init_TagFilteredContentSource(),init_factory()}));function useRouter(){return inject(routerKey)}function useRoute(t){return inject(routeLocationKey)}var isArray,NavigationType,NavigationDirection,NavigationFailureSymbol,NavigationFailureType,matchedRouteKey,viewDepthKey,routerKey,routeLocationKey,routerViewLocationKey,init_vue_router=__esmMin((()=>{init_vue_runtime_esm_bundler(),Array.isArray,(function(t){t.pop=`pop`,t.push=`push`})(NavigationType||(NavigationType={})),(function(t){t.back=`back`,t.forward=`forward`,t.unknown=``})(NavigationDirection||(NavigationDirection={})),Symbol(process.env.NODE_ENV===`production`?``:`navigation failure`),(function(t){t[t.aborted=4]=`aborted`,t[t.cancelled=8]=`cancelled`,t[t.duplicated=16]=`duplicated`})(NavigationFailureType||(NavigationFailureType={})),Symbol(process.env.NODE_ENV===`production`?``:`router view location matched`),Symbol(process.env.NODE_ENV===`production`?``:`router view depth`),routerKey=Symbol(process.env.NODE_ENV===`production`?``:`router`),routeLocationKey=Symbol(process.env.NODE_ENV===`production`?``:`route location`),Symbol(process.env.NODE_ENV===`production`?``:`router view location`)})),init_style=__esmMin((()=>{}));function registerRuntimeHelpers(t){Object.getOwnPropertySymbols(t).forEach(c=>{helperNameMap[c]=t[c]})}function createRoot(t,c=``){return{type:0,source:c,children:t,helpers:new Set,components:[],directives:[],hoists:[],imports:[],cached:[],temps:0,codegenNode:void 0,loc:locStub}}function createVNodeCall(t,c,u,d,m,g,b,S=!1,C=!1,w=!1,T=locStub){return t&&(S?(t.helper(OPEN_BLOCK),t.helper(getVNodeBlockHelper(t.inSSR,w))):t.helper(getVNodeHelper(t.inSSR,w)),b&&t.helper(WITH_DIRECTIVES)),{type:13,tag:c,props:u,children:d,patchFlag:m,dynamicProps:g,directives:b,isBlock:S,disableTracking:C,isComponent:w,loc:T}}function createArrayExpression(t,c=locStub){return{type:17,loc:c,elements:t}}function createObjectExpression(t,c=locStub){return{type:15,loc:c,properties:t}}function createObjectProperty(t,c){return{type:16,loc:locStub,key:isString$1(t)?createSimpleExpression(t,!0):t,value:c}}function createSimpleExpression(t,c=!1,u=locStub,d=0){return{type:4,loc:u,content:t,isStatic:c,constType:c?3:d}}function createInterpolation(t,c){return{type:5,loc:c,content:isString$1(t)?createSimpleExpression(t,!1,c):t}}function createCompoundExpression(t,c=locStub){return{type:8,loc:c,children:t}}function createCallExpression(t,c=[],u=locStub){return{type:14,loc:u,callee:t,arguments:c}}function createFunctionExpression(t,c=void 0,u=!1,d=!1,m=locStub){return{type:18,params:t,returns:c,newline:u,isSlot:d,loc:m}}function createConditionalExpression(t,c,u,d=!0){return{type:19,test:t,consequent:c,alternate:u,newline:d,loc:locStub}}function createCacheExpression(t,c,u=!1,d=!1){return{type:20,index:t,value:c,needPauseTracking:u,inVOnce:d,needArraySpread:!1,loc:locStub}}function createBlockStatement(t){return{type:21,body:t,loc:locStub}}function createTemplateLiteral(t){return{type:22,elements:t,loc:locStub}}function createIfStatement(t,c,u){return{type:23,test:t,consequent:c,alternate:u,loc:locStub}}function createAssignmentExpression(t,c){return{type:24,left:t,right:c,loc:locStub}}function createSequenceExpression(t){return{type:25,expressions:t,loc:locStub}}function createReturnStatement(t){return{type:26,returns:t,loc:locStub}}function getVNodeHelper(t,c){return t||c?CREATE_VNODE:CREATE_ELEMENT_VNODE}function getVNodeBlockHelper(t,c){return t||c?CREATE_BLOCK:CREATE_ELEMENT_BLOCK}function convertToBlock(t,{helper:c,removeHelper:u,inSSR:d}){t.isBlock||(t.isBlock=!0,u(getVNodeHelper(d,t.isComponent)),c(OPEN_BLOCK),c(getVNodeBlockHelper(d,t.isComponent)))}function isTagStartChar(t){return t>=97&&t<=122||t>=65&&t<=90}function isWhitespace(t){return t===32||t===10||t===9||t===12||t===13}function isEndOfTagSection(t){return t===47||t===62||isWhitespace(t)}function toCharCodes(t){let c=new Uint8Array(t.length);for(let u=0;u<t.length;u++)c[u]=t.charCodeAt(u);return c}function getCompatValue(t,{compatConfig:c}){let u=c&&c[t];return t===`MODE`?u||3:u}function isCompatEnabled(t,c){let u=getCompatValue(`MODE`,c),d=getCompatValue(t,c);return u===3?d===!0:d!==!1}function checkCompatEnabled(t,c,u,...d){let m=isCompatEnabled(t,c);return process.env.NODE_ENV!==`production`&&m&&warnDeprecation(t,c,u,...d),m}function warnDeprecation(t,c,u,...d){if(getCompatValue(t,c)===`suppress-warning`)return;let{message:m,link:g}=deprecationData[t],b=`(deprecation ${t}) ${typeof m==`function`?m(...d):m}${g?`
|
|
463
463
|
Details: ${g}`:``}`,S=SyntaxError(b);S.code=t,u&&(S.loc=u),c.onWarn(S)}function defaultOnError(t){throw t}function defaultOnWarn(t){process.env.NODE_ENV!==`production`&&console.warn(`[Vue warn] ${t.message}`)}function createCompilerError(t,c,u,d){let m=process.env.NODE_ENV===`production`?`https://vuejs.org/error-reference/#compiler-${t}`:(u||errorMessages)[t]+(d||``),g=SyntaxError(String(m));return g.code=t,g.loc=c,g}function walkIdentifiers(t,c,u=!1,d=[],m=Object.create(null)){}function isReferencedIdentifier(t,c,u){return!1}function isInDestructureAssignment(t,c){if(t&&(t.type===`ObjectProperty`||t.type===`ArrayPattern`)){let t=c.length;for(;t--;){let u=c[t];if(u.type===`AssignmentExpression`)return!0;if(u.type!==`ObjectProperty`&&!u.type.endsWith(`Pattern`))break}}return!1}function isInNewExpression(t){let c=t.length;for(;c--;){let u=t[c];if(u.type===`NewExpression`)return!0;if(u.type!==`MemberExpression`)break}return!1}function walkFunctionParams(t,c){for(let u of t.params)for(let t of extractIdentifiers(u))c(t)}function walkBlockDeclarations(t,c){for(let u of t.body)if(u.type===`VariableDeclaration`){if(u.declare)continue;for(let t of u.declarations)for(let u of extractIdentifiers(t.id))c(u)}else if(u.type===`FunctionDeclaration`||u.type===`ClassDeclaration`){if(u.declare||!u.id)continue;c(u.id)}else isForStatement(u)&&walkForStatement(u,!0,c)}function isForStatement(t){return t.type===`ForOfStatement`||t.type===`ForInStatement`||t.type===`ForStatement`}function walkForStatement(t,c,u){let d=t.type===`ForStatement`?t.init:t.left;if(d&&d.type===`VariableDeclaration`&&(d.kind===`var`?c:!c))for(let t of d.declarations)for(let c of extractIdentifiers(t.id))u(c)}function extractIdentifiers(t,c=[]){switch(t.type){case`Identifier`:c.push(t);break;case`MemberExpression`:let u=t;for(;u.type===`MemberExpression`;)u=u.object;c.push(u);break;case`ObjectPattern`:for(let u of t.properties)u.type===`RestElement`?extractIdentifiers(u.argument,c):extractIdentifiers(u.value,c);break;case`ArrayPattern`:t.elements.forEach(t=>{t&&extractIdentifiers(t,c)});break;case`RestElement`:extractIdentifiers(t.argument,c);break;case`AssignmentPattern`:extractIdentifiers(t.left,c);break}return c}function unwrapTSNode(t){return TS_NODE_TYPES.includes(t.type)?unwrapTSNode(t.expression):t}function isCoreComponent(t){switch(t){case`Teleport`:case`teleport`:return TELEPORT;case`Suspense`:case`suspense`:return SUSPENSE;case`KeepAlive`:case`keep-alive`:return KEEP_ALIVE;case`BaseTransition`:case`base-transition`:return BASE_TRANSITION}}function advancePositionWithClone(t,c,u=c.length){return advancePositionWithMutation({offset:t.offset,line:t.line,column:t.column},c,u)}function advancePositionWithMutation(t,c,u=c.length){let d=0,m=-1;for(let t=0;t<u;t++)c.charCodeAt(t)===10&&(d++,m=t);return t.offset+=u,t.line+=d,t.column=m===-1?t.column+u:u-m,t}function assert(t,c){if(!t)throw Error(c||`unexpected compiler condition`)}function findDir(t,c,u=!1){for(let d=0;d<t.props.length;d++){let m=t.props[d];if(m.type===7&&(u||m.exp)&&(isString$1(c)?m.name===c:c.test(m.name)))return m}}function findProp(t,c,u=!1,d=!1){for(let m=0;m<t.props.length;m++){let g=t.props[m];if(g.type===6){if(u)continue;if(g.name===c&&(g.value||d))return g}else if(g.name===`bind`&&(g.exp||d)&&isStaticArgOf(g.arg,c))return g}}function isStaticArgOf(t,c){return!!(t&&isStaticExp(t)&&t.content===c)}function hasDynamicKeyVBind(t){return t.props.some(t=>t.type===7&&t.name===`bind`&&(!t.arg||t.arg.type!==4||!t.arg.isStatic))}function isText$1(t){return t.type===5||t.type===2}function isVSlot(t){return t.type===7&&t.name===`slot`}function isTemplateNode(t){return t.type===1&&t.tagType===3}function isSlotOutlet(t){return t.type===1&&t.tagType===2}function getUnnormalizedProps(t,c=[]){if(t&&!isString$1(t)&&t.type===14){let u=t.callee;if(!isString$1(u)&&propsHelperSet.has(u))return getUnnormalizedProps(t.arguments[0],c.concat(t))}return[t,c]}function injectProp(t,c,u){let d,m=t.type===13?t.props:t.arguments[2],g=[],b;if(m&&!isString$1(m)&&m.type===14){let t=getUnnormalizedProps(m);m=t[0],g=t[1],b=g[g.length-1]}if(m==null||isString$1(m))d=createObjectExpression([c]);else if(m.type===14){let t=m.arguments[0];!isString$1(t)&&t.type===15?hasProp(c,t)||t.properties.unshift(c):m.callee===TO_HANDLERS?d=createCallExpression(u.helper(MERGE_PROPS),[createObjectExpression([c]),m]):m.arguments.unshift(createObjectExpression([c])),!d&&(d=m)}else m.type===15?(hasProp(c,m)||m.properties.unshift(c),d=m):(d=createCallExpression(u.helper(MERGE_PROPS),[createObjectExpression([c]),m]),b&&b.callee===GUARD_REACTIVE_PROPS&&(b=g[g.length-2]));t.type===13?b?b.arguments[0]=d:t.props=d:b?b.arguments[0]=d:t.arguments[2]=d}function hasProp(t,c){let u=!1;if(t.key.type===4){let d=t.key.content;u=c.properties.some(t=>t.key.type===4&&t.key.content===d)}return u}function toValidAssetId(t,c){return`_${c}_${t.replace(/[^\w]/g,(c,u)=>c===`-`?`_`:t.charCodeAt(u).toString())}`}function hasScopeRef(t,c){if(!t||Object.keys(c).length===0)return!1;switch(t.type){case 1:for(let u=0;u<t.props.length;u++){let d=t.props[u];if(d.type===7&&(hasScopeRef(d.arg,c)||hasScopeRef(d.exp,c)))return!0}return t.children.some(t=>hasScopeRef(t,c));case 11:return hasScopeRef(t.source,c)?!0:t.children.some(t=>hasScopeRef(t,c));case 9:return t.branches.some(t=>hasScopeRef(t,c));case 10:return hasScopeRef(t.condition,c)?!0:t.children.some(t=>hasScopeRef(t,c));case 4:return!t.isStatic&&isSimpleIdentifier(t.content)&&!!c[t.content];case 8:return t.children.some(t=>isObject$1(t)&&hasScopeRef(t,c));case 5:case 12:return hasScopeRef(t.content,c);case 2:case 3:case 20:return!1;default:return process.env.NODE_ENV,!1}}function getMemoedVNodeCall(t){return t.type===14&&t.callee===WITH_MEMO?t.arguments[1].returns:t}function parseForExpression(t){let c=t.loc,u=t.content,d=u.match(forAliasRE);if(!d)return;let[,m,g]=d,createAliasExpression=(t,u,d=!1)=>{let m=c.start.offset+u;return createExp(t,!1,getLoc(m,m+t.length),0,d?1:0)},b={source:createAliasExpression(g.trim(),u.indexOf(g,m.length)),value:void 0,key:void 0,index:void 0,finalized:!1},S=m.trim().replace(stripParensRE,``).trim(),C=m.indexOf(S),w=S.match(forIteratorRE);if(w){S=S.replace(forIteratorRE,``).trim();let t=w[1].trim(),c;if(t&&(c=u.indexOf(t,C+S.length),b.key=createAliasExpression(t,c,!0)),w[2]){let d=w[2].trim();d&&(b.index=createAliasExpression(d,u.indexOf(d,b.key?c+t.length:C+S.length),!0))}}return S&&(b.value=createAliasExpression(S,C,!0)),b}function getSlice(t,c){return currentInput.slice(t,c)}function endOpenTag(t){tokenizer.inSFCRoot&&(currentOpenTag.innerLoc=getLoc(t+1,t+1)),addNode(currentOpenTag);let{tag:c,ns:u}=currentOpenTag;u===0&¤tOptions.isPreTag(c)&&inPre++,currentOptions.isVoidTag(c)?onCloseTag(currentOpenTag,t):(stack.unshift(currentOpenTag),(u===1||u===2)&&(tokenizer.inXML=!0)),currentOpenTag=null}function onText(t,c,u){{let c=stack[0]&&stack[0].tag;c!==`script`&&c!==`style`&&t.includes(`&`)&&(t=currentOptions.decodeEntities(t,!1))}let d=stack[0]||currentRoot,m=d.children[d.children.length-1];m&&m.type===2?(m.content+=t,setLocEnd(m.loc,u)):d.children.push({type:2,content:t,loc:getLoc(c,u)})}function onCloseTag(t,c,u=!1){u?setLocEnd(t.loc,backTrack(c,60)):setLocEnd(t.loc,lookAhead(c,62)+1),tokenizer.inSFCRoot&&(t.children.length?t.innerLoc.end=extend$2({},t.children[t.children.length-1].loc.end):t.innerLoc.end=extend$2({},t.innerLoc.start),t.innerLoc.source=getSlice(t.innerLoc.start.offset,t.innerLoc.end.offset));let{tag:d,ns:m,children:g}=t;if(inVPre||(d===`slot`?t.tagType=2:isFragmentTemplate(t)?t.tagType=3:isComponent(t)&&(t.tagType=1)),tokenizer.inRCDATA||(t.children=condenseWhitespace(g)),m===0&¤tOptions.isIgnoreNewlineTag(d)){let t=g[0];t&&t.type===2&&(t.content=t.content.replace(/^\r?\n/,``))}m===0&¤tOptions.isPreTag(d)&&inPre--,currentVPreBoundary===t&&(inVPre=tokenizer.inVPre=!1,currentVPreBoundary=null),tokenizer.inXML&&(stack[0]?stack[0].ns:currentOptions.ns)===0&&(tokenizer.inXML=!1);{let c=t.props;if(process.env.NODE_ENV!==`production`&&isCompatEnabled(`COMPILER_V_IF_V_FOR_PRECEDENCE`,currentOptions)){let u=!1,d=!1;for(let m=0;m<c.length;m++){let g=c[m];if(g.type===7&&(g.name===`if`?u=!0:g.name===`for`&&(d=!0)),u&&d){warnDeprecation(`COMPILER_V_IF_V_FOR_PRECEDENCE`,currentOptions,t.loc);break}}}if(!tokenizer.inSFCRoot&&isCompatEnabled(`COMPILER_NATIVE_TEMPLATE`,currentOptions)&&t.tag===`template`&&!isFragmentTemplate(t)){process.env.NODE_ENV!==`production`&&warnDeprecation(`COMPILER_NATIVE_TEMPLATE`,currentOptions,t.loc);let c=stack[0]||currentRoot,u=c.children.indexOf(t);c.children.splice(u,1,...t.children)}let u=c.find(t=>t.type===6&&t.name===`inline-template`);u&&checkCompatEnabled(`COMPILER_INLINE_TEMPLATE`,currentOptions,u.loc)&&t.children.length&&(u.value={type:2,content:getSlice(t.children[0].loc.start.offset,t.children[t.children.length-1].loc.end.offset),loc:u.loc})}}function lookAhead(t,c){let u=t;for(;currentInput.charCodeAt(u)!==c&&u<currentInput.length-1;)u++;return u}function backTrack(t,c){let u=t;for(;currentInput.charCodeAt(u)!==c&&u>=0;)u--;return u}function isFragmentTemplate({tag:t,props:c}){if(t===`template`){for(let t=0;t<c.length;t++)if(c[t].type===7&&specialTemplateDir.has(c[t].name))return!0}return!1}function isComponent({tag:t,props:c}){if(currentOptions.isCustomElement(t))return!1;if(t===`component`||isUpperCase(t.charCodeAt(0))||isCoreComponent(t)||currentOptions.isBuiltInComponent&¤tOptions.isBuiltInComponent(t)||currentOptions.isNativeTag&&!currentOptions.isNativeTag(t))return!0;for(let t=0;t<c.length;t++){let u=c[t];if(u.type===6){if(u.name===`is`&&u.value&&(u.value.content.startsWith(`vue:`)||checkCompatEnabled(`COMPILER_IS_ON_ELEMENT`,currentOptions,u.loc)))return!0}else if(u.name===`bind`&&isStaticArgOf(u.arg,`is`)&&checkCompatEnabled(`COMPILER_IS_ON_ELEMENT`,currentOptions,u.loc))return!0}return!1}function isUpperCase(t){return t>64&&t<91}function condenseWhitespace(t,c){let u=currentOptions.whitespace!==`preserve`,d=!1;for(let c=0;c<t.length;c++){let m=t[c];if(m.type===2)if(inPre)m.content=m.content.replace(windowsNewlineRE,`
|
|
464
464
|
`);else if(isAllWhitespace(m.content)){let g=t[c-1]&&t[c-1].type,b=t[c+1]&&t[c+1].type;!g||!b||u&&(g===3&&(b===3||b===1)||g===1&&(b===3||b===1&&hasNewlineChar(m.content)))?(d=!0,t[c]=null):m.content=` `}else u&&(m.content=condense(m.content))}return d?t.filter(Boolean):t}function isAllWhitespace(t){for(let c=0;c<t.length;c++)if(!isWhitespace(t.charCodeAt(c)))return!1;return!0}function hasNewlineChar(t){for(let c=0;c<t.length;c++){let u=t.charCodeAt(c);if(u===10||u===13)return!0}return!1}function condense(t){let c=``,u=!1;for(let d=0;d<t.length;d++)isWhitespace(t.charCodeAt(d))?u||(c+=` `,u=!0):(c+=t[d],u=!1);return c}function addNode(t){(stack[0]||currentRoot).children.push(t)}function getLoc(t,c){return{start:tokenizer.getPos(t),end:c==null?c:tokenizer.getPos(c),source:c==null?c:getSlice(t,c)}}function cloneLoc(t){return getLoc(t.start.offset,t.end.offset)}function setLocEnd(t,c){t.end=tokenizer.getPos(c),t.source=getSlice(t.start.offset,c)}function dirToAttr(t){let c={type:6,name:t.rawName,nameLoc:getLoc(t.loc.start.offset,t.loc.start.offset+t.rawName.length),value:void 0,loc:t.loc};if(t.exp){let u=t.exp.loc;u.end.offset<t.loc.end.offset&&(u.start.offset--,u.start.column--,u.end.offset++,u.end.column++),c.value={type:2,content:t.exp.content,loc:u}}return c}function createExp(t,c=!1,u,d=0,m=0){return createSimpleExpression(t,c,u,d)}function emitError(t,c,u){currentOptions.onError(createCompilerError(t,getLoc(c,c),void 0,u))}function reset(){tokenizer.reset(),currentOpenTag=null,currentProp=null,currentAttrValue=``,currentAttrStartIndex=-1,currentAttrEndIndex=-1,stack.length=0}function baseParse(t,c){if(reset(),currentInput=t,currentOptions=extend$2({},defaultParserOptions),c){let t;for(t in c)c[t]!=null&&(currentOptions[t]=c[t])}if(process.env.NODE_ENV!==`production`&&!currentOptions.decodeEntities)throw Error(`[@vue/compiler-core] decodeEntities option is required in browser builds.`);tokenizer.mode=currentOptions.parseMode===`html`?1:currentOptions.parseMode===`sfc`?2:0,tokenizer.inXML=currentOptions.ns===1||currentOptions.ns===2;let u=c&&c.delimiters;u&&(tokenizer.delimiterOpen=toCharCodes(u[0]),tokenizer.delimiterClose=toCharCodes(u[1]));let d=currentRoot=createRoot([],t);return tokenizer.parse(currentInput),d.loc=getLoc(0,t.length),d.children=condenseWhitespace(d.children),currentRoot=null,d}function cacheStatic(t,c){walk(t,void 0,c,isSingleElementRoot(t,t.children[0]))}function isSingleElementRoot(t,c){let{children:u}=t;return u.length===1&&c.type===1&&!isSlotOutlet(c)}function walk(t,c,u,d=!1,m=!1){let{children:g}=t,b=[];for(let c=0;c<g.length;c++){let S=g[c];if(S.type===1&&S.tagType===0){let t=d?0:getConstantType(S,u);if(t>0){if(t>=2){S.codegenNode.patchFlag=-1,b.push(S);continue}}else{let t=S.codegenNode;if(t.type===13){let c=t.patchFlag;if((c===void 0||c===512||c===1)&&getGeneratedPropsConstantType(S,u)>=2){let c=getNodeProps(S);c&&(t.props=u.hoist(c))}t.dynamicProps&&(t.dynamicProps=u.hoist(t.dynamicProps))}}}else if(S.type===12&&(d?0:getConstantType(S,u))>=2){b.push(S);continue}if(S.type===1){let c=S.tagType===1;c&&u.scopes.vSlot++,walk(S,t,u,!1,m),c&&u.scopes.vSlot--}else if(S.type===11)walk(S,t,u,S.children.length===1,!0);else if(S.type===9)for(let c=0;c<S.branches.length;c++)walk(S.branches[c],t,u,S.branches[c].children.length===1,m)}let S=!1;if(b.length===g.length&&t.type===1){if(t.tagType===0&&t.codegenNode&&t.codegenNode.type===13&&isArray$3(t.codegenNode.children))t.codegenNode.children=getCacheExpression(createArrayExpression(t.codegenNode.children)),S=!0;else if(t.tagType===1&&t.codegenNode&&t.codegenNode.type===13&&t.codegenNode.children&&!isArray$3(t.codegenNode.children)&&t.codegenNode.children.type===15){let c=getSlotNode(t.codegenNode,`default`);c&&(c.returns=getCacheExpression(createArrayExpression(c.returns)),S=!0)}else if(t.tagType===3&&c&&c.type===1&&c.tagType===1&&c.codegenNode&&c.codegenNode.type===13&&c.codegenNode.children&&!isArray$3(c.codegenNode.children)&&c.codegenNode.children.type===15){let u=findDir(t,`slot`,!0),d=u&&u.arg&&getSlotNode(c.codegenNode,u.arg);d&&(d.returns=getCacheExpression(createArrayExpression(d.returns)),S=!0)}}if(!S)for(let t of b)t.codegenNode=u.cache(t.codegenNode);function getCacheExpression(t){let c=u.cache(t);return m&&u.hmr&&(c.needArraySpread=!0),c}function getSlotNode(t,c){if(t.children&&!isArray$3(t.children)&&t.children.type===15){let u=t.children.properties.find(t=>t.key===c||t.key.content===c);return u&&u.value}}b.length&&u.transformHoist&&u.transformHoist(g,u,t)}function getConstantType(t,c){let{constantCache:u}=c;switch(t.type){case 1:if(t.tagType!==0)return 0;let d=u.get(t);if(d!==void 0)return d;let m=t.codegenNode;if(m.type!==13||m.isBlock&&t.tag!==`svg`&&t.tag!==`foreignObject`&&t.tag!==`math`)return 0;if(m.patchFlag===void 0){let d=3,g=getGeneratedPropsConstantType(t,c);if(g===0)return u.set(t,0),0;g<d&&(d=g);for(let m=0;m<t.children.length;m++){let g=getConstantType(t.children[m],c);if(g===0)return u.set(t,0),0;g<d&&(d=g)}if(d>1)for(let m=0;m<t.props.length;m++){let g=t.props[m];if(g.type===7&&g.name===`bind`&&g.exp){let m=getConstantType(g.exp,c);if(m===0)return u.set(t,0),0;m<d&&(d=m)}}if(m.isBlock){for(let c=0;c<t.props.length;c++)if(t.props[c].type===7)return u.set(t,0),0;c.removeHelper(OPEN_BLOCK),c.removeHelper(getVNodeBlockHelper(c.inSSR,m.isComponent)),m.isBlock=!1,c.helper(getVNodeHelper(c.inSSR,m.isComponent))}return u.set(t,d),d}else return u.set(t,0),0;case 2:case 3:return 3;case 9:case 11:case 10:return 0;case 5:case 12:return getConstantType(t.content,c);case 4:return t.constType;case 8:let g=3;for(let u=0;u<t.children.length;u++){let d=t.children[u];if(isString$1(d)||isSymbol(d))continue;let m=getConstantType(d,c);if(m===0)return 0;m<g&&(g=m)}return g;case 20:return 2;default:return process.env.NODE_ENV,0}}function getConstantTypeOfHelperCall(t,c){if(t.type===14&&!isString$1(t.callee)&&allowHoistedHelperSet.has(t.callee)){let u=t.arguments[0];if(u.type===4)return getConstantType(u,c);if(u.type===14)return getConstantTypeOfHelperCall(u,c)}return 0}function getGeneratedPropsConstantType(t,c){let u=3,d=getNodeProps(t);if(d&&d.type===15){let{properties:t}=d;for(let d=0;d<t.length;d++){let{key:m,value:g}=t[d],b=getConstantType(m,c);if(b===0)return b;b<u&&(u=b);let S;if(S=g.type===4?getConstantType(g,c):g.type===14?getConstantTypeOfHelperCall(g,c):0,S===0)return S;S<u&&(u=S)}}return u}function getNodeProps(t){let c=t.codegenNode;if(c.type===13)return c.props}function createTransformContext(t,{filename:c=``,prefixIdentifiers:u=!1,hoistStatic:d=!1,hmr:m=!1,cacheHandlers:g=!1,nodeTransforms:b=[],directiveTransforms:S={},transformHoist:C=null,isBuiltInComponent:w=NOOP,isCustomElement:T=NOOP,expressionPlugins:E=[],scopeId:D=null,slotted:O=!0,ssr:Or=!1,inSSR:kr=!1,ssrCssVars:Ar=``,bindingMetadata:jr=EMPTY_OBJ,inline:Mr=!1,isTS:Nr=!1,onError:Pr=defaultOnError,onWarn:Fr=defaultOnWarn,compatConfig:Ir}){let Lr=c.replace(/\?.*$/,``).match(/([^/\\]+)\.\w+$/),Rr={filename:c,selfName:Lr&&capitalize(camelize(Lr[1])),prefixIdentifiers:u,hoistStatic:d,hmr:m,cacheHandlers:g,nodeTransforms:b,directiveTransforms:S,transformHoist:C,isBuiltInComponent:w,isCustomElement:T,expressionPlugins:E,scopeId:D,slotted:O,ssr:Or,inSSR:kr,ssrCssVars:Ar,bindingMetadata:jr,inline:Mr,isTS:Nr,onError:Pr,onWarn:Fr,compatConfig:Ir,root:t,helpers:new Map,components:new Set,directives:new Set,hoists:[],imports:[],cached:[],constantCache:new WeakMap,temps:0,identifiers:Object.create(null),scopes:{vFor:0,vSlot:0,vPre:0,vOnce:0},parent:null,grandParent:null,currentNode:t,childIndex:0,inVOnce:!1,helper(t){let c=Rr.helpers.get(t)||0;return Rr.helpers.set(t,c+1),t},removeHelper(t){let c=Rr.helpers.get(t);if(c){let u=c-1;u?Rr.helpers.set(t,u):Rr.helpers.delete(t)}},helperString(t){return`_${helperNameMap[Rr.helper(t)]}`},replaceNode(t){if(process.env.NODE_ENV!==`production`){if(!Rr.currentNode)throw Error(`Node being replaced is already removed.`);if(!Rr.parent)throw Error(`Cannot replace root node.`)}Rr.parent.children[Rr.childIndex]=Rr.currentNode=t},removeNode(t){if(process.env.NODE_ENV!==`production`&&!Rr.parent)throw Error(`Cannot remove root node.`);let c=Rr.parent.children,u=t?c.indexOf(t):Rr.currentNode?Rr.childIndex:-1;if(process.env.NODE_ENV!==`production`&&u<0)throw Error(`node being removed is not a child of current parent`);!t||t===Rr.currentNode?(Rr.currentNode=null,Rr.onNodeRemoved()):Rr.childIndex>u&&(Rr.childIndex--,Rr.onNodeRemoved()),Rr.parent.children.splice(u,1)},onNodeRemoved:NOOP,addIdentifiers(t){},removeIdentifiers(t){},hoist(t){isString$1(t)&&(t=createSimpleExpression(t)),Rr.hoists.push(t);let c=createSimpleExpression(`_hoisted_${Rr.hoists.length}`,!1,t.loc,2);return c.hoisted=t,c},cache(t,c=!1,u=!1){let d=createCacheExpression(Rr.cached.length,t,c,u);return Rr.cached.push(d),d}};return Rr.filters=new Set,Rr}function transform(t,c){let u=createTransformContext(t,c);traverseNode(t,u),c.hoistStatic&&cacheStatic(t,u),c.ssr||createRootCodegen(t,u),t.helpers=new Set([...u.helpers.keys()]),t.components=[...u.components],t.directives=[...u.directives],t.imports=u.imports,t.hoists=u.hoists,t.temps=u.temps,t.cached=u.cached,t.transformed=!0,t.filters=[...u.filters]}function createRootCodegen(t,c){let{helper:u}=c,{children:d}=t;if(d.length===1){let u=d[0];if(isSingleElementRoot(t,u)&&u.codegenNode){let d=u.codegenNode;d.type===13&&convertToBlock(d,c),t.codegenNode=d}else t.codegenNode=u}else if(d.length>1){let m=64;process.env.NODE_ENV!==`production`&&d.filter(t=>t.type!==3).length===1&&(m|=2048),t.codegenNode=createVNodeCall(c,u(FRAGMENT),void 0,t.children,m,void 0,void 0,!0,void 0,!1)}}function traverseChildren(t,c){let u=0,nodeRemoved=()=>{u--};for(;u<t.children.length;u++){let d=t.children[u];isString$1(d)||(c.grandParent=c.parent,c.parent=t,c.childIndex=u,c.onNodeRemoved=nodeRemoved,traverseNode(d,c))}}function traverseNode(t,c){c.currentNode=t;let{nodeTransforms:u}=c,d=[];for(let m=0;m<u.length;m++){let g=u[m](t,c);if(g&&(isArray$3(g)?d.push(...g):d.push(g)),c.currentNode)t=c.currentNode;else return}switch(t.type){case 3:c.ssr||c.helper(CREATE_COMMENT);break;case 5:c.ssr||c.helper(TO_DISPLAY_STRING);break;case 9:for(let u=0;u<t.branches.length;u++)traverseNode(t.branches[u],c);break;case 10:case 11:case 1:case 0:traverseChildren(t,c);break}c.currentNode=t;let m=d.length;for(;m--;)d[m]()}function createStructuralDirectiveTransform(t,c){let u=isString$1(t)?c=>c===t:c=>t.test(c);return(t,d)=>{if(t.type===1){let{props:m}=t;if(t.tagType===3&&m.some(isVSlot))return;let g=[];for(let b=0;b<m.length;b++){let S=m[b];if(S.type===7&&u(S.name)){m.splice(b,1),b--;let u=c(t,S,d);u&&g.push(u)}}return g}}}function createCodegenContext(t,{mode:c=`function`,prefixIdentifiers:u=c===`module`,sourceMap:d=!1,filename:m=`template.vue.html`,scopeId:g=null,optimizeImports:b=!1,runtimeGlobalName:S=`Vue`,runtimeModuleName:C=`vue`,ssrRuntimeModuleName:w=`vue/server-renderer`,ssr:T=!1,isTS:E=!1,inSSR:D=!1}){let O={mode:c,prefixIdentifiers:u,sourceMap:d,filename:m,scopeId:g,optimizeImports:b,runtimeGlobalName:S,runtimeModuleName:C,ssrRuntimeModuleName:w,ssr:T,isTS:E,inSSR:D,source:t.source,code:``,column:1,line:1,offset:0,indentLevel:0,pure:!1,map:void 0,helper(t){return`_${helperNameMap[t]}`},push(t,c=-2,u){O.code+=t},indent(){newline(++O.indentLevel)},deindent(t=!1){t?--O.indentLevel:newline(--O.indentLevel)},newline(){newline(O.indentLevel)}};function newline(t){O.push(`
|
|
465
465
|
`+` `.repeat(t),0)}return O}function generate(t,c={}){let u=createCodegenContext(t,c);c.onContextCreated&&c.onContextCreated(u);let{mode:d,push:m,prefixIdentifiers:g,indent:b,deindent:S,newline:C,scopeId:w,ssr:T}=u,E=Array.from(t.helpers),D=E.length>0,O=!g&&d!==`module`;if(genFunctionPreamble(t,u),m(`function ${T?`ssrRender`:`render`}(${(T?[`_ctx`,`_push`,`_parent`,`_attrs`]:[`_ctx`,`_cache`]).join(`, `)}) {`),b(),O&&(m(`with (_ctx) {`),b(),D&&(m(`const { ${E.map(aliasHelper).join(`, `)} } = _Vue
|