type Random = () => number; /** Intentionally hand-picked words: readable names beat an opaque random identifier. */ export const adjectives = [ "amber", "ancient", "ardent", "autumn", "bold", "brisk", "bright", "calm", "celestial", "clear", "cobalt", "crimson", "curious", "daring", "dawn", "distant", "eager", "electric", "fading", "feral", "flowing", "flowering", "gentle", "golden", "grand", "hidden", "hollow", "hushed", "iron", "ivory", "jolly", "keen", "lively", "lunar", "mellow", "misty", "modern", "mossy", "nimble", "northern", "open", "orange", "patient", "pearl", "quiet", "radiant", "rapid", "red", "rising", "royal", "rustic", "sable", "sacred", "silver", "soft", "solar", "steady", "summer", "swift", "tidal", "verdant", "violet", "warm", "wild", "willow", "winter", "wise", "young", ]; export const nouns = [ "anchor", "arch", "arrow", "basin", "beacon", "birch", "bird", "bridge", "brook", "canyon", "castle", "chicken", "circle", "cloud", "comet", "copper", "creek", "crown", "dawn", "delta", "drift", "falcon", "field", "fire", "forest", "garden", "gate", "glade", "harbor", "hawk", "hill", "island", "lake", "lantern", "leaf", "marsh", "meadow", "moon", "mountain", "ocean", "orchard", "otter", "path", "peak", "pine", "planet", "rain", "river", "road", "rook", "sail", "shadow", "shore", "sky", "spring", "star", "stone", "storm", "stream", "summit", "thunder", "trail", "valley", "water", "wave", "willow", "wind", "wing", "wood", ]; function pick(words: readonly string[], random: Random): string { let index = Math.min(words.length - 1, Math.max(0, Math.floor(random() * words.length))); return words[index]!; } export function documentTitle(random: Random = Math.random): string { return `${pick(adjectives, random)}-${pick(nouns, random)}`; } /** A random starting point, followed by every possible readable title exactly once. */ export function* documentTitles(random: Random = Math.random): IterableIterator { let count = adjectives.length * nouns.length; let start = Math.min(count - 1, Math.max(0, Math.floor(random() * count))); for (let offset = 0; offset < count; offset++) { let index = (start + offset) % count; let adjective = adjectives[Math.floor(index / nouns.length)]!; let noun = nouns[index % nouns.length]!; yield `${adjective}-${noun}`; } }