@vue-skuilder/standalone-ui 0.2.3 → 0.2.4

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.
@@ -8662,7 +8662,7 @@ var stack$1, isWarning, ErrorCodes$1, ErrorTypeStrings$1, queue$1, flushIndex, p
8662
8662
  readonly: () => readonly,
8663
8663
  ref: () => ref,
8664
8664
  registerRuntimeCompiler: () => registerRuntimeCompiler,
8665
- render: () => render,
8665
+ render: () => render$1,
8666
8666
  renderList: () => renderList,
8667
8667
  renderSlot: () => renderSlot,
8668
8668
  resolveComponent: () => resolveComponent,
@@ -9165,7 +9165,7 @@ function normalizeContainer(t) {
9165
9165
  }
9166
9166
  return process.env.NODE_ENV !== "production" && window.ShadowRoot && t instanceof window.ShadowRoot && t.mode === "closed" && warn$2("mounting on a ShadowRoot with `{mode: \"closed\"}` may lead to unpredictable bugs"), t;
9167
9167
  }
9168
- var policy, tt$3, unsafeToTrustedHTML, svgNS, mathmlNS, doc, templateContainer, nodeOps, TRANSITION$1, ANIMATION, vtcKey, DOMTransitionPropsValidators, TransitionPropsValidators, decorate$1, Transition, callHook, hasExplicitCallback, endId, vShowOriginalDisplay, vShowHidden, vShow, CSS_VAR_TEXT, displayRE, semicolonRE, importantRE, prefixes, prefixCache, xlinkNS, veiKey, optionsModifierRE, cachedNow, p, getNow, isNativeOn, patchProp, REMOVAL, defineSSRCustomElement, BaseClass, VueElement, positionMap, newPositionMap, moveCbKey, enterCbKey, decorate, TransitionGroup, getModelAssigner, assignKey, vModelText, vModelCheckbox, vModelRadio, vModelSelect, vModelDynamic, systemModifiers, modifierGuards, withModifiers, keyNames, withKeys, rendererOptions, renderer, enabledHydration, render, hydrate, createApp, createSSRApp, ssrDirectiveInitialized, initDirectivesForSSR, init_runtime_dom_esm_bundler = __esmMin((() => {
9168
+ var policy, tt$3, unsafeToTrustedHTML, svgNS, mathmlNS, doc, templateContainer, nodeOps, TRANSITION$1, ANIMATION, vtcKey, DOMTransitionPropsValidators, TransitionPropsValidators, decorate$1, Transition, callHook, hasExplicitCallback, endId, vShowOriginalDisplay, vShowHidden, vShow, CSS_VAR_TEXT, displayRE, semicolonRE, importantRE, prefixes, prefixCache, xlinkNS, veiKey, optionsModifierRE, cachedNow, p, getNow, isNativeOn, patchProp, REMOVAL, defineSSRCustomElement, BaseClass, VueElement, positionMap, newPositionMap, moveCbKey, enterCbKey, decorate, TransitionGroup, getModelAssigner, assignKey, vModelText, vModelCheckbox, vModelRadio, vModelSelect, vModelDynamic, systemModifiers, modifierGuards, withModifiers, keyNames, withKeys, rendererOptions, renderer, enabledHydration, render$1, hydrate, createApp, createSSRApp, ssrDirectiveInitialized, initDirectivesForSSR, init_runtime_dom_esm_bundler = __esmMin((() => {
9169
9169
  if (init_runtime_core_esm_bundler(), init_runtime_core_esm_bundler(), init_shared_esm_bundler(), policy = void 0, tt$3 = typeof window < "u" && window.trustedTypes, tt$3) try {
9170
9170
  policy = /* @__PURE__ */ tt$3.createPolicy("vue", { createHTML: (t) => t });
9171
9171
  } catch (t) {
@@ -9330,7 +9330,7 @@ var policy, tt$3, unsafeToTrustedHTML, svgNS, mathmlNS, doc, templateContainer,
9330
9330
  }
9331
9331
  }
9332
9332
  _update() {
9333
- render(this._createVNode(), this._root);
9333
+ render$1(this._createVNode(), this._root);
9334
9334
  }
9335
9335
  _createVNode() {
9336
9336
  let t = {};
@@ -9563,9 +9563,9 @@ var policy, tt$3, unsafeToTrustedHTML, svgNS, mathmlNS, doc, templateContainer,
9563
9563
  let d = hyphenate(u.key);
9564
9564
  if (c.some((t) => t === d || keyNames[t] === d)) return t(u);
9565
9565
  });
9566
- }, rendererOptions = /* @__PURE__ */ extend$2({ patchProp }, nodeOps), enabledHydration = !1, render = (...t) => {
9566
+ }, rendererOptions = /* @__PURE__ */ extend$2({ patchProp }, nodeOps), enabledHydration = !1, render$1 = /* @__PURE__ */ __name$2((...t) => {
9567
9567
  ensureRenderer().render(...t);
9568
- }, hydrate = (...t) => {
9568
+ }, "render"), hydrate = (...t) => {
9569
9569
  ensureHydrationRenderer().hydrate(...t);
9570
9570
  }, createApp = (...t) => {
9571
9571
  let c = ensureRenderer().createApp(...t);
@@ -26489,6 +26489,85 @@ function mountMixerDebugger() {
26489
26489
  let t = window;
26490
26490
  t.skuilder = t.skuilder || {}, t.skuilder.mixer = mixerDebugAPI;
26491
26491
  }
26492
+ function registerActiveController(t) {
26493
+ activeController = t;
26494
+ }
26495
+ function getActiveController() {
26496
+ return activeController;
26497
+ }
26498
+ function toggleSessionOverlay() {
26499
+ if (typeof document > "u") {
26500
+ logger.info("[Session Overlay] No DOM available (non-browser host); overlay unavailable.");
26501
+ return;
26502
+ }
26503
+ overlayEl ? (teardown(), logger.info("[Session Overlay] Hidden.")) : (mount(), logger.info("[Session Overlay] Shown. Toggle off with window.skuilder.session.dbgOverlay()."));
26504
+ }
26505
+ function mount() {
26506
+ overlayEl = document.createElement("div"), overlayEl.id = OVERLAY_ID, Object.assign(overlayEl.style, {
26507
+ position: "fixed",
26508
+ top: "8px",
26509
+ left: "8px",
26510
+ zIndex: "2147483647",
26511
+ maxWidth: "320px",
26512
+ maxHeight: "90vh",
26513
+ overflowY: "auto",
26514
+ padding: "8px 10px",
26515
+ background: "rgba(17, 24, 39, 0.92)",
26516
+ color: "#e5e7eb",
26517
+ font: "11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace",
26518
+ borderRadius: "6px",
26519
+ boxShadow: "0 4px 16px rgba(0,0,0,0.4)",
26520
+ pointerEvents: "auto",
26521
+ userSelect: "none"
26522
+ }), document.body.appendChild(overlayEl), render(), pollHandle = setInterval(render, POLL_MS);
26523
+ }
26524
+ function teardown() {
26525
+ pollHandle !== null && (clearInterval(pollHandle), pollHandle = null), overlayEl?.parentNode && overlayEl.parentNode.removeChild(overlayEl), overlayEl = null;
26526
+ }
26527
+ function render() {
26528
+ if (!overlayEl) return;
26529
+ spinnerFrame++;
26530
+ let t = getActiveController();
26531
+ if (!t) {
26532
+ overlayEl.innerHTML = headerHtml() + "<div style=\"opacity:.65\">No active session.</div>";
26533
+ return;
26534
+ }
26535
+ let c = t.getDebugSnapshot();
26536
+ overlayEl.innerHTML = headerHtml() + replanHtml(c) + metaHtml(c) + hintsHtml(c.sessionHints) + queueHtml("reviewQ", "reviewQ", c.reviewQ) + queueHtml("newQ", "newQ", c.newQ) + queueHtml("failedQ", "failedQ", c.failedQ), overlayEl.querySelectorAll("[data-q]").forEach((t) => {
26537
+ t.onclick = () => {
26538
+ let c = t.dataset.q;
26539
+ c && (expanded[c] = !expanded[c], render());
26540
+ };
26541
+ });
26542
+ }
26543
+ function headerHtml() {
26544
+ return "<div style=\"font-weight:600;color:#93c5fd;margin-bottom:4px\">⚙ SessionController</div>";
26545
+ }
26546
+ function replanHtml(t) {
26547
+ return t.replanActive ? `<div style="margin-bottom:6px;color:#fde047">${SPINNER_FRAMES[spinnerFrame % SPINNER_FRAMES.length]} replanning <span style="opacity:.85">[${esc(t.replanLabel ?? "(auto)")}]</span></div>` : "<div style=\"margin-bottom:6px;opacity:.45\">○ idle</div>";
26548
+ }
26549
+ function metaHtml(t) {
26550
+ return `<div style="margin-bottom:6px">${[
26551
+ `time ${formatTime(t.secondsRemaining)}${t.hasCardGuarantee ? ` \xB7 <span style="color:#fbbf24">guarantee ${t.minCardsGuarantee}</span>` : ""}`,
26552
+ `well-indicated left: ${t.wellIndicatedRemaining}`,
26553
+ `current: ${t.currentCard ? esc(t.currentCard) : "<span style=\"opacity:.6\">—</span>"}`
26554
+ ].map((t) => `<div>${t}</div>`).join("")}</div>`;
26555
+ }
26556
+ function hintsHtml(t) {
26557
+ let c = [];
26558
+ return t && (t.boostTags && Object.keys(t.boostTags).length && c.push("boost: " + Object.entries(t.boostTags).map(([t, c]) => `${esc(t)}<span style="opacity:.6">\xD7${c}</span>`).join(", ")), t.boostCards && Object.keys(t.boostCards).length && c.push("boostCards: " + Object.entries(t.boostCards).map(([t, c]) => `${esc(t)}<span style="opacity:.6">\xD7${c}</span>`).join(", ")), t.requireCards?.length && c.push(`require: ${t.requireCards.map(esc).join(", ")}`), t.requireTags?.length && c.push(`requireTags: ${t.requireTags.map(esc).join(", ")}`), t.excludeTags?.length && c.push(`exclude: ${t.excludeTags.map(esc).join(", ")}`), t.excludeCards?.length && c.push(`excludeCards: ${t.excludeCards.map(esc).join(", ")}`)), `<div style="margin-bottom:6px"><div style="color:#86efac">sessionHints</div>${c.length ? c.map((t) => `<div style="margin-left:6px">${t}</div>`).join("") : "<div style=\"margin-left:6px;opacity:.6\">none</div>"}</div>`;
26559
+ }
26560
+ function queueHtml(t, c, u) {
26561
+ let d = u.length > INLINE_THRESHOLD, m = !d || expanded[t], g = d ? expanded[t] ? "▾ " : "▸ " : "", b = u.dequeueCount ? ` <span style="opacity:.5">drawn ${u.dequeueCount}</span>` : "", S = d ? "cursor:pointer;color:#f9a8d4" : "color:#f9a8d4", C = `<div${d ? ` data-q="${t}"` : ""} style="${S}">${g}${c}: ${u.length}${b}</div>`, w = "";
26562
+ return w = m && u.cards.length ? "<ol style=\"margin:2px 0 6px 0;padding-left:20px\">" + u.cards.map((t) => `<li style="white-space:nowrap">${esc(t)}</li>`).join("") + "</ol>" : u.cards.length ? `<div style="margin:1px 0 6px 6px;opacity:.55">(${u.length} cards \u2014 click to expand)</div>` : "<div style=\"margin:1px 0 6px 6px;opacity:.5\">empty</div>", C + w;
26563
+ }
26564
+ function formatTime(t) {
26565
+ let c = Math.max(0, Math.round(t));
26566
+ return `${Math.floor(c / 60)}:${(c % 60).toString().padStart(2, "0")}`;
26567
+ }
26568
+ function esc(t) {
26569
+ return t.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
26570
+ }
26492
26571
  function startSessionTracking(t, c, u) {
26493
26572
  clearRunHistory();
26494
26573
  let d = `session-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
@@ -26599,7 +26678,7 @@ function mountSessionDebugger() {
26599
26678
  let t = window;
26600
26679
  t.skuilder = t.skuilder || {}, t.skuilder.session = sessionDebugAPI;
26601
26680
  }
26602
- 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, 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, activeSession, sessionHistory, MAX_HISTORY, sessionDebugAPI, SessionController, init_dist = __esmMin((() => {
26681
+ 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, 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, expanded, activeSession, sessionHistory, MAX_HISTORY, sessionDebugAPI, SessionController, init_dist = __esmMin((() => {
26603
26682
  init_defineProperty(), init_index_browser_es$5(), init_index_browser_es(), init_index_es(), import___vite_browser_external = /* @__PURE__ */ __toESM$2(require___vite_browser_external(), 1), import___vite_browser_external$1 = /* @__PURE__ */ __toESM$2(require___vite_browser_external(), 1), import___vite_browser_external$2 = /* @__PURE__ */ __toESM$2(require___vite_browser_external(), 1), init_moment(), init_dist$1(), init_esm_browser(), import_browser_ponyfill = /* @__PURE__ */ __toESM$2(require_browser_ponyfill(), 1), import_browser_ponyfill$1 = /* @__PURE__ */ __toESM$2(require_browser_ponyfill(), 1), import_browser = /* @__PURE__ */ __toESM$2(require_browser(), 1), __defProp = Object.defineProperty, __getOwnPropNames = Object.getOwnPropertyNames, __glob = (t) => (c) => {
26604
26683
  var u = t[c];
26605
26684
  if (u) return u();
@@ -31690,7 +31769,22 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31690
31769
  help() {
31691
31770
  logger.info("\n🎨 Mixer Debug API\n\nCommands:\n .showLastMix() Show summary of most recent mixer run\n .showRun(id|index) Show summary of a specific run (by index or ID suffix)\n .explainSourceBalance() Analyze source balance and selection patterns\n .compareScores() Compare score distributions across sources\n .showCard(cardId) Show mixer decisions for a specific card\n .listRuns() List all captured runs in table format\n .export() Export run history as JSON for bug reports\n .clear() Clear run history\n .runs Access raw run history array\n .help() Show this help message\n\nExample:\n window.skuilder.mixer.showLastMix()\n window.skuilder.mixer.explainSourceBalance()\n window.skuilder.mixer.compareScores()\n");
31692
31771
  }
31693
- }, mountMixerDebugger(), init_logger(), init_PipelineDebugger(), activeSession = null, sessionHistory = [], MAX_HISTORY = 5, sessionDebugAPI = {
31772
+ }, mountMixerDebugger(), init_logger(), init_PipelineDebugger(), init_logger(), activeController = null, OVERLAY_ID = "skuilder-session-overlay", POLL_MS = 300, INLINE_THRESHOLD = 5, SPINNER_FRAMES = [
31773
+ "⠋",
31774
+ "⠙",
31775
+ "⠹",
31776
+ "⠸",
31777
+ "⠼",
31778
+ "⠴",
31779
+ "⠦",
31780
+ "⠧",
31781
+ "⠇",
31782
+ "⠏"
31783
+ ], spinnerFrame = 0, overlayEl = null, pollHandle = null, expanded = {
31784
+ reviewQ: !1,
31785
+ newQ: !1,
31786
+ failedQ: !1
31787
+ }, activeSession = null, sessionHistory = [], MAX_HISTORY = 5, sessionDebugAPI = {
31694
31788
  get sessions() {
31695
31789
  return [...sessionHistory];
31696
31790
  },
@@ -31700,6 +31794,9 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31700
31794
  showQueue() {
31701
31795
  showCurrentQueue();
31702
31796
  },
31797
+ dbgOverlay() {
31798
+ toggleSessionOverlay();
31799
+ },
31703
31800
  showHistory(t = 0) {
31704
31801
  showPresentationHistory(t);
31705
31802
  },
@@ -31730,7 +31827,7 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31730
31827
  sessionHistory.length = 0, logger.info("[Session Debug] Session history cleared.");
31731
31828
  },
31732
31829
  help() {
31733
- logger.info("\n🎯 Session Debug API\n\nCommands:\n .showQueue() Show current queue state (active session only)\n .showHistory(index?) Show presentation history (0=current/last, 1=previous, etc)\n .showInterleaving(index?) Analyze course interleaving pattern\n .listSessions() List all tracked sessions\n .export() Export session data as JSON for bug reports\n .clear() Clear session history\n .sessions Access raw session history array\n .active Access active session (if any)\n .help() Show this help message\n\nExample:\n window.skuilder.session.showHistory()\n window.skuilder.session.showInterleaving()\n window.skuilder.session.showQueue()\n");
31830
+ logger.info("\n🎯 Session Debug API\n\nCommands:\n .dbgOverlay() Toggle the pinned live overlay (queues, hints, timer)\n .showQueue() Show current queue state (active session only)\n .showHistory(index?) Show presentation history (0=current/last, 1=previous, etc)\n .showInterleaving(index?) Analyze course interleaving pattern\n .listSessions() List all tracked sessions\n .export() Export session data as JSON for bug reports\n .clear() Clear session history\n .sessions Access raw session history array\n .active Access active session (if any)\n .help() Show this help message\n\nExample:\n window.skuilder.session.showHistory()\n window.skuilder.session.showInterleaving()\n window.skuilder.session.showQueue()\n");
31734
31831
  }
31735
31832
  }, mountSessionDebugger(), init_logger(), SessionController = (_SessionController2 = class _SessionController extends Loggable {
31736
31833
  set sessionRecord(t) {
@@ -31750,11 +31847,11 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31750
31847
  return this.newQ.toString + "\n" + this.reviewQ.toString + "\n" + this.failedQ.toString;
31751
31848
  }
31752
31849
  constructor(t, c, u, d, m, g) {
31753
- super(), _defineProperty$2(this, "_className", "SessionController"), _defineProperty$2(this, "services", void 0), _defineProperty$2(this, "srsService", void 0), _defineProperty$2(this, "eloService", void 0), _defineProperty$2(this, "hydrationService", void 0), _defineProperty$2(this, "mixer", void 0), _defineProperty$2(this, "dataLayer", void 0), _defineProperty$2(this, "courseNameCache", /* @__PURE__ */ new Map()), _defineProperty$2(this, "_defaultBatchLimit", 20), _defineProperty$2(this, "_initialReviewCap", 200), _defineProperty$2(this, "sources", void 0), _defineProperty$2(this, "_sessionRecord", []), _defineProperty$2(this, "_currentCard", null), _defineProperty$2(this, "reviewQ", new ItemQueue()), _defineProperty$2(this, "newQ", new ItemQueue()), _defineProperty$2(this, "failedQ", new ItemQueue()), _defineProperty$2(this, "_replanPromise", null), _defineProperty$2(this, "_wellIndicatedRemaining", 0), _defineProperty$2(this, "_suppressQualityReplan", !1), _defineProperty$2(this, "_minCardsGuarantee", 0), _defineProperty$2(this, "_sessionHints", null), _defineProperty$2(this, "_outcomeObservers", []), _defineProperty$2(this, "_sessionControls", null), _defineProperty$2(this, "startTime", void 0), _defineProperty$2(this, "endTime", void 0), _defineProperty$2(this, "_secondsRemaining", void 0), _defineProperty$2(this, "_intervalHandle", void 0), this.dataLayer = u, this.mixer = m || new QuotaRoundRobinMixer(), this.srsService = new SrsService(u.getUserDB()), this.eloService = new EloService(u, u.getUserDB()), this.hydrationService = new CardHydrationService(d, (t) => u.getCourseDB(t), () => this._getItemsToHydrate()), this.services = { response: new ResponseProcessor(this.srsService, this.eloService) }, this.sources = t, this.startTime = /* @__PURE__ */ new Date(), this._secondsRemaining = c, this.endTime = new Date(this.startTime.valueOf() + 1e3 * this._secondsRemaining), g?.defaultBatchLimit !== void 0 && (this._defaultBatchLimit = g.defaultBatchLimit), g?.initialReviewCap !== void 0 && (this._initialReviewCap = g.initialReviewCap), g?.outcomeObservers?.length && (this._outcomeObservers = [...g.outcomeObservers]), this.log(`Session constructed:
31850
+ super(), _defineProperty$2(this, "_className", "SessionController"), _defineProperty$2(this, "services", void 0), _defineProperty$2(this, "srsService", void 0), _defineProperty$2(this, "eloService", void 0), _defineProperty$2(this, "hydrationService", void 0), _defineProperty$2(this, "mixer", void 0), _defineProperty$2(this, "dataLayer", void 0), _defineProperty$2(this, "courseNameCache", /* @__PURE__ */ new Map()), _defineProperty$2(this, "_defaultBatchLimit", 20), _defineProperty$2(this, "_initialReviewCap", 200), _defineProperty$2(this, "sources", void 0), _defineProperty$2(this, "_sessionRecord", []), _defineProperty$2(this, "_currentCard", null), _defineProperty$2(this, "reviewQ", new ItemQueue()), _defineProperty$2(this, "newQ", new ItemQueue()), _defineProperty$2(this, "failedQ", new ItemQueue()), _defineProperty$2(this, "_replanPromise", null), _defineProperty$2(this, "_activeReplanLabel", null), _defineProperty$2(this, "_wellIndicatedRemaining", 0), _defineProperty$2(this, "_suppressQualityReplan", !1), _defineProperty$2(this, "_minCardsGuarantee", 0), _defineProperty$2(this, "_sessionHints", null), _defineProperty$2(this, "_outcomeObservers", []), _defineProperty$2(this, "_sessionControls", null), _defineProperty$2(this, "startTime", void 0), _defineProperty$2(this, "endTime", void 0), _defineProperty$2(this, "_secondsRemaining", void 0), _defineProperty$2(this, "_intervalHandle", void 0), this.dataLayer = u, this.mixer = m || new QuotaRoundRobinMixer(), this.srsService = new SrsService(u.getUserDB()), this.eloService = new EloService(u, u.getUserDB()), this.hydrationService = new CardHydrationService(d, (t) => u.getCourseDB(t), () => this._getItemsToHydrate()), this.services = { response: new ResponseProcessor(this.srsService, this.eloService) }, this.sources = t, this.startTime = /* @__PURE__ */ new Date(), this._secondsRemaining = c, this.endTime = new Date(this.startTime.valueOf() + 1e3 * this._secondsRemaining), g?.defaultBatchLimit !== void 0 && (this._defaultBatchLimit = g.defaultBatchLimit), g?.initialReviewCap !== void 0 && (this._initialReviewCap = g.initialReviewCap), g?.outcomeObservers?.length && (this._outcomeObservers = [...g.outcomeObservers]), this.log(`Session constructed:
31754
31851
  startTime: ${this.startTime}
31755
31852
  endTime: ${this.endTime}
31756
31853
  defaultBatchLimit: ${this._defaultBatchLimit}
31757
- initialReviewCap: ${this._initialReviewCap}`);
31854
+ initialReviewCap: ${this._initialReviewCap}`), registerActiveController(this);
31758
31855
  }
31759
31856
  tick() {
31760
31857
  this._secondsRemaining = Math.floor((this.endTime.valueOf() - Date.now()) / 1e3), this._secondsRemaining <= 0 && clearInterval(this._intervalHandle);
@@ -31788,21 +31885,21 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31788
31885
  if (!u) return this.log("Replan already in progress, coalescing unhinted auto-replan"), this._replanPromise;
31789
31886
  let t = c.label ? ` [${c.label}]` : "";
31790
31887
  this.log(`Replan in progress; queueing hint-bearing replan${t} behind in-flight run`);
31791
- let d = this._replanPromise.catch(() => void 0).then(() => this._runReplan(c));
31792
- return this._replanPromise = d.finally(() => {
31793
- this._replanPromise === d && (this._replanPromise = null);
31794
- }), d;
31888
+ let d = this._replanPromise.catch(() => void 0).then(() => this._runReplan(c)), m = d.finally(() => {
31889
+ this._replanPromise === m && (this._replanPromise = null, this._activeReplanLabel = null);
31890
+ });
31891
+ return this._replanPromise = m, d;
31795
31892
  }
31796
- let d = this._runReplan(c);
31797
- this._replanPromise = d.finally(() => {
31798
- this._replanPromise === d && (this._replanPromise = null);
31799
- }), await d;
31893
+ let d = this._runReplan(c), m = d.finally(() => {
31894
+ this._replanPromise === m && (this._replanPromise = null, this._activeReplanLabel = null);
31895
+ });
31896
+ this._replanPromise = m, await d;
31800
31897
  }
31801
31898
  _replanHasIntent(t) {
31802
- return !!(t.label || 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);
31899
+ 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);
31803
31900
  }
31804
31901
  async _runReplan(t) {
31805
- t.hints || (t.hints = {});
31902
+ this._activeReplanLabel = t.label ?? "(auto)", t.hints || (t.hints = {});
31806
31903
  let c = t.hints, u = new Set(c.excludeCards ?? []);
31807
31904
  this._currentCard?.item.cardID && u.add(this._currentCard.item.cardID);
31808
31905
  for (let t of this._sessionRecord) u.add(t.card.card_id);
@@ -31816,6 +31913,30 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31816
31913
  getSessionHints() {
31817
31914
  return this._sessionHints;
31818
31915
  }
31916
+ getDebugSnapshot() {
31917
+ let describe = (t) => {
31918
+ let c = [];
31919
+ for (let u = 0; u < t.length; u++) c.push(t.peek(u).cardID);
31920
+ return {
31921
+ length: t.length,
31922
+ dequeueCount: t.dequeueCount,
31923
+ cards: c
31924
+ };
31925
+ };
31926
+ return {
31927
+ secondsRemaining: this.secondsRemaining,
31928
+ hasCardGuarantee: this.hasCardGuarantee,
31929
+ minCardsGuarantee: this._minCardsGuarantee,
31930
+ wellIndicatedRemaining: this._wellIndicatedRemaining,
31931
+ currentCard: this._currentCard?.item.cardID ?? null,
31932
+ sessionHints: this._sessionHints,
31933
+ replanActive: this._replanPromise !== null,
31934
+ replanLabel: this._activeReplanLabel,
31935
+ reviewQ: describe(this.reviewQ),
31936
+ newQ: describe(this.newQ),
31937
+ failedQ: describe(this.failedQ)
31938
+ };
31939
+ }
31819
31940
  mergeSessionHints(t) {
31820
31941
  this._sessionHints = mergeHints2([this._sessionHints, t]) ?? null, this.log(`Session hints merged: ${JSON.stringify(this._sessionHints)}`);
31821
31942
  }
@@ -31848,10 +31969,10 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
31848
31969
  }
31849
31970
  }
31850
31971
  async _replanUncoalesced(t) {
31851
- let c = this._runReplan(t);
31852
- this._replanPromise = c.finally(() => {
31853
- this._replanPromise === c && (this._replanPromise = null);
31854
- }), await c;
31972
+ let c = this._runReplan(t), u = c.finally(() => {
31973
+ this._replanPromise === u && (this._replanPromise = null, this._activeReplanLabel = null);
31974
+ });
31975
+ this._replanPromise = u, await c;
31855
31976
  }
31856
31977
  normalizeReplanOptions(t) {
31857
31978
  if (!t) return {};
@@ -32015,9 +32136,9 @@ ${c.id}:`), logger.info(JSON.stringify(c.doc, null, 2));
32015
32136
  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) {
32016
32137
  this._suppressQualityReplan = !1;
32017
32138
  let t = this.reviewQ.length + this.failedQ.length;
32018
- 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();
32139
+ 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" });
32019
32140
  }
32020
- 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()), this._secondsRemaining <= 0 && this.failedQ.length === 0 && this._minCardsGuarantee <= 0) return this._currentCard = null, endSessionTracking(), null;
32141
+ 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;
32021
32142
  let c = 3, u = 250, d = 0;
32022
32143
  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) {
32023
32144
  if (d++, d >= 3) {