Product preview
Spaced-repetition flashcards from the course preview — no account, progress stays on this device.
Flashcard decks
Know it cold.
Tap a card to flip. Be honest with yourself — mark Know only if you'd get it right on exam day. Retention feeds 20% of your readiness score.
(function(){
var C = window.CRAMLAB, stage = document.getElementById('stage');
var decksEl = document.getElementById('decks');
var domains = [];
C.FLASHCARDS.forEach(function(c){ if (domains.indexOf(c.domain) < 0) domains.push(c.domain); });
// diagnostic topics -> flashcard domains
var TOPIC_TO_DOMAIN = {
'TX Regulation': 'TX Regulation',
'General Concepts': 'General Concepts',
'Property': 'Property',
'Auto': 'Auto & Casualty',
'Workers\u2019 Comp': 'Workers\u2019 Comp & Other',
'Other Lines': 'Workers\u2019 Comp & Other'
};
function deckStats(domain){
var cards = C.FLASHCARDS.filter(function(c){ return c.domain === domain; });
var st = C.state().flashcards;
var seen = cards.filter(function(c){ return st[c.id]; }).length;
return { total: cards.length, seen: seen };
}
/* "Review my misses" smart deck: cards from the domains behind your
diagnostic misses, plus TX state-law must-knows. Capped at 40. */
function missDeck(){
var d = C.state().diagnostic;
var misses = d ? d.perTopic : null;
var picked = [], seenIds = {};
function add(c){ if (!seenIds[c.id] && picked.length < 40){ seenIds[c.id]=1; picked.push(c); } }
if (misses) {
var weak = C.TOPICS.slice().sort(function(a,b){
var pa = misses[a]||{right:0,total:1}, pb = misses[b]||{right:0,total:1};
return (pa.right/pa.total) - (pb.right/pb.total);
});
weak.forEach(function(t){
var p = misses[t] || {right:0,total:0};
if (!p.total || (p.right/p.total) >= 0.85) return;
var dom = TOPIC_TO_DOMAIN[t];
C.FLASHCARDS.filter(function(c){ return c.domain === dom; }).slice(0,8).forEach(add);
});
}
// TX state-law must-knows always included (exam's favorite numbers)
C.FLASHCARDS.filter(function(c){ return c.domain === 'TX Regulation'; }).forEach(add);
if (picked.length < 20) {
C.shuffle(C.FLASHCARDS).forEach(function(c){ if (picked.length < 40) add(c); });
}
return C.shuffle(picked);
}
function missSummary(){
var d = C.state().diagnostic;
if (!d) return 'No diagnostic yet — seeded with TX state-law must-knows. Take the diagnostic and this deck rebuilds around your misses.';
var weak = C.TOPICS.filter(function(t){
var p = d.perTopic[t]||{right:0,total:0}; return p.total && (p.right/p.total) < 0.85;
});
return weak.length
? 'Seeded from your misses in: ' + weak.join(' · ') + ' — plus TX must-knows.'
: 'No weak topics on your last diagnostic — seeded with TX state-law must-knows.';
}
function renderDecks(){
decksEl.innerHTML = '';
var md = document.createElement('button');
md.className = 'deck smart';
md.innerHTML = 'Smart deck · ~40 cards
Review my misses
' +
'' + C.esc(missSummary()) + '
';
md.addEventListener('click', function(){ studySmart(); });
decksEl.appendChild(md);
domains.forEach(function(d){
var s = deckStats(d);
var b = document.createElement('button');
b.className = 'deck';
b.innerHTML = '' + s.seen + ' / ' + s.total + ' reviewed
' +
'' + C.esc(d) + '
Tap to study this deck.
';
b.addEventListener('click', function(){ study(d); });
decksEl.appendChild(b);
});
}
var queue, qi, domain, reshow;
function advance(){
if (qi < queue.length - 1) { qi++; renderCard(); }
else { finishDeck(); }
}
/* SM-2-lite: a "don't know" re-queues the card ~5 positions later (max 2
re-shows per session); "know" cards retire to the back of the line. */
function rateSmart(knew){
C.recordFlashcard(queue[qi].id, knew);
var card = queue[qi];
if (!knew) {
reshow[card.id] = (reshow[card.id]||0) + 1;
if (reshow[card.id] <= 2) {
var at = Math.min(queue.length, qi + 6);
queue.splice(at, 0, card);
}
}
advance();
}
function rate(knew){
C.recordFlashcard(queue[qi].id, knew);
advance();
}
function studySmart(){
domain = 'Review my misses';
queue = missDeck();
reshow = {};
if (!queue.length) { renderDecks(); return; }
qi = 0;
renderCard(true);
}
function study(d){
domain = d;
// weak-first: unreviewed and "don't know" cards surface first
var st = C.state().flashcards;
var cards = C.FLASHCARDS.filter(function(c){ return c.domain === d; });
var weak = cards.filter(function(c){ return !st[c.id] || !st[c.id].knew; });
var known = cards.filter(function(c){ return st[c.id] && st[c.id].knew; });
queue = C.shuffle(weak).concat(C.shuffle(known));
qi = 0;
renderCard(false);
}
function renderCard(smart){
var c = queue[qi];
stage.innerHTML =
'' +
'' + C.esc(domain) + ' · Card ' + (qi+1) + ' of ' + queue.length + '
' +
'' +
'
Term
' + C.esc(c.term) + '
' +
'
Definition
' + C.esc(c.def) + '
' +
'
' +
'' +
'' +
'' +
'
' +
'Tap the card to flip it.' +
(smart ? ' Missed cards come back a few cards later — that’s the spaced repetition.' : '') + '
';
var fc = document.getElementById('fcard');
fc.addEventListener('click', function(){ fc.classList.toggle('flipped'); });
document.getElementById('backBtn').addEventListener('click', function(){
stage.innerHTML = 'Product preview' +
'Spaced-repetition flashcards from the course preview — no account, progress stays on this device.
' +
'Flashcard decksKnow it cold.
' +
'Tap a card to flip. Be honest with yourself — mark Know only if you\'d get it right on exam day. Retention feeds 20% of your readiness score.
' +
'';
decksEl = document.getElementById('decks');
renderDecks();
});
document.getElementById('knowBtn').addEventListener('click', function(){ smart ? rateSmart(true) : rate(true); });
document.getElementById('dontBtn').addEventListener('click', function(){ smart ? rateSmart(false) : rate(false); });
}
function finishDeck(){
var st = C.state().flashcards;
var known = queue.filter(function(c){ return st[c.id] && st[c.id].knew; }).length;
stage.innerHTML = '' +
'
Deck complete' + C.esc(domain) + '
' +
'
' + known + '/' + queue.length + '
' +
'
cards you know in this deck.
' +
'
';
document.getElementById('againBtn').addEventListener('click', function(){
if (domain === 'Review my misses') studySmart(); else study(domain);
});
}
renderDecks();
})();