// Composable for fetching random words for password generation // Uses Random Word API with fallback to EFF Diceware word list export function useRandomWords() { // EFF Diceware short word list (optimized for memorability) // Source: https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases const FALLBACK_WORDS = [ "able", "acid", "aged", "also", "area", "army", "away", "baby", "back", "ball", "band", "bank", "base", "bath", "bear", "beat", "been", "beer", "bell", "belt", "best", "bike", "bill", "bird", "blow", "blue", "boat", "body", "bold", "bolt", "bomb", "bond", "bone", "book", "boom", "born", "boss", "both", "bowl", "bulk", "burn", "bush", "busy", "cage", "cake", "call", "calm", "came", "camp", "card", "care", "cart", "case", "cash", "cast", "cell", "chat", "chip", "city", "clad", "clay", "clip", "club", "clue", "coal", "coat", "code", "coil", "coin", "cold", "come", "cook", "cool", "cope", "copy", "cord", "core", "cork", "cost", "crab", "crew", "crop", "crow", "curl", "cute", "damp", "dare", "dark", "dash", "data", "date", "dawn", "days", "dead", "deaf", "deal", "dean", "dear", "debt", "deck", "deed", "deep", "deer", "demo", "deny", "desk", "dial", "dice", "died", "diet", "disc", "dish", "disk", "dock", "does", "dome", "done", "doom", "door", "dose", "down", "drag", "draw", "drew", "drip", "drop", "drug", "drum", "dual", "duck", "dull", "dumb", "dump", "dune", "dunk", "dust", "duty", "each", "earl", "earn", "ease", "east", "easy", "edge", "edit", "else", "even", "ever", "evil", "exam", "exit", "face", "fact", "fade", "fail", "fair", "fake", "fall", "fame", "farm", "fast", "fate", "fear", "feed", "feel", "feet", "fell", "felt", "fern", "file", "fill", "film", "find", "fine", "fire", "firm", "fish", "fist", "five", "flag", "flat", "fled", "flew", "flip", "flow", "folk", "fond", "food", "fool", "foot", "ford", "fork", "form", "fort", "foul", "four", "free", "from", "fuel", "full", "fund", "gain", "game", "gang", "gate", "gave", "gear", "gene", "gift", "girl", "give", "glad", "glow", "glue", "goal", "goat", "gods", "goes", "gold", "golf", "gone", "good", "gray", "grew", "grey", "grid", "grim", "grin", "grip", "grow", "gulf", "hair", "half", "hall", "halt", "hand", "hang", "hard", "harm", "hate", "have", "hawk", "head", "heal", "hear", "heat", "held", "hell", "help", "herb", "here", "hero", "hide", "high", "hill", "hint", "hire", "hold", "hole", "holy", "home", "hood", "hook", "hope", "horn", "host", "hour", "huge", "hung", "hunt", "hurt", "icon", "idea", "inch", "into", "iron", "item", "jail", "jane", "jazz", "jean", "john", "join", "joke", "juan", "jump", "june", "jury", "just", "keen", "keep", "kent", "kept", "kick", "kids", "kill", "kind", "king", "kiss", "knee", "knew", "know", "lack", "lady", "laid", "lake", "lamb", "lamp", "land", "lane", "last", "late", "lead", "leaf", "lean", "left", "lend", "lens", "less", "levy", "lied", "life", "lift", "like", "lily", "line", "link", "lion", "list", "live", "load", "loan", "lock", "lodge", "loft", "logo", "long", "look", "loop", "lord", "lose", "loss", "lost", "loud", "love", "luck", "lung", "made", "maid", "mail", "main", "make", "male", "mall", "many", "mark", "mars", "mask", "mass", "mate", "math", "mayo", "maze", "meal", "mean", "meat", "meet", "melt", "menu", "mess", "mice", "mild", "mile", "milk", "mill", "mind", "mine", "mint", "miss", "mist", "mode", "mood", "moon", "more", "most", "move", "much", "mule", "must", "myth", "nail", "name", "navy", "near", "neat", "neck", "need", "news", "next", "nice", "nick", "nine", "noah", "node", "none", "noon", "norm", "nose", "note", "noun", "nuts", "okay", "once", "ones", "only", "onto", "open", "oral", "oven", "over", "pace", "pack", "page", "paid", "pain", "pair", "palm", "park", "part", "pass", "past", "path", "peak", "pick", "pier", "pike", "pile", "pill", "pine", "pink", "pipe", "plan", "play", "plot", "plug", "plus", "poem", "poet", "pole", "poll", "pond", "pony", "pool", "poor", "pope", "pork", "port", "pose", "post", "pour", "pray", "prep", "prey", "pull", "pump", "pure", "push", "quit", "race", "rack", "rage", "raid", "rail", "rain", "rank", "rare", "rate", "rays", "read", "real", "rear", "rely", "rent", "rest", "rice", "rich", "ride", "ring", "rise", "risk", "road", "rock", "rode", "role", "roll", "roof", "room", "root", "rope", "rose", "ross", "ruin", "rule", "rush", "ruth", "safe", "saga", "sage", "said", "sail", "sake", "sale", "salt", "same", "sand", "sank", "save", "says", "scan", "scar", "seal", "seat", "seed", "seek", "seem", "seen", "self", "sell", "semi", "send", "sent", "sept", "sets", "shed", "ship", "shop", "shot", "show", "shut", "sick", "side", "sign", "silk", "sing", "sink", "site", "size", "skin", "skip", "slam", "slap", "slip", "slow", "snap", "snow", "soft", "soil", "sold", "sole", "some", "song", "soon", "sort", "soul", "spot", "star", "stay", "stem", "step", "stir", "stop", "such", "suit", "sung", "sunk", "sure", "swim", "tail", "take", "tale", "talk", "tall", "tank", "tape", "task", "team", "tear", "tech", "tell", "tend", "tent", "term", "test", "text", "than", "that", "them", "then", "they", "thin", "this", "thus", "tide", "tied", "tier", "ties", "till", "time", "tiny", "tips", "tire", "told", "toll", "tone", "tony", "took", "tool", "tops", "torn", "toss", "tour", "town", "tray", "tree", "trek", "trim", "trio", "trip", "true", "tube", "tune", "turn", "twin", "type", "unit", "upon", "used", "user", "vary", "vast", "verb", "very", "vice", "view", "visa", "void", "vote", "wade", "wage", "wait", "wake", "walk", "wall", "ward", "warm", "warn", "wash", "wave", "ways", "weak", "wear", "week", "well", "went", "were", "west", "what", "when", "whom", "wide", "wife", "wild", "will", "wind", "wine", "wing", "wire", "wise", "wish", "with", "wolf", "wood", "wool", "word", "wore", "work", "worm", "worn", "wrap", "yard", "yeah", "year", "your", "zone", "zoom" ]; // Try to fetch random words from API, fallback to local list async function getRandomWords(count = 4): Promise { try { // Try Random Word API first const response = await fetch( `https://random-word-api.herokuapp.com/word?number=${count}` ); if (response.ok) { const words = await response.json(); if (Array.isArray(words) && words.length === count) { return words; } } } catch (error) { console.warn("[RandomWords] API failed, using fallback words:", error); } // Fallback: pick random words from local list const words: string[] = []; const usedIndices = new Set(); while (words.length < count) { const index = Math.floor(Math.random() * FALLBACK_WORDS.length); if (!usedIndices.has(index)) { usedIndices.add(index); words.push(FALLBACK_WORDS[index]); } } return words; } return { getRandomWords }; }