{\n\t"origin": [\n\t\t"It's like #titles# meets #titles#.",\n\t\t"Like #titles#, but #compadj#.",\n\t\t"#imagine# #titles#, but with #element#.",\n\t\t"It's like #titles# meets #titles#, with #element#.",\n\t\t"It's #titles# meets #titles#.",\n\t\t"This #format# is like if #writer# made #titles#.",\n\t\t"This #format# is like if #titles# was #genre#.",\n\t\t"It's a #format# of if #titles# was combined with #titles#, but #compadj#.",\n\t\t"It's a #genre# version of #titles#.",\n\t\t"It's a #genre# version of #titles#, with #element#.",\n\t\t"It's a #genre# take on #titles#.",\n\t\t"It's like if #titles# was set #setting#.",\n\t\t"It's like if #titles# met #titles#, but #setting#.",\n\t\t"It's like a #genre# version of #titles#, but #setting#.",\n\t\t"It's like #titles#, but #compadj# and #setting#.",\n\t\t"It's a #genre# #format# with #element#, set #setting#.",\n\t\t"#imagine# if #writer# did a #genre# #format#.",\n\t\t"#imagine# if #writer# and #writer# did a #genre# #format#.",\n\t\t"#imagine# if #writer# did a #genre# #format#, set #setting#.",\n\t\t"It's a #genre# #format# set #setting# with #element# and #element#.",\n\t\t"It's a #format# set #setting# with #genre# #element# and #element#.",\n\t\t"This #format# is a #genre# #storytype# with #element#.",\n\t\t"A #storytype# about #element# and #element#, #setting#.",\n\t\t"#support# #format# that's like #titles#, but #genre#.",\n\t\t"#support# #format# that's like if #writer# had made #titles#.",\n\t\t"#support# #format# that's like if #writer# had made #titles#, but with #element#.",\n\t\t"It's a #format# set #setting#, but with #character# as the #role#.",\n\t\t"#imagine# #titles#, but with #character# as the #role#.",\n\t\t"It's a #format# set #setting#, but with #character# as the #role# and #element#.",\n\t\t"#imagine# #titles# set #setting#, with #character# as the #role#.",\n\t\t"#imagine# a #format# version of #titles#.",\n\t\t"#imagine# a #format# version of #titles# made by #writer#.",\n\t\t"#imagine# a #genre# #format# version of #titles# made by #writer#.",\n\t\t"#imagine# a #genre# #format# version of #titles#, but with #character# as the #role#.",\n\t\t"#imagine# #titles#, but by #writer# with #writer#.",\n\t\t"It's like #titles#, but for #audience#.",\n\t\t"It's like #titles#, but with #element# and for #audience#.",\n\t\t"It's like #titles# meets #titles#, but for #audience#.",\n\t\t"#imagine# #titles#, but #compadj# and for #audience#."\n\t],\n\t"titles": [\n\t\t"Game of Thrones",\n\t\t"Harry Potter",\n\t\t"The Hunger Games",\n\t\t"Star Wars",\n\t\t"Star Trek",\n\t\t"Jurassic Park",\n\t\t"Veronica Mars",\n\t\t"Buffy the Vampire Slayer",\n\t\t"Welcome to Night Vale",\n\t\t"The Breakfast Club",\n\t\t"The Avengers",\n\t\t"Superman",\n\t\t"Batman",\n\t\t"Twilight",\n\t\t"50 Shades of Grey",\n\t\t"James Bond",\n\t\t"The Da Vinci Code",\n\t\t"Undertale",\n\t\t"Mass Effect",\n\t\t"Firefly",\n\t\t"Battlestar Galactica",\n\t\t"Blade Runner",\n\t\t"Neon Genesis Evangelion",\n\t\t"Adventure Time",\n\t\t"Steven Universe",\n\t\t"Invader Zim",\n\t\t"Love Actually",\n\t\t"Metropolis",\n\t\t"Koyaanisqatsi",\n\t\t"The Mortal Instruments",\n\t\t"Divergent",\n\t\t"Avatar: The Last Airbender",\n\t\t"Digimon",\n\t\t"Doctor Who",\n\t\t"Homestuck",\n\t\t"Pokémon",\n\t\t"Tomb Raider",\n\t\t"The X-Files",\n\t\t"Bones",\n\t\t"Glee",\n\t\t"Lord of the Rings",\n\t\t"The Simpsons",\n\t\t"Supernatural",\n\t\t"Teen Wolf",\n\t\t"My Little Pony",\n\t\t"Sherlock",\n\t\t"The Perks of Being a Wallflower",\n\t\t"Pirates of the Caribbean ",\n\t\t"The Chronicles of Narnia",\n\t\t"Stargate",\n\t\t"Frozen",\n\t\t"Minions",\n\t\t"NCIS",\n\t\t"Les Miserables",\n\t\t"CSI",\n\t\t"Law and Order",\n\t\t"Back to the Future",\n\t\t"Alice in Wonderland",\n\t\t"The Hobbit",\n\t\t"The Vampire Diaries",\n\t\t"Torchwood",\n\t\t"Hamlet",\n\t\t"Downton Abbey",\n\t\t"Mean Girls",\n\t\t"Spider-Man",\n\t\t"X-Men",\n\t\t"Teenage Mutant Ninja Turtles",\n\t\t"The Great British Bake-Off",\n\t\t"The Walking Dead",\n\t\t"Naruto",\n\t\t"The Office",\n\t\t"Parks and Recreation",\n\t\t"The Little Prince",\n\t\t"A Tale Of Two Cities",\n\t\t"The Catcher in the Rye",\n\t\t"Anne of Green Gables",\n\t\t"Charlotte's Web",\n\t\t"Zorro",\n\t\t"Left Behind",\n\t\t"The Matrix",\n\t\t"Dungeons and Dragons",\n\t\t"Ghost World",\n\t\t"His Dark Materials",\n\t\t"Slaughterhouse-Five",\n\t\t"Doogie Howser, MD",\n\t\t"La Bohème",\n\t\t"Pacific Rim",\n\t\t"Final Fantasy VII",\n\t\t"South Park",\n\t\t"Animal Crossing",\n\t\t"Divergent",\n\t\t"The Odyssey",\n\t\t"Citizen Kane",\n\t\t"Loony Toons",\n\t\t"Animaniacs",\n\t\t"Watership Down",\n\t\t"Don Quixote",\n\t\t"Blair Witch Project",\n\t\t"Lawrence of Arabia",\n\t\t"1984",\n\t\t"A Brave New World",\n\t\t"Gone With the Wind",\n\t\t"Up",\n\t\t"Fallout",\n\t\t"Inception",\n\t\t"Titanic",\n\t\t"Hedwig and the Angry Inch",\n\t\t"Discworld",\n\t\t"The Legend of Zelda",\n\t\t"Sonic the Hedgehog",\n\t\t"Avatar: The Last Airbender",\n\t\t"Morrowind",\n\t\t"Kingdom Hearts",\n\t\t"Metal Gear Solid",\n\t\t"Power Rangers",\n\t\t"World of Warcraft",\n\t\t"Warhammer 40k",\n\t\t"Call of Duty",\n\t\t"Death Note",\n\t\t"The Dresden Files",\n\t\t"Futurama",\n\t\t"The Muppets",\n\t\t"Homestuck",\n\t\t"Sailor Moon",\n\t\t"Sherlock Holmes",\n\t\t"Animorphs",\n\t\t"Breaking Bad",\n\t\t"Mad Men",\n\t\t"The Royal Tenenbaums",\n\t\t"A Clockwork Orange",\n\t\t"Scott Pilgrim",\n\t\t"To Kill A Mockingbird",\n\t\t"High School Musical",\n\t\t"Archie",\n\t\t"Leverage",\n\t\t"The Daily Show",\n\t\t"The Nutcracker",\n\t\t"A Midsummer Night's Dream",\n\t\t"Survivor",\n\t\t"Fight Club",\n\t\t"Bojack Horseman",\n\t\t"Arrested Development",\n\t\t"Peanuts",\n\t\t"King of the Hill",\n\t\t"Rushmore",\n\t\t"Rocky",\n\t\t"Rocky Horror Picture Show",\n\t\t"Indiana Jones",\n\t\t"Breakfast at Tiffany's",\n\t\t"Terminator",\n\t\t"The Graduate",\n\t\t"Hannibal",\n\t\t"Hearthstone",\n\t\t"King Kong",\n\t\t"Robin Hood",\n\t\t"Forrest Gump",\n\t\t"The Princess Bride",\n\t\t"Dr. Strangelove",\n\t\t"Die Hard",\n\t\t"The Devil Wears Prada",\n\t\t"Scarface",\n\t\t"The Godfather",\n\t\t"The Sopranos",\n\t\t"The Brave Little Toaster",\n\t\t"The Lone Ranger",\n\t\t"The Tempest",\n\t\t"Dexter",\n\t\t"How to Win Friends & Influence People",\n\t\t"Little Miss Sunshine",\n\t\t"Napolean Dynamite",\n\t\t"The Little Prince",\n\t\t"Apocalypse Now",\n\t\t"No Country for Old Men",\n\t\t"The Girl With the Dragon Tattoo",\n\t\t"Homestar Runner",\n\t\t"Candy Crush",\n\t\t"The Boondock Saints",\n\t\t"Sesame Street",\n\t\t"The Gods Must Be Crazy",\n\t\t"Holy Grail",\n\t\t"Little Shop of Horrors",\n\t\t"Sweeney Todd",\n\t\t"Pulp Fiction",\n\t\t"Reservoir Dogs",\n\t\t"Lock, Stock and Two Smoking Barrels",\n\t\t"A Christmas Carol",\n\t\t"The Incredible Journey",\n\t\t"Old Yeller",\n\t\t"Bridge to Terabithia",\n\t\t"Flowers for Algernon",\n\t\t"The Great Gatsby",\n\t\t"Howard the Duck",\n\t\t"Chinatown",\n\t\t"Casablanca",\n\t\t"Mastering the Art Of French Cooking",\n\t\t"Destiny",\n\t\t"Civilization V",\n\t\t"Catch-22",\n\t\t"Katamari Damacy",\n\t\t"Neuromancer",\n\t\t"Pandemic",\n\t\t"Settlers of Catan",\n\t\t"Shadowrun",\n\t\t"Mad Max: Fury Road",\n\t\t"Mad Max",\n\t\t"Arthur",\n\t\t"Wishbone",\n\t\t"The Toast",\n\t\t"The Ring",\n\t\t"Lassie",\n\t\t"Garfield",\n\t\t"Have Spacesuit, Will Travel",\n\t\t"Death Of A Salesman",\n\t\t"Waiting for Godot",\n\t\t"Mystery Science Theatre 3000",\n\t\t"The Babysitters' Club",\n\t\t"Sweet Valley High",\n\t\t"The Boxcar Children",\n\t\t"A Series of Unfortunate Events",\n\t\t"The Apple Lisa",\n\t\t"Virtual Boy",\n\t\t"Dark Souls",\n\t\t"Ace Attorney",\n\t\t"Redwall",\n\t\t"Foundation",\n\t\t"Gilmore Girls",\n\t\t"Tales of Symphonia",\n\t\t"The Wizard of Oz",\n\t\t"The Twilight Zone",\n\t\t"Skies of Arcadia",\n\t\t"Disneyland",\n\t\t"Disney World",\n\t\t"Conan the Barbarian",\n\t\t"Chitty Chitty Bang Bang",\n\t\t"The Addams Family",\n\t\t"Rent",\n\t\t"Kushiel's Dart",\n\t\t"America's Army",\n\t\t"Nethack",\n\t\t"Dwarf Fortress",\n\t\t"Diplomacy",\n\t\t"Project Runway",\n\t\t"Survivor",\n\t\t"Calvin and Hobbes",\n\t\t"RollerCoaster Tycoon",\n\t\t"The Curious Incident of the Dog in the Night-Time",\n\t\t"Apollo 13",\n\t\t"Degrassi",\n\t\t"Temeraire",\n\t\t"The Expanse",\n\t\t"Clerks",\n\t\t"The Sims",\n\t\t"SimCity 2000",\n\t\t"Oregon Trail",\n\t\t"Snow Crash",\n\t\t"Mavis Beacon Teaches Typing",\n\t\t"Metroid",\n\t\t"Scooby Do",\n\t\t"Rent",\n\t\t"The Road Not Taken",\n\t\t"Howl",\n\t\t"Green Eggs and Ham",\n\t\t"Harold And The Purple Crayon",\n\t\t"Where The Wild Things Are",\n\t\t"Jumanji",\n\t\t"Amelia Bedelia",\n\t\t"Curious George",\n\t\t"George and Martha",\n\t\t"The Giver",\n\t\t"Holes",\n\t\t"Madeline",\n\t\t"Are You There, God? It's Me, Margaret",\n\t\t"The Giving Tree",\n\t\t"Winnie-the-Pooh",\n\t\t"A Wrinkle in Time",\n\t\t"Ender's Game",\n\t\t"The Wheel Of Time",\n\t\t"Watchmen",\n\t\t"2001: A Space Odyssey",\n\t\t"Starship Troopers",\n\t\t"20,000 Leagues Under The Sea",\n\t\t"Xanth",\n\t\t"Hackers",\n\t\t"Sabriel",\n\t\t"The Lion King",\n\t\t"Mary Poppins"\n\t],\n\t"compadj": [\n\t\t"grittier",\n\t\t"for grown-ups",\n\t\t"gayer",\n\t\t"political",\n\t\t"darker",\n\t\t"creepier",\n\t\t"on ice",\n\t\t"based on a true story",\n\t\t"based on real life",\n\t\t"family-friendly",\n\t\t"postmodern",\n\t\t"communist",\n\t\t"Marxist",\n\t\t"more cynical",\n\t\t"with swears",\n\t\t"with cusses",\n\t\t"bleaker",\n\t\t"grimdark",\n\t\t"bloodier",\n\t\t"gorier",\n\t\t"sexier",\n\t\t"updated for today's audiences",\n\t\t"for children",\n\t\t"longer",\n\t\t"shorter",\n\t\t"classier",\n\t\t"in 3D",\n\t\t"educational",\n\t\t"more muscular",\n\t\t"pornier",\n\t\t"in bikinis",\n\t\t"with less swearing",\n\t\t"without swearing",\n\t\t"shittier",\n\t\t"beachier",\n\t\t"hardcore",\n\t\t"funkier"\n\t],\n\t"element": [\n\t\t"detectives",\n\t\t"wizards",\n\t\t"magic",\n\t\t"women",\n\t\t"aliens",\n\t\t"fairies",\n\t\t"existentialism",\n\t\t"romance",\n\t\t"more sex",\n\t\t"lesbians",\n\t\t"evil AI",\n\t\t"time travel",\n\t\t"cats",\n\t\t"vampires",\n\t\t"werewolves",\n\t\t"a love triangle",\n\t\t"time travel",\n\t\t"elves",\n\t\t"hackers",\n\t\t"a plot",\n\t\t"secret agents",\n\t\t"robots",\n\t\t"killer robots",\n\t\t"mansplaining",\n\t\t"homoerotic subtext",\n\t\t"robots",\n\t\t"guns",\n\t\t"bigger guns",\n\t\t"hoverboards",\n\t\t"higher stakes",\n\t\t"tights",\n\t\t"lens flares",\n\t\t"teenage drama",\n\t\t"angst",\n\t\t"kaiju",\n\t\t"giant robots",\n\t\t"swords",\n\t\t"bees",\n\t\t"psychic bees",\n\t\t"princesses",\n\t\t"giant swords",\n\t\t"an all female cast",\n\t\t"mutants",\n\t\t"super soldiers",\n\t\t"zombies",\n\t\t"puzzles",\n\t\t"mermaids",\n\t\t"infidelity",\n\t\t"cancer",\n\t\t"economic insecurity",\n\t\t"cuddling",\n\t\t"governnment oppression",\n\t\t"martial arts",\n\t\t"puppies",\n\t\t"car chases",\n\t\t"terrorism",\n\t\t"superheroes",\n\t\t"Norse mythology",\n\t\t"mice",\n\t\t"mutants",\n\t\t"twisted backstories",\n\t\t"hardboiled detectives",\n\t\t"singing",\n\t\t"musical numbers",\n\t\t"an unreliable narrator",\n\t\t"gratuitous sex",\n\t\t"nudity",\n\t\t"a greek chorus",\n\t\t"gender",\n\t\t"mole men",\n\t\t"orcs",\n\t\t"cannibalism",\n\t\t"avocados",\n\t\t"montages",\n\t\t"80s music montages",\n\t\t"valkyries",\n\t\t"vikings",\n\t\t"amazons",\n\t\t"geisha",\n\t\t"llamas",\n\t\t"sirens",\n\t\t"indoor plumbing",\n\t\t"cockney accents",\n\t\t"a creepy little girl",\n\t\t"dogs",\n\t\t"witches",\n\t\t"bioterrorism",\n\t\t"nukes",\n\t\t"runes",\n\t\t"dinosaurs",\n\t\t"caffeine",\n\t\t"recreational drugs",\n\t\t"corporate sponsorship",\n\t\t"single biome planets",\n\t\t"gay robots",\n\t\t"horses",\n\t\t"a nightmare difficulty mode",\n\t\t"squid",\n\t\t"birds",\n\t\t"memes",\n\t\t"breakfast foods",\n\t\t"bondage",\n\t\t"rainbows",\n\t\t"bagpipes",\n\t\t"fashion",\n\t\t"lasers",\n\t\t"goggles",\n\t\t"dragons",\n\t\t"chickens",\n\t\t"penguins",\n\t\t"allegory",\n\t\t"extra apostrophes",\n\t\t"capitalism",\n\t\t"poorly constructed invented languages",\n\t\t"hacking",\n\t\t"airships",\n\t\t"a hedge maze",\n\t\t"pizza",\n\t\t"skyscrapers",\n\t\t"archologies",\n\t\t"glitch art",\n\t\t"murder",\n\t\t"sexy aliens",\n\t\t"weddings",\n\t\t"interpersonal drama",\n\t\t"family drama",\n\t\t"poorly considered worldbuilding",\n\t\t"a laugh track",\n\t\t"alienation",\n\t\t"macroeconomics",\n\t\t"an alien virus",\n\t\t"a minion saying \s"bazinga\s"",\n\t\t"fasism",\n\t\t"an occult hand",\n\t\t"aliens that are obviously stand-ins for the Soviet Union",\n\t\t"moon lawyers",\n\t\t"dragon men",\n\t\t"bagpipes",\n\t\t"actors who appear eerily similar",\n\t\t"a co-op mode",\n\t\t"local multiplayer",\n\t\t"unicorns and rainbows",\n\t\t"pandering references to nerd culture",\n\t\t"more zombies",\n\t\t"a completely unlikeable male protagonist"\n\t],\n\t"format": [\n\t\t"comic",\n\t\t"comic book",\n\t\t"graphic novel",\n\t\t"movie",\n\t\t"novel",\n\t\t"short story",\n\t\t"short story collection",\n\t\t"poetry collection",\n\t\t"twitter bot",\n\t\t"podcast",\n\t\t"video game",\n\t\t"Twine game",\n\t\t"visual novel",\n\t\t"experimental film",\n\t\t"TV series",\n\t\t"play",\n\t\t"stage play",\n\t\t"one-act play",\n\t\t"Netflix original series",\n\t\t"mini-series",\n\t\t"comedy special",\n\t\t"anime",\n\t\t"manga",\n\t\t"rock opera",\n\t\t"installation art piece",\n\t\t"collectible card game",\n\t\t"board game",\n\t\t"documentary",\n\t\t"wildlife documentary",\n\t\t"Lego set",\n\t\t"manifesto",\n\t\t"ballet",\n\t\t"webcomic",\n\t\t"vlog",\n\t\t"painting",\n\t\t"triptych",\n\t\t"novelty twitter account",\n\t\t"amusement park ride",\n\t\t"model railroad layout",\n\t\t"mystery box subscription service",\n\t\t"sitcom",\n\t\t"zine",\n\t\t"shaggy dog story",\n\t\t"sea shanty",\n\t\t"antinovel",\n\t\t"fable",\n\t\t"collection of letters",\n\t\t"psalm",\n\t\t"dirge",\n\t\t"incantation",\n\t\t"novelty popsicle",\n\t\t"lipstick",\n\t\t"magazine",\n\t\t"MySpace page",\n\t\t"music video",\n\t\t"concept album",\n\t\t"tower defense game",\n\t\t"ballad",\n\t\t"Christmas carol",\n\t\t"MUD",\n\t\t"iPhone game",\n\t\t"tableau vivant",\n\t\t"MMO"\n\t],\n\t"writer": [\n\t\t"George Lucas",\n\t\t"Cory Doctorow",\n\t\t"John Scalzi",\n\t\t"George RR Martin",\n\t\t"HP Lovecraft",\n\t\t"John Cage",\n\t\t"Joss Whedon",\n\t\t"John Green",\n\t\t"Studio Ghibli",\n\t\t"Arthur Conan Doyle",\n\t\t"Shakespeare",\n\t\t"Tom Stoppard",\n\t\t"Steven Moffat",\n\t\t"JJ Abrams",\n\t\t"Jim Butcher",\n\t\t"Stephen King",\n\t\t"Dean Koontz",\n\t\t"Anne Rice",\n\t\t"Tolkein",\n\t\t"Malcolm Gladwell",\n\t\t"Adam Sandler",\n\t\t"Douglas Adams",\n\t\t"Chuck Palahniuk",\n\t\t"Bret Easton Ellis",\n\t\t"Alan Moore",\n\t\t"Neil Gaiman",\n\t\t"James Cameron",\n\t\t"Michael Bay",\n\t\t"Frank Miller",\n\t\t"Christopher Nolan",\n\t\t"Russell T Davies",\n\t\t"Bryan Fuller",\n\t\t"Lena Dunham",\n\t\t"M Night Shyamalan",\n\t\t"Hayao Miyazaki",\n\t\t"Walt Disney",\n\t\t"Akira Kurosawa",\n\t\t"Haruki Murakami",\n\t\t"William Gibson",\n\t\t"Neal Stephenson",\n\t\t"Oscar Wilde",\n\t\t"Seth MacFarlane",\n\t\t"Raymond Chandler",\n\t\t"Frank Lloyd Wright",\n\t\t"Kafka",\n\t\t"Nikola Tesla",\n\t\t"Homer",\n\t\t"Terry Pratchett",\n\t\t"Oprah",\n\t\t"Mark Twain",\n\t\t"dril",\n\t\t"Teddy Roosevelt",\n\t\t"Pixar",\n\t\t"Bioware",\n\t\t"Disney",\n\t\t"Pixar",\n\t\t"Tina Fey",\n\t\t"Philip K. Dick",\n\t\t"Wes Anderson",\n\t\t"David Lynch",\n\t\t"Banksy",\n\t\t"Quentin Tarantino",\n\t\t"Sufjan Stevens",\n\t\t"Eddie Izzard",\n\t\t"Janeane Garofalo",\n\t\t"Robin Williams",\n\t\t"Charlie Chaplin",\n\t\t"Lexi Alexander",\n\t\t"Tolstoy",\n\t\t"Martha Stewart",\n\t\t"American Girl",\n\t\t"Salvador Dali",\n\t\t"Brian Eno",\n\t\t"Friedrich Nietzsche",\n\t\t"Foucalt",\n\t\t"Kanye West",\n\t\t"Jhonen Vasquez",\n\t\t"Rebecca Sugar",\n\t\t"Monty Python",\n\t\t"John Cleese",\n\t\t"Fyodor Dostoyevsky",\n\t\t"Will Wright",\n\t\t"Neal Stephenson",\n\t\t"Jim Henson",\n\t\t"Charolette Bronte",\n\t\t"Heinlein",\n\t\t"Marcel Duchamp",\n\t\t"Gene Roddenberry",\n\t\t"Steve Jobs",\n\t\t"Nintendo",\n\t\t"Adult Swim",\n\t\t"Lisa Frank",\n\t\t"Michael Moore",\n\t\t"Jane Austen",\n\t\t"SkyMall",\n\t\t"Virginia Woolf ",\n\t\t"The Brothers Grimm",\n\t\t"Hans Christian Andersen",\n\t\t"Devo",\n\t\t"Bjork",\n\t\t"Kraftwerk",\n\t\t"Anne Bronte",\n\t\t"Shirley Jackson",\n\t\t"Kevin Smith",\n\t\t"Steve Jackson Games",\n\t\t"Jack Kerouac",\n\t\t"Dr. Seuss",\n\t\t"Shel Silverstein",\n\t\t"Roald Dahl",\n\t\t"Rob Liefeld",\n\t\t"Judy Blume",\n\t\t"Eric Carle",\n\t\t"Emily Dickinson",\n\t\t"Sappho",\n\t\t"Anne McCaffrey",\n\t\t"R. A. Salvatore",\n\t\t"Jasper Fforde",\n\t\t"Iain Banks",\n\t\t"Connie Willis",\n\t\t"Kage Baker",\n\t\t"Lord Byron",\n\t\t"Mary Shelley",\n\t\t"Jules Verne",\n\t\t"HG Wells",\n\t\t"Tennyson",\n\t\t"Machiavelli",\n\t\t"Aleister Crowley",\n\t\t"Karl Marx",\n\t\t"CS Lewis",\n\t\t"William S. Burroughs",\n\t\t"Confucius",\n\t\t"Vātsyāyana"\n\t],\n\t"genre": [\n\t\t"cyberpunk",\n\t\t"biopunk",\n\t\t"horror",\n\t\t"feminist",\n\t\t"Lovecraftian",\n\t\t"hard sci-fi",\n\t\t"paranormal",\n\t\t"paranormal romance",\n\t\t"post-futurist",\n\t\t"queer",\n\t\t"western",\n\t\t"crowdsourced",\n\t\t"apocalyptic",\n\t\t"Christian fiction",\n\t\t"steampunk",\n\t\t"retrofuturistic",\n\t\t"epic fantasy",\n\t\t"noir",\n\t\t"magical realism",\n\t\t"swashbuckling",\n\t\t"musical",\n\t\t"operatic",\n\t\t"furry",\n\t\t"space opera",\n\t\t"solarpunk",\n\t\t"psychadelic",\n\t\t"alternate history",\n\t\t"super sentai",\n\t\t"dada",\n\t\t"socialist",\n\t\t"legal thriller",\n\t\t"thriller",\n\t\t"courtroom drama",\n\t\t"dramedy",\n\t\t"brutalist",\n\t\t"Art Deco",\n\t\t"gothic",\n\t\t"regency romance",\n\t\t"Western",\n\t\t"erotica",\n\t\t"political satire",\n\t\t"pulp",\n\t\t"fantasy of manners",\n\t\t"superhero",\n\t\t"comic fantasy",\n\t\t"splatterpunk",\n\t\t"southern gothic",\n\t\t"Lovecraftian",\n\t\t"occult detective",\n\t\t"nanopunk",\n\t\t"atompunk",\n\t\t"alternate history",\n\t\t"medical thriller",\n\t\t"melodramatic",\n\t\t"yaoi",\n\t\t"yuri",\n\t\t"first-person shooter",\n\t\t"roguelike",\n\t\t"mecha",\n\t\t"death metal",\n\t\t"filk",\n\t\t"swing house",\n\t\t"platformer",\n\t\t"avant-garde",\n\t\t"big band",\n\t\t"chiptune",\n\t\t"math rock",\n\t\t"pop punk",\n\t\t"edutainment"\n\t],\n\t"setting": [\n\t\t"in space",\n\t\t"on spaceships",\n\t\t"in a magic school",\n\t\t"in the Wild West",\n\t\t"during the Regency",\n\t\t"in modern New York City",\n\t\t"in a coffee shop",\n\t\t"in Arthurian England",\n\t\t"in the future",\n\t\t"in a futuristic Tokyo",\n\t\t"in an alternate universe where the Confederacy won the Civil War",\n\t\t"in an alternate universe where the Nazis won WWII",\n\t\t"on a deserted island",\n\t\t"in an abandoned warehouse",\n\t\t"in an abandoned factory",\n\t\t"in a spy agency",\n\t\t"on a train",\n\t\t"on a college campus",\n\t\t"in a prestigious private boarding school",\n\t\t"in a bookstore",\n\t\t"in a quaint English village",\n\t\t"in a modern high school",\n\t\t"in a country manor",\n\t\t"in Victorian London",\n\t\t"in cyberspace",\n\t\t"during the zombie apocalypse",\n\t\t"in an alternate universe where Leo DiCaprio has won an Oscar",\n\t\t"in a 1950s ad agency",\n\t\t"in a bar",\n\t\t"on the high seas",\n\t\t"on a road trip",\n\t\t"in Atlantis",\n\t\t"in Feudal Japan",\n\t\t"in Greenwich Village",\n\t\t"in a DMV",\n\t\t"in a capitalist dystopia",\n\t\t"in a nudist colony",\n\t\t"in a spooky deserted city",\n\t\t"in a library",\n\t\t"during a war between magic and technology",\n\t\t"in a sewer",\n\t\t"in a jungle",\n\t\t"in a tomb",\n\t\t"in a rural medieval village",\n\t\t"in the BBC Quarry",\n\t\t"on a beach",\n\t\t"in an onsen",\n\t\t"in a strip club",\n\t\t"in the undercity",\n\t\t"in Venice",\n\t\t"on airships",\n\t\t"in a gayborhood",\n\t\t"in a diner",\n\t\t"in an abandoned mine",\n\t\t"in a haunted house",\n\t\t"in a hidden village of forest elves",\n\t\t"in a hospital",\n\t\t"in a matriarchal society",\n\t\t"in a magic library",\n\t\t"in a 50s malt shop",\n\t\t"in a casino",\n\t\t"in the New York subway system",\n\t\t"at sea",\n\t\t"entirely in a mall",\n\t\t"underground",\n\t\t"in a bouncy castle",\n\t\t"in the antebellum South",\n\t\t"in a Southern manor"\n\t],\n\t"storytype": [\n\t\t"coming-of-age story",\n\t\t"rags to riches story",\n\t\t"adventure",\n\t\t"mystery",\n\t\t"allegory",\n\t\t"bildungsroman",\n\t\t"whodunnit"\n\t],\n\t"imagine": [\n\t\t"Imagine",\n\t\t"Picture",\n\t\t"Think about",\n\t\t"Just imagine",\n\t\t"I need you to picture",\n\t\t"OK, so picture",\n\t\t"Picture this:",\n\t\t"Imagine this:"\n\t],\n\t"character": [\n\t\t"Yoda",\n\t\t"Dumbledore",\n\t\t"Steve Rogers",\n\t\t"Superman",\n\t\t"Lex Luthor",\n\t\t"Han Solo",\n\t\t"Al Gore",\n\t\t"Teddy Roosevelt",\n\t\t"Miss Havisham",\n\t\t"Aragorn",\n\t\t"Bilbo Baggins",\n\t\t"Severus Snape",\n\t\t"Samuel L Jackson",\n\t\t"Tyler Durden",\n\t\t"Cloud Strife",\n\t\t"Luigi",\n\t\t"Bowser",\n\t\t"Benedict Cumberbatch",\n\t\t"Luke Cage",\n\t\t"Holden Caulfield",\n\t\t"Fox Mulder",\n\t\t"Dana Scully",\n\t\t"HK-47",\n\t\t"Natalie Dormer",\n\t\t"Joseph Gordon-Levitt",\n\t\t"Black Widow",\n\t\t"Ellen Ripley",\n\t\t"Sherlock Holmes",\n\t\t"Alyson Hannigan",\n\t\t"Wil Wheaton",\n\t\t"Jason Segal",\n\t\t"GLaDOS",\n\t\t"Lupita Nyong'o",\n\t\t"Cthulhu",\n\t\t"Khorne",\n\t\t"Jughead",\n\t\t"James Bond",\n\t\t"Arnold Schwarzenegger",\n\t\t"Lestat",\n\t\t"Hannibal Lecter",\n\t\t"Idris Elba",\n\t\t"Commander Shepard",\n\t\t"BB-8",\n\t\t"Meryl Streep",\n\t\t"Merlin",\n\t\t"Caliban",\n\t\t"Steve Irwin",\n\t\t"Stephen Colbert",\n\t\t"Hugo Weaving",\n\t\t"Sephiroth",\n\t\t"John Galt",\n\t\t"Nicki Minaj",\n\t\t"Snoopy",\n\t\t"Siri",\n\t\t"Strong Bad",\n\t\t"Clippy",\n\t\t"Elmo",\n\t\t"Johnny Depp",\n\t\t"Scrooge",\n\t\t"Scrooge McDuck",\n\t\t"Bugs Bunny",\n\t\t"Robert Oppenheimer",\n\t\t"Martin Sheen",\n\t\t"Oscar Isaac",\n\t\t"Kermit",\n\t\t"Miss Piggy",\n\t\t"Carmen Sandiego",\n\t\t"Chewbacca",\n\t\t"Pikachu",\n\t\t"Picard",\n\t\t"Riker",\n\t\t"Worf",\n\t\t"Kirk",\n\t\t"Spock",\n\t\t"Data",\n\t\t"GIR",\n\t\t"Leslie Knope",\n\t\t"Ron Swanson",\n\t\t"Puppycat",\n\t\t"Deadpool",\n\t\t"Captain Ahab",\n\t\t"Lucifer",\n\t\t"Batman",\n\t\t"Tony Stark",\n\t\t"Wonder Woman",\n\t\t"Alfred",\n\t\t"Betty Crocker",\n\t\t"The Energizer Bunny",\n\t\t"Pippi Longstocking",\n\t\t"Legolas"\n\t],\n\t"support": [\n\t\t"Please support my",\n\t\t"Kickstart this",\n\t\t"Crowdfund this",\n\t\t"Crowdfund a",\n\t\t"Kickstart this",\n\t\t"This will be groundbreaking: "\n\t],\n\t"role": [\n\t\t"villain",\n\t\t"antagonist",\n\t\t"protagonist",\n\t\t"love interest",\n\t\t"sidekick",\n\t\t"damsel in distress",\n\t\t"mentor",\n\t\t"butler",\n\t\t"murderer",\n\t\t"detective",\n\t\t"president",\n\t\t"best friend",\n\t\t"misunderstood genius",\n\t\t"ghost",\n\t\t"evil old man",\n\t\t"witch",\n\t\t"evil dictator",\n\t\t"devil",\n\t\t"antihero",\n\t\t"foil",\n\t\t"ninja"\n\t],\n\t"audience": [\n\t\t"kids",\n\t\t"families",\n\t\t"atheists",\n\t\t"libertarians",\n\t\t"Christians",\n\t\t"cats",\n\t\t"nerds",\n\t\t"geeks",\n\t\t"toddlers",\n\t\t"assholes",\n\t\t"millennials",\n\t\t"teens",\n\t\t"tweens",\n\t\t"hipsters",\n\t\t"modern audiences",\n\t\t"moms",\n\t\t"dads",\n\t\t"young adults",\n\t\t"men's rights activists",\n\t\t"fascists",\n\t\t"stoners"\n\t]\n}\n
v.2016-09-05
//requires jquery\n\n// input: an array of objects\n//\t\t a property that each of those object have\n// output: an array of the properties of all the objects\nwindow.skimObjectArray = function(objectArray, property){\n\tconsole.log("skimObjectArray(", "objectArray", objectArray, "property", property, ")")\n\tvar values = [];\n\n\tfor (var i = 0; i < objectArray.length; i++) {\n\t\tvar thingToAdd = objectArray[i][property];\n\t\tif(typeof thingToAdd === "object"){\n\t\t\t// i hope to god this works\n\t\t\tthingToAdd = objectArray[i][property].join("\sn")\n\t\t}\n\t\tvalues.push( thingToAdd );\n\t};\n\n\tvalues = values.join("\sn");\n\tvalues = values.split("\sn")\n\n\treturn values;\n}\n\nStory.prototype.appendCorpora = function(){\n\tvar corporaToAppend = tale.lookup("tags", "corpus");\n\tif(!corporaToAppend.length) return;\n\n\tfor(var i in corporaToAppend){\n\t\tvar currentPassage = corporaToAppend[i].title;\n\n\t\t// the rules are the concatenation of each symbol in this passage\n\t\tvar rules = [];\n\t\tvar lines = tale.passages[currentPassage].text.split("\sn")\n\t\tfor(var j in lines){\n\t\t\tvar line = lines[j];\n\t\t\tvar location = line.split("#");\n\t\t\tconsole.log("location: ", location);\n\t\t\tvar corpusLocation = location[0];\n\n\t\t\t// fetch me that sweet sweet boy\n\t\t\tvar corpus = $.ajax({\n\t\t\t\tdataType: "json",\n\t\t\t\turl: corpusLocation,\n\t\t\t\tasync: false\n\t\t\t});\n\t\t\tcorpus = corpus.responseJSON;\n\n\t\t\t// drill down to the array we want\n\t\t\tfor (var i = 1; i < location.length; i++) {\n\t\t\t\tconsole.log("corpus: ", corpus);\n\t\t\t\t// if there's a ! at the beginning of a location, skim the objArray for that property\n\t\t\t\tif(location[i][0] === "!"){\n\t\t\t\t\tcorpus = skimObjectArray(corpus, location[i].substring(1));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcorpus = corpus[ location[i] ]\n\t\t\t};\n\n\t\t\tconsole.log("corpus: ", corpus);\n\t\t\t// add this into the symbol-in-progress\n\t\t\trules = rules.concat(corpus);\n\t\t\tconsole.log("rules: ", rules)\n\t\t}\n\n\t\t// the name of this symbol is the name of the passage\n\t\tvar finalJSON = "{ \s"" + currentPassage + "\s": " + JSON.stringify(rules) + " }";\n\n\t\t// save our dark deeds to the passage\n\t\ttale.passages[currentPassage].text = finalJSON;\n\n\t\t//tag this as JSON so it gets appended in the next step\n\t\ttale.passages[currentPassage].tags.push("JSON")\n\t}\n\n\tconsole.log("corpora loaded")\n}\n\nStory.prototype.appendJSON = function() {\n\tvar JSONtoAppend = tale.lookup("tags", "JSON");\n\tif(!JSONtoAppend.length) return;\n\n\tfor(i in JSONtoAppend){\n\t\tvar newJSON = JSON.parse(JSONtoAppend[i].text);\n\t\t$.extend(this.data, newJSON);\n\t}\n\tconsole.log("JSON appended");\n}\n\nfunction Story(){\n\tvar grammars = tale.lookup("tags", "grammar", "title");\n\tthis.data = {};\n\n\tvar links = /(\s[\s[\sb)(.+?)(\sb\s]\s])/g;\n\tvar sublinks = /([^\s[\s]]+)*(.+)/\n\n\tfunction convertSyntax(match, p1, p2, p3){\n\t\t// If a passage is invoked that's tagged as a grammar, change Twine links into Tracery symbols.\n\t\t// e.g.: [[animal]] => #animal#\n\t\t// e.g.: [[animal][capitalize]] => #animal.capitalize#\n\n\t\t// p1 is left brackets, p3 is right brackets\n\t\tvar targetLink = p2.split("][")[0];\n\t\tvar modifiers = p2.split("][").slice(1, p2.length).join(".");\n\t\tmodifiers = modifiers?("." + modifiers):"";\n\t\t\n\t\tvar trace = "#" + targetLink + modifiers + "#";\n\t\t\n\t\tvar linkIsGrammar = false;\n\t\tvar tags = tale.get(targetLink).tags\n\t\tfor(var i = 0; i < tags.length; i++){\n\t\t\tif(tags[i] == "grammar" || tags[i] == "corpus"){\n\t\t\t\tlinkIsGrammar = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn linkIsGrammar?trace:match;\n\t}\n\n\tfor(var i in grammars){\n\t\tif(grammars[i] == undefined) continue;\n\n\t\t// Passage names become grammar names, Passage text becomes grammar text. \n\t\tvar newSymbol = grammars[i].title\n\t\tvar newText = grammars[i].text\n\n\t\tvar link = /(\s[\s[\sb)(.+?)(\sb\s]\s])/g;\n\t\tnewText = newText.replace(link, convertSyntax);\n\t\t// Get everything that's being linked to.\n\n\t\tthis.data[newSymbol] = newText.split('\sn');\n\t}\n\n\tthis.appendCorpora();\n\tthis.appendJSON();\n\tconsole.log("Story: ", this);\n}\nStory.prototype.constructor = Story;\n\n// Append this to the tale object because I don't know where else to put it.\nTale.prototype.story = new Story();\n\nStory.prototype.toHTML = function() {\n\tvar output = [];\n\tvar tab = " ";\n\tvar beg = '\sn' + tab + "\s"<span class=\s"grammarContents\s">{{{"\n\tvar end = "}}}</span>\s""\n\n\tfor(var i in this.data){\n\t\tvar gram = "<span class=\s"grammarTitle\s">\s"" + i + "\s"</span>: [";\n\t\tgram += beg + this.data[i].join(end + ',' + beg) + end;\n\t\tgram += "]";\n\t\toutput.push(gram);\n\t}\n\treturn "{\sn" + output.join(",\sn") + "\sn}";\n}\n\nTale.prototype.JSONtoTwee = function() {\n\tvar JSONtoConvert = tale.lookup("tags", "JSON");\n\tvar combinedJSON = ""\n\n\tfor (var i in JSONtoConvert){\n\t\tcombinedJSON += JSONtoConvert[i].text;\n\t}\n\n\t// Note the {{{}}} delimiters in textPost. This is intended for display in Twine, so\n\t// if you're just running these raw they aren't necessary.\n\tvar regex = {titlesPre: /\st"(.+)": \s[/g, titlesPost: "<br>:: $1 [grammar]",\n\t\t\t\t textPre: /\st*"(.+)",*(?:\sn\st)?(?:\s],)*\sn/g, textPost: "{{{$1}}}<br>"}\n\n\tvar tweeOutput = combinedJSON.replace(regex.titlesPre, regex.titlesPost);\n\ttweeOutput = tweeOutput.replace(regex.textPre, regex.textPost);\n\ttweeOutput = tweeOutput.replace(/({\sn)|(]\sn})/g, "")\n\n\treturn tweeOutput;\n}
window.tracery = {\n utilities : {}\n};\n\n(function () {/**\n * @author Kate Compton\n */\n\nfunction inQuotes(s) {\n return '"' + s + '"';\n};\n\nfunction parseAction(action) {\n return action;\n};\n\n// tag format\n// a thing to expand, plus actions\n\nfunction parseTag(tag) {\n var errors = [];\n var prefxns = [];\n var postfxns = [];\n\n var lvl = 0;\n var start = 0;\n\n var inPre = true;\n\n var symbol,\n mods;\n\n function nonAction(end) {\n if (start !== end) {\n var section = tag.substring(start, end);\n if (!inPre) {\n errors.push("multiple possible expansion symbols in tag!" + tag);\n } else {\n inPre = false;\n var split = section.split(".");\n symbol = split[0];\n mods = split.slice(1, split.length);\n }\n\n }\n start = end;\n };\n\n for (var i = 0; i < tag.length; i++) {\n var c = tag.charAt(i);\n\n switch(c) {\n case '[':\n if (lvl === 0) {\n nonAction(i);\n }\n\n lvl++;\n break;\n case ']':\n lvl--;\n if (lvl === 0) {\n var section = tag.substring(start + 1, i);\n if (inPre)\n prefxns.push(parseAction(section));\n else\n postfxns.push(parseAction(section));\n start = i + 1;\n }\n break;\n\n default:\n if (lvl === 0) {\n\n }\n break;\n\n }\n }\n nonAction(i);\n\n if (lvl > 0) {\n var error = "Too many '[' in rule " + inQuotes(tag);\n errors.push(error);\n\n }\n\n if (lvl < 0) {\n var error = "Too many ']' in rule " + inQuotes(tag);\n errors.push(error);\n\n }\n\n return {\n preActions : prefxns,\n postActions : postfxns,\n symbol : symbol,\n mods : mods,\n raw : tag,\n errors : errors,\n };\n};\n\n// Split a rule into sections\nfunction parseRule(rule) {\n var sections = [];\n var errors = [];\n if (!( typeof rule == 'string' || rule instanceof String)) {\n errors.push("Cannot parse non-string rule " + rule);\n sections.errors = errors;\n return sections;\n }\n\n if (rule.length === 0) {\n return [];\n }\n\n var lvl = 0;\n var start = 0;\n var inTag = false;\n\n function createSection(end) {\n var section = rule.substring(start, end);\n if (section.length > 0) {\n if (inTag)\n sections.push(parseTag(section));\n else\n sections.push(section);\n }\n inTag = !inTag;\n start = end + 1;\n\n }\n\n for (var i = 0; i < rule.length; i++) {\n var c = rule.charAt(i);\n\n switch(c) {\n case '[':\n lvl++;\n break;\n case ']':\n lvl--;\n break;\n case '#':\n if (lvl === 0) {\n createSection(i);\n }\n break;\n default:\n break;\n\n }\n\n }\n\n if (lvl > 0) {\n var error = "Too many '[' in rule " + inQuotes(rule);\n errors.push(error);\n\n }\n\n if (lvl < 0) {\n var error = "Too many ']' in rule " + inQuotes(rule);\n errors.push(error);\n\n }\n\n if (inTag) {\n var error = "Odd number of '#' in rule " + inQuotes(rule);\n errors.push(error);\n }\n\n createSection(rule.length);\n sections.errors = errors;\n return sections;\n};\n\nfunction testParse(rule, shouldFail) {\n console.log("-------");\n console.log("Test parse rule: " + inQuotes(rule) + " " + shouldFail);\n var parsed = parseRule(rule);\n if (parsed.errors && parsed.errors.length > 0) {\n for (var i = 0; i < parsed.errors.length; i++) {\n console.log(parsed.errors[i]);\n }\n }\n \n\n}\n\nfunction testParseTag(tag, shouldFail) {\n console.log("-------");\n console.log("Test parse tag: " + inQuotes(tag) + " " + shouldFail);\n var parsed = parseTag(tag);\n if (parsed.errors && parsed.errors.length > 0) {\n for (var i = 0; i < parsed.errors.length; i++) {\n console.log(parsed.errors[i]);\n }\n }\n}\n\ntracery.testParse = testParse;\ntracery.testParseTag = testParseTag;\ntracery.parseRule = parseRule;\ntracery.parseTag = parseTag;\n\n\nfunction spacer(size) {\n var s = "";\n for (var i = 0; i < size * 3; i++) {\n s += " ";\n }\n return s;\n}\n\n/* Simple JavaScript Inheritance\n * By John Resig http://ejohn.org/\n * MIT Licensed.\n */\n\nfunction extend(destination, source) {\n for (var k in source) {\n if (source.hasOwnProperty(k)) {\n destination[k] = source[k];\n }\n }\n return destination;\n}\n\n// Inspired by base2 and Prototype\n(function() {\n var initializing = false,\n fnTest = /xyz/.test(function() { xyz;\n }) ? /\sb_super\sb/ : /.*/;\n\n // The base Class implementation (does nothing)\n this.Class = function() {\n };\n\n // Create a new Class that inherits from this class\n Class.extend = function(prop) {\n var _super = this.prototype;\n\n // Instantiate a base class (but only create the instance,\n // don't run the init constructor)\n initializing = true;\n var prototype = new this();\n initializing = false;\n\n // Copy the properties over onto the new prototype\n for (var name in prop) {\n // Check if we're overwriting an existing function\n prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn) {\n return function() {\n var tmp = this._super;\n\n // Add a new ._super() method that is the same method\n // but on the super-class\n this._super = _super[name];\n\n // The method only need to be bound temporarily, so we\n // remove it when we're done executing\n var ret = fn.apply(this, arguments);\n this._super = tmp;\n\n return ret;\n };\n })(name, prop[name]) : prop[name];\n }\n\n // The dummy class constructor\n function Class() {\n // All construction is actually done in the init method\n if (!initializing && this.init)\n this.init.apply(this, arguments);\n }\n\n // Populate our constructed prototype object\n Class.prototype = prototype;\n\n // Enforce the constructor to be what we expect\n Class.prototype.constructor = Class;\n\n // And make this class extendable\n Class.extend = arguments.callee;\n\n return Class;\n };\n})();\n\n/**\n * @author Kate\n */\n\nvar Rule = function(raw) {\n this.raw = raw;\n this.sections = parseRule(raw);\n\n};\n\nRule.prototype.getParsed = function() {\n if (!this.sections)\n this.sections = parseRule(raw);\n\n return this.sections;\n};\n\nRule.prototype.toString = function() {\n return this.raw;\n};\n\nRule.prototype.toJSONString = function() {\n return this.raw;\n};\n\n/**\n * @author Kate\n */\n\nvar RuleWeighting = Object.freeze({\n RED : 0,\n GREEN : 1,\n BLUE : 2\n});\n\nvar RuleSet = function(rules) {\n // is the rules obj an array? A RuleSet, or a string?\n if (rules.constructor === Array) {\n // make a copy\n rules = rules.slice(0, rules.length);\n } else if (rules.prototype === RuleSet) {\n // clone\n } else if ( typeof rules == 'string' || rules instanceof String) {\n var args = Array.prototype.slice.call(arguments);\n rules = args;\n } else {\n console.log(rules);\n throw ("creating ruleset with unknown object type!");\n }\n\n // create rules and their use counts\n\n this.rules = rules;\n this.parseAll();\n\n this.uses = [];\n this.startUses = [];\n this.totalUses = 0;\n for (var i = 0; i < this.rules.length; i++) {\n this.uses[i] = 0;\n this.startUses[i] = this.uses[i];\n this.totalUses += this.uses[i];\n }\n\n};\n\n//========================================================\n// Iterating over rules\n\nRuleSet.prototype.parseAll = function(fxn) {\n for (var i = 0; i < this.rules.length; i++) {\n if (this.rules[i].prototype !== Rule)\n this.rules[i] = new Rule(this.rules[i]);\n }\n\n};\n\n//========================================================\n// Iterating over rules\n\nRuleSet.prototype.mapRules = function(fxn) {\n return this.rules.map(function(rule, index) {\n return fxn(rule, index);\n });\n};\n\nRuleSet.prototype.applyToRules = function(fxn) {\n for (var i = 0; i < this.rules.length; i++) {\n fxn(this.rules[i], i);\n }\n};\n//========================================================\nRuleSet.prototype.get = function() {\n var index = this.getIndex();\n\n return this.rules[index];\n};\n\nRuleSet.prototype.getRandomIndex = function() {\n return Math.floor(this.uses.length * Math.random());\n};\n\nRuleSet.prototype.getIndex = function() {\n // Weighted distribution\n // Imagine a bar of length 1, how to divide the length\n // s.t. a random dist will result in the dist we want?\n\n var index = this.getRandomIndex();\n // What if the uses determine the chance of rerolling?\n\n var median = this.totalUses / this.uses.length;\n\n var count = 0;\n while (this.uses[index] > median && count < 20) {\n index = this.getRandomIndex();\n count++;\n }\n\n // reroll more likely if index is too much higher\n\n return index;\n};\n\nRuleSet.prototype.decayUses = function(pct) {\n this.totalUses = 0;\n for (var i = 0; i < this.uses; i++) {\n\n this.uses[index] *= 1 - pct;\n this.totalUses += this.uses[index];\n }\n};\n\nRuleSet.prototype.testRandom = function() {\n console.log("Test random");\n var counts = [];\n for (var i = 0; i < this.uses.length; i++) {\n counts[i] = 0;\n }\n\n var testCount = 10 * this.uses.length;\n for (var i = 0; i < testCount; i++) {\n\n var index = this.getIndex();\n this.uses[index] += 1;\n\n counts[index]++;\n this.decayUses(.1);\n }\n\n for (var i = 0; i < this.uses.length; i++) {\n console.log(i + ":\st" + counts[i] + " \st" + this.uses[i]);\n }\n};\n\nRuleSet.prototype.getSaveRules = function() {\n var jsonRules = this.rules.map(function(rule) {\n return rule.toJSONString();\n });\n\n return jsonRules;\n};\n\n/**\n * @author Kate Compton\n */\n\nvar Action = function(node, raw) {\n\n this.node = node;\n this.grammar = node.grammar;\n this.raw = raw;\n\n};\n\nAction.prototype.activate = function() {\n\n var node = this.node;\n node.actions.push(this);\n\n // replace any hashtags\n this.amended = this.grammar.flatten(this.raw);\n\n var parsed = parseTag(this.amended);\n var subActionRaw = parsed.preActions;\n if (subActionRaw && subActionRaw.length > 0) {\n this.subactions = subActionRaw.map(function(action) {\n return new Action(node, action);\n });\n\n }\n\n if (parsed.symbol) {\n var split = parsed.symbol.split(":");\n\n if (split.length === 2) {\n this.push = {\n symbol : split[0],\n\n // split into multiple rules\n rules : split[1].split(","),\n };\n // push\n node.grammar.pushRules(this.push.symbol, this.push.rules);\n\n } else\n throw ("Unknown action: " + parsed.symbol);\n }\n\n if (this.subactions) {\n for (var i = 0; i < this.subactions.length; i++) {\n this.subactions[i].activate();\n }\n }\n\n};\n\nAction.prototype.deactivate = function() {\n if (this.subactions) {\n for (var i = 0; i < this.subactions.length; i++) {\n this.subactions[i].deactivate();\n }\n }\n\n if (this.push) {\n this.node.grammar.popRules(this.push.symbol, this.push.rules);\n }\n};\n\n/**\n * @author Kate Compton\n */\n\nvar isConsonant = function(c) {\n c = c.toLowerCase();\n switch(c) {\n case 'a':\n return false;\n case 'e':\n return false;\n case 'i':\n return false;\n case 'o':\n return false;\n case 'u':\n return false;\n\n }\n return true;\n};\n\nfunction endsWithConY(s) {\n if (s.charAt(s.length - 1) === 'y') {\n return isConsonant(s.charAt(s.length - 2));\n }\n return false;\n};\n\nvar universalModifiers = {\n capitalizeAll : function(s) {\n return s.replace(/(?:^|\ss)\sS/g, function(a) {\n return a.toUpperCase();\n });\n\n },\n\n capitalize : function(s) {\n return s.charAt(0).toUpperCase() + s.slice(1);\n\n },\n\n inQuotes : function(s) {\n return '"' + s + '"';\n },\n\n comma : function(s) {\n var last = s.charAt(s.length - 1);\n if (last === ",")\n return s;\n if (last === ".")\n return s;\n if (last === "?")\n return s;\n if (last === "!")\n return s;\n return s + ",";\n },\n\n beeSpeak : function(s) {\n // s = s.replace("s", "zzz");\n\n s = s.replace(/s/, 'zzz');\n return s;\n },\n\n a : function(s) {\n if (!isConsonant(s.charAt()))\n return "an " + s;\n return "a " + s;\n\n },\n\n s : function(s) {\n\n var last = s.charAt(s.length - 1);\n\n switch(last) {\n case 'y':\n\n // rays, convoys\n if (!isConsonant(s.charAt(s.length - 2))) {\n return s + "s";\n }\n // harpies, cries\n else {\n return s.slice(0, s.length - 1) + "ies";\n }\n break;\n\n // oxen, boxen, foxen\n case 'x':\n return s.slice(0, s.length - 1) + "en";\n case 'z':\n return s.slice(0, s.length - 1) + "es";\n case 'h':\n return s.slice(0, s.length - 1) + "es";\n\n default:\n return s + "s";\n };\n\n },\n\n ed : function(s) {\n\n var index = s.indexOf(" ");\n var s = s;\n var rest = "";\n if (index > 0) {\n rest = s.substring(index, s.length);\n s = s.substring(0, index);\n\n }\n\n var last = s.charAt(s.length - 1);\n\n switch(last) {\n case 'y':\n\n // rays, convoys\n if (isConsonant(s.charAt(s.length - 2))) {\n return s.slice(0, s.length - 1) + "ied" + rest;\n\n }\n // harpies, cries\n else {\n return s + "ed" + rest;\n }\n break;\n case 'e':\n return s + "d" + rest;\n\n break;\n\n default:\n return s + "ed" + rest;\n };\n }\n};\n/**\n * @author Kate Compton\n */\n\n// A tracery expansion node\nvar nodeCount = 0;\n\nvar ExpansionNode = Class.extend({\n init : function() {\n this.depth = 0;\n this.id = nodeCount;\n nodeCount++;\n this.childText = "[[UNEXPANDED]]";\n },\n\n setParent : function(parent) {\n if (parent) {\n this.depth = parent.depth + 1;\n this.parent = parent;\n this.grammar = parent.grammar;\n }\n },\n\n expand : function() {\n // do nothing\n return "???";\n },\n\n expandChildren : function() {\n\n if (this.children) {\n this.childText = "";\n for (var i = 0; i < this.children.length; i++) {\n this.children[i].expand();\n this.childText += this.children[i].finalText;\n }\n this.finalText = this.childText;\n }\n\n },\n\n createChildrenFromSections : function(sections) {\n var root = this;\n this.children = sections.map(function(section) {\n\n if ( typeof section == 'string' || section instanceof String) {\n // Plaintext\n return new TextNode(root, section);\n } else {\n return new TagNode(root, section);\n }\n });\n }\n});\n\nvar RootNode = ExpansionNode.extend({\n init : function(grammar, rawRule) {\n this._super();\n this.grammar = grammar;\n this.parsedRule = parseRule(rawRule);\n },\n\n expand : function() {\n var root = this;\n this.createChildrenFromSections(this.parsedRule);\n\n // expand the children\n this.expandChildren();\n },\n});\n\nvar TagNode = ExpansionNode.extend({\n init : function(parent, parsedTag) {\n this._super();\n\n if (!(parsedTag !== null && typeof parsedTag === 'object')) {\n if ( typeof parsedTag == 'string' || parsedTag instanceof String) {\n console.warn("Can't make tagNode from unparsed string!");\n parsedTag = parseTag(parsedTag);\n\n } else {\n console.log("Unknown tagNode input: ", parsedTag);\n throw ("Can't make tagNode from strange tag!");\n\n }\n }\n\n this.setParent(parent);\n $.extend(this, parsedTag);\n },\n\n expand : function() {\n if (tracery.outputExpansionTrace)\n console.log(r.sections);\n\n this.rule = this.grammar.getRule(this.symbol);\n\n this.actions = [];\n\n // Parse the rule if it hasn't been already\n this.createChildrenFromSections(this.rule.getParsed());\n\n // Do any pre-expansion actions!\n for (var i = 0; i < this.preActions.length; i++) {\n var action = new Action(this, this.preActions[i]);\n action.activate();\n }\n\n // Map each child section to a node\n if (!this.rule.sections)\n console.log(this.rule);\n\n this.expandChildren();\n\n for (var i = 0; i < this.actions.length; i++) {\n\n this.actions[i].deactivate();\n }\n\n this.finalText = this.childText;\n for (var i = 0; i < this.mods.length; i++) {\n this.finalText = this.grammar.applyMod(this.mods[i], this.finalText);\n }\n\n },\n\n toLabel : function() {\n return this.symbol;\n },\n toString : function() {\n return "TagNode '" + this.symbol + "' mods:" + this.mods + ", preactions:" + this.preActions + ", postactions" + this.postActions;\n }\n});\n\nvar TextNode = ExpansionNode.extend({\n isLeaf : true,\n init : function(parent, text) {\n this._super();\n\n this.setParent(parent);\n\n this.text = text;\n\n this.finalText = text;\n },\n expand : function() {\n // do nothing\n },\n\n toLabel : function() {\n return this.text;\n }\n});\n\n/**\n * @author Kate Compton\n */\n\nfunction Symbol(grammar, key) {\n this.grammar = grammar;\n this.key = key;\n this.currentRules = undefined;\n this.ruleSets = [];\n\n};\n\nSymbol.prototype.loadFrom = function(rules) {\n\n rules = this.wrapRules(rules);\n this.baseRules = rules;\n\n this.ruleSets.push(rules);\n this.currentRules = this.ruleSets[this.ruleSets.length - 1];\n\n};\n\n//========================================================\n// Iterating over rules\n\nSymbol.prototype.mapRules = function(fxn) {\n\n return this.currentRules.mapRules(fxn);\n};\n\nSymbol.prototype.applyToRules = function(fxn) {\n this.currentRules.applyToRules(fxn);\n};\n\n//==================================================\n// Rule pushpops\nSymbol.prototype.wrapRules = function(rules) {\n if (rules.prototype !== RuleSet) {\n if (Array.isArray(rules)) {\n return new RuleSet(rules);\n } else if ( typeof rules == 'string' || rules instanceof String) {\n return new RuleSet(rules);\n } else {\n throw ("Unknown rules type: " + rules);\n }\n }\n // already a ruleset\n return rules;\n};\n\nSymbol.prototype.pushRules = function(rules) {\n rules = this.wrapRules(rules);\n this.ruleSets.push(rules);\n this.currentRules = this.ruleSets[this.ruleSets.length - 1];\n};\n\nSymbol.prototype.popRules = function() {\n var exRules = this.ruleSets.pop();\n\n if (this.ruleSets.length === 0) {\n //console.warn("No more rules for " + this + "!");\n }\n this.currentRules = this.ruleSets[this.ruleSets.length - 1];\n};\n\n// Clear everything and set the rules\nSymbol.prototype.setRules = function(rules) {\n\n rules = this.wrapRules(rules);\n this.ruleSets = [rules];\n this.currentRules = rules;\n\n};\n\nSymbol.prototype.addRule = function(rule) {\n this.currentRules.addRule(seed);\n};\n\n//========================================================\n// selection\n\nSymbol.prototype.select = function() {\n this.isSelected = true;\n\n};\n\nSymbol.prototype.deselect = function() {\n this.isSelected = false;\n};\n\n//==================================================\n// Getters\n\nSymbol.prototype.getRule = function(seed) {\n return this.currentRules.get(seed);\n};\n\n//==================================================\n\nSymbol.prototype.toString = function() {\n return this.key + ": " + this.currentRules + "(overlaying " + (this.ruleSets.length - 1) + ")";\n};\nSymbol.prototype.toJSON = function() {\n\n var rules = this.baseRules.rules.map(function(rule) {\n return '"' + rule.raw + '"';\n });\n return '"' + this.key + '"' + ": [" + rules.join(", ") + "]";\n};\n\nSymbol.prototype.toHTML = function(useSpans) {\n var keySpan = '"' + this.key + '"';\n if (useSpans)\n keySpan = "<span class='symbol symbol_" + this.key + "'>" + keySpan + "</span>";\n\n var rules = this.baseRules.rules.map(function(rule) {\n var s = '"' + rule.raw + '"';\n if (useSpans)\n s = "<span class='rule'>" + s + "</span>";\n return s;\n });\n return keySpan + ": [" + rules.join(", ") + "]";\n};\n\n/**\n * @author Kate Compton\n */\n\nfunction Grammar() {\n this.clear();\n};\n\nGrammar.prototype.clear = function() {\n // Symbol library\n this.symbols = {};\n \n this.errors = [];\n \n // Modifier library\n this.modifiers = {};\n\n // add the universal mods\n for (var mod in universalModifiers) {\n if (universalModifiers.hasOwnProperty(mod))\n this.modifiers[mod] = universalModifiers[mod];\n }\n};\n//========================================================\n// Loading\n\nGrammar.prototype.loadFrom = function(obj) {\n var symbolSrc;\n\n this.clear();\n\n if (obj.symbols !== undefined) {\n symbolSrc = obj.symbols;\n } else {\n symbolSrc = obj;\n }\n\n // get all json keys\n var keys = Object.keys(symbolSrc);\n\n this.symbolNames = [];\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n this.symbolNames.push(key);\n\n this.symbols[key] = new Symbol(this, key);\n this.symbols[key].loadFrom(symbolSrc[key]);\n }\n\n};\n\nGrammar.prototype.toHTML = function(useSpans) {\n // get all json keys\n var keys = Object.keys(this.symbols);\n\n this.symbolNames = [];\n\n var lines = [];\n\n var count = 0;\n for (var i = 0; i < keys.length; i++) {\n\n var key = keys[i];\n var symbol = this.symbols[key];\n\n if (symbol && symbol.baseRules) {\n\n lines.push(" " + this.symbols[key].toHTML(useSpans));\n\n }\n };\n\n var s;\n s = lines.join(",</p><p>");\n s = "{<p>" + s + "</p>}";\n return s;\n};\n\nGrammar.prototype.toJSON = function() {\n // get all json keys\n var keys = Object.keys(this.symbols);\n\n this.symbolNames = [];\n\n var lines = [];\n\n var count = 0;\n for (var i = 0; i < keys.length; i++) {\n\n var key = keys[i];\n var symbol = this.symbols[key];\n\n if (symbol && symbol.baseRules) {\n\n lines.push(" " + this.symbols[key].toJSON());\n\n }\n };\n\n var s;\n s = lines.join(",\sn");\n s = "{\sn" + s + "\sn}";\n return s;\n};\n\n//========================================================\n// selection\n\nGrammar.prototype.select = function() {\n this.isSelected = true;\n};\n\nGrammar.prototype.deselect = function() {\n this.isSelected = false;\n};\n\n//========================================================\n// Iterating over symbols\n\nGrammar.prototype.mapSymbols = function(fxn) {\n var symbols = this.symbols;\n return this.symbolNames.map(function(name) {\n return fxn(symbols[name], name);\n });\n};\n\nGrammar.prototype.applyToSymbols = function(fxn) {\n for (var i = 0; i < this.symbolNames.length; i++) {\n var key = this.symbolNames[i];\n fxn(this.symbols[key], key);\n }\n};\n\n//========================================================\nGrammar.prototype.addOrGetSymbol = function(key) {\n if (this.symbols[key] === undefined)\n this.symbols[key] = new Symbol(key);\n\n return this.symbols[key];\n};\n\nGrammar.prototype.pushRules = function(key, rules) {\n var symbol = this.addOrGetSymbol(key);\n symbol.pushRules(rules);\n};\n\nGrammar.prototype.popRules = function(key, rules) {\n var symbol = this.addOrGetSymbol(key);\n var popped = symbol.popRules();\n\n if (symbol.ruleSets.length === 0) {\n // remove symbol\n this.symbols[key] = undefined;\n }\n};\n\nGrammar.prototype.applyMod = function(modName, text) {\n if (!this.modifiers[modName]) {\n console.log(this.modifiers);\n throw ("Unknown mod: " + modName);\n }\n return this.modifiers[modName](text);\n};\n\n//============================================================\nGrammar.prototype.getRule = function(key, seed) {\n var symbol = this.symbols[key];\n if (symbol === undefined) {\n var r = new Rule("{{" + key + "}}");\n\n r.error = "Missing symbol " + key;\n return r;\n }\n\n var rule = symbol.getRule();\n if (rule === undefined) {\n var r = new Rule("[" + key + "]");\n console.log(r.sections);\n r.error = "Symbol " + key + " has no rule";\n return r;\n }\n\n return rule;\n};\n\n//============================================================\n// Expansions\nGrammar.prototype.expand = function(raw) {\n\n // Start a new tree\n var root = new RootNode(this, raw);\n\n root.expand();\n\n return root;\n};\n\nGrammar.prototype.flatten = function(raw) {\n\n // Start a new tree\n var root = new RootNode(this, raw);\n\n root.expand();\n\n return root.childText;\n};\n\n//===============\n\nGrammar.prototype.analyze = function() {\n this.symbolNames = [];\n for (var name in this.symbols) {\n if (this.symbols.hasOwnProperty(name)) {\n this.symbolNames.push(name);\n }\n }\n\n // parse every rule\n\n for (var i = 0; i < this.symbolNames.length; i++) {\n var key = this.symbolNames[i];\n var symbol = this.symbols[key];\n // parse all\n for (var j = 0; j < symbol.baseRules.length; j++) {\n var rule = symbol.baseRules[j];\n rule.parsed = tracery.parse(rule.raw);\n // console.log(rule);\n\n }\n }\n\n};\n\nGrammar.prototype.selectSymbol = function(key) {\n console.log(this);\n var symbol = this.get(key);\n};\n/**\n * @author Kate Compton\n\n */\n\ntracery.createGrammar = function(obj) {\n var grammar = new Grammar();\n grammar.loadFrom(obj);\n return grammar;\n};\n\ntracery.test = function() {\n\n console.log("==========================================");\n console.log("test tracery");\n\n // good\n tracery.testParse("", false);\n tracery.testParse("fooo", false);\n tracery.testParse("####", false);\n tracery.testParse("#[]#[]##", false);\n tracery.testParse("#someSymbol# and #someOtherSymbol#", false);\n tracery.testParse("#someOtherSymbol.cap.pluralize#", false);\n tracery.testParse("#[#do some things#]symbol.mod[someotherthings[and a function]]#", false);\n tracery.testParse("#[fxn][fxn][fxn[subfxn]]symbol[[fxn]]#", false);\n tracery.testParse("#[fxn][#fxn#][fxn[#subfxn#]]symbol[[fxn]]#", false);\n tracery.testParse("#hero# ate some #color# #animal.s#", false);\n tracery.testParseTag("[action]symbol.mod1.mod2[postAction]", false);\n\n // bad\n tracery.testParse("#someSymbol# and #someOtherSymbol", true);\n tracery.testParse("#[fxn][fxn][fxn[subfxn]]symbol[fxn]]#", true);\n\n // bad\n tracery.testParseTag("stuff[action]symbol.mod1.mod2[postAction]", true);\n tracery.testParseTag("[action]symbol.mod1.mod2[postAction]stuff", true);\n\n tracery.testParse("#hero# ate some #color# #animal.s#", true);\n tracery.testParse("#[#setPronouns#][#setOccupation#][hero:#name#]story#", true);\n\n};\n \n})();
jquery:on\nhash:off\nbookmark:on\nmodernizr:off\nundo:on\nobfuscate:off\nexitprompt:off\nblankcss:off\n
<<silently>>\nUses the parameter if one was passed. Then, checks for the $symbol variable. If neither is present, uses "origin". Clears $symbol at the end.\n\n<<if parameter(0)>>\n\t<<set $symbol to parameter(0)>>\n<<else>><<if $symbol>>\n\tNo need to do anything.\n<<else>>\n\t<<set $symbol to "origin">>\n<<endif>><<endif>>\n\n<<endsilently>><<print console.log("trace " + $symbol)>><<print tale.grammar.flatten("#" + $symbol + "#")>><<forget $symbol>>
// Returns an array of traces, each different from the one preceding it unless retrace() maxes out attempts.\n\nwindow.traceArray = function(symbol, num){\n\tvar output = [];\n\toutput.push( trace(symbol) );\n\n\tfor (var i = 1; i < num; i++) {\n\t\toutput.push( retrace(symbol, output[i-1]) );\n\t};\n\n\treturn output;\n}
<<twineceryInit>>\n<<traceryInit>>
String.prototype.contains = function(substring){\n\tif (substring.constructor === Array){\n\t\tfor (var i = 0; i < substring.length; i++){\n\t\t\tif(this.contains(substring[i])){\n\t\t\t\treturn substring[i]; // Non-empty string evaluates to true\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t} else {\n\t\treturn this.indexOf(substring) > 0;\n\t}\n}
// Returns a new version of a given expansion.\nwindow.retrace = function(symbol, old, maxAttempts){\n\tif(maxAttempts === undefined){\n\t\tmaxAttempts = 32;\n\t}\n\tif(!(maxAttempts > 1)){\n\t\tmaxAttempts = 1;\n\t}\n\t\n\tvar output = "", attempts = 0;\n\tdo{\n\t\toutput = trace(symbol);\n\t\tattempts++;\n\t}while(output == old && attempts < maxAttempts)\n\n//\tconsole.log("retrace:"\n//\t\t\t\t+ "\sn\stold: " + old\n//\t\t\t\t+ "\sn\stnew: " + output\n//\t\t\t\t+ "\sn\stattempts: " + attempts)\n\treturn output;\n}
<<tracelink "origin">>\n
body {\n margin: 2%;\n}\n#passages{\n margin: 0;\n padding: 0;\n border: 0;\n width:96%;\n margin: auto;\n}\n.passage {\n font-size:6em; \n color: #888;\n text-shadow: #888 0 0 0.05em;\n}\n@media screen and (max-width: 960px) {\n .passage {\n font-size: 4em;\n }\n}\n@media screen and (max-width: 640px) {\n .passage {\n font-size: 3em;\n }\n}\na.internalLink, a.externalLink {\n color: #eee;\n text-shadow: #eee 0 0 0.07em;\n}\na.internalLink:hover, a.externalLink:hover {\n color: #fff;\n text-decoration: none;\n text-shadow: #fff 0 0 0.09em;\n}\n#sidebar {\n\tdisplay:none;\n}\nbody\n{\n background-color: #990033 ;\n}
window.grammar = function(rule){\n\treturn tale.get(rule).text.split('\sn');\n}
// Expands a symbol and returns the output.\nwindow.trace = function(symbol){\n\tif(symbol === undefined){\n\t\tsymbol = "origin";\n\t}\n\tif(tale.grammar === undefined){\n\t\tconsole.log("Couldn't find the grammar object.");\n\t\treturn "ERROR: Grammar object not found.";\n\t}\n\n\tvar output = tale.grammar.flatten("#" + symbol + "#")\t\n//\tconsole.log(symbol + " expands to:\sn" + output);\n\treturn output;\n}
// This is a slightly modified version of Leon Arnott's cyclinglink macro.\n\nversion.extensions.tracelinkMacro = {\n\tmajor: 0,\n\tminor: 1,\n\trevision: 0\n};\nmacros.tracelink = {\n\thandler: function(a, b, c) {\n\t\tvar rl = "traceLink";\n\n\t\tfunction toggleText(w) {\n\t\t\tw.classList.remove("traceLinkInit");\n\t\t\tw.classList.toggle(rl + "Enabled");\n\t\t\tw.classList.toggle(rl + "Disabled");\n\t\t\tw.style.display = ((w.style.display == "none") ? "inline" : "none")\n\t\t}\n\t\tswitch (c[c.length - 1]) {\n\t\t\tcase "end":\n\t\t\t\tvar end = true;\n\t\t\t\tc.pop();\n\t\t\t\tbreak;\n\t\t\tcase "out":\n\t\t\t\tvar out = true;\n\t\t\t\tc.pop();\n\t\t\t\tbreak\n\t\t}\n\t\tvar v = "";\n\t\tif (c.length && c[0][0] == "$") {\n\t\t\tv = c[0].slice(1);\n\t\t\tc.shift()\n\t\t}\n\t\tvar h = state.history[0].variables;\n\t\tif (out && h[v] === "") {\n\t\t\treturn\n\t\t}\n\t\tvar l = Wikifier.createInternalLink(a, null);\n\t\tl.className = "internalLink cyclingLink";\n\t\tl.setAttribute("data-cycle", 0);\n\n\t\t// Prebake a bunch of traces and use those as our links to cycle through.\n\t\tc = traceArray(c[0], 64);\n\n\t\tfor (var i = 0; i < c.length; i++) {\n\t\t\tvar on = (i == Math.max(c.indexOf(h[v]), 0));\n\t\t\tvar d = insertElement(null, "span", null, "traceLinkInit traceLink" + ((on) ? "En" : "Dis") + "abled");\n\t\t\tif (on) {\n\t\t\t\th[v] = c[i];\n\t\t\t\tl.setAttribute("data-cycle", i)\n\t\t\t} else {\n\t\t\t\td.style.display = "none"\n\t\t\t}\n\t\t\tinsertText(d, c[i]);\n\t\t\tif (on && end && i == c.length - 1) {\n\t\t\t\tl.parentNode.replaceChild(d, l)\n\t\t\t} else {\n\t\t\t\tl.appendChild(d)\n\t\t\t}\n\t\t}\n\t\tl.onclick = function() {\n\t\t\tvar t = this.childNodes;\n\t\t\tvar u = this.getAttribute("data-cycle") - 0;\n\t\t\tvar m = t.length;\n\t\t\ttoggleText(t[u]);\n\t\t\tu = (u + 1);\n\t\t\tif (!(out && u == m)) {\n\t\t\t\tu %= m;\n\t\t\t\tif (v) {\n\t\t\t\t\th[v] = c[u]\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\th[v] = ""\n\t\t\t}\n\t\t\tif ((end || out) && u == m - (end ? 1 : 0)) {\n\t\t\t\tif (end) {\n\t\t\t\t\tvar n = this.removeChild(t[u]);\n\t\t\t\t\tn.className = rl + "End";\n\t\t\t\t\tn.style.display = "inline";\n\t\t\t\t\tthis.parentNode.replaceChild(n, this)\n\t\t\t\t} else {\n\t\t\t\t\tthis.parentNode.removeChild(this);\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\ttoggleText(t[u]);\n\t\t\tthis.setAttribute("data-cycle", u)\n\t\t}\n\t}\n};
Nerd Garbage Bot
Nora Reed with Tracery/Twine help from Vin Tanner
<<if !tale.grammar>>\n\t<<if tracery>>\n\t\t<<set tale.grammar = tracery.createGrammar(tale.story.data)>>\n\t\t<<print console.log("grammar: ", tale.grammar)>>\n\t<<else>>\n\t\t<<print console.log("grammar instantiation failed")>>\n\t<<endif>>\n<<endif>>