diff --git a/config/wordlist.txt b/config/wordlist.txt new file mode 100644 index 000000000..8353a7e51 --- /dev/null +++ b/config/wordlist.txt @@ -0,0 +1,8192 @@ +aaron +aback +abacus +abalone +abandon +abase +abash +abate +abbey +abbott +abby +abduct +abducts +abdul +abed +abel +abhor +abhors +abide +abides +abject +ablaze +able +abner +aboard +abode +abodes +abort +aborted +aborts +about +above +abraham +absent +absentee +absorb +absorbed +absorbing +absorbs +absurd +abuse +abyss +academies +academy +acadia +accent +accents +accept +accepts +accra +accrue +accuse +ace +aces +acetic +ache +ached +aches +achy +acid +acidic +acids +acing +acme +acne +acorn +acorns +acquit +acre +acres +acrid +acrobat +act +acted +acting +action +actions +active +actor +actors +actress +actresses +acts +acuity +acute +adage +adages +adagio +adam +adams +adapt +add +added +adder +addict +adding +addle +address +addresses +adds +adele +adept +adieu +adios +adjust +adjusted +adjusting +adjusts +adler +adlib +admin +admiral +admirals +admit +admits +admitted +admitting +adobe +adolf +adonis +adopt +adopted +adopting +adopts +adore +adorn +adrian +ads +adult +adultery +adults +advent +adverb +advert +advise +advised +advises +advising +aegis +aerial +aerosol +aesop +afar +affair +affairs +affine +affix +afghan +afire +afoot +afraid +africa +afro +aft +after +again +agatha +agave +age +aged +agenda +agent +ages +agile +aging +aglow +agnes +agnew +ago +agony +agree +ahead +ahoy +aid +aide +aided +aides +aiken +ail +aim +aimed +aiming +aims +air +airline +airlines +airport +airports +airway +aisle +aisles +ajar +ajax +akin +alabama +aladdin +alamo +alan +alarm +alarms +alas +alaska +albert +albino +album +albums +alchemy +alcohol +alcoholic +alden +alder +ale +alec +aleck +aleph +alert +ales +alex +alexa +alfonso +alfred +alfredo +algae +algebra +alia +alias +alibi +alice +alicia +alien +alight +align +alike +alimony +alive +alkali +all +allan +allay +allen +alley +allied +allow +alloy +allure +ally +allyn +alma +almanac +almond +almost +alms +aloe +aloft +aloha +alone +along +alonzo +aloof +aloud +alpha +alpine +alps +also +altar +alter +alto +alum +alumni +alvarez +alvin +always +amadeus +amanda +amass +amaze +amazon +amber +ambient +amble +ambush +ambushed +ambushing +amen +amend +amended +amends +america +american +americans +amid +amigo +amigos +amino +amish +amiss +amity +ammo +ammonia +amnesia +amok +among +amour +amp +ample +amply +amps +amulet +amulets +amuse +amy +anagram +analog +analogy +analyze +analyzed +analyzes +anatomy +anchor +and +andes +andre +andrea +andrew +android +andy +anew +angel +angela +angelo +anger +angie +angle +angles +anglo +angola +angry +angst +angus +animal +anise +anita +ankle +ankles +ann +anna +anne +annex +annie +annoy +annual +annul +anomaly +answer +ant +antares +ante +antenna +anti +antic +anton +antonio +ants +anvil +any +anyhow +anyway +aorta +apache +apart +apathy +ape +apes +apex +aphid +aplomb +apnea +apollo +appeal +appear +appeared +appearing +appears +append +apple +apply +apricot +april +apron +apropos +apt +aqua +arab +arabs +arbor +arc +arcade +arch +archer +archers +arches +archive +archived +archives +arcs +arctic +ardent +are +area +areas +arena +ares +argo +argon +argue +argus +aria +arid +ariel +arise +arizona +ark +arkansas +arlene +arm +armada +armed +armor +armored +armors +arms +army +arnold +aroma +aromas +arose +array +arrays +arrear +arrive +arrived +arrives +arriving +arrow +arsenal +arsenals +arson +art +artery +arthur +artie +artisan +artisans +artist +artists +arts +aruba +ascend +ash +ashen +ashes +ashley +ashy +asia +asian +aside +ask +asked +askew +asks +asleep +aspect +aspen +aspire +aspired +aspires +aspirin +aspiring +asset +assets +assist +assisted +assists +assure +aster +asthma +astral +asylum +ate +athena +athens +athlete +athletes +atla +atlanta +atlas +atoll +atom +atomic +atoms +atone +atop +attic +attire +aubrey +audio +audit +audited +auditing +audits +audrey +auger +august +aunt +aunts +aura +aural +auras +aurora +austin +austria +auto +autumn +avail +avalon +avatar +avenue +average +avert +avery +avian +aviate +avid +avoid +avon +avow +await +awaited +awaiting +awaits +awake +award +aware +awash +away +awe +awful +awl +awoke +awry +axe +axels +axes +axial +axiom +axis +axle +axles +axon +ayers +aztec +azure +babe +babel +babes +babies +baboon +baboons +baby +bach +back +backup +bacon +bad +bade +badge +badger +badgers +badly +baffle +bag +bagel +baggage +bagged +baggy +bags +bahama +bail +bails +bait +bake +baker +bakers +bakes +balance +balanced +balances +bald +baldy +bale +bali +balk +balkan +balky +ball +ballad +balled +ballet +balloon +balloons +ballot +ballots +balls +balm +balms +balmy +balsa +bambi +bambino +bamboo +ban +banal +banana +bananas +band +bandit +bandits +bands +bandy +bane +bang +bangs +banish +banjo +banjos +bank +banks +bar +barb +barbara +barber +barbs +barcode +bard +bare +barf +barfly +bargain +barge +bark +barks +barley +barn +barns +baron +barony +barrel +barry +bars +bart +barter +base +basel +bases +bash +basic +basil +basin +basins +basis +bask +basket +bass +basso +baste +bat +batch +bate +bater +bates +bath +bathe +baths +baton +bats +batteries +battery +bauble +baud +bauer +bavaria +bawd +bawdy +bawl +baxter +bay +bayed +bayonet +bayou +bays +bazaar +bazooka +beach +beaches +beacon +bead +beads +beady +beak +beam +beams +bean +beans +bear +beard +bears +beast +beat +beatles +beats +beauty +beaver +bebop +becalm +beck +becker +becky +bed +beds +bee +beech +beef +beefy +been +beep +beeps +beer +beers +bees +beet +beets +befall +befit +before +beg +began +beget +beggar +beggars +begged +begging +begin +begs +begun +behave +behaved +behaves +behaving +behind +beige +being +beirut +belch +belfry +belgium +belie +belief +beliefs +bell +bella +belle +bellow +bells +belly +belong +below +belt +belts +bemoan +bemoans +ben +bench +benches +bend +bender +bends +benefit +benign +benny +bent +bereft +beret +berg +berlin +bermuda +bern +bernard +berra +berry +bert +berth +bess +best +bet +beta +beth +bethel +betray +bets +betsy +betty +between +bevel +beware +beyond +bezel +bianca +bias +bib +bible +bicep +biceps +bicycle +bid +bide +bids +big +bike +biker +bikini +bikinis +bile +bilge +bilk +bill +billow +bills +billy +bimbo +bin +binary +bind +binds +bing +binge +binged +binges +bingo +bins +biology +biota +biped +birch +bird +birdie +birds +birth +biscuit +bishop +bismark +bison +bisque +bit +bite +bites +bits +bitten +black +blade +blair +blake +blame +blamed +blames +blaming +bland +blank +blare +blast +blaze +bleak +bleat +bled +bleed +bleeding +bleeds +blend +bless +blesses +blew +blimp +blimps +blind +blinded +blinds +blink +blinking +blinks +blip +blips +bliss +blithe +blitz +bloat +bloated +bloating +bloats +blob +blobs +block +blocked +blocking +blocks +bloke +blond +blonde +blood +bloom +blot +blotch +blotches +blots +blow +blown +blows +blue +blues +bluff +blunt +blur +blurs +blurt +blush +blythe +boa +boar +board +boards +boars +boast +boasted +boasting +boasts +boat +boats +bob +bobby +bobcat +bobs +bock +bode +body +bog +bogart +bogey +bogs +bogus +bohemia +boil +boiled +boiling +boils +boise +bold +bolo +bolt +bolts +bomb +bombay +bombs +bon +bonanza +bond +bonds +bone +bones +bongo +bongos +bonjour +bonobo +bonus +bonuses +bony +boo +booby +boogie +book +books +boom +booms +boon +boost +boot +booth +booths +boots +booty +booze +bop +borax +border +borders +bore +bored +bores +boric +boris +born +borne +boron +bosch +bosom +boson +boss +bosses +bossy +boston +botanic +botch +both +bottle +bottles +bough +boulder +boulders +bouncy +bound +bounded +bounds +bourn +bout +bouts +bovine +bow +bowed +bowel +bowie +bowl +bowls +bows +box +boxed +boxer +boxes +boxing +boxy +boy +boyish +boyle +boys +bozo +bra +brace +brad +brady +brag +bragging +brags +braid +brain +brains +brainy +brake +brakes +bran +brand +brands +brandt +brandy +brant +brash +brass +brassy +brat +brats +braun +brave +bravery +bravo +brawl +brawls +brawn +brazil +bread +breads +break +breaking +breaks +breath +bred +breed +breeds +breeze +bremen +brenda +breve +brews +brian +briar +bribe +bribed +bribes +bribing +brice +brick +bricks +bride +brides +bridge +bridges +brief +brig +brigade +brim +brine +bring +brink +briny +brisk +british +broad +brock +broil +broke +broken +bronco +bronx +bronze +brood +broods +brook +broom +broth +brother +brothers +brow +brown +brows +browse +bruce +bruin +brunch +bruno +brunt +brush +brutal +brute +bryan +bryant +bryce +buck +bucket +bucks +bud +buddha +buddy +budge +budget +buds +buenos +buff +buffalo +bug +buggy +bugle +bugs +build +built +bulb +bulbs +bulge +bulk +bulky +bull +bulls +bully +bum +bump +bumps +bumpy +bums +bun +bunch +bunches +bunco +bundle +bunk +bunker +bunkers +bunny +buns +bunt +bunts +bunyan +buoy +bureau +burger +burgers +buried +burly +burma +burn +burned +burns +burnt +burp +burps +burro +burst +burton +bury +bus +bush +bushel +bushy +bust +busy +but +butane +butch +butte +butter +button +buttons +butyl +buxom +buy +buyer +buyers +buys +buzz +buzzer +buzzy +bye +bylaw +byline +bypass +byron +byte +bytes +cab +cabal +cabana +cabaret +cabin +cabinet +cabins +cable +cables +cacao +cache +cackle +cacti +cactus +caddy +cadet +cadets +cadre +caesar +cafe +cafes +cage +caged +cages +cagey +cairn +cairo +cajun +cake +cakes +caleb +calf +calibre +calico +california +call +calls +callus +calm +calms +calorie +calve +calvin +calypso +cam +camber +came +camel +camelot +camels +cameo +camera +camilla +camp +camps +campus +can +canada +canal +canals +canary +cancer +candid +candle +candy +cane +caned +canes +cannon +cannons +cannot +canny +canoe +canon +canopy +cans +cantina +cantor +canvas +canvases +canyon +cap +cape +caped +caper +capital +capri +capsule +captain +car +caramel +carat +caravan +carbon +card +cardinal +care +career +cares +caress +caret +cargo +carl +carla +carlo +carlos +carmen +carmine +carol +carolina +carp +carpet +carrie +carrot +carrots +carry +cars +carson +cart +cartel +cartels +carter +cartoon +carts +carve +carved +carves +case +cases +casey +cash +cashew +casino +casinos +casio +cask +casket +caskets +casks +cast +caste +casting +castle +castles +castro +casts +cat +catalog +catalogs +catch +cathy +catnip +cats +catty +caulk +cause +cave +cavern +caves +caviar +cavort +caw +cease +cecil +cecilia +cedar +cede +celery +cell +cello +celtic +cement +census +cent +centaur +center +central +cents +centuries +century +ceramic +ceres +cern +ceylon +chad +chafe +chaff +chai +chain +chains +chair +chairs +chalk +chamber +chambers +champ +chance +change +changed +changes +channel +chant +chanted +chanting +chants +chaos +chap +chapel +chapels +chapter +chapters +char +chard +chariot +charles +charlie +charm +charms +chart +charter +charters +charts +chase +chases +chasm +chaste +chat +chats +cheap +cheapen +cheat +cheats +check +cheek +cheeky +cheer +cheers +cheese +chef +chefs +chemist +chemists +cherry +cherub +chess +chest +chew +chews +chewy +chic +chicago +chick +chicken +chickens +chicks +chide +chief +chiefs +child +chile +chili +chill +chilly +chime +chimes +chimp +chin +china +chink +chip +chips +chirp +chisel +chit +chive +chloe +chock +choice +choir +choke +choked +chokes +chomp +choose +chop +chopin +chops +choral +chord +chore +chose +chosen +chow +chris +chrome +chuck +chug +chum +chump +chunk +churn +chute +ciao +cicada +cicadas +cider +cigar +cigars +cilia +cinch +cindy +cinema +cipher +ciphers +circa +circle +circuit +circuits +circus +cite +cities +citizen +citizens +citrus +city +civic +civil +clad +claim +claimed +claims +clam +clammy +clamp +clan +clang +clank +clans +clap +claps +clara +clarinet +clarion +clark +clash +clashes +clasp +class +classic +classics +claudia +claus +clause +claw +claws +clay +clean +cleans +clear +cleat +clef +cleft +clerk +clerks +clever +cliche +click +clicks +client +cliff +climax +climb +cling +clinic +clink +clip +clive +cloak +cloaks +clock +clocks +clod +clog +clomp +clone +close +closet +clot +cloth +cloud +clout +clover +clovers +clown +cloy +club +clubs +cluck +clue +clues +clump +clumsy +clung +coach +coal +coast +coat +coats +coax +cob +cobalt +cobble +cobra +cockle +cockpit +cocky +coco +cocoa +coconut +cod +coda +coddle +code +coded +codes +cody +coed +cog +cogent +cogs +coif +coil +coils +coin +coins +coke +cola +colby +cold +cole +collect +colon +colonel +colonies +colony +color +colorado +colors +colt +columbia +columbus +coma +comb +combat +combine +combo +come +comedy +comet +comets +comfy +comic +comma +command +commands +common +commons +compact +companies +company +complex +comply +comrade +con +conan +concert +conch +concord +condo +condor +conduct +cone +coney +confide +congo +conic +connect +connected +connects +conner +conrad +consul +contact +context +contour +contours +control +controls +convert +convex +convey +convoy +conway +cony +cook +cooks +cooky +cool +cooley +coon +coop +cooper +coors +coos +cop +cope +copes +copper +cops +copy +coral +cord +cordon +cordova +cords +core +cores +cork +corks +corn +corner +cornet +corny +corona +correct +correctly +cortex +corvus +cosmic +cosmos +cost +costs +costume +costumes +cosy +cot +cotton +couch +couches +cough +could +count +counted +coup +coupe +couple +couples +coupon +courage +course +court +courts +cousin +cove +cover +covers +covet +cow +cowboy +cowl +cows +cox +coy +coyote +coyotes +cozy +crab +crack +craft +crafts +crag +craig +cram +cramp +crane +cranes +crank +cranks +crap +craps +crash +crass +crate +crater +craw +crawl +crayon +craze +crazy +creak +cream +credit +credo +creed +creek +creep +creole +crepe +crept +cress +crest +crete +crew +crib +cricket +cried +crime +crimp +crimson +crisis +crisp +critic +croak +crock +crocus +croft +crone +crook +croon +crop +crops +cross +crouch +crow +crowd +crown +crows +crud +crude +cruel +crumb +crump +crunch +crush +crushed +crushes +crust +crux +cruz +cry +crypt +crypts +crystal +crystals +cub +cuba +cuban +cube +cubes +cubic +cubist +cubs +cuddle +cue +cues +cuff +cull +cult +cults +culture +cultures +cumin +cup +cupful +cupid +cups +cur +curb +curd +cure +cured +cures +curfew +curie +curl +curled +curls +current +curries +curry +curse +curt +curtain +curve +curves +cusp +cuss +cut +cute +cutlet +cuts +cyan +cycle +cyclone +cyclops +cymbal +cynic +cyril +cyrus +cyst +czar +czech +dab +dad +dada +daddy +daffy +daft +dagger +dahlia +daily +dairy +dais +daisy +dakar +dakota +dale +dallas +dally +dam +damage +damages +dame +damon +damp +dams +damsel +dan +dance +danced +dances +dandy +dane +dang +danger +daniel +dank +danny +dante +danube +dare +dared +dares +dark +darken +darn +darry +dart +darts +darwin +dash +data +date +dates +datum +daub +daunt +dave +david +davis +dawn +dawson +day +days +daze +dazed +dazes +deacon +dead +deadly +deaf +deal +deals +dealt +dean +dear +death +debase +debbie +debby +debit +debra +debri +debris +debt +debts +debug +debut +decade +decades +decaing +decal +decay +december +decibel +decide +decimal +deck +declare +declared +decor +decoy +decree +decry +deed +deeds +deem +deep +deer +defect +defend +defer +define +deform +deft +defy +degree +deify +deign +deity +delaware +delay +delete +deleted +delhi +deli +delia +deliver +dell +delphi +delta +delve +demand +demark +demo +demon +demur +den +denial +denim +denmark +denny +dense +density +dent +denton +dents +denver +deny +depend +depends +deposit +deposits +depot +depth +depute +deputy +derby +desert +deserts +design +desire +desist +desk +desks +detach +detached +detail +detect +detected +detects +deter +detox +detroit +deuce +deus +develop +devil +devoid +devon +dew +dewey +dexter +diablo +diagram +dial +dialog +dials +diamond +diana +diane +diaper +diary +dibble +dibs +dice +did +die +died +diego +diem +dies +diesel +diet +diets +diety +dig +digit +digital +digits +digs +dike +dilate +dilemma +dill +dim +dime +dimes +dimly +dims +din +dine +diner +diners +ding +dingo +dingy +dinner +dinners +diode +dip +diploma +dips +dirac +dire +direct +directed +directs +dirge +dirk +dirt +dirty +disc +disco +dish +dishes +disk +disney +dispute +disputed +distant +disuse +ditch +ditches +ditto +ditty +diva +divan +dive +dives +divide +divided +dixie +dixon +dizzy +doc +dock +docket +doctor +doctors +dodge +doe +does +dog +dogma +dogs +doily +doing +dolby +dolce +dole +doll +dollar +dollars +dolly +dolphin +dolphins +dolt +domain +dome +domed +domino +don +donald +done +donna +donor +donut +doom +door +dope +dopey +dora +doric +doris +dorm +dormant +dose +dot +dote +dots +double +doubt +doug +dough +dour +douse +dove +dover +doves +dow +dowel +down +downs +dowry +doyle +doze +dozen +drab +draco +draft +drag +dragon +dragons +drain +drained +drains +drake +drama +drank +drape +drastic +draw +drawl +drawn +dread +dreaded +dreads +dream +dreamy +dreg +dregs +dress +dressy +drew +dried +drier +dries +drift +drifting +drill +drink +drinks +drip +drips +drive +driver +droid +droids +droll +drone +drool +droop +drop +drops +drove +drown +drug +drugs +druid +drum +drums +drunk +dry +dryad +dual +dub +dublin +duck +ducks +duct +dud +dude +due +duel +dueler +dues +duet +duff +duffy +dug +duke +dull +duly +dumb +dumbo +dummy +dump +dumps +dumpy +dunce +dune +dung +dunham +dunk +dunlop +duo +duos +dupe +during +dusk +dusky +dust +dusty +dutch +duty +dwarf +dwell +dwelt +dwight +dwyer +dye +dyed +dying +dylan +dynamic +dynamo +dynamos +dynasty +dyne +each +eager +eagle +ear +earl +early +earn +earns +ears +earth +ease +easel +easing +east +eastern +easy +eat +eaten +eater +eats +eave +eaves +ebb +ebony +echo +echoes +eclipse +ecology +economy +eddie +eddy +eden +edgar +edge +edges +edgy +edible +edict +edify +edison +edit +edith +edition +editions +editor +editors +edits +educate +educated +edward +edwin +eel +eels +eerie +efface +effect +effects +egan +egg +eggroll +eggs +ego +egress +egret +egypt +eight +eighteen +eighth +eighty +eject +elastic +elate +elbow +elder +eldon +elect +electra +elegant +elegy +element +elena +eleven +eleventh +elf +elfin +elide +elite +eliza +elk +elks +ella +ellen +ellipse +ellis +elm +elmer +elms +elope +elroy +else +elsie +elton +elude +elves +elvis +email +embalm +embargo +embark +embed +ember +emerald +emery +emil +emily +emit +emits +emma +emmy +emory +emote +emotion +empire +employ +empty +emu +enact +enamel +end +ended +ending +endive +ends +enema +enemy +energy +engine +england +english +engulf +enid +enigma +enjoy +enmity +ennui +enrico +ensue +enter +entrap +entry +envoy +envy +eon +eons +epic +epics +episode +epoch +epoxy +epsom +equal +equals +equator +equip +era +erase +erato +ere +erect +erg +ergo +eric +erica +erie +erin +ernest +ernie +ernst +erode +eros +erosion +err +errand +error +erupt +erwin +escape +escort +eskimo +essay +essex +ester +etch +eternal +ethan +ethel +ether +ethic +ethics +ethnic +ethos +ethyl +eucre +euler +eureka +euro +europe +eva +evade +evan +evans +eve +even +evening +event +ever +everest +every +evict +evident +evil +evoke +evolve +ewe +exact +exalt +exam +example +exams +excel +except +excess +exert +exhibit +exile +exist +exit +exits +exodus +exotic +expand +expel +explain +explore +expo +export +express +extant +extend +extent +extol +extra +extreme +exude +exult +eye +eyed +eyes +ezra +fable +fabric +face +faces +facet +facile +fact +factor +factory +facts +fad +fade +fads +fail +faint +fair +fairs +fairy +faith +fake +faker +falcon +fall +false +fame +family +famous +fan +fancy +fang +fangs +fanout +fans +fantasy +far +farce +fare +fargo +farm +farmer +farms +fashion +fast +fat +fatal +fate +father +fats +fatty +fault +faun +fauna +faust +faux +fawn +fax +faze +fear +fears +feast +feat +feather +february +fed +fee +feeble +feed +feeds +feel +feels +fees +feet +feign +feint +felice +felix +fell +felt +femur +fence +fend +fermi +fern +ferrari +ferric +ferry +fertile +fest +fetal +fetch +fetid +fetus +feud +feudal +fever +few +fez +fiasco +fiat +fib +fiber +fickle +fiction +fidel +fief +field +fiend +fiery +fiesta +fifteen +fifth +fifty +fig +fight +figs +figure +fiji +filch +file +filed +files +filet +fill +filler +filly +film +films +filmy +filter +filth +fin +final +finale +finance +finch +find +finder +fine +fined +finer +finger +finish +finite +fink +finland +fiona +fir +fire +firm +first +fish +fished +fisher +fishy +fist +fit +fits +five +fix +fixed +fizz +fjord +flab +flack +flag +flail +flair +flak +flake +flaky +flame +flank +flap +flare +flash +flask +flat +flavor +flaw +flax +flay +flea +fleck +fled +flee +fleet +fleming +flesh +flew +flex +flick +flier +flies +flight +flinch +fling +flint +flip +flipper +flirt +flit +float +flock +flog +flood +floor +flop +floppy +flora +floral +florida +flour +flout +flow +flower +flown +floyd +flu +flub +fluff +fluid +fluke +flung +flush +flute +flux +fly +flyer +flynn +foal +foam +foamy +fob +focal +foci +focus +fodder +foe +foes +fog +foggy +foil +fold +folio +folk +folly +fond +font +food +fool +foot +fop +for +foray +forbid +force +ford +forest +forever +forge +forget +forgot +fork +form +formal +format +forms +formula +fort +forte +forth +fortune +forty +forum +forward +fossil +foul +found +four +fourteen +fourth +fovea +fowl +fox +foxes +foxtrot +foxy +foyer +fractal +fragile +frail +frame +fran +franc +franca +france +francis +frank +fraud +fray +freak +fred +freddie +free +freed +freedom +freer +freeze +freezer +french +frenzy +freon +fresh +fret +freud +friar +friday +fried +friend +fries +fright +frill +frilly +frisbee +frisky +fritz +frock +frog +frogs +from +frond +front +frost +froth +frown +froze +frozen +fruit +fry +fuchsia +fudge +fuel +fugue +fuji +full +fully +fumble +fume +fumes +fun +fund +funds +fungal +fungi +fungus +funk +funky +funny +fur +furry +furs +fury +fuse +fuss +fussy +future +fuzz +fuzzy +gab +gable +gabriel +gadget +gaffe +gag +gage +gags +gain +gait +gal +gala +galaxy +gale +galileo +gall +gallery +gallop +game +games +gamma +gamut +gander +gang +gangs +gap +gape +gapes +gaps +garage +garb +garbage +garbo +garcia +garden +gargle +garish +garlic +garner +garth +gary +gas +gash +gasp +gasps +gassy +gate +gates +gator +gauche +gaudy +gauge +gaul +gaunt +gauss +gauze +gave +gavel +gavin +gawk +gawky +gaze +gazed +gazes +gear +gears +gecko +geese +gel +gelatin +geld +gem +gemini +gems +gene +general +genes +genesis +genetic +geneva +genie +genius +genoa +genre +gent +gentle +gentry +genuine +genus +geo +george +georgia +gerbil +germ +german +germany +germs +get +gets +getty +ghana +ghent +ghetto +ghost +ghoul +ghouls +giant +gibson +giddy +gift +gifts +gig +gila +gilbert +gild +giles +gill +gills +gilt +gimbal +gimpy +gin +gina +ginger +giraffe +gird +girl +girls +girth +gist +give +given +gives +gizmo +glacier +glad +gladdy +glade +glamor +glance +gland +glare +glass +glaze +gleam +glean +glee +glen +glib +glide +glint +gloat +glob +global +globe +glom +gloom +gloria +glory +gloss +glove +glow +glows +glucose +glue +glued +gluey +gluing +glum +glut +glyph +gnarl +gnarly +gnash +gnat +gnaw +gnaws +gnome +gnu +goa +goad +goal +goals +goat +goats +goblet +goblin +god +godly +gods +goes +goggle +gogo +going +gold +golem +golf +goliath +golly +gomez +gondola +gone +gong +goo +good +goods +gooey +goof +goofy +goon +goose +gopher +gordon +gore +gorge +gorilla +gory +gosh +gospel +gossip +got +gouda +gouge +gourd +gout +gown +gowns +grab +grabs +grace +grad +grade +grady +graft +grail +grain +gram +grams +grand +granite +grant +grape +graph +graphs +grasp +grass +grate +grave +gravel +gravity +gravy +gray +graze +great +greece +greed +greedy +greek +green +greet +greg +gregory +gremlin +greta +grew +grey +grid +grief +grieve +griffin +grill +grim +grime +grimy +grin +grind +grins +grip +gripe +gripes +grips +grit +groan +groat +grog +groin +groom +groove +grope +gross +ground +group +grout +grove +grovel +grow +growl +grown +grows +grub +grubs +gruff +grunt +guam +guano +guard +guava +guess +guest +guide +guild +guile +guilt +guinea +guise +guitar +gulag +gulf +gull +gulls +gully +gulp +gum +gumbo +gummy +gun +gunk +gunky +guns +guppy +gurgle +guru +gus +gush +gust +gustav +gusts +gusty +gut +guts +gutsy +guy +guyana +guys +gwen +gym +gypsum +gypsy +gyro +habit +habitat +hack +had +hades +hadron +hag +hague +haiku +hail +hair +hairs +hairy +haiti +hal +hale +haley +half +hall +halls +halo +halt +halts +halve +ham +hamlet +hammer +hams +hand +handle +hands +handy +hang +hanger +hank +hanna +hannah +hanoi +hans +hansel +hap +happy +harbor +hard +hardly +hardy +hare +harem +hark +harlem +harley +harm +harmony +harms +harold +harp +harps +harpy +harris +harry +harsh +harvard +harvest +harvey +has +hash +haste +hasty +hat +hatch +hate +hater +hates +hatred +hats +haul +hauls +haunt +haunts +havana +have +haven +havoc +haw +hawaii +hawk +hawks +hay +hayes +hazard +haze +hazel +hazy +head +heads +heady +heal +heals +healy +heap +heaps +hear +heard +hears +heart +heat +heath +heats +heave +heaven +heavy +hebrew +heck +heckle +hectic +hedge +heed +heel +heels +heft +hefty +height +heir +heirs +held +helen +helena +helga +helium +helix +hell +hello +helm +help +hem +hemp +hems +hen +hence +henry +hens +her +hera +herb +herbal +herbert +herbs +herd +here +herman +hero +heroic +heron +herons +hers +hertz +hew +hewn +hex +hexagon +hexed +hey +hid +hide +hides +high +higher +hijack +hike +hikes +hill +hills +hilly +hilt +him +hind +hindi +hindu +hinge +hint +hints +hip +hippie +hippo +hippy +hips +hire +hired +hires +his +hiss +history +hit +hitch +hits +hive +hives +hoard +hoax +hob +hobbit +hobby +hobo +hoc +hock +hockey +hodge +hodges +hoe +hog +hogan +hogs +hoist +hold +holds +holdup +hole +holes +holiday +hollow +holly +holt +holy +home +hone +honest +honesty +honey +hong +honk +honor +hood +hoof +hook +hooks +hookup +hoop +hoot +hop +hope +hopes +hops +horde +horizon +horn +horse +horus +hose +host +hostel +hot +hotbox +hotel +hotrod +hound +hour +house +houston +hovel +hover +how +howdy +howl +howls +hoyle +hub +hubbub +hubby +huber +hubs +huck +hue +hued +hues +huey +huff +hug +huge +hugo +hugs +hula +hulk +hull +hum +human +humid +humor +hump +humps +hums +humus +hun +hunch +hundred +hung +hunk +hunt +hunter +hunts +hurl +huron +hurrah +hurry +hurt +husband +hush +husk +husky +hut +hutch +hyde +hydra +hydro +hyena +hymn +hymnal +hype +hyper +hypo +iambic +ian +ibex +ibis +ibiza +ice +iceberg +iced +icicle +icing +icky +icon +icons +icy +ida +idaho +idea +ideal +ideals +ideas +idiom +idle +idly +idol +idols +idyll +iffy +igloo +ignite +igor +iliad +ill +image +imagine +imbibe +imbue +imitate +immune +immure +imp +impact +impel +imply +import +impress +imps +inane +inapt +inca +incest +inch +include +incur +index +india +indiana +indies +indigo +inept +inert +infamy +infant +infect +infer +infix +info +infra +ingot +ingrid +inhale +initial +ink +inky +inlay +inlet +inn +inner +inns +input +insect +inset +inside +instant +instead +insult +intel +intend +inter +into +intro +invent +invest +invite +invoke +ion +ionic +ions +iota +iowa +iran +iraq +iraqi +irate +ire +irene +iris +irish +irk +irked +iron +ironic +irons +irony +isaac +isabel +isis +islam +island +isle +isotope +israel +issue +italian +italy +itch +itchy +item +items +ivan +ivory +ivy +jab +jack +jackal +jacket +jackson +jacob +jade +jaded +jaguar +jail +jaime +jake +jam +jamaica +jamb +james +jan +jane +january +janus +japan +jar +jargon +jars +jasmine +jason +jaunt +java +jaw +jaws +jay +jazz +jazzy +jean +jeans +jedi +jeep +jeer +jeers +jeff +jello +jelly +jenny +jerk +jerks +jerky +jerome +jerry +jersey +jess +jesse +jessica +jest +jester +jesus +jet +jets +jew +jewel +jewish +jibe +jiffy +jig +jiggle +jigs +jill +jilt +jim +jimmy +jinx +jive +joan +job +jobs +jock +jockey +jody +joe +joel +joey +jog +jogs +john +join +joins +joint +joke +joker +jokes +jolly +jolt +jon +jonas +jones +jordan +jorge +jose +josef +joseph +josh +joshua +jostle +jot +jots +joule +journal +joust +jove +jowl +jowls +jowly +joy +joyce +juan +judas +jude +judge +judo +judy +jug +juggle +jugs +juice +juicy +juju +juke +jukes +julep +jules +julia +julie +juliet +julio +julius +july +jumbo +jump +jumps +jumpy +june +jungle +junior +junk +junky +juno +junta +jupiter +juror +jury +just +justice +jut +jute +kabul +kafka +kale +kane +kansas +kant +kappa +kaput +karate +karen +karl +karma +karol +karp +kate +kathy +katie +katz +kava +kayak +kazoo +keats +keel +keen +keep +keeps +keg +kegs +keith +keller +kelly +kelp +kemp +ken +kennel +kentucky +kenya +kepler +kept +kermit +kerry +kettle +kevin +key +keyed +keys +khaki +khan +khmer +kick +kicks +kid +kidney +kids +kiev +kill +kills +kiln +kilo +kilt +kilts +kim +kimono +kin +kind +kinds +kinetic +king +kingdom +kings +kink +kinky +kiosk +kirby +kirk +kiss +kit +kitchen +kite +kites +kitty +kiva +kiwi +klaus +klaxon +klutz +knack +knave +knead +knee +kneel +knees +knelt +knew +knick +knife +knight +knit +knits +knob +knobs +knock +knoll +knot +knots +know +known +knows +knox +koala +kodak +kong +kook +kooks +kooky +korea +kraft +kraut +krebs +kudos +kurd +kurt +kyle +kyoto +lab +label +labor +labs +lace +laces +lack +lacks +lactic +lacuna +lacy +lad +ladder +laden +ladle +lads +lady +lag +lager +lagoon +lagos +lags +laid +lain +lair +laity +lake +lakes +lam +lamar +lamb +lambs +lame +lamp +lamps +lance +land +lands +lane +lang +lanky +laos +lap +lapel +laps +lapse +laptop +lard +large +lark +larks +larry +lars +larsen +larva +larynx +laser +lash +lass +lasso +last +latch +late +later +latest +latex +lathe +latin +laud +laugh +launch +laura +lava +law +lawn +lawns +laws +lax +lay +layer +lays +layup +lazarus +laze +lazy +lea +leach +lead +leads +leaf +leafy +leak +leaks +leaky +lean +leap +leaps +leapt +lear +learn +leary +lease +leash +least +leave +lecture +led +ledge +lee +leech +leeds +leek +leer +leers +leery +leeway +left +lefty +leg +legacy +legal +legend +legion +legs +leland +lemma +lemon +lend +lends +length +lenin +lenny +lenore +lens +lent +leo +leon +leona +leonid +leopard +leper +leroy +less +lesson +lest +let +lets +letter +lev +levee +level +lever +levi +levis +levy +lewd +lewis +lexical +lexicon +liar +liars +libel +liberal +libido +libra +library +libya +lice +license +lick +licks +lid +lids +lie +lied +lien +lies +lieu +life +lift +lifts +light +like +liked +liken +likes +lilac +lilly +lilt +lily +lima +limb +limbo +limbs +lime +limit +limp +limps +lin +lincoln +lind +linda +linden +line +linear +linen +lines +lingo +link +lint +linus +lion +lip +lipid +lips +liquid +lira +lisa +lisbon +lisp +list +listen +lists +lit +liter +lithe +lithium +little +live +liven +liver +livid +living +liz +lizzie +llama +lloyd +load +loaf +loan +loaner +lob +lobby +lobe +lobs +lobster +local +locate +loch +lock +locks +locus +lode +lodge +loft +lofty +log +logan +loge +logic +logical +logo +logs +loin +loins +loire +lois +loiter +loki +lola +lomb +lome +london +lone +lonely +loner +long +longer +longs +look +looks +loom +loon +loony +loop +loose +loot +lope +lopez +lops +lord +lore +lorenzo +lose +loser +loses +loss +lossy +lost +lot +lots +lotto +lotus +lou +loud +louis +louise +louisiana +louse +lousy +lout +love +loved +lover +low +lower +lowry +loyal +lucas +luce +lucia +lucid +luck +lucky +lucy +ludwig +lug +luge +luger +lugs +luis +luke +lull +lumbar +lumen +lump +lumps +lumpy +luna +lunar +lunch +lung +lunge +lungs +lurch +lure +lurid +luring +lurk +lurks +lush +lust +lusty +lute +luxury +lydia +lye +lying +lymph +lynch +lynx +lyon +lyre +lyric +macaw +mace +mach +machine +macho +mack +macro +mad +madam +made +madly +madman +madonna +madrid +mae +maestro +mafia +magenta +magi +magic +magma +magnet +magnum +magoo +magpie +maid +maids +mail +mailbox +maim +maims +main +maine +maize +major +make +malady +male +mali +malice +malign +mall +malls +malt +malta +mama +mambo +mammal +mammoth +man +mana +manager +mandolin +mane +mange +mango +mania +manic +manila +manly +manna +manor +manse +mantle +manual +many +maori +map +maple +maps +mar +maraud +marble +march +marco +marcy +mares +marge +margin +margo +maria +marie +marimba +marin +marina +marine +mariner +mario +marion +mark +market +marks +marlin +marlon +marrow +marry +mars +marsh +mart +martin +martyr +marvin +marx +mary +maryland +mash +mask +masks +mason +mass +mast +master +masts +mat +match +mate +mated +mateo +mates +math +matrix +mats +matt +matte +mature +matzo +maul +mauls +mauve +mavis +maw +max +maxim +maxima +maximum +maxwell +may +maya +maybe +mayday +mayer +mayhem +mayo +mayor +maze +mazes +mead +meadow +meal +meals +mealy +mean +meaning +means +meant +meat +meaty +mecca +medal +media +medic +medical +medics +medium +medley +medusa +meek +meet +meets +meg +mega +mel +meld +melee +mellow +melody +melon +melt +melts +member +memo +memoir +memory +memos +memphis +men +mend +mendez +mendoza +mends +menlo +mental +mentor +menu +meow +merck +mercury +mercy +mere +merge +merit +merits +merlin +merry +mesa +mescal +mesh +meson +mess +message +messy +met +metal +meteor +meter +method +metro +mew +mexico +meyer +meyers +mezzo +miami +mice +michael +mickey +micro +mid +midas +middle +midge +midst +miff +might +miguel +mike +milan +mild +mildew +mile +miles +milk +milky +mill +miller +millet +million +mills +milo +milt +mime +mimes +mimi +mimic +mimosa +mince +mind +minds +mine +mined +miner +mineral +minerva +mines +mini +minimal +minimum +mink +minnesota +minnow +minor +minsk +mint +mints +minty +minus +minute +mira +miracle +mirage +miranda +mire +mired +mirror +mirth +miser +misery +miss +mission +missy +mist +mistake +mister +mists +misty +mit +mite +mites +mitts +mix +mixed +mixer +mixes +mixture +mixup +moan +moans +moat +moats +mob +mobil +mobile +mobs +moby +mock +mocks +modal +mode +model +modem +modern +modest +modish +modular +moe +mogul +moist +mojo +molar +mold +molds +mole +moles +molly +molt +molten +mom +moment +mommy +mona +monaco +monad +monarch +monday +mondo +money +monic +monica +monitor +monk +monkey +mono +monster +montana +month +monty +moo +mooch +mood +moods +moody +moon +moons +moose +moot +mop +mope +mopes +mops +moral +morale +morbid +more +morgan +morn +morning +moron +morph +morris +morse +morsel +mort +mortal +mosaic +moser +moses +moss +mossy +most +mot +mote +motel +moth +mother +moths +motif +motor +motto +mould +mound +mount +mourn +mouse +mousy +mouth +move +moved +moves +movie +mow +mowed +mower +mows +moxie +mozart +much +muck +mucus +mud +muddy +muff +muffin +mug +muggy +mugs +muir +mulch +mule +mules +mull +multi +mumble +mumps +munch +mung +munich +munson +muon +mural +muriel +murk +murky +muse +muses +museum +mush +mushy +music +musical +musk +musky +muslim +muss +mussel +must +mustang +musty +mute +muted +mutt +myers +mylar +myopia +myra +myron +myrrh +myself +mystery +mystic +myth +myths +nab +nabs +nadia +nadir +nag +nagoya +nags +nail +nails +naked +name +named +names +nancy +naomi +nap +nape +napkin +naps +nary +nasal +nash +nasty +natal +natasha +nate +native +natty +natural +nature +nausea +naval +nave +navel +navy +nay +neal +near +nearby +neat +nebraska +nebula +neck +necks +nectar +ned +need +needle +needs +needy +negate +neigh +neil +nell +nelsen +nelson +neon +nepal +neptune +nerd +nero +nerve +ness +nest +nests +net +nets +network +neuron +neutral +neutron +nevada +never +new +newly +news +newt +newton +next +nexus +nib +nibs +nice +nicer +nicety +niche +nick +nickel +niece +nifty +niger +nigh +night +nil +nile +nimbus +nina +nine +nineteen +ninety +ninja +ninth +nip +nirvana +nit +nitric +nitro +nitty +nix +nixon +noah +nob +nobel +noble +nobody +nod +nodal +node +nods +noel +noise +noisy +nolan +nomad +nominal +nonce +none +nook +noon +noose +nope +nor +nora +norm +norma +normal +north +norway +nose +noses +nosy +not +notch +note +noted +notes +nothing +notre +noun +nouns +nova +novak +novel +november +now +nowhere +nuance +nubia +nuclear +nuclei +nucleus +nude +nudge +nuke +null +numb +number +numeric +nun +nuns +nurse +nut +nutmeg +nuts +nutty +nylon +nymph +oaf +oak +oaken +oakley +oar +oars +oases +oasis +oat +oath +oats +oberon +obese +obey +obeys +obit +object +objet +oboe +obscure +observe +ocarina +occur +ocean +ochre +oct +octal +octave +octavia +octet +october +octopus +odd +oddity +odds +ode +odin +odium +odor +odors +off +offal +offend +offer +office +oft +often +ogden +ogle +ogled +ogles +ogre +ohio +ohm +oil +oiled +oils +oily +oink +okay +okays +okinawa +oklahoma +okra +olaf +olav +old +olden +older +oldy +olga +olive +oliver +olivia +olympic +omaha +oman +omega +omen +omens +omicron +omit +omits +once +one +onion +only +onset +onto +onus +onward +onyx +ooze +oozed +opal +opals +open +openly +opens +opera +opinion +opium +optic +optimal +optimum +option +opus +oral +orange +orate +orb +orbit +orbital +orbs +orca +orchid +ordain +order +ore +oregano +oregon +organ +organic +orient +origami +origin +orion +orlando +ornery +orphan +osaka +oscar +osier +oslo +othello +other +otis +otter +otto +ouch +ought +ounce +our +ours +oust +out +outdo +outer +outlaw +outside +ouzo +ova +oval +ovals +ovary +ovate +oven +ovens +over +overt +ovid +owe +owed +owen +owens +owes +owing +owl +owls +own +owned +owner +owners +owns +oxen +oxeye +oxford +oxide +oxnard +oxygen +ozark +ozone +pablo +pabst +pace +paces +pacific +pack +package +packet +packs +pact +pad +paddy +padre +pads +pagan +page +pages +pagoda +paid +pail +pain +pains +paint +pair +pal +palace +paladin +pale +pall +palm +palma +palms +pals +palsy +pam +pamela +pan +panama +pancake +panda +pandora +pane +panel +pang +panic +pans +pansy +pant +panther +pants +panty +papa +papal +paper +pappy +paprika +papua +par +paradox +parch +pardon +parent +pareto +pariah +paris +park +parker +parking +parks +parlor +parody +parole +parrot +parry +parse +parsley +part +partner +parts +party +pascal +pass +passage +passive +past +pasta +paste +pastel +pasty +pat +patch +patent +path +paths +patient +patio +patriot +patrol +pats +patsy +pattern +patton +patty +paul +paula +pauli +paulo +pause +pave +paved +paves +paw +pawed +pawn +pawns +paws +pax +pay +payday +paz +pea +peace +peach +peak +peaks +peaky +peal +pear +pearl +pears +peas +peat +pebble +pecan +peck +pecks +pedal +pedro +peek +peel +peep +peer +peeve +peg +pegasus +peggy +pegs +pelican +pelt +pen +penal +pence +pencil +pend +penguin +penny +pens +pent +peony +people +pep +pepper +peppy +percent +perch +percy +perez +perfect +perform +perfume +peril +period +perk +perks +perky +perm +permit +perry +persia +person +perth +peru +peruse +pest +pests +pet +petal +pete +peter +petit +petri +pets +petty +pew +phage +phantom +phase +phenol +phi +phil +phoenix +phone +phony +photo +phrase +phyla +physic +piano +pica +picasso +piccolo +pick +picks +pickup +picky +picnic +picture +pie +piece +pier +pierce +pierre +piers +pies +piety +pig +pigeon +pigment +pigs +pigsty +pike +pile +piles +pilgrim +pill +pills +pilot +pimple +pin +pinball +pinch +pine +pines +ping +pinion +pink +pins +pint +pinto +pinup +pioneer +pious +pip +pipe +piper +pique +pirate +piston +pit +pita +pitch +pith +pithy +pitney +pits +pity +pius +pivot +pixel +pixie +pizza +place +plague +plaid +plain +plan +plane +planet +plank +plant +plasm +plasma +plastic +plat +plate +plato +play +playa +plays +plaza +plea +plead +pleas +pleat +pledge +pliny +plod +plods +plop +plot +plots +plow +plows +ploy +ploys +pluck +plug +plugs +plum +plumb +plume +plump +plums +plunk +plus +plush +plushy +pluto +ply +poach +pocket +pod +podge +podium +pods +poe +poem +poems +poet +poetic +poetry +pogo +poi +point +poise +poison +poke +poked +poker +pokes +polar +polaris +pole +poles +police +polio +politic +politics +polk +polka +poll +polls +polo +polygon +pomona +pomp +poncho +pond +ponds +pong +pony +pooch +pooh +pool +pools +poor +pop +popcorn +pope +poppy +pops +popular +porch +pore +pores +pork +porous +port +portal +portia +porto +ports +portugal +pose +posed +poses +posey +posh +posit +posse +post +postage +poster +posts +pot +potato +pots +potter +pouch +pound +pour +pours +pout +pouts +pow +powder +power +pox +prague +pram +prank +prawn +pray +prays +precise +preen +prefer +prefix +prelude +premium +prep +prepare +present +press +presto +pretend +pretty +prey +price +prick +pride +prig +prim +prime +primp +prince +print +printer +prior +prism +prissy +private +privy +prize +pro +probe +problem +process +prod +prodigy +prods +product +profile +program +project +prom +promise +promo +prone +prong +proof +prop +propel +proper +props +propyl +prose +prosper +protect +protest +proton +proud +prove +provide +prow +prowl +proxy +prude +prune +prunes +pry +psalm +psych +pub +public +pubs +puce +puck +pucker +puddle +puddly +pudgy +puerto +puff +puffin +puffs +puffy +pug +puke +pull +pulls +pulp +pulsar +pulse +puma +pump +pumps +pun +punch +punic +punish +punk +punks +punky +puns +punt +punts +puny +pup +pupil +puppy +pure +purge +purify +purple +purse +pus +push +pushy +put +puts +putty +puzzle +pygmy +pyramid +pyre +pyrex +pyrite +python +qatar +quack +quad +quaff +quail +quake +quality +qualm +quark +quarry +quart +quarter +quash +quasi +quay +queasy +quebec +queen +quell +query +quest +queue +quick +quid +quiet +quill +quilt +quilts +quint +quip +quips +quirk +quit +quite +quits +quiver +quiz +quota +quote +rabbi +rabbit +rabid +race +raced +races +rachel +rack +racy +radar +radial +radical +radii +radio +radish +radium +radius +radon +rafael +raft +rafts +rag +rage +raged +rags +raid +raids +rail +rails +rain +rainbow +rains +rainy +raise +raisin +raj +raja +rake +raked +rakes +rally +ralph +ram +raman +rambo +ramirez +ramp +rams +ramsey +ran +ranch +random +rang +range +ranger +rangy +rank +ranks +rant +rants +rap +rapid +raps +rapt +rare +rascal +rash +rasp +rat +rate +rated +rates +rating +ratio +rats +rattle +rave +raved +raven +ravioli +raw +ray +raymond +rays +raze +razor +reach +read +reads +ready +reagan +real +realm +ream +reap +rear +reave +rebel +rebut +recap +recipe +recital +reck +record +recur +recycle +red +redeem +redo +reduce +reed +reeds +reef +reek +reeks +reel +reels +reese +reeve +refer +reflex +reform +regal +regard +regina +region +regis +regular +rehab +reich +reid +reign +rein +reins +reject +relax +relay +relic +rely +reman +remark +remedy +remit +remix +remora +remote +remus +rend +renew +reno +renown +rent +rents +rep +repair +repay +repeat +repel +repent +reply +report +reps +reptile +request +rerun +reset +resin +resort +respect +respond +rest +rests +result +resume +retch +return +reuse +reveal +revel +reverse +revet +review +revved +reward +rewove +rex +rheum +rhine +rhino +rho +rhode +rhyme +rib +ribbon +ribs +ricardo +rice +rich +richard +richmond +rick +rico +rid +ride +rider +ridge +rifle +rift +rig +riga +rigel +right +rigid +rigs +riley +rill +rim +rims +rind +ring +ringo +rings +rink +rinse +rio +riot +riots +rip +ripe +ripen +ripley +rips +rise +risen +risk +risky +rite +ritual +ritz +rival +river +rivet +riviera +roach +road +roads +roam +roar +roast +rob +robe +robert +robin +robot +robs +rock +rocket +rocks +rocky +rod +rode +rodent +rodeo +rods +roe +roger +rogue +roil +role +roll +rolls +roman +rome +romeo +romp +ron +ronald +rondo +rood +roof +rook +rookie +room +rooms +roomy +roost +root +roots +rope +rosa +rose +rosen +rosetta +ross +rosy +rot +rote +roth +rotor +rots +rouge +rough +round +rouse +rout +route +rove +rover +row +rowdy +rows +roy +royal +royce +rub +rubber +rube +ruben +rubric +rubs +ruby +ruddy +rude +rudolf +rudy +rue +rufus +rug +rugged +rugs +ruin +ruins +rule +ruler +rules +rum +rumen +rummy +rumor +rump +rumpus +run +rune +runes +rung +runs +runt +runty +runway +rupee +rural +ruse +rush +russ +russia +russian +russo +rust +rusts +rusty +rut +ruth +ruts +rutty +ryan +rye +saber +sabine +sable +sabrina +sack +sacks +sacred +sad +sadden +saddle +sadly +safari +safe +safer +safes +sag +saga +sagas +sage +sags +sahara +said +sail +sailor +sails +saint +sake +salad +salami +salary +sale +salem +sales +saline +salk +sally +salmon +salon +salsa +salt +salts +salty +salute +salve +salvo +sam +samba +same +sammy +samoa +sample +samuel +sanchez +sand +sandal +sandra +sands +sandy +sane +sang +sanity +sank +santa +santana +sap +sappy +saps +sarah +sardine +sari +sase +sash +sat +satan +satin +saturday +saturn +satyr +sauce +saucy +saudi +saul +sauna +savage +save +saved +saves +savory +savoy +savvy +saw +saws +sawyer +sax +saxon +say +says +scab +scala +scald +scale +scalp +scam +scamp +scan +scans +scar +scare +scarf +scarlet +scars +scary +scene +scent +scholar +school +scion +scoff +scold +scoop +scoot +scope +scorch +score +scorn +scorpio +scott +scour +scout +scow +scowl +scram +scrap +scrape +scratch +screen +screw +scrip +script +scrod +scroll +scrub +scuba +scud +scuff +scull +scum +scurry +sea +seal +seals +seam +seams +sean +sear +seas +season +seat +seats +seattle +second +secret +sect +section +sector +sects +secure +sedan +seduce +see +seed +seeds +seedy +seek +seeks +seem +seems +seen +seep +seer +seers +sees +seethe +segment +seize +select +self +selfish +sell +sells +semi +seminar +senator +send +sends +seneca +senior +sense +sensor +sent +sentry +seoul +sepia +september +sequel +sequin +serf +serial +serif +serpent +serum +serve +service +servo +sesame +set +seth +sets +setup +seven +seventeen +seventh +seventy +sever +severe +sew +sewed +sewer +sewn +sews +shack +shade +shadow +shady +shaft +shag +shaggy +shah +shake +shaken +shaky +shale +shall +shallow +sham +shame +shampoo +shank +shannon +shape +shard +shards +share +shark +sharon +sharp +shave +shaw +shawl +she +shear +sheath +shed +sheds +sheen +sheep +sheer +sheet +sheik +shelf +shell +shelter +sheriff +sherman +shift +shifty +shill +shim +shin +shine +shins +shiny +ship +ships +shire +shirk +shirt +shiv +shoal +shock +shoe +shoes +shone +shook +shoot +shoots +shop +shops +shore +short +shot +shots +shout +shove +show +shown +shows +showy +shrank +shred +shrew +shriek +shrike +shrink +shrub +shrug +shuck +shun +shunt +shut +shuts +shy +shyly +siam +sick +side +siege +siena +sienna +sierra +siesta +sieve +sift +sifts +sigh +sight +sigma +sign +signal +signs +silence +silicon +silk +silks +silky +sill +silly +silo +silt +silty +silver +similar +simon +simons +simple +sin +sinai +sinatra +since +sincere +sine +sinew +sing +singe +single +sings +sink +sinks +sins +sinus +sioux +sip +sips +sir +sire +siren +sis +sister +sit +site +sites +sits +six +sixteen +sixth +sixty +size +sizes +ska +skate +skew +ski +skid +skids +skied +skiers +skies +skiff +skiffs +skiing +skill +skim +skimp +skimpy +skims +skin +skip +skips +skirt +skis +skit +skits +skulk +skull +skunk +sky +slab +slabs +slack +slag +slain +slalom +slam +slams +slang +slant +slap +slaps +slash +slat +slate +slater +slave +slaw +slay +sled +sleds +sleek +sleep +sleet +slept +slew +slice +slick +slid +slide +slim +slime +slimy +sling +slip +slips +slit +sliver +sloan +slob +slog +slogan +sloop +slop +slope +sloppy +slops +slosh +slot +sloth +slots +slow +slows +slug +slugs +sluice +slum +slump +slums +slung +slur +slurp +slurs +sly +slyly +smack +small +smart +smash +smear +smell +smelt +smile +smirk +smith +smithy +smock +smog +smoggy +smoke +smoky +smooth +smudgy +smug +smut +snack +snafu +snag +snail +snails +snake +snap +snaps +snare +snark +snarl +snatch +sneak +sneer +sniff +snip +snipe +snob +snobs +snook +snoop +snore +snort +snot +snout +snow +snows +snowy +snub +snubs +snuff +snug +soak +soaks +soap +soapy +soar +soars +sob +sober +sobs +social +society +sock +socks +sod +soda +sofa +sofia +soft +soften +soggy +soil +soils +sol +solar +sold +sole +solemn +solid +solo +solomon +solve +soma +somber +some +son +sonar +sonata +song +songs +sonic +sonny +sonora +sons +sony +soon +soot +sooth +sop +soprano +sore +sorry +sort +sorts +sot +sough +soul +sound +soup +soupy +sour +source +sousa +south +soviet +sow +sown +sows +soy +soyuz +spa +space +spade +spain +spam +span +spank +spans +spar +spare +spark +sparks +sparta +spas +spasm +spat +spawn +spay +speak +spear +special +speck +sped +speech +speed +spell +spend +spent +sperm +spew +sphere +sphinx +spice +spicy +spider +spies +spike +spill +spilt +spin +spine +spins +spiral +spire +spires +spirit +spit +spite +spits +spitz +splat +splay +spline +split +spock +spoil +spoke +sponge +sponsor +spoof +spook +spooky +spool +spoon +spore +sport +spot +spots +spout +sprain +sprang +spray +sprays +spree +sprig +spring +spruce +spry +spud +spun +spunk +spur +spurn +spurs +spurt +spy +squad +square +squat +squaw +squid +squint +squirm +stab +stabs +stack +stacy +stadium +staff +stag +stage +staid +stain +stains +stair +stake +stale +stalk +stall +stamp +stan +stance +stand +stank +stanza +staph +star +stare +stark +stars +start +stash +stat +state +static +stats +statue +status +stave +stay +stays +stead +steady +steak +steal +steam +steed +steel +steep +steer +stein +stella +stem +stems +step +steps +stereo +sterile +stern +steve +stew +stick +sticky +stiff +stigma +stile +still +sting +stingy +stink +stint +stir +stirs +stock +stoic +stoke +stole +stomp +stone +stony +stood +stool +stoop +stop +stops +store +stork +storm +stormy +story +stout +stove +stow +strafe +strange +strap +straw +stray +street +stretch +strewn +strike +strip +stroll +strong +strum +strut +stuart +stub +stuck +stud +student +studio +study +stuff +stuffy +stump +stun +stung +stunk +stuns +stunt +style +styx +suave +sub +subject +subs +subtle +subtly +subway +such +suck +sucks +sudan +suds +sue +sued +suede +sues +suez +sugar +suit +suite +suits +sulfur +sulk +sulks +sulky +sully +sultan +sultry +sum +sumac +summer +summon +sumo +sums +sun +sunday +sung +sunk +sunny +suns +sunset +sunup +sup +super +supper +support +supra +supreme +sure +surf +surge +survive +susan +sushi +susie +suss +suzy +swag +swam +swami +swamp +swampy +swan +swanky +swans +swap +swarm +swart +swat +swath +sway +sways +swear +sweat +sweaty +swede +sweden +sweep +sweet +swell +swept +swift +swig +swim +swims +swine +swing +swipe +swirl +swish +swiss +switch +swoop +sword +swore +sworn +swum +swung +sybil +sykes +sylvan +symbol +syria +syrup +system +tab +table +tablet +taboo +tabs +tacit +tack +tacky +taco +tacoma +tact +tactic +tad +taffy +taft +tag +tags +tahiti +tahoe +taiga +tail +tailor +tails +taint +take +taken +takes +talc +tale +talent +tales +talk +talks +tall +tallow +tally +talon +tam +tame +tamer +tampa +tamper +tan +tang +tango +tangy +tank +tanks +tans +tanya +tao +tap +tape +taped +taper +tapes +tapir +taps +tar +tara +tardy +target +tariff +tarp +tarry +tart +tarts +tarzan +task +taste +tasty +tattle +tattoo +tau +taunt +taurus +taut +tavern +tawny +tax +taxi +tea +teach +teacher +teacup +teak +teal +team +teams +tear +tease +tech +ted +teddy +tee +teem +teen +teens +teensy +tees +teeth +teflon +telecom +telex +tell +tells +temper +temple +tempo +tempt +ten +tend +tends +tenet +tennis +tenor +tens +tense +tensor +tent +tenth +tents +tepee +tepid +term +terms +tern +terry +terse +test +tests +testy +texan +texas +text +textile +thai +than +thank +that +thatch +thaw +thaws +the +theft +their +them +theme +then +theory +there +thermos +these +theta +they +thick +thief +thigh +thin +thing +think +thins +third +thirsty +thirteen +thirty +this +thomas +thong +thor +thorn +thorny +thousand +threat +three +threw +throb +throes +throw +throws +thrum +thud +thug +thumb +thump +thursday +thwart +thyme +tiara +tiber +tibet +tibia +tic +tick +ticket +ticks +tics +tidal +tidbit +tide +tidy +tie +tied +tier +ties +tiger +tight +tilde +tile +tiled +tiles +till +tilt +tilth +tim +time +times +timid +tin +tina +tine +tinge +tinny +tint +tiny +tip +tipoff +tips +tipsy +tire +tired +tires +titan +titanic +tithe +title +titus +toad +toads +toast +tobacco +toby +today +toe +toes +tofu +tog +toga +togo +togs +toil +toilet +toils +token +tokyo +told +toll +tolls +tom +tomato +tomb +tombs +tome +tommy +ton +tonal +tone +tong +tonga +tonic +tonight +tonk +tons +tonsil +tony +too +took +tool +tools +toot +tooth +top +topaz +topic +topple +tops +topsy +torah +torch +torn +tornado +toronto +torpedo +torso +tort +torus +toss +tot +total +tote +totem +tots +touch +tough +tour +tourist +tours +tout +tow +towel +tower +town +tows +toxic +toxin +toy +toys +trace +track +tract +tractor +tracy +trade +traffic +tragedy +trail +train +trait +tram +tramp +trance +transit +trap +trapeze +traps +trash +travel +trawl +tray +trays +tread +treat +treble +tree +trees +trek +trench +trend +tress +triad +trial +triangle +tribal +tribe +tribune +trick +tricky +trident +tried +tries +trill +trilogy +trim +trims +trinity +trio +trip +tripe +tripod +trips +trite +triton +trivial +trod +troll +trombone +troop +tropic +trot +trots +trout +troy +truce +truck +trudge +trudy +true +truly +trumpet +trunk +truss +trust +truth +try +tub +tuba +tube +tubes +tubs +tuck +tudor +tues +tuesday +tuft +tufts +tug +tugs +tulane +tulip +tulsa +tumble +tuna +tunas +tune +tuned +tunic +tunis +tunnel +tuple +turbine +turbo +turf +turin +turk +turkey +turn +turquoise +turtle +turvy +tush +tusk +tusks +tussle +tutor +tutu +tux +twain +tweak +tweed +twelfth +twelve +twenty +twice +twig +twigs +twill +twin +twine +twins +twirl +twist +twisty +twit +two +twos +tyburn +tycoon +tying +tyke +tyler +type +typed +types +typic +typo +tyson +uganda +ugly +ulcer +ultra +umber +umbra +umpire +unary +uncle +uncut +under +undo +undue +unfit +unhand +unhook +unicorn +uniform +unify +union +unique +unit +unite +united +units +unity +unix +unsafe +untie +until +unto +unwed +update +upend +uphill +uphold +upon +upper +uproar +upset +uptake +upton +uranium +urban +urea +urge +urged +urgent +urges +urine +urn +ursula +usage +use +used +useful +user +uses +usher +usual +usurp +utah +utile +utmost +utopia +utter +uvula +vacuum +vague +vail +vain +vale +valet +valeur +valid +valor +value +valve +vampire +van +vane +vanilla +vans +vapor +variant +vase +vases +vast +vat +vatican +vats +vault +veal +vector +veer +veers +vega +veggie +veil +vein +veins +velcro +veldt +vellum +velvet +venal +vendor +vends +venial +venice +venom +vent +vents +ventura +venus +vera +verb +verbs +verge +verify +verity +vermont +vern +verne +verona +verse +version +vertigo +verve +very +vessel +vest +vests +vet +veteran +veto +vets +vex +vexed +vexes +via +vial +vials +vibes +vibrate +vicar +vice +vices +vichy +vicky +victor +victory +video +vie +vienna +view +vigil +vigor +viking +vile +villa +village +vincent +vine +vines +vinyl +viola +violet +violin +viper +virgil +virginia +virgo +virtual +virus +visa +visible +vision +visit +visitor +visor +vista +visual +vital +vitamin +viva +vivian +vivid +vixen +vocal +vodka +vogue +voice +void +volcano +volga +volt +voltage +volts +volume +vomit +voodoo +vortex +vote +vouch +vow +vowel +vows +voyage +voyager +vulcan +vulture +vying +wack +wacky +wad +wade +wades +wafer +waffle +wag +wage +wager +wages +waggle +wagon +wags +waif +wail +wails +waist +wait +waiter +waive +wake +waken +waldo +wale +walk +wall +walls +wally +walrus +walsh +walt +walter +walton +waltz +wan +wand +wane +wang +want +wants +war +warble +ward +warden +ware +warm +warmth +warn +warning +warns +warp +warren +wars +wart +warts +warty +wary +was +wash +washington +washy +wasp +wasps +wast +waste +watch +water +watt +watts +wave +waved +waver +waves +wavy +wax +waxen +waxy +way +wayne +ways +weak +weal +wealth +wean +wear +wears +weary +weather +weave +web +weber +webs +webster +wed +wedding +wedge +wednesday +weds +weed +weedy +week +weekend +weeks +weep +weeps +weigh +weir +weird +welch +welcome +weld +well +wells +welsh +welt +wendy +went +wept +were +west +western +wet +wets +whack +whale +wham +wharf +what +wheat +wheel +wheels +whelp +when +where +which +whig +while +whim +whine +whinny +whip +whips +whir +whirl +whisk +whiskey +whit +white +whiz +who +whole +whom +whoop +whoosh +whose +why +wick +wide +widen +wider +widow +width +wield +wife +wig +wigs +wild +wile +wiley +will +william +wills +willy +wilma +wilt +wily +wimp +wimpy +win +wince +winch +wind +window +windup +windy +wine +wines +wing +wings +wink +winks +winner +wins +winter +wipe +wire +wires +wiry +wisconsin +wisdom +wise +wiser +wish +wisp +wispy +wit +witch +with +wits +witty +wive +wizard +woe +woes +wok +woke +wolf +woman +womb +women +won +wonder +wong +wood +woods +woody +woof +wool +woozy +word +words +wordy +wore +work +world +worm +worms +wormy +worn +worry +worse +worst +worth +would +wound +wove +woven +wow +wrack +wraith +wrap +wrath +wreak +wreck +wren +wring +wrist +writ +write +writhe +wrong +wrote +wry +wyatt +wyoming +xenon +xerox +xylem +yacht +yak +yale +yalta +yam +yams +yang +yank +yankee +yanks +yard +yards +yarn +yaw +yawn +yawns +yeah +year +yearn +yeast +yeasty +yell +yellow +yemen +yen +yep +yes +yet +yew +yews +yield +yin +yip +yips +yodel +yoga +yogi +yogurt +yoke +yokel +yolk +yore +york +you +young +your +yours +youth +yowl +yowls +yoyo +yucca +yuck +yukon +yule +zaire +zap +zaps +zeal +zealot +zebra +zen +zenith +zero +zeroes +zest +zesty +zeta +zeus +ziggy +zigzag +zilch +zinc +zing +zinger +zion +zip +zipper +zippers +zips +ziti +zodiac +zoe +zone +zoned +zoning +zoo +zoom +zooms +zoos +zulu +zurich diff --git a/messages/uniworx/de.msg b/messages/uniworx/de.msg index afbffb76e..ab5dc2045 100644 --- a/messages/uniworx/de.msg +++ b/messages/uniworx/de.msg @@ -91,6 +91,7 @@ SheetDelText submissionNo@Int: Dies kann nicht mehr rückgängig gemacht w SheetDelOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh}: #{sheetName} gelöscht. SheetUploadMode: Abgabe von Dateien +SheetSubmissionMode: Abgabe-Modus SheetExercise: Aufgabenstellung SheetHint: Hinweis SheetHintFrom: Hinweis ab @@ -111,6 +112,8 @@ SheetActiveTo: Abgabefrist SheetHintFromTip: Ohne Datum nie für Teilnehmer sichtbar, Korrektoren können diese Dateien immer herunterladen SheetSolutionFromTip: Ohne Datum nie für Teilnehmer sichtbar, Korrektoren können diese Dateien immer herunterladen SheetMarkingTip: Hinweise zur Korrektur, sichtbar nur für Korrektoren +SheetPseudonym: Persönliches Abgabe-Pseudonym +SheetGeneratePseudonym: Generieren SheetErrVisibility: Sichtbarkeit muss vor Beginn der Abgabefrist liegen SheetErrDeadlineEarly: Ende der Abgabefrist muss nach deren Beginn liegen @@ -155,6 +158,8 @@ UnauthorizedSheetTime: Dieses Übungsblatt ist momentan nicht freigegeben. UnauthorizedSubmissionOwner: Sie sind an dieser Abgabe nicht beteiligt. UnauthorizedSubmissionRated: Diese Abgabe ist noch nicht korrigiert. UnauthorizedSubmissionCorrector: Sie sind nicht der Korrektor für diese Abgabe. +UnauthorizedUserSubmission: Nutzer dürfen für dieses Übungsblatt keine Abgaben erstellen. +UnauthorizedCorrectorSubmission: Korrektoren dürfen für dieses Übungsblatt keine Abgaben erstellen. OnlyUploadOneFile: Bitte nur eine Datei hochladen. DeprecatedRoute: Diese Ansicht ist obsolet und könnte in Zukunft entfallen. UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben. @@ -307,6 +312,10 @@ UploadModeNone: Kein Upload UploadModeUnpack: Upload, einzelne Datei UploadModeNoUnpack: Upload, ZIP-Archive entpacken +SheetNoSubmission: Keine Abgabe +SheetCorrectorSubmissions: Abgaben durch Korrektoren +SheetUserSubmissions: Direkte Abgabe + SubmissionNoUploadExpected: Es ist keine Abgabe von Dateien vorgesehen. FieldPrimary: Hauptfach diff --git a/models b/models index cb599b025..d53603dd1 100644 --- a/models +++ b/models @@ -111,11 +111,18 @@ Sheet hintFrom UTCTime Maybe solutionFrom UTCTime Maybe uploadMode UploadMode + submissionMode SheetSubmissionMode default='UserSubmissions' CourseSheet course name SheetEdit user UserId time UTCTime sheet SheetId +SheetPseudonym + sheet SheetId + pseudonym Pseudonym + user UserId + UniqueSheetPseudonym sheet pseudonym + UniqueSheetPseudonymUser sheet user SheetCorrector user UserId sheet SheetId diff --git a/package.yaml b/package.yaml index c9f2e9858..656ac5902 100644 --- a/package.yaml +++ b/package.yaml @@ -93,6 +93,7 @@ dependencies: - connection - universe - universe-base +- random - random-shuffle - th-abstraction - HaskellNet @@ -104,6 +105,7 @@ dependencies: - aeson-pretty - resourcet - postgresql-simple +- word24 # The library contains all of our application code. The executable # defined below is just a thin wrapper. diff --git a/routes b/routes index 6116665dc..5a4d9b4a6 100644 --- a/routes +++ b/routes @@ -72,7 +72,7 @@ /edit SEditR GET POST /delete SDelR GET POST /subs SSubsR GET POST -- for lecturer only - /subs/new SubmissionNewR GET POST !timeANDregistered + /subs/new SubmissionNewR GET POST !timeANDregisteredANDuser-submissions /subs/own SubmissionOwnR GET !free -- just redirect /sub/#CryptoFileNameSubmission SubmissionR !correctorANDisRead: / SubShowR GET POST !ownerANDtime !ownerANDisRead @@ -80,6 +80,7 @@ /correction CorrectionR GET POST !corrector !ownerANDisReadANDrated !/#SubmissionFileType/*FilePath SubDownloadR GET !owner /correctors SCorrR GET POST + /pseudonym SPseudonymR POST !registeredANDcorrector-submissions !/#SheetFileType/*FilePath SFileR GET !timeANDregistered !timeANDmaterials !corrector diff --git a/src/Foundation.hs b/src/Foundation.hs index 6bef15386..6dfa15ce7 100644 --- a/src/Foundation.hs +++ b/src/Foundation.hs @@ -481,6 +481,22 @@ knownTags = Map.fromList -- should not throw exceptions, i.e. no getBy404 or req return Authorized r -> $unsupportedAuthPredicate "rated" r ) + ,("user-submissions", APDB $ \route _ -> case route of + CSheetR tid ssh csh shn _ -> maybeT (unauthorizedI MsgUnauthorizedUserSubmission) $ do + Entity cid _ <- MaybeT . getBy $ TermSchoolCourseShort tid ssh csh + Entity _ Sheet{sheetSubmissionMode} <- MaybeT . getBy $ CourseSheet cid shn + guard $ sheetSubmissionMode == UserSubmissions + return Authorized + r -> $unsupportedAuthPredicate "user-submissions" r + ) + ,("corrector-submissions", APDB $ \route _ -> case route of + CSheetR tid ssh csh shn _ -> maybeT (unauthorizedI MsgUnauthorizedCorrectorSubmission) $ do + Entity cid _ <- MaybeT . getBy $ TermSchoolCourseShort tid ssh csh + Entity _ Sheet{sheetSubmissionMode} <- MaybeT . getBy $ CourseSheet cid shn + guard $ sheetSubmissionMode == CorrectorSubmissions + return Authorized + r -> $unsupportedAuthPredicate "corrector-submissions" r + ) ,("isRead", APHandler . const $ bool (return Authorized) (unauthorizedI MsgUnauthorizedWrite)) ,("isWrite", APHandler . const $ bool (unauthorizedI MsgUnauthorized) (return Authorized)) ] diff --git a/src/Handler/Sheet.hs b/src/Handler/Sheet.hs index 92aed1fab..bb3e5d78a 100644 --- a/src/Handler/Sheet.hs +++ b/src/Handler/Sheet.hs @@ -14,6 +14,7 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE MultiWayIf, LambdaCase #-} {-# LANGUAGE TupleSections #-} +{-# LANGUAGE NamedFieldPuns #-} module Handler.Sheet where @@ -62,6 +63,12 @@ import Data.Monoid (Sum(..), Any(..)) import Control.Lens -- import Utils.Lens +import qualified Data.Text as Text +import qualified Data.Aeson as Aeson + +import Control.Monad.Random.Class (MonadRandom(..)) +import Utils.Sql + instance Eq (Unique Sheet) where (CourseSheet cid1 name1) == (CourseSheet cid2 name2) = @@ -82,6 +89,7 @@ data SheetForm = SheetForm , sfVisibleFrom :: Maybe UTCTime , sfActiveFrom :: UTCTime , sfActiveTo :: UTCTime + , sfSubmissionMode :: SheetSubmissionMode , sfUploadMode :: UploadMode , sfSheetF :: Maybe (Source Handler (Either FileId File)) , sfHintFrom :: Maybe UTCTime @@ -120,6 +128,7 @@ makeSheetForm msId template = identForm FIDsheet $ \html -> do & setTooltip MsgSheetActiveFromTip) (sfActiveFrom <$> template) <*> areq utcTimeField (fslI MsgSheetActiveTo) (sfActiveTo <$> template) + <*> areq submissionModeField (fslI MsgSheetSubmissionMode) ((sfSubmissionMode <$> template) <|> pure UserSubmissions) <*> areq uploadModeField (fslI MsgSheetUploadMode) ((sfUploadMode <$> template) <|> pure (Upload True)) <*> aopt (multiFileField $ oldFileIds SheetExercise) (fslI MsgSheetExercise) (sfSheetF <$> template) <*> aopt utcTimeField (fslpI MsgSheetHintFrom "Datum, sonst nur für Korrektoren" @@ -244,6 +253,21 @@ getSheetListR tid ssh csh = do $(widgetFile "sheetList") $(widgetFile "widgets/sheetTypeSummary") +data ButtonGeneratePseudonym = BtnGenerate + deriving (Enum, Eq, Ord, Bounded, Read, Show) +instance Universe ButtonGeneratePseudonym +instance Finite ButtonGeneratePseudonym + +$(return []) + +instance PathPiece ButtonGeneratePseudonym where + toPathPiece = $(nullaryToPathPiece ''ButtonGeneratePseudonym [Text.unwords . drop 1 . splitCamel]) + fromPathPiece = finiteFromPathPiece + +instance Button UniWorX ButtonGeneratePseudonym where + label BtnGenerate = [whamlet|_{MsgSheetGeneratePseudonym}|] + cssClass BtnGenerate = BCDefault + -- Show single sheet getSShowR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html getSShowR tid ssh csh shn = do @@ -307,6 +331,12 @@ getSShowR tid ssh csh shn = do visibleFrom <- traverse (formatTime SelFormatDateTime) $ sheetVisibleFrom sheet when (NTop (sheetVisibleFrom sheet) >= NTop cTime) $ addMessageI Warning $ maybe MsgSheetInvisible MsgSheetInvisibleUntil visibleFrom + mPseudonym <- runMaybeT $ do + uid <- MaybeT maybeAuthId + Entity _ SheetPseudonym{sheetPseudonymPseudonym} <- MaybeT . runDB . getBy $ UniqueSheetPseudonymUser sid uid + return . Text.unwords . map CI.original $ review pseudonymWords sheetPseudonymPseudonym + (generateWidget, generateEnctype) <- generateFormPost $ \csrf -> + over _2 ((toWidget csrf <>) . fvInput) <$> mreq (buttonField BtnGenerate) "" Nothing defaultLayout $ do setTitleI $ MsgSheetTitle tid ssh csh shn sheetFrom <- formatTime SelFormatDateTime $ sheetActiveFrom sheet @@ -315,6 +345,26 @@ getSShowR tid ssh csh shn = do solutionFrom <- traverse (formatTime SelFormatDateTime) $ sheetSolutionFrom sheet $(widgetFile "sheetShow") +postSPseudonymR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler TypedContent +postSPseudonymR tid ssh csh shn = do + uid <- requireAuthId + shId <- runDB $ fetchSheetId tid ssh csh shn + let + genPseudonym = do + inserted <- runDB . setSerializable $ do + candidate <- liftIO getRandom + fmap (const candidate) <$> insertUnique (SheetPseudonym shId candidate uid) + case inserted of + Nothing -> genPseudonym + Just ps -> return ps + ps <- genPseudonym + let ps' = Text.unwords . map CI.original $ review pseudonymWords ps + selectRep $ do + provideRep $ return ps' + provideRep . return $ Aeson.String ps' + provideRep (redirect $ CSheetR tid ssh csh shn SShowR :: Handler Html) + + getSFileR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> SheetFileType -> FilePath -> Handler TypedContent getSFileR tid ssh csh shn typ title = do results <- runDB $ E.select $ E.from $ @@ -366,6 +416,7 @@ getSheetNewR tid ssh csh = do , sfVisibleFrom = addOneWeek <$> sheetVisibleFrom , sfActiveFrom = addOneWeek sheetActiveFrom , sfActiveTo = addOneWeek sheetActiveTo + , sfSubmissionMode = sheetSubmissionMode , sfUploadMode = sheetUploadMode , sfSheetF = Nothing , sfHintFrom = addOneWeek <$> sheetHintFrom @@ -400,6 +451,7 @@ getSEditR tid ssh csh shn = do , sfVisibleFrom = sheetVisibleFrom , sfActiveFrom = sheetActiveFrom , sfActiveTo = sheetActiveTo + , sfSubmissionMode = sheetSubmissionMode , sfUploadMode = sheetUploadMode , sfSheetF = Just . yieldMany . map Left . Set.elems $ sheetFileIds SheetExercise , sfHintFrom = sheetHintFrom @@ -441,6 +493,7 @@ handleSheetEdit tid ssh csh msId template dbAction = do , sheetHintFrom = sfHintFrom , sheetSolutionFrom = sfSolutionFrom , sheetUploadMode = sfUploadMode + , sheetSubmissionMode = sfSubmissionMode } mbsid <- dbAction newSheet case mbsid of diff --git a/src/Handler/Utils/Form.hs b/src/Handler/Utils/Form.hs index 1061f4256..0da366171 100644 --- a/src/Handler/Utils/Form.hs +++ b/src/Handler/Utils/Form.hs @@ -228,6 +228,13 @@ uploadModeField = selectFieldList , (MsgUploadModeUnpack , Upload True ) ] +submissionModeField :: Field Handler SheetSubmissionMode +submissionModeField = selectFieldList + [ (MsgSheetNoSubmission, NoSubmissions) + , (MsgSheetCorrectorSubmissions, CorrectorSubmissions) + , (MsgSheetUserSubmissions, UserSubmissions) + ] + zipFileField :: Bool -- ^ Unpack zips? -> Field Handler (Source Handler File) zipFileField doUnpack = Field{..} diff --git a/src/Jobs.hs b/src/Jobs.hs index 5008b0e35..302736570 100644 --- a/src/Jobs.hs +++ b/src/Jobs.hs @@ -10,7 +10,6 @@ , QuasiQuotes , NamedFieldPuns , MultiWayIf - , NumDecimals #-} module Jobs @@ -43,6 +42,7 @@ import Data.Monoid (Last(..)) import Data.Semigroup (Max(..)) import Utils.Lens +import Utils.Sql import Control.Monad.Random (evalRand, uniform, mkStdGen) @@ -81,9 +81,6 @@ import Data.Time.Zones import Control.Concurrent.STM (retry) -import Database.PostgreSQL.Simple (sqlErrorHint) -import Control.Monad.Catch (handleIf) - data JobQueueException = JInvalid QueuedJobId QueuedJob | JLocked QueuedJobId InstanceId UTCTime @@ -346,17 +343,6 @@ runDBJobs act = do forM_ jIds $ writeJobCtl . JobCtlPerform return ret -setSerializable :: DB a -> DB a -setSerializable act = setSerializable' (0 :: Integer) - where - act' = [executeQQ|SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|] *> act - - setSerializable' (min 10 -> logBackoff) = - handleIf - (\e -> sqlErrorHint e == "The transaction might succeed if retried.") - (\e -> $logWarnS "SQL" (tshow e) *> threadDelay (1e3 * 2 ^ logBackoff) *> setSerializable' (succ logBackoff)) - act' - pruneLastExecs :: Crontab JobCtl -> DB () pruneLastExecs crontab = runConduit $ selectSource [] [] .| C.mapM_ ensureCrontab where diff --git a/src/Model/Types.hs b/src/Model/Types.hs index 87d6d579d..5643349cf 100644 --- a/src/Model/Types.hs +++ b/src/Model/Types.hs @@ -8,6 +8,7 @@ {-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts, UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE BinaryLiterals #-} {-- # LANGUAGE ExistentialQuantification #-} -- for DA type {-# OPTIONS_GHC -fno-warn-orphans #-} -- for instance PathPiece (CI Text) @@ -74,6 +75,13 @@ import Mail (MailLanguages(..)) import Utils.DateTime (DateTimeFormat(..), SelDateTimeFormat(..)) import Numeric.Natural +import Data.Word.Word24 (Word24) +import Data.Bits +import Data.Ix +import Data.List (genericIndex, elemIndex) +import System.Random (Random(..)) + +import Model.Types.Wordlist instance PathPiece UUID where @@ -226,6 +234,16 @@ data UploadMode = NoUpload | Upload { unpackZips :: Bool } deriveJSON defaultOptions ''UploadMode derivePersistFieldJSON ''UploadMode +data SheetSubmissionMode = NoSubmissions + | CorrectorSubmissions + | UserSubmissions + deriving (Show, Read, Eq, Ord, Enum, Bounded) + +deriveJSON defaultOptions + { constructorTagModifier = intercalate "-" . map toLower . splitCamel + } ''SheetSubmissionMode +derivePersistField "SheetSubmissionMode" + data ExamStatus = Attended | NoShow | Voided deriving (Show, Read, Eq, Ord, Enum, Bounded) derivePersistField "ExamStatus" @@ -241,8 +259,6 @@ deriveJSON defaultOptions ''Load derivePersistFieldJSON ''Load - - instance Semigroup Load where (Load byTut prop) <> (Load byTut' prop') = Load byTut'' (prop + prop') where @@ -518,6 +534,45 @@ instance ToBackendKey SqlBackend record => Hashable (Key record) where derivePersistFieldJSON ''MailLanguages +newtype Pseudonym = Pseudonym Word24 + deriving (Eq, Ord, Read, Show) + deriving newtype (Bounded, Enum, Integral, Num, Real, Bits, FiniteBits, Ix) + + +instance PersistField Pseudonym where + toPersistValue p = toPersistValue (fromIntegral p :: Word32) + fromPersistValue = fmap (fromIntegral :: Word32 -> Pseudonym) . fromPersistValue + +instance PersistFieldSql Pseudonym where + sqlType _ = SqlInt32 + +instance Random Pseudonym where + randomR (lo, hi) gen = over _1 (fromIntegral :: Word32 -> Pseudonym) $ randomR (min 0 $ fromIntegral lo, max 0b111111111111 $ fromIntegral hi) gen + random = randomR (0, 0b111111111111) + +pseudonymWordlist :: [CI Text] +pseudonymWordlist = $(wordlist "config/wordlist.txt") + +pseudonymWords :: Prism' [CI Text] Pseudonym +pseudonymWords = prism' pToWords pFromWords + where + pFromWords :: [CI Text] -> Maybe Pseudonym + pFromWords [w1, w2] + | Just i1 <- elemIndex w1 pseudonymWordlist + , Just i2 <- elemIndex w2 pseudonymWordlist + , i1 <= maxWord, i2 <= maxWord + = Just $ shift (fromIntegral i1) (-12) .|. fromIntegral i2 + pFromWords _ = Nothing + + pToWords :: Pseudonym -> [CI Text] + pToWords p = [ genericIndex pseudonymWordlist $ shift p 12 .&. maxWord + , genericIndex pseudonymWordlist $ p .&. maxWord + ] + + maxWord :: Num a => a + maxWord = 0b111111111111 + + -- Type synonyms type Email = Text diff --git a/src/Model/Types/Wordlist.hs b/src/Model/Types/Wordlist.hs new file mode 100644 index 000000000..d4bab9e8c --- /dev/null +++ b/src/Model/Types/Wordlist.hs @@ -0,0 +1,40 @@ +{-# LANGUAGE NoImplicitPrelude + , TemplateHaskell + , ViewPatterns + , OverloadedStrings + #-} + +module Model.Types.Wordlist (wordlist) where + +import ClassyPrelude hiding (lift) + +import Language.Haskell.TH +import Language.Haskell.TH.Syntax (qAddDependentFile, Lift(..)) + +import Data.Text (Text) +import qualified Data.Text as Text +import qualified Data.Text.IO as Text + +import qualified Data.CaseInsensitive as CI + +wordlist :: FilePath -> ExpQ +wordlist file = do + qAddDependentFile file + wordlist' <- runIO $ filter ((||) <$> not . isComment <*> isWord) . Text.lines <$> Text.readFile file + listE $ map (\(Text.unpack -> word) -> [e|CI.mk $ Text.pack $(lift word)|]) wordlist' + +isWord :: Text -> Bool +isWord t + | [w] <- Text.words t + , w == t + = True + | otherwise + = False + +isComment :: Text -> Bool +isComment line = or + [ commentSymbol `Text.isPrefixOf` Text.stripStart line + , Text.null $ Text.strip line + ] + where + commentSymbol = "#" diff --git a/src/Utils/Sql.hs b/src/Utils/Sql.hs new file mode 100644 index 000000000..5e456bc28 --- /dev/null +++ b/src/Utils/Sql.hs @@ -0,0 +1,30 @@ +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE QuasiQuotes #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE ViewPatterns #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE NumDecimals #-} +{-# LANGUAGE FlexibleContexts #-} + +module Utils.Sql + ( setSerializable + ) where + +import ClassyPrelude.Yesod + +import Database.Persist.Sql + +import Database.PostgreSQL.Simple (sqlErrorHint) +import Control.Monad.Catch (handleIf) + +setSerializable :: (MonadLogger m, MonadCatch m, MonadBase IO m, MonadIO m) => ReaderT SqlBackend m a -> ReaderT SqlBackend m a +setSerializable act = setSerializable' (0 :: Integer) + where + act' = [executeQQ|SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|] *> act + + setSerializable' (min 10 -> logBackoff) = + handleIf + (\e -> sqlErrorHint e == "The transaction might succeed if retried.") + (\e -> $logWarnS "Sql" (tshow e) *> threadDelay (1e3 * 2 ^ logBackoff) *> setSerializable' (succ logBackoff)) + act' + diff --git a/templates/sheetShow.cassius b/templates/sheetShow.cassius new file mode 100644 index 000000000..88a0e3b7f --- /dev/null +++ b/templates/sheetShow.cassius @@ -0,0 +1,2 @@ +.pseudonym + font-family: monospace \ No newline at end of file diff --git a/templates/sheetShow.hamlet b/templates/sheetShow.hamlet index 47e2014b9..69f967573 100644 --- a/templates/sheetShow.hamlet +++ b/templates/sheetShow.hamlet @@ -25,6 +25,14 @@ $maybe marking <- sheetMarkingText sheet