@@ -73,6 +73,15 @@ interface WordOptions {  
		
	
		
			
			    count: boolean;  
		
	
		
			
			}  
		
	
		
			
			 
		
	
		
			
			const emptyConfig: WordOptions = {  
		
	
		
			
			  capital: false,  
		
	
		
			
			  count: false,  
		
	
		
			
			  kind: NounKind.Specific,  
		
	
		
			
			  plural: false,  
		
	
		
			
			  proper: false,  
		
	
		
			
			  vowel: VowelSound.Default  
		
	
		
			
			}  
		
	
		
			
			 
		
	
		
			
			export type TextLike = { toString: () => string }  
		
	
		
			
			 
		
	
		
			
			// updates as needed  
		
	
	
		
			
				
				
				
				
					 
			
			@@ -96,61 +105,98 @@ export class DynText {  
		
	
		
			
			    return (this.parts.map(part => part.toString())).join('')  
		
	
		
			
			  }  
		
	
		
			
			}  
		
	
		
			
			export class Noun implements Pluralizable {  
		
	
		
			
			  constructor (private singularNoun: string, private pluralNoun: string|null = null, private options: WordOptions = { plural: false, capital: false, proper: false, kind: NounKind.Specific, vowel: VowelSound.Default, count: true }) {  
		
	
		
			
			 
		
	
		
			
			export abstract class Word {  
		
	
		
			
			  constructor (public opt: WordOptions = emptyConfig) {  
		
	
		
			
			 
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get capital (): Noun {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options)  
		
	
		
			
			  abstract configure (opts: WordOptions): Word;  
		
	
		
			
			  abstract toString (): string;  
		
	
		
			
			 
		
	
		
			
			  // These functions are pure; they don't mutate the original object.  
		
	
		
			
			  // This is necessary to avoid causing chaos.  
		
	
		
			
			 
		
	
		
			
			  get capital (): Word {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.capital = true  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun, opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get plural (): Noun {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options)  
		
	
		
			
			  get plural (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.plural = true  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun,  opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get proper (): Noun  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options )  
		
	
		
			
			  get proper (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.proper = true  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun,  opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get improper (): Noun  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options )  
		
	
		
			
			  get improper (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.proper = false  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun,  opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get specific (): Noun  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options )  
		
	
		
			
			  get specific (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.kind = NounKind.Specific  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun,  opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get nonspecific (): Noun  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options )  
		
	
		
			
			  get nonspecific (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.kind = NounKind.Nonspecific  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun,  opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get all (): Noun  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options )  
		
	
		
			
			  get all (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.kind = NounKind.All  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun,  opts)  
		
	
		
			
			    return this.configure( opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get uncountable (): Noun  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.options )  
		
	
		
			
			  get uncountable (): Word  {  
		
	
		
			
			    const opts: WordOptions = Object.assign({}, this.opt)  
		
	
		
			
			    opts.count = false  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun, opts)  
		
	
		
			
			    return this.configure(opts)  
		
	
		
			
			  }  
		
	
		
			
			}  
		
	
		
			
			 
		
	
		
			
			export class RandomWord extends Word {  
		
	
		
			
			  private last: number  
		
	
		
			
			 
		
	
		
			
			  constructor (public choices: Array<Word>, opt: WordOptions = emptyConfig) {  
		
	
		
			
			    super(opt)  
		
	
		
			
			    this.last = -1  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  configure (opts: WordOptions): Word {  
		
	
		
			
			    return new RandomWord(this.choices, opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  toString (): string {  
		
	
		
			
			    let choice  
		
	
		
			
			 
		
	
		
			
			    do {  
		
	
		
			
			      choice = Math.floor(Math.random() * this.choices.length)  
		
	
		
			
			    } while (choice === this.last)  
		
	
		
			
			 
		
	
		
			
			    this.last = choice  
		
	
		
			
			    return this.choices[choice].configure(this.opt).toString()  
		
	
		
			
			  }  
		
	
		
			
			}  
		
	
		
			
			 
		
	
		
			
			export class Noun extends Word {  
		
	
		
			
			  constructor (private singularNoun: string, private pluralNoun: string|null = null, private options: WordOptions = emptyConfig) {  
		
	
		
			
			    super(options)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  get isPlural (): boolean {  
		
	
		
			
			    return this.options.plural  
		
	
		
			
			  configure (opts: WordOptions): Word  {  
		
	
		
			
			    return new Noun(this.singularNoun, this.pluralNoun, opts)   
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  toString (): string {  
		
	
	
		
			
				
				
					 
			
			@@ -208,6 +254,20 @@ export class ProperNoun extends Noun {  
		
	
		
			
			  }  
		
	
		
			
			}  
		
	
		
			
			 
		
	
		
			
			export class Adjective extends Word {  
		
	
		
			
			  constructor (private adjective: string, opt: WordOptions = emptyConfig) {  
		
	
		
			
			    super(opt)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  configure (opts: WordOptions): Word {  
		
	
		
			
			    return new Adjective(this.adjective, opts)  
		
	
		
			
			  }  
		
	
		
			
			 
		
	
		
			
			  toString (): string {  
		
	
		
			
			    return this.adjective  
		
	
		
			
			  }  
		
	
		
			
			}  
		
	
		
			
			 
		
	
		
			
			interface PronounDict {  
		
	
		
			
			    subjective: string;  
		
	
		
			
			    objective: string;