Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion GNN

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description The Galactic News Network. The Galactic News Network.
Identifier oolite.oxp.Svengali.GNN oolite.oxp.Svengali.GNN
Title GNN GNN
Category Ambience Ambience
Author Svengali Svengali
Version 1.2 1.2
Tags ambience, child, news ambience, child, news
Required Oolite Version
Maximum Oolite Version
Required Expansions
  • oolite.oxp.Svengali.Library:1.7.1
  • oolite.oxp.Svengali.Library:1.7.1
  • Optional Expansions
    Conflict Expansions
    Information URL http://wiki.alioth.net/index.php/GNN n/a
    Download URL https://wiki.alioth.net/img_auth.php/1/1e/GNN1.2.oxz n/a
    License CC-by-nc-sa 4.0 CC-by-nc-sa 4.0
    File Size n/a
    Upload date 1610873245

    Documentation

    Also read http://wiki.alioth.net/index.php/GNN

    Readme.txt

    GNN 1.2 for Oolite
    Copyright 2009-2018 by DaddyHoggy, Drew, Disembodied and Svengali.
    Licences: see below
    November 2018
    
    REQUIREMENTS:
    - Oolite v1.88
    - Library v1.7.1
    
    
    PROBLEMS:
    In case of problems, please report it: http://aegidian.org/bb/viewtopic.php?f=4&t=19419
    
    Please include the following infos:
    - Oolites version (and if trunk or nightly is used the revision number)
    - OS, Graphics card (and driver version)
    - Fullscreen/Windowed mode
    - Shader mode
    - List of used OXPs (incl. versions)
    
    Licences:
    Creative Commons Attribution-NonCommercial-ShareAlike 4.0 Unported License.
    To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ or
     send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.
    

    Equipment

    This expansion declares no equipment.

    Ships

    This expansion declares no ships.

    Models

    This expansion declares no models.

    Scripts

    Path
    Scripts/GNN.js
    /* global clock,expandDescription,expandMissionText,galaxyNumber,mission,missionVariables,player,system,worldScripts,Vector3D */
    /* (C) DaddyHoggy, Drew, Disembodied and Svengali 2009-2018, License CC-by-nc-sa-4.0 */
    (function(){
    "use strict";
    this.name = "GNN";
    this.description = "The Galactic News Network";
    
    this.$snoop = {
    	audio: true,
    	fifo: [],
    	hot: [],
    	maxDays: 24,
    	nextNews: 0,
    	unused: []
    };
    this.$doop = {
    	ext: [ // Some events
    		{ws:"AsteroidStorm",prop:{name:"badRockKiller",v:"PLAYER"},mV:{name:"asteroids",v:"asteroids_OVER"},
    			act:{EX:"AsteroidStorm",m:"badrock",p:1,Model:"badrock",Spin:1}},
    		{ws:"oolite-constrictor-hunt",mV:{name:"conhunt",v:"CONSTRICTOR_DESTROYED"},
    			act:{m:"conhunt",p:1,Model:"constrictor",Spin:1}},
    		{ws:"oolite-nova",mV:{name:"nova",v:"NOVA_ESCAPED_SYSTEM"},
    			act:{m:"nova",p:1,Mat:{"lib_null.png":{emission_map:"GNN_solar.png",fragment_shader:"GNN_solar.fs",vertex_shader:"lib_simple.vs",
    			textures:["GNN_solar.png",{name:"lib_explode2.png",repeat_s:true,repeat_t:true}],uniforms:{colorMap:{type:"texture",value:0},
    			fxMap:{type:"texture",value:1},Time:"timeElapsedSinceSpawn"}}}}}
    	],
    	hud: false,
    	inf: {Name:"GNN",Display:"Config",Alive:"$doop.inf",
    		Bool:{B0:{Name:"$snoop.audio",Def:true,Desc:"Audio"}},
    		SInt:{S0:{Name:"$snoop.maxDays",Def:24,Min:12,Max:99,Desc:"Interval"},Info:"^GNN_INFS"}
    	},
    	intern: 206,
    	expImages:[[],[],[],[]],
    	expPrefixes:[]
    };
    this.startUp = function(){
    	var infos,oxpID,i, k = this.$snoop;
    	if(missionVariables.GNN){
    		infos = JSON.parse(missionVariables.GNN);
    		for(i=0;i<infos.unused.length;i++){
    			if(!infos.unused[i]) continue;
    			oxpID = infos.unused[i].ID;
    			if(worldScripts[oxpID]) k.fifo.push(infos.unused[i]);
    			else k.unused.push(infos.unused[i]);
    		}
    		for(i=0;i<infos.fifo.length;i++){
    			if(!infos.fifo[i]) continue;
    			oxpID = infos.fifo[i].ID;
    			if(worldScripts[oxpID]) k.fifo.push(infos.fifo[i]);
    			else k.unused.push(infos.fifo[i]);
    		}
    		k.nextNews = infos.nextNews;
    		for(i=0;i<infos.hot.length;i++){
    			if(infos.hot[i]) k.hot.push(infos.hot[i]);
    		}
    		k.audio = infos.audio;
    		k.maxDays = infos.maxDays;
    	}
    	this._aid = worldScripts.Lib_Main._lib;
    	delete this.startUp;
    };
    this.startUpComplete = function(){
    	this._updInterface(player.ship.dockedStation);
    	this._resort();
    	worldScripts.Lib_Config._registerSet(this.$doop.inf);
    	for(var i=0;i<this.$doop.ext.length;i++){
    		if(!worldScripts[this.$doop.ext[i].ws]) this.$doop.ext[i] = null;
    	}
    	this.$doop.ext = this._aid.arrOmit(this.$doop.ext,null);
    	delete this.startUpComplete;
    };
    this.playerWillSaveGame = function(){
    	missionVariables.GNN = JSON.stringify(this.$snoop);
    };
    this.shipWillDockWithStation = function(){
    	var i,obj,pass;
    	for(i=0;i<this.$doop.ext.length;i++){
    		pass = 0;
    		obj = this.$doop.ext[i];
    		if(obj.prop){
    			if(worldScripts[obj.ws][obj.prop.name]===obj.prop.v) pass++;
    		} else pass++;
    		if(obj.mV){
    			if(missionVariables[obj.mV.name]===obj.mV.v) pass++;
    		} else pass++;
    		if(pass===2) this._addHot(obj.act);
    	}
    };
    this.shipExitedWitchspace = function(){
    	if(galaxyNumber === 3 && missionVariables.nova === "TWO_HRS_TO_ZERO") missionVariables.GNN_nova = system.name;
    };
    this._addHot = function(o){
    	var x = {ID:"GNN",Message:o.m,Priority:o.p,Delay:clock.days+1};
    	if(o.Model){
    		x.Model = o.Model;
    		if(o.Spin) x.Spin = o.Spin;
    	}
    	if(o.EX) x.EX = o.EX;
    	if(o.Tex) x.Tex = o.Tex;
    	if(o.Mat) x.Mat = o.Mat;
    	this.$snoop.hot.push(x);
    };
    this.shipDockedWithStation = function(st){
    	if(player.ship.docked){
    		this._updInterface(st);
    		this._resort();
    	}
    };
    this.dayChanged = function(newday){
    	var x = Math.floor(Math.random()*100),i,obj,m, k = this.$snoop;
    	for(i=0;i<k.hot.length;i++){
    		obj = k.hot[i];
    		if(obj && obj.Delay<=newday){
    			if(obj.ID==="GNN"){
    				obj.AutoPos = 1;
    				obj.Message = "GNN_"+obj.Message;
    				if(obj.EX) obj.ID = obj.EX;
    			}
    			if(worldScripts[obj.ID]) k.fifo.push(obj);
    			else k.unused.push(obj);
    			k.hot[i] = null;
    			k.hot = this._aid.arrOmit(k.hot,null);
    			i--;
    		}
    	}
    	if(k.hot.length) k.hot = this._aid.arrOmit(k.hot,null);
    	if(k.fifo.length<3){
    		if(newday>k.nextNews){
    			switch(x){
    				case 5: m = "GNN_A"; break;
    				case 9: m = "GNN_B"; break;
    				case 13: m = "GNN_C"; break;
    				case 17: m = "GNN_D"; break;
    				default: m = "Intern";
    			}
    			k.fifo.push({ID:"GNN",Message:m,Priority:5});
    			k.nextNews = newday+this._aid.randXY(Math.floor(k.maxDays/2),k.maxDays);
    		}
    	}
    	if(player.ship.docked) this._updInterface(player.ship.dockedStation);
    };
    this._doScreen = function(){worldScripts.GNN.$doop.hud = player.ship.hudHidden; player.ship.hudHidden = true; worldScripts.GNN._showScreen(); return;};
    this._showScreen = function(obj){
    	if(!player.ship.docked || system.isInterstellarSpace) return false;
    	var what,ret,ws;
    	var head = {
    		choices: {BACK:"Back"},
    		exitScreen: "GUI_SCREEN_INTERFACES",
    		message: "No news available.",
    		model: "lib_ms_helper",
    		music: "GNN.ogg",
    		overlay: {name:"GNN_clean.png",height:512},
    		screenID: this.name,
    		spinModel: false,
    		title: ""
    	};
    	if(obj){ // Direct
    		if(this._aid.typeGet(obj)!=="object" || !obj.ID || !obj.Message) return false;
    		var news = this._setStandards(obj);
    		this._showInserted(head,news);
    	} else {
    		if(this.$snoop.fifo.length){
    			if(this.$snoop.fifo.length>1) head.choices.NEXT = "Next message";
    			what = this.$snoop.fifo[0];
    			if(what.ID==="GNN"){
    				switch(what.Message){
    					case "Intern": ret = this._showInternal(head); break;
    					case "GNN_A":
    					case "GNN_B":
    					case "GNN_C":
    					case "GNN_D": ret = this._showInternal(head,what.Message); break;
    					default: ret = this._showInserted(head,what); break;
    				}
    			} else ret = this._showInserted(head,what);
    		} else return false;
    	}
    	if(ret){
    		this.$snoop.fifo.shift();
    		this._updInterface(player.ship.dockedStation);
    		if(what.CB){
    			ws = worldScripts[what.ID];
    			if(what.CBID) this._aid.objPass(ws,what.CB,what.CBID);
    			else this._aid.objPass(ws,what.CB,what.Message);
    		}
    	}
    	return true;
    };
    this._setHead = function(head,obj){
    	var em,extI,ov,r,txt;
    	if(obj.Agency){
    		switch(obj.Agency){
    			case 1: ov = "A1"+this._aid.randXY(1,4); em = 1; break;
    			case 2: ov = "A2"+this._aid.randXY(1,4); em = 2; break;
    			case 3: ov = "A3"+this._aid.randXY(1,3); em = 3; break;
    			default: ov = "A4"+this._aid.randXY(1,4); em = 4; break;
    		}
    	} else if(obj.Pic){
    		// External image pack?
    		if(obj.PicExt){
    			if(this.$doop.expPrefixes.indexOf(obj.PicExt)!==-1) head.overlay = obj.Pic;
    		} else head.overlay = obj.Pic;
    	}
    	if(ov){
    		// Expanded image pool
    		extI = this.$doop.expImages[em-1];
    		if(extI.length && Math.random()>0.5){
    			r = this._aid.randXY(0,extI.length-1);
    			head.overlay = {name:extI[r],height:512};
    		} else head.overlay.name = "GNN_"+ov+".png";
    	}
    	if(obj.Music) head.music = obj.Music;
    	if(!this.$snoop.audio) head.music = null;
    	txt = expandMissionText(obj.Message);
    	if(obj.DKey) txt = expandDescription(obj.Message);
    	if(!txt) txt = obj.Message;
    	worldScripts.Lib_PAD.$config.last.news = txt;
    	head.message = "\n\n\n\n\n\n\n\n"+txt;
    	if(obj.Model){
    		head.model = obj.Model;
    		if(obj.Spin) head.spinModel = true;
    	}
    	return head;
    };
    this._setModelDef = function(obj,em){
    	var md = mission.displayModel,pa,pb,d,n;
    	if(md){
    		if(obj.Pos) md.position = obj.Pos;
    		if(em) this._aid.setMaterials(md,{mat:{"lib_null.png":{emission_map:"GNN_"+em+".png",fragment_shader:"GNN_"+em+".fs",vertex_shader:"lib_simple.vs",textures:[{name:"GNN_"+em+".png",repeat_s:true,repeat_t:true},{name:"GNN_blur.png",repeat_s:true,repeat_t:true}],uniforms:{colorMap:{type:"texture",value:0},fxMap:{type:"texture",value:1},Time:"timeElapsedSinceSpawn"}}}});
    		if(obj.Tex) this._aid.setMaterials(md,{mat:{"lib_null.png":{emission_map:obj.Tex}}});
    		if(obj.Mat) this._aid.setMaterials(md,{mat:obj.Mat});
    		if(obj.AutoPos){
    			pa = md.position;
    			pb = new Vector3D([28.4,20.2,84]);
    			d = pa.z*2.5/pb.z;
    			if(md.name==="lib_ms_helper") d = 1;
    			n = [pb.x*d,pb.y*d,pb.z*d];
    			md.position = n;
    			md.orientation = [1,0,0,0];
    		}
    		if(obj.Ori) md.orientation = obj.Ori;
    	}
    };
    this._showInserted = function(head,obj){
    	head = this._setHead(head,obj);
    	mission.runScreen(head,this._choices);
    	if(obj.Model) this._setModelDef(obj);
    	else this._setModelDef(obj,obj.Agency?obj.Agency:1);
    	return 1;
    };
    this._showInternal = function(head,gen){
    	var em,n,nstr,ov,r,txt,extI;
    	if(gen){
    		ov = "A1"+this._aid.randXY(1,4);
    		em = 1;
    		txt = worldScripts.GNN_PhraseGen._makePhrase(gen);
    	} else {
    		n = this._aid.randXY(1,this.$doop.intern);
    		nstr = this._aid.toNLZ(n,4);
    		txt = expandMissionText("GNN_"+nstr);
    		if(txt[0]==="#"){
    			switch(txt[1]){
    				case "1": ov = "A1"+this._aid.randXY(1,4); em = 1; break;
    				case "2": ov = "A2"+this._aid.randXY(1,4); em = 2; break;
    				case "3": ov = "A3"+this._aid.randXY(1,3); em = 3; break;
    				default: ov = "A4"+this._aid.randXY(1,4); em = 4; break;
    			}
    			txt = txt.substr(2);
    		} else {
    			ov = "A4"+this._aid.randXY(1,4);
    			em = 4;
    		}
    	}
    	// Expanded image pool
    	extI = this.$doop.expImages[em-1];
    	if(extI.length && Math.random()>0.5){
    		r = this._aid.randXY(0,extI.length-1);
    		head.overlay = {name:extI[r],height:512};
    	} else head.overlay = {name:"GNN_"+ov+".png",height:512};
    	head.message = "\n\n\n\n\n\n\n\n"+txt;
    	worldScripts.Lib_PAD.$config.last.news = txt;
    	if(!this.$snoop.audio) head.music = null;
    	mission.runScreen(head,this._choices);
    	this._setModelDef({AutoPos:1},em);
    	return 1;
    };
    this._choices = function(choice){
    	switch(choice){
    		case "NEXT": worldScripts.GNN._showScreen(); break;
    		case "BACK": player.ship.hudHidden = worldScripts.GNN.$doop.hud;
    	}
    };
    this._updInterface = function(st){
    	if((st.isMainStation || (st.scriptInfo && st.scriptInfo.GNN) || st.hasNPCTraffic) && !system.isInterstellarSpace){
    		if(this.$snoop.fifo.length){
    			player.ship.dockedStation.setInterface("GNN",{
    				title:"Galactic News Network. ("+this.$snoop.fifo.length+" available)",
    				category:"News",
    				summary:"4 established news agencies bringing you the latest news. Directly onto your screen, through your eyeballs and into your brain.",
    				callback:this._doScreen.bind(this)}
    			);
    		} else player.ship.dockedStation.setInterface("GNN",null);
    	}
    };
    this._setStandards = function(obj){
    	var o = this._aid.objClone(obj);
    	if(o.Agency) o.Pic = null;
    	if(!o.Priority) o.Priority = 3;
    	if(o.Model) o.Tex = null;
    	else {
    		o.Ori = null;
    		o.Pos = null;
    	}
    	if(!o.Pos) o.AutoPos = 1;
    	return o;
    };
    this._insertNews = function(obj){
    	if(this._aid.typeGet(obj)!=="object" || !obj.ID || !obj.Message) return 1;
    	var news = this._setStandards(obj), no ,i;
    	if(news.Delay){
    		for(i=0;i<this.$snoop.hot.length;i++){
    			if(this.$snoop.hot[i].ID===obj.ID && this.$snoop.hot[i].Message===obj.Message) no = 1;
    		}
    		if(!no){
    			news.Delay += clock.days;
    			this.$snoop.hot.push(news);
    		}
    	} else {
    		for(i=0;i<this.$snoop.fifo.length;i++){
    			if(this.$snoop.fifo[i].ID===obj.ID && this.$snoop.fifo[i].Message===obj.Message) no = 1;
    		}
    		if(!no){
    			this.$snoop.fifo.push(news);
    			if(player.ship.docked){
    				this._resort();
    				this._updInterface(player.ship.dockedStation);
    			}
    		}
    	}
    	return 0;
    };
    this._resort = function(){
    	if(this.$snoop.fifo.length>1) this.$snoop.fifo = this._aid.arrSortBy(this.$snoop.fifo,'Priority');
    };
    this._addExtImages = function(arr,ws){
    	if(this._aid.typeGet(arr)!=="array" || typeof(ws)!=="string") return false;
    	this.$doop.expImages = this._aid.arrConcat(this.$doop.expImages,arr);
    	this.$doop.expPrefixes.push(ws);
    	return true;
    };
    this._Help = function(what){
    	var h;
    	switch(what){
    		case "_insertNews": h = "GNN_HELP_insertNews"; break;
    		case "_showScreen": h = "GNN_HELP_showScreen"; break;
    		case "_addExtImages": h = "GNN_HELP_addExtImages"; break;
    		default: h = "GNN_HELP";
    	}
    	return expandMissionText(h);
    };
    }).call(this);
    
    Scripts/GNN_PhraseGen.js
    /* jshint bitwise:false, forin:false */
    /* global clock,expandDescription,expandMissionText,galaxyNumber,log,player,system,worldScripts,System,Timer */
    /* (C) Disembodied and Svengali 2009-2018, License CC-by-nc-sa-4.0 */
    (function(){
    "use strict";
    this.name = "GNN_PhraseGen";
    
    this.$recGuard = true;
    this.$galaxyStats = [];
    this.startUp = function(){
    	delete this.startUp;
    	this.$init = true;
    	this.$spec = {
    		currentSystem: {},
    		rndBrew: [],
    		rndFirstName: [],
    		rndShipName: [],
    		rndSurName: [],
    		rndSystem: [],
    		idsA: ["I","II","III","IV","V","VI","VII","IX","X"],
    		idsB: ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],
    		idsC: ["0","1","2","3","4","5","6","7","8","9"]
    	};
    	this.$pool = worldScripts.GNN_Words.pool;
    	this.$irNouns = worldScripts.GNN_Words.irregularNouns;
    	this.$irVerbs = worldScripts.GNN_Words.irregularVerbs;
    	this.$suptive = worldScripts.GNN_Words.superlatives;
    	this._getGalaxy();
    	this._fillInBits(1);
    };
    /* Experimental
    this.startUpComplete = function(){
    	var d = "",s;
    	for(var i=0;i<256;i++){
    		s = this.$galaxyStats[i];
    		d += s.name+"|"+s.description+"#";
    	}
    	worldScripts.Lib_PAD._addPageInCategory("SYSTEMS.ALMANACH",{$hide:d});
    };
    */
    // Entry point for OXPs.
    this._makePhrase = function(set,pattern,store,seed,cst){
    	if(!set) return(false);
    	if(typeof(set)==='object') this.$stdObj = set;
    	else {
    		if(typeof(this.$pool[set])==='undefined') return false;
    		this.$stdObj = this.$pool[set];
    	}
    	var option = {
    		patt: null,
    		store: 0,
    		seed: 0,
    		cst: []
    	};
    	if(typeof(pattern)!=='undefined') option.patt = pattern;
    	if(store) option.store = true;
    	if(seed) option.seed = seed;
    	if(cst) option.cst = cst;
    	var t = this._buildPhrase(option.patt,option.store,option.seed,option.cst);
    	return t;
    };
    // Entry point for OXPs.
    this._addSample = function(samplename,obj,clone){
    	if(typeof(obj) !== 'object' || typeof(samplename) !== 'string' || typeof(this.$pool[samplename]) !== 'undefined') return false;
    	if(clone) this.$pool[samplename] = this._cloneObj(obj);
    	else this.$pool[samplename] = obj;
    	return true;
    };
    this._fillInBits = function(rep){
    	this.$spec.rndBrew = [];
    	this.$spec.rndFirstName = [];
    	this.$spec.rndShipName = [];
    	this.$spec.rndSurName = [];
    	if(rep) this.$spec.rndSystem = this.$galaxyStats;
    	this._setCur();
    	this.$spec.rndFirstName.push(this._makePhrase("GNN_Names","1"));
    	this.$spec.rndFirstName.push(this._makePhrase("GNN_Names","2"));
    	this.$spec.rndFirstName.push(this._makePhrase("GNN_Names","12"));
    	this.$spec.rndSurName.push(this._makePhrase("GNN_Names","{1"));
    	this.$spec.rndSurName.push(this._makePhrase("GNN_Names","{1"));
    	this.$spec.rndSurName.push(this._makePhrase("GNN_Names","{1"));
    	this.$spec.rndBrew.push(this._makePhrase("GNN_NamesBrews"));
    	this.$spec.rndShipName.push(this._makePhrase("GNN_NamesShips"));
    	delete this.$init;
    };
    this._setCur = function(){
    	if(system.isInterstellarSpace) this.$spec.currentSystem = {description:"interstellar",economy:-1,government:-1,ID:-1,inhabitant:"none",name:"interstellar",population:-1,productivity:-1,radius:-1,sun:false,techlevel:-1};
    	else this.$spec.currentSystem = this.$galaxyStats[system.ID];
    };
    this.shipWillDockWithStation = function(){
    	if(!system.isInterstellarSpace) this._fillInBits();
    };
    this.shipWillLaunchFromStation = function(){
    	this._setCur();
    };
    this.playerEnteredNewGalaxy = function(){
    	this.$init = true;
    	this._getGalaxy();
    	this._fillInBits(1);
    };
    this.shipWillExitWitchspace = function(){
    	if(this.$init) return;
    	this._setCur();
    };
    this.$stdObj = {
    	fieldA:[],fieldB:[],fieldC:[],fieldD:[],fieldE:[],fieldF:[],fieldG:[],fieldH:[],fieldI:[],
    	fieldJ:[],fieldK:[],fieldL:[],fieldM:[],fieldN:[],fieldO:[],fieldP:[],fieldQ:[],fieldR:[],
    	sentences:[],custom:[],splitRules:[]
    };
    this.$fields = [["fieldA","fieldJ"],["fieldB","fieldK"],["fieldC","fieldL"],["fieldD","fieldM"],
    	["fieldE","fieldN"],["fieldF","fieldO"],["fieldG","fieldP"],["fieldH","fieldQ"],["fieldI","fieldR"]];
    this._cloneObj = function(srcInstance){
    	if(typeof(srcInstance)!=='object' || srcInstance===null) return srcInstance;
    	var newInstance = srcInstance.constructor();
    	for(var i in srcInstance) newInstance[i] = this._cloneObj(srcInstance[i]);
    	return newInstance;
    };
    this._random = function(maxnum){
    	return maxnum*(Math.random()%1) | 0;
    };
    // Random number in range a-b in steps of s
    this._rndRange = function(a,b,s){
    	var x = Math.random();
    	var y = (b*x)-(a*x)+1;
    	if(!y) return a;
    	var z = Math.floor(y/s);
    	return a+z*s;
    };
    // First letter uppercase
    this._initialCap = function(str){
    	if(!str) return "";
    	return str[0].toUpperCase() + str.substr(1);
    };
    // Rules
    this._makePlural = function(word){
    	// e,f,h,o,s,x,y
    	if(/[^es]s$/.test(word)) return word;
    	if(/fe$/.test(word)) return word.replace(/fe$/,"ves");
    	if(/e$/.test(word)) return word + "s";
    	if(/(?:[^ei]x|[^o]o|[es]s|[cs]h)$/.test(word)) return word + "es";
    	if(/s$/.test(word)) return word;
    	if(/[^aeou]y$/.test(word)) return word.replace(/y$/,"ies");
    	if(/[^erf]f$/.test(word)) return word.replace(/f$/,"ves");
    	if(/[ei]x$/.test(word)) return word.replace(/[ei]x$/,"ices");
    	return word + "s";
    };
    // Rules
    this._makePast = function(word){
    	// b,e,l,p,y
    	if(/e$/.test(word)) return word + "d";
    	if(/[^aeou]y$/.test(word)) return word.replace(/y$/,"ied");
    	if(/[^adeliosy][aeioy][bcdfgjklmnpqrsvz]$/.test(word)) return word + word[word.length-1] + "ed";
    	return word + "ed";
    };
    this._makeVerbPhrase = function(word,tense,markPlural){
    	var wsp = word.split(" ");
    	var wspl = wsp.length;
    	for(var i=0;i<wspl;i++){
    		var t = wsp[i].match(/[\$&]/g);
    		if(t && t.length){
    			var raw = wsp[i].replace(/[\$&]/g,""),flagP,flagS,flagH,flagI;
    			var ex = raw.match(/[^A-Za-z=]/g);
    			if(ex) raw = raw.replace(/[^A-Za-z=]/g,"");
    			var tl = t.length;
    			for(var o=0;o<tl;o++){
    				switch(t[o]){
    					case "&":
    						flagI=1;
    						raw = raw.replace(/=/," ");
    						if(typeof(this.$irVerbs[raw])!=='undefined') raw = this.$irVerbs[raw][(tense<4?tense:3)];
    						else flagI=0;
    						break;
    					case "$":
    						switch(tense){
    							case 0: if(markPlural) flagS=1; break;
    							case 1: if(!flagI) flagS=1; break;
    							case 2: flagP=1; break;
    							case 3: flagP=1; break;
    							case 4: flagH=1; flagP=1; break;
    						}
    						break;
    				}
    			}
    			if(flagS) raw = this._makePlural(raw);
    			if(flagI) flagI = 0;
    			else if(flagP) raw = this._makePast(raw);
    			if(flagH) raw = (markPlural?"have ":"has ")+raw;
    			if(ex) raw = raw + ex[0];
    			wsp[i] = raw;
    		}
    	}
    	return wsp.join(" ");
    };
    this._handleRules = function(wrd,tense,nextPlural,markShift,donot){
    	if(/[\$$^&]/.test(wrd)){
    		var irregNoun = 0;
    		// Verbs
    		if(/\$/.test(wrd)) wrd = this._makeVerbPhrase(wrd,tense,nextPlural);
    		else { // Nouns
    			var ex = wrd.match(/[^A-Za-z=]/g);
    			if(ex) wrd = wrd.replace(/[^A-Za-z=&]/g,"");
    			if(/&/g.test(wrd)){
    				irregNoun = 1;
    				wrd = wrd.replace(/&/,"");
    			}
    			if(nextPlural){
    				if(irregNoun && typeof(this.$irNouns[wrd])!=='undefined') wrd = this.$irNouns[wrd];
    				else wrd = this._makePlural(wrd);
    			}
    			if(ex) wrd = wrd + ex[0];
    		}
    	} else {
    		if(nextPlural && donot<2) wrd = this._makePlural(wrd);
    	}
    	return wrd;
    };
    this._handleCombiners = function(wrd,markShift,rec){
    	var last = 0;
    	var z = wrd.indexOf("[");
    	var y = wrd.charAt(z+1);
    	var x = this.$fields[y-1][markShift];
    	var w = this._getField(x,last,rec);
    	wrd = wrd.replace(/\[\d\]/,w[0]);
    	last = w[1];
    	if(rec<5){
    		if(/\[\d\]/g.test(w[0])){
    			rec++;
    			wrd = this._handleCombiners(wrd,markShift,rec);
    		}
    		rec--;
    		if(/\[\d\]/g.test(wrd)){
    			rec++;
    			wrd = this._handleCombiners(wrd,markShift,rec);
    		}
    		rec--;
    	} else if(this.$recGuard) log(this.name,"Warning! - FieldCombiner recursion limit.\n\nwrd:"+wrd+" : "+x+" : "+y+" : "+z+" : "+rec);
    	return wrd;
    };
    this._handleNV = function(word,tense,nextPlural,markShift){
    	var wr = word.split(" ");
    	var n = wr.length;
    	for(var i=0;i<n;i++){
    		var wrd = wr[i];
    		// field combiner
    		if(/\[\d\]/g.test(wrd)) wrd = this._handleCombiners(wrd,markShift,0);
    		// Verbs, nouns
    		var c = wrd.split(" ");
    		if(c.length>1){
    			var cc = c.length;
    			for(var o=0;o<cc;o++){
    				c[o] = this._handleRules(c[o],tense,nextPlural,markShift,cc);
    			}
    			wrd = c.join(" ");
    		} else wrd = this._handleRules(wrd,tense,nextPlural,markShift,n);
    		wrd = wrd.replace(/&$/,"");
    		wr[i] = wrd;
    	}
    	word = wr.join(" ");
    	return word;
    };
    this._cmpConditions = function(w,c,v,a){
    	switch(c){
    		case "<":
    			if(a<2){
    				if(this.$spec.currentSystem[w]<v) return true;
    			} else if(this.$spec.rndSystem[this.$lSys][w]<v) return true;
    			break;
    		case ">":
    			if(a<2){
    				if(this.$spec.currentSystem[w]>v) return true;
    			} else if(this.$spec.rndSystem[this.$lSys][w]>v) return true;
    			break;
    		case ":":
    			if(a<2){
    				if(this.$spec.currentSystem[w]==v) return true;
    			} else if(this.$spec.rndSystem[this.$lSys][w]==v) return true;
    			break;
    		case "!":
    			if(a<2){
    				if(this.$spec.currentSystem[w]!=v) return true;
    			} else if(this.$spec.rndSystem[this.$lSys][w]!=v) return true;
    			break;
    	}
    	return false;
    };
    this._parseConditions = function(wrd,remB){
    	var left = false, right = false, compare = 1, w = wrd.split(")"), c;
    	var wl = w.length;
    	for(var q=0;q<wl;q++){
    		var ex = w[q].match(/\(/g);
    		if(ex){
    			var exl = ex.length;
    			for(var i=0;i<exl;i++){
    				compare = 1;
    				var con = w[q].match(/\(.*/);
    				var act = con[0].split("="); // split conditions from actions (Sg:0,e<5 [4]|[7]
    				switch(act[0].charAt(1)){ // A,B,D,M,P,S,X,Y
    					case "A": compare = 5; break;
    					case "B": compare = 3; break;
    					case "D": compare = 4; break;
    					case "M": return expandMissionText(act[0].substr(3));
    					case "S":
    						compare = 2;
    						// prepare @S
    						if(this.$lSys<0) this._getRNDSystem();
    						break;
    					case "X": return expandDescription("["+act[0].substr(3)+"]");
    					case "Y": compare = 6; break;
    				}
    				// conditions
    				switch(compare){
    					case 1:
    					case 2:
    						c = act[0].substr(2).split(","); // multiple conditions
    						var cl = c.length;
    						for(var u=0;u<cl;u++){
    							var cx = c[u][1], cy = c[u].substr(2), cz;
    							switch(c[u][0]){
    								case "c": cz = "productivity"; break;
    								case "d":
    									var rega = new RegExp(cy,"g");
    									if(compare===1) left = rega.test(this.$spec.currentSystem.description);
    									else left = rega.test(this.$spec.rndSystem[this.$lSys].description);
    									if(cx==='!') left = !left;
    									break;
    								case "e": cz = "economy"; break;
    								case "g": cz = "government"; break;
    								case "i":
    									var regb = new RegExp(cy,"gi");
    									if(compare===1) left = regb.test(this.$spec.currentSystem.inhabitant);
    									else left = regb.test(this.$spec.rndSystem[this.$lSys].inhabitant);
    									if(cx==='!') left = !left;
    									break;
    								case "p": cz = "population"; break;
    								case "r": cz = "radius"; break;
    								case "s": cz = "sun"; break;
    								case "t": cz = "techlevel"; break;
    							}
    							if(cz) left = this._cmpConditions(cz,cx,cy,compare);
    							if(!left) break;
    						}
    						break;
    					case 3: //Bits
    						c = act[0].substr(2);
    						var bitID = parseInt(c)%30;
    						if(act.length<2){
    							if(c[c.length-1]==="+"){
    								this.$bits |= (1<<bitID);
    								left = true;
    							} else if(c[c.length-1]==="-"){
    								this.$bits &= ~(1<<bitID);
    								left = true;
    							}
    						}
    						if((this.$bits&(1<<bitID))!=0) left = true;
    						break;
    					case 4: //Dice
    						c = act[0].substr(2);
    						if(act.length<2){
    							var ns = c.split(",");
    							right = this._rndRange(+ns[0],+ns[1],+ns[2]);
    							left = true;
    						} else {
    							if(c>Math.floor(Math.random()*100)) left = true;
    						}
    						break;
    					case 5: //All
    						c = parseInt(act[0].substr(2));
    						if((this.$bits&c)===c) left = true;
    						break;
    					case 6: //Any
    						c = parseInt(act[0].substr(2));
    						if(this.$bits&c) left = true;
    						break;
    				}
    				// actions
    				if(act.length>1){
    					var acc = act[1].split("|");
    					if(!left){
    						if(acc.length>1) right = acc[1];
    					} else right = acc[0];
    				}
    				if(right) w[q] = w[q].replace(/\(.*/,right);
    				else w[q] = w[q].replace(/\(.*/,"");
    			}
    		}
    	}
    	wrd = w.join("");
    	if(remB) wrd = wrd.replace(/[\[\]]/g,"");
    	return wrd;
    };
    this._getField = function(field,last,rec){
    	var sp = this.$stdObj[field].length;
    	var r = this._random(sp);
    	if(this.$salt) r = ((0x357941*this.$salt)>>16)%sp;
    	else if(r===last) r = this._random(sp);
    	if(rec){
    		if(rec===5) r = sp-1;
    		else r = (r+rec)%sp;
    	}
    	var wrd = this.$stdObj[field][r];
    	if(/\([ABDMPSXY]/g.test(wrd)) wrd = this._parseConditions(wrd);
    	return([wrd,r]);
    };
    this._getRNDSystem = function(){
    	var sp = this.$spec.rndSystem.length,r;
    	if(this.$salt) r = ((0x357941*this.$salt)>>16)%sp;
    	else {
    		r = this._random(sp);
    		var reselect = 0;
    		while(r===this.$lSys){
    			r = this._random(sp);
    			reselect++;
    			if(reselect>10) break;
    		}
    	}
    	this.$lSys = r;
    	return r;
    };
    this._buildPhrase = function(OXPPattern,store,sd,cst,cpf,foo){
    	var pattern, cp = -1;
    	if(sd) sd = sd&0x1ff;
    	if(OXPPattern){
    		if(typeof(OXPPattern)==='object'){
    			cp = this._random(OXPPattern.length);
    			pattern = OXPPattern[cp];
    		} else {
    			cp = 0;
    			pattern = OXPPattern;
    		}
    	} else {
    		if(sd){
    			var sp = this.$stdObj.sentences.length;
    			cp = ((0x357941*sd)>>16)%sp;
    		} else cp = this._random(this.$stdObj.sentences.length);
    		pattern = this.$stdObj.sentences[cp];
    	}
    	var aFlag = 0, markShift = 0, tense = 0, nextPlural = 0, nextSpecial = 0, nextUpper = 1;
    	var lastA = -1, lastB = -1, lastC = -1, lastD = -1, lastE = -1, lastF = -1, lastG = -1, lastH = -1, lastI = -1;
    	var info = {num:""}, za = [], zb = 0, zc = [], zd = 0, wOffset = 0, lasts;
    	if(!foo){
    		this.$lSys = -1; this.$salt = (sd?sd:0)&0x1ff; this.$bits = 0; this.$limit = 0;
    		if(this.$stdObj.custom && this.$stdObj.custom.length){
    			if(!cst) this.$bits = this.$stdObj.custom[0];
    			else {
    				this.$bits = cst[0];
    				this.$stdObj.custom = cst;
    			}
    		}
    		lasts = {rndBrew:[],rndFirstName:[],rndSurName:[],rndShipName:[],rndSystem:[],rndTitle:[],lastWords:[]};
    	} else {
    		lasts = foo;
    		wOffset = foo.lastWords.length;
    		nextUpper = 0;
    	}
    	if(/\([ABDMPSXY]/g.test(pattern)){
    		za = pattern.match(/\([a-zA-Z0-9,:!><=\)\[\]\| @\+-_\{\}]+\)/g);
    		pattern = pattern.replace(/\([a-zA-Z0-9,:!><=\)\[\]\| @\+-_\{\}]+\)/g,"@?");
    	}
    	if(/\[[a-zA-Z_]+\]/g.test(pattern)){
    		zc = pattern.match(/\[[a-zA-Z_]+\]/g);
    		pattern = pattern.replace(/\[[a-zA-Z_]+\]/g,"@[");
    	}
    	pattern = pattern.split(" ");
    	var denpat = pattern.length, r = -1, tmp = null;
    	for(var p=0;p<denpat;p++){
    		var lenpat = pattern[p].length, txt = "", wrd = "", pushit = 0;
    		for (var ichr = 0; ichr < lenpat; ichr++){
    			var chr = pattern[p].charAt(ichr);
    			if(!nextSpecial){
    				switch(chr){
    					case '@': nextSpecial = 1; continue;
    					case '1':
    						tmp = this._getField(this.$fields[0][markShift],lastA);
    						wrd = tmp[0]; lastA = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '2':
    						tmp = this._getField(this.$fields[1][markShift],lastB);
    						wrd = tmp[0]; lastB = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '3':
    						tmp = this._getField(this.$fields[2][markShift],lastC);
    						wrd = tmp[0]; lastC = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '4':
    						tmp = this._getField(this.$fields[3][markShift],lastD);
    						wrd = tmp[0]; lastD = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '5':
    						tmp = this._getField(this.$fields[4][markShift],lastE);
    						wrd = tmp[0]; lastE = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '6':
    						tmp = this._getField(this.$fields[5][markShift],lastF);
    						wrd = tmp[0]; lastF = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '7':
    						tmp = this._getField(this.$fields[6][markShift],lastG);
    						wrd = tmp[0]; lastG = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '8':
    						tmp = this._getField(this.$fields[7][markShift],lastH);
    						wrd = tmp[0]; lastH = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '9':
    						tmp = this._getField(this.$fields[8][markShift],lastI);
    						wrd = tmp[0]; lastI = tmp[1]; pushit = 1;
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						break;
    					case '.': wrd = chr; nextUpper = 2; break;
    					case '!': wrd = chr; nextUpper = 2; break;
    					case '?': wrd = chr; nextUpper = 2; break;
    					case '#': tense = 1; continue;
    					case '_': tense = 2; continue;
    					case '^': tense = 3; continue;
    					case '*': tense = 4; continue;
    					case '>': nextPlural = 1; continue;
    					case '<': nextPlural = 0; continue;
    					case '|': nextPlural = (Math.random()>0.5?1:0); continue;
    					case '+': nextUpper = 1; continue;
    					case '{': markShift = 1; continue;
    					case '}': markShift = 0; continue;
    					default: wrd = chr;
    				}
    				if(pushit && store){
    					if(info[p]) info[p] += wrd;
    					else info[p] = wrd;
    				}
    				tense = 0; nextPlural = 0;
    			} else { // @
    				var where = "", sys = false, ovr = false, spc;
    				switch(chr){
    					case 'a':
    						r = this._random(this.$spec.idsA.length);
    						wrd = this.$spec.idsA[r];
    						if(store) info.num += wrd;
    						break;
    					case 'B': wrd = player.bounty+" Cr"; break;
    					case 'b':
    						r = this._random(this.$spec.idsB.length);
    						wrd = this.$spec.idsB[r];
    						if(store) info.num += wrd;
    						break;
    					case 'C': wrd = player.name; break;
    					case 'c':
    						r = this._random(this.$spec.idsC.length);
    						wrd = this.$spec.idsC[r];
    						if(store) info.num += wrd;
    						break;
    					case 'D': wrd = player.ship.displayName; break;
    					case 'd': wrd = String(clock.days-Math.floor(Math.random()*7)); break;
    					case 'F':
    						where = "rndFirstName";
    						break;
    					case 'f':
    						if(lasts.rndFirstName.length){
    							if(+pattern[p].charAt(ichr+1)+1){ // trickery
    								wrd = lasts.rndFirstName[+pattern[p].charAt(ichr+1)];
    								ichr++;
    							} else wrd = lasts.rndFirstName[lasts.rndFirstName.length-1];
    						} else where = "rndFirstName";
    						break;
    					case 'h':
    						if(this.$lSys<0) r = this._getRNDSystem();
    						wrd = this.$spec.rndSystem[this.$lSys].inhabitant.toLowerCase();
    						lasts.lastWords.push(wrd);
    						if(store) info.lastInhabitant = wrd;
    						break;
    					case 'I': wrd = player.ship.name; break;
    					case 'i':
    						if(lasts.rndShipName.length){
    							if(+pattern[p].charAt(ichr+1)+1){ // trickery
    								wrd = lasts.rndShipName[+pattern[p].charAt(ichr+1)];
    								ichr++;
    							} else wrd = lasts.rndShipName[lasts.rndShipName.length-1];
    						} else where = "rndShipName";
    						break;
    					case 'L': wrd = player.legalStatus; break;
    					case 'N':
    						where = "rndSurName";
    						break;
    					case 'n':
    						if(lasts.rndSurName.length){
    							if(+pattern[p].charAt(ichr+1)+1){ // trickery
    								wrd = lasts.rndSurName[+pattern[p].charAt(ichr+1)];
    								ichr++;
    							} else wrd = lasts.rndSurName[lasts.rndSurName.length-1];
    						} else where = "rndSurName";
    						break;
    					case 'P':
    						wrd = this.$spec.currentSystem.name;
    						if(store) info.currentSystemName = wrd;
    						break;
    					case 'R': wrd = player.rank; break;
    					case 'S':
    						sys = true;
    						ovr = true;
    						where = "rndSystem";
    						break;
    					case 's':
    						sys = true;
    						where = "rndSystem";
    						break;
    					case 'T': wrd = (player.ship.target?player.ship.target.name:""); break;
    					case 'W':
    						wrd = this._parseConditions("(Si:human=[GNN_Names]|[GNN_NamesOther])");
    						if(this.$limit<3){
    							this.$limit++;
    							var wwa = this.$stdObj;
    							this.$stdObj = this.$pool[wrd.substr(1,wrd.length-2)];
    							wrd = this._buildPhrase(null,0,sd,0,0,lasts);
    							if(!this.$stdObj.splitRules) lasts.lastWords.push(wrd);
    							this.$stdObj = wwa;
    							if(store) info[p] = wrd;
    							this.$limit--;
    						}
    						break;
    					case 'X':
    						if(this.$lSys<0) r = this._getRNDSystem();
    						break;
    					case 'Y':
    						if(this.$stdObj.custom){
    							if(+pattern[p].charAt(ichr+1)+1){ // trickery
    								wrd = this.$stdObj.custom[+pattern[p].charAt(ichr+1)];
    								ichr++;
    							}
    						}
    						break;
    					case 'Z':
    						where = "rndBrew";
    						break;
    					case 'z':
    						if(lasts.rndBrew.length){
    							if(+pattern[p].charAt(ichr+1)+1){ // trickery
    								wrd = lasts.rndBrew[+pattern[p].charAt(ichr+1)];
    								ichr++;
    							} else wrd = lasts.rndBrew[lasts.rndBrew.length-1];
    						} else where = "rndBrew";
    						break;
    					case '0':
    					case '1':
    					case '2':
    					case '3':
    					case '4':
    					case '5':
    					case '6':
    					case '7':
    					case '8':
    					case '9':
    						if(foo){
    							if(lasts.lastWords.length>chr) wrd = lasts.lastWords[+chr+wOffset];
    						} else {
    							if(lasts.lastWords.length>chr) wrd = lasts.lastWords[+chr];
    						}
    						break;
    					case '?':
    						var zla;
    						wrd = this._parseConditions(za[zb]);
    						if(wrd.charAt(0)===" "){
    							spc = 1;
    							wrd = wrd.trim();
    						}
    						if(/\[\d\]/.test(wrd)) wrd = this._handleCombiners(wrd,markShift,0);
    						wrd = this._handleNV(wrd,tense,nextPlural,markShift);
    						if(this.$limit<3 && /\[[a-zA-Z_]+\]/.test(wrd)){
    							zla = wrd.substr(1,wrd.length-2);
    							if(this.$pool[zla]){
    								this.$limit++;
    								var wwb = this.$stdObj;
    								this.$stdObj = this.$pool[zla];
    								wrd = this._buildPhrase(null,0,sd,0,0,lasts);
    								if(!this.$stdObj.splitRules) lasts.lastWords.push(wrd);
    								this.$stdObj = wwb;
    								if(store) info[p] = wrd;
    								wOffset = 0;
    								this.$limit--;
    							}
    						} else if(/[\{\}]/.test(wrd)){
    							if(wrd==="{") markShift = 1;
    							if(wrd==="}") markShift = 0;
    							wrd = wrd.substr(1);
    						} else {
    							if(this.$limit>2){
    								if(this.$recGuard) log(this.name,"Warning! - Sample recursion limit. "+zla);
    							}
    							if(!this.$stdObj.splitRules) if(wrd) lasts.lastWords.push(wrd);
    						}
    						if(spc) wrd = " "+wrd;
    						zb++;
    						break;
    					case '[':
    						var zlb = zc[zd];
    						var zk = zlb.substr(1,zlb.length-2);
    						if(this.$limit<3 && this.$pool[zk]){
    							this.$limit++;
    							var wwc = this.$stdObj;
    							this.$stdObj = this.$pool[zk];
    							wrd = this._buildPhrase(null,0,sd,0,0,lasts);
    							if(!this.$stdObj.splitRules) lasts.lastWords.push(wrd);
    							this.$stdObj = wwc;
    							if(store) info[p] = wrd;
    							this.$limit--;
    						} else {
    							if(this.$limit>2){
    								if(this.$recGuard) log(this.name,"Warning! - Sample recursion limit. "+zlb);
    								wrd = zlb;
    							}
    						}
    						zd++;
    						break;
    					default: wrd = chr;
    				}
    				if(where){
    					if(sys){
    						if(ovr || (sys && this.$lSys<0)) r = this._getRNDSystem();
    						wrd = this.$spec[where][this.$lSys].name;
    						if(nextPlural){
    							wrd = this._makePlural(wrd);
    							nextPlural = 0;
    						}
    					} else {
    						r = this._random(this.$spec[where].length);
    						wrd = this.$spec[where][r];
    					}
    					lasts[where].push(wrd);
    				}
    				if(wrd && wrd[0]==="@"){
    					pattern[p] = pattern[p].replace(/@\?/,wrd);
    					p--;
    					nextSpecial = 0;
    					continue;
    				}
    				nextSpecial = 0;
    			}
    			if(nextUpper){
    				if(nextUpper>1) nextUpper--;
    				else {
    					wrd = this._initialCap(wrd);
    					nextUpper = 0;
    				}
    			}
    			txt += wrd;
    		}
    		pattern[p] = txt;
    		if(txt.length===1){
    			if(txt==="a") aFlag = 1;
    			else if(txt==="A") aFlag = 2;
    			else aFlag = 0;
    		} else {
    			if(aFlag){
    				if(typeof(this.$suptive[txt])!=='undefined'){
    					var rep = pattern[p-1].split(" ");
    					if(aFlag>1) rep[rep.length-1] = "The";
    					else rep[rep.length-1] = "the";
    					pattern[p-1] = rep.join(" ");
    				} else {
    					if(/^[FHLMNRSX][A-Z]/.test(txt)) pattern[p-1] = pattern[p-1]+"n"; // a -> an
    					else if(/^u/i.test(txt)){
    						if(/^u[^aeiou\d\s][^aeiou\d\s]/i.test(txt)) pattern[p-1] = pattern[p-1]+"n"; // a -> an
    						else if(/^un[aeou]/i.test(txt)) pattern[p-1] = pattern[p-1]+"n"; // a -> an
    						else if(/^uni/i.test(txt) && /^unim|(?:ive|ble)$/i.test(txt)) pattern[p-1] = pattern[p-1]+"n"; // a -> an
    					} else {
    						if(/^(?:[aei]|o[^ne]|ho(?:ur|nest|no|mage|mbre|rs d')|he(?:ir|rb))/i.test(txt)) pattern[p-1] = pattern[p-1]+"n"; // a -> an
    					}
    				}
    				aFlag = 0;
    			} else if(/\ba\b$/.test(txt)) aFlag = 1;
    		}
    	}
    	if(!foo || (foo && this.$limit===1)){
    		if(this.$stdObj.splitRules){
    			switch(this.$stdObj.splitRules[cp]){
    				case 1:
    					lasts.rndFirstName.push(pattern[0]);
    					lasts.rndSurName.push(pattern[1]);
    					lasts.rndTitle.push("");
    					break;
    				case 2:
    					lasts.rndSurName.push(pattern[0]);
    					lasts.rndFirstName.push("");
    					lasts.rndTitle.push("");
    					break;
    				case 3:
    					lasts.rndFirstName.push(pattern[0]);
    					lasts.rndTitle.push(pattern[1]);
    					lasts.rndSurName.push(pattern[2]);
    					break;
    				case 4:
    					lasts.rndTitle.push(pattern[0]);
    					lasts.rndFirstName.push(pattern[1]);
    					lasts.rndSurName.push(pattern[2]);
    					break;
    				case 21:
    					lasts.rndShipName.push(pattern.join(" "));
    					break;
    				case 22:
    					lasts.rndBrew.push(pattern.join(" "));
    					break;
    			}
    		}
    	}
    	var fin = pattern.join(" ");
    	if(cpf){
    		if(store){
    			info.store = lasts;
    			info.bits = parseInt(this.$bits);
    			return([fin,info,cp,lasts]);
    		} else return([fin,cp,lasts]);
    	}
    	if(store){
    		info.store = lasts;
    		info.bits = parseInt(this.$bits);
    		return([fin,info]);
    	}
    	return fin;
    };
    this.systemInformationChanged = function(gal,sys,key,newValue){
    	if(gal!==galaxyNumber || !this.$galaxyStats.length || sys<0 || sys>255) return;
    	var nope = ["description","economy","ID","government","inhabitant","name","population","productivity","radius","sun_gone_nova","techlevel"].indexOf(key);
    	if(nope===-1) return;
    	if(key==="sun_gone_nova") this.$galaxyStats[sys].sun = (newValue?false:true);
    	else this.$galaxyStats[sys][key] = newValue;
    };
    // Still slow! The string expansion (descriptions,etc) are eating it up.
    this._getGalaxy = function(){
    	this.$galaxyStats = [];
    	var gn = galaxyNumber,c,sy;
    	for(var i=0;i<256;i++){
    		c = System.infoForSystem(gn,i);
    		sy = {
    			description: c.description,
    			economy: c.economy,
    			government: c.government,
    			ID: i,
    			inhabitant: c.inhabitant,
    			name: c.name,
    			population: c.population,
    			productivity: c.productivity,
    			radius: c.radius,
    			sun: (c.sun_gone_nova?false:true),
    			techlevel: c.techlevel
    		};
    		this.$galaxyStats.push(sy);
    	}
    };
    }).call(this);
    
    Scripts/GNN_Words.js
    /* (C) Disembodied and Svengali 2009-2018, License CC-by-nc-sa-4.0 */
    (function(){
    "use strict";
    this.name = "GNN_Words";
    
    this.pool = {
    	GNN_Blessing:{
    		fieldA: ["(X GNN_wish2)"],
    		fieldB: ["(X GNN_bless1)"],
    		fieldC: ["(X GNN_bless2)"],
    		fieldD: ["(X GNN_bless3)"],
    		fieldE: ["(X GNN_wish3)"],
    		fieldF: ["(X GNN_P009)"],
    		fieldG: [],
    		fieldH: [],
    		fieldI: [],
    		fieldJ: [],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["+1 [GNN_NamesGods] 2 you!","[GNN_NamesGods] 2 you!","+1 [GNN_NamesGods] 3 5 6!","+1 [GNN_NamesGods] 4 you with 5!"]
    	},
    	GNN_CommWelcome:{
    		fieldA: ["(Y0x30=[2], [7]|[3])"],
    		fieldB: ["(X GNN_status1)"],
    		fieldC: ["(Y0x6=[4].|[5], [6])"],
    		fieldD: ["(X GNN_welcome1)","(X GNN_welcome2)"],
    		fieldE: ["Glad to see you, Sir","It's good that you're here, Commander","(X GNN_welcome1)"],
    		fieldF: ["(Y0x200021=[7]|[8])"],
    		fieldG: ["(X GNN_join1)"],
    		fieldH: ["(X GNN_status2)"],
    		fieldI: ["over."],
    		fieldJ: ["(B7=[2]|[3])"],
    		fieldK: ["Who do you think you are... [9]?","You vicious [8]!","(X GNN_threat2)"],
    		fieldL: ["(Y0x4100=[4]|[5])"],
    		fieldM: ["You stupid [8]!","(X GNN_threat3)"],
    		fieldN: ["(B6=[6],|[7])"],
    		fieldO: ["Bah","Nah","Jeeze","(X GNN_inter1)"],
    		fieldP: ["(X GNN_ask1)","(X GNN_askleave1)"],
    		fieldQ: ["(X GNN_bandit1)"],
    		fieldR: ["(X GNN_bandit2)"],
    		sentences: ["(Y0x50c0={)+1 @Y1, }9","@Y1 here. (Y0x50c0={)+1","(Y0x50c0={)+(B7=[GNN_PirateInsult]|[1]) @Y1, }9"],
    		custom: [0xc0002,"Captain Illych Bartok"],
    		splitRules: []
    	},
    	GNN_Names:{
    		fieldA: ["Aga[8]","Aid[4]","Ala[5]","Al[6]","An[4]","Ar[7]","Ay[4]","Balde[3]","Bal[4]","Bar[5]","Beo[3]","Boro[5]","Bran[3]","Bray[6]","Bra[9]","Bren[9]","Cal[3]","Ced[4]","Clem[9]","Col[3]","Cor[3]","Co[9]","Dago[5]","Dan[7]","Den[9]","Dor[7]","Dor[8]","Drago[5]","Dun[7]","Ed[6]","El[4]","Eme[2]","Eo[7]","Fin[7]","Gala[3]","Gal[4]","Gar[2]","God[9]","Gor[3]","Har[7]","Jeg[3]","Jew[6]","Ker[3]","Mal[3]","Mar[3]","Nor[6]","Palo[5]","Peli[3]","Ran[4]","Rey[6]","Re[4]","Re[7]","Ri[4]","Ro[5]","Ter[2]","Wal[4]","Wes[7]","Wil[6]","Y[3]","(X GNN_names1)","(X GNN_names4)"],
    		fieldB: ["reth","rett","sch"],
    		fieldC: ["(X GNN_syl2)"],
    		fieldD: ["ders","drew","drick","dy","ek","mund","ric"],
    		fieldE: ["bar","man","mir"],
    		fieldF: ["bert","dy","gar","mon","mond"],
    		fieldG: ["gar","ley","mer","n","nall","ward"],
    		fieldH: ["karr","khan","mir","rath","son"],
    		fieldI: ["dall","dan","ders","drick"],
    		fieldJ: ["(X GNN_syl3)"],
    		fieldK: ["(X GNN_syl4)"],
    		fieldL: ["(X GNN_syl5)"],
    		fieldM: ["(X GNN_names13)"],
    		fieldN: ["(X GNN_names14)"],
    		fieldO: ["(X GNN_names15)"],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["1 {12","1 {13","1 +{46","1 +{56","1 +{52","1 [GNN_NamesOolite]"],
    		splitRules: [1,1,1,1,1,1]
    	},
    	GNN_NamesBrews:{
    		fieldA: ["(X GNN_brew1)"],
    		fieldB: ["(X GNN_brew2)"],
    		fieldC: ["(X GNN_brew3)"],
    		fieldD: ["(X GNN_brew4)"],
    		fieldE: ["(X GNN_brew5)"],
    		fieldF: [],
    		fieldG: [],
    		fieldH: [],
    		fieldI: [],
    		fieldJ: [],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["@s's 1 3 4","3 4","3's 5","1 3","2 3 4","2 3's 5","2 1 3"],
    		splitRules: [22,22,22,22,22,22,22]
    	},
    	GNN_NamesGods:{
    		fieldA: ["(X GNN_god4)"],
    		fieldB: ["(X GNN_god5)"],
    		fieldC: ["many","(X GNN_few2)","(X GNN_few3)"],
    		fieldD: ["eyes","heads","hands","horns","limbs","tongues","eggs","hosts"],
    		fieldE: ["eyed","headed","handed","horned"],
    		fieldF: [],
    		fieldG: [],
    		fieldH: [],
    		fieldI: [],
    		fieldJ: ["(X GNN_sh1)","(X GNN_syl6)"],
    		fieldK: ["(X GNN_sh2)","(X GNN_syl7)"],
    		fieldL: ["(X GNN_sh1)","(X GNN_syl8)"],
    		fieldM: ["(X GNN_sh2)","(X GNN_syl9)"],
    		fieldN: ["(X GNN_names3)"],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["+1 {12","{12 the }+2","{12 of the }+3 +4","+3-5 {12","+1 {12 of the }+3 +4","+1 {34","{34 the }+2","{34 of the }+3 +4","+3-5 {34","+1 {34 of the }+3 +4","+1 {5","{5 the }+2","{5 of the }+3 +4","+3-5 {5","+1 {5 of the }+3 +4"]
    	},
    	GNN_NamesOolite:{
    		fieldA: [],
    		fieldB: ["[2]-[3]","ben [3]","Mc[3]","Ol'[3]","Ath[5]","Br[9]an","Bran[4]","C[7][4]","D[7][4]","Dav[9][4]","Denn[9][4]","Eccl[5]","Fa[9]r[4]","Folk[4]","Garr[5]","Good[4]","Hector","Inn[5]","Jam[5]","Jon[4]","Kir[4]","L[9]ttle[4]","L[7][4]","Na[9]l[4]","Neil[4]","Peter[4]","Orbit[4]","Roger[4]","Sam[4]","Star[4]","Th[8]r[4]","Wilkin[4]","William[4]"],
    		fieldC: ["Ath[5]","Br[9]an","Bran[4]","C[7][4]","D[7][4]","Dav[9][4]","Denn[9][4]","Folk[4]","Garri[4]","Good[4]","Hector","Inn[5]","Jam[5]","Jon[4]","Kir[4]","L[9]ttle[4]","L[7][4]","Na[9]l[4]","Neil[4]","Peter[4]","Roger[4]","Sam[4]","Star[4]","Th[8]r[4]","Wilkin[4]","William[4]"],
    		fieldD: ["b[8]rn","f[8]r","st[8]n","sen","son","son","sdott[9]r","s","s","sby","er","f[9]re","l[9]ng"],
    		fieldE: ["e","[6]b[8]rn","[6]f[8]r","[6]st[8]n","[6]sen","[6]son","eson","[6]sdott[9]r","[6]s","es","esby","[6]f[9]re","l[9]ng"],
    		fieldF: ["i","e","e","ie"],
    		fieldG: ["ar","aw","arre","our"],
    		fieldH: ["e","o","u","ou","ai"],
    		fieldI: ["i","y"],
    		fieldJ: [],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["3","2"],
    		splitRules: [2,2]
    	},
    	GNN_NamesOther:{
    		fieldA: ["(X GNN_sh1)","(X GNN_syl6)"],
    		fieldB: ["(X GNN_syl1)"],
    		fieldC: ["(X GNN_syl7)"],
    		fieldD: ["(X GNN_names3)"],
    		fieldE: [],
    		fieldF: [],
    		fieldG: ["(B28+)(B29+)[2][3]"],
    		fieldH: ["[4]"],
    		fieldI: ["[1][2]","[2][3]"],
    		fieldJ: ["(B28+)(B29+)[2]"],
    		fieldK: ["Al","Alex","Alto","Amanda","Amber","Apollo","Baldrin","Beck[3]","Begg[3]","Biff","Bonnie","Brooke","Buck[3]","Cain","Check[3]","Chip","Churchill","Claire","Clifford","Constantine","Dakota","Darren","Dick[3]","Don","Dugg[3]","Dusty","Ernie","Fanny","Felix","Ford","Frenzy","Ginger","Hannibal","Holly","Jack","Joaquin","Kipper","Mack[3]","Marlon","Mick[3]","Mo","Montgomery","Moritz","Myles","Nat","Orion","Penny","Reav[3]","Red","Rock[3]","Ryan","Sal","Sand[3]","Tiff[3]"],
    		fieldL: ["annie","ers","ie","y"],
    		fieldM: [],
    		fieldN: ["(B28+)(B29+)[6]"],
    		fieldO: ["(X GNN_names12)"],
    		fieldP: [],
    		fieldQ: ["(B28+)(B29+)[9]"],
    		fieldR: ["(X GNN_names16)"],
    		sentences: ["{+(Si:rodent=[1]|)+(Si:feline=[1]|)+(Si:bird=[5]|)+(Si:frog=[8]|)}+(Si:lobster=[7]|)+(Si:lizard=[8]|)+(Si:insect=[9]|)+{(Si:human=[8]|) {+(B28=|[9])+(B29=[GNN_NamesOolite]|)"],
    		splitRules: [1]
    	},
    	GNN_NamesPirates:{
    		fieldA: ["(X GNN_names6)","[6]shanks"],
    		fieldB: ["(X GNN_names1)","(X GNN_names2)"],
    		fieldC: [],
    		fieldD: ["(X GNN_names7)","[8]balls","[8]beard","Mc[2]"],
    		fieldE: ["(X GNN_names11)","The Rusty [7]"],
    		fieldF: ["(X GNN_color2)"],
    		fieldG: ["Butter Cutter","Broadsword","Cutlass","Dagger","Epee","Knife","Saber","Scabbard"],
    		fieldH: ["(X GNN_color1)"],
    		fieldI: [],
    		fieldJ: [],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["2 '1' 4","2 '5' 4","2 '5' 4","2 '1' 4","Long 2 4"],
    		splitRules: [3,3,3,3,4]
    	},
    	GNN_NamesShips:{
    		fieldA: ["(X GNN_names8)","(X GNN_color1)"],
    		fieldB: ["(X GNN_names5)"],
    		fieldC: ["(X GNN_names9)"],
    		fieldD: ["(X GNN_title2)"],
    		fieldE: ["(X GNN_names10)"],
    		fieldF: [],
    		fieldG: [],
    		fieldH: [],
    		fieldI: [],
    		fieldJ: [],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["The 1 2","The 1 3","The +4 2","The +4 5"],
    		splitRules: [21,21,21,21]
    	},
    	GNN_PirateInsult:{
    		fieldA: ["(X GNN_anim1)"],
    		fieldB: ["(X GNN_body1)"],
    		fieldC: ["(X GNN_bucket1)"],
    		fieldD: ["(X GNN_spit1)"],
    		fieldE: ["(X GNN_god3)"],
    		fieldF: ["(X GNN_god2)"],
    		fieldG: ["(X GNN_god1)"],
    		fieldH: ["(X GNN_insult1)"],
    		fieldI: ["(X GNN_wish1)"],
    		fieldJ: ["(X GNN_threat1)"],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["9 5 |7 8 your 2!","9 5 |7 8 your 2, you 1!","9 5 |7 8 your 2, you 6 1!","9 5 |7 8 your 2, you 6 3 of 4!","9 5 |7 8 your 2, you 6 3 of 1 4!","9 5 |7 of @s 8 your 2!","9 5 |7 of @s 8 your 2, you 1!","9 5 |7 of @s 8 your 2, you 6 1!","9 5 |7 of @s 8 your 2, you 6 3 of 4!","9 5 |7 of @s 8 your 2, you 6 3 of 1 4!","You 1!","You 6 1!","You 6 3 of 4!","You 6 3 of 1 4!","{1 }8 you!","{1 }8 you, you 1!","{1 }8 you, you 6 1!","{1 }8 you, you 6 3 of 4!","{1 }8 you, you 6 3 of 1 4!","{1 }8 your 2!","{1 }8 your 2, you 1!","{1 }8 your 2, you 6 1!","{1 }8 your 2, you 6 3 of 4!","{1 }8 your 2, you 6 3 of 1 4!"]
    	},
    	GNN_Precious:{
    		fieldA: ["(X GNN_color1)","(X GNN_color2)","(X GNN_color3)","(X GNN_god3)"],
    		fieldB: ["(X GNN_anim1)","(X GNN_god1)","(X GNN_precious1)"],
    		fieldC: ["(X GNN_bucket1)"],
    		fieldD: ["(X GNN_bottle1)"],
    		fieldE: [],
    		fieldF: [],
    		fieldG: [],
    		fieldH: [],
    		fieldI: [],
    		fieldJ: [],
    		fieldK: [],
    		fieldL: [],
    		fieldM: [],
    		fieldN: [],
    		fieldO: [],
    		fieldP: [],
    		fieldQ: [],
    		fieldR: [],
    		sentences: ["1 +>2","3 of 1 +>2","4 of [GNN_NamesBrews]","1 +>2","3 of 1 +>2"]
    	},
    	GNN_A:{
    		fieldA: ["(X GNN_factory1)","(X GNN_govhouse1)","(X GNN_house1)","(X GNN_install1)"],
    		fieldB: ["(X GNN_incident1)"],
    		fieldC: ["(X GNN_big1)"],
    		fieldD: ["(X GNN_many1)"],
    		fieldE: ["county seat","(X GNN_major1)"],
    		fieldF: ["(X GNN_inofficial1)"],
    		fieldG: ["(X GNN_document1)"],
    		fieldH: ["(X GNN_destroy1)"],
    		fieldI: ["(X GNN_reveal1)"],
    		fieldJ: ["(X GNN_device1)"],
    		fieldK: ["(X GNN_tragedy1)"],
    		fieldL: ["(X GNN_inoperable1)"],
    		fieldM: ["(X GNN_official1)"],
    		fieldN: ["(X GNN_P006)"],
    		fieldO: ["(X GNN_P007)"],
    		fieldP: ["(X GNN_P008)"],
    		fieldQ: ["(X GNN_inoperable2)"],
    		fieldR: ["in the next days","within the next days"],
    		sentences: ["@XA 3 2 _8 4 >1 at >@s 5 district, injuring 4 (X GNN_citizen1) earlier this morning. 6 >7 9 that this {2 could have been ^3, but ^8 >1 ^3 the >7. '6,' said (Si:human=[GNN_Names]|[GNN_NamesOther]), >@s 4. 'But the }3 {2 }_8 important structures here{5 9.'"]
    	},
    	GNN_B:{
    		fieldA: ["(X GNN_citizen1)","(X GNN_trader1)"],
    		fieldB: ["expressed approval of","applauded","celebrated","cheered","hailed","acclaimed"],
    		fieldC: ["notorious","infamous","feared"],
    		fieldD: ["(X GNN_bandit1)"],
    		fieldE: ["plagued","afflicted","cursed","preyed on","attacked"],
    		fieldF: ["in recent","for many","for the last several"],
    		fieldG: ["weeks","months","years"],
    		fieldH: ["Adjudicator","Judge","(Sg:0=local chieftain|[9])","(Sg:1=Sheriff|[9])","(Sg:1=Royal Justiciar|[9])","(Sg:1=King's Hand|[9])","(Sg:3=State Prosecutor|[9])","(Sg:3=Archimandrite|[9])","(Sg!4=Priest of Justice|[9])","(Sg:4=People's Representative|[9])","(Sg:4=State Prosecutor|[9])","(Sg:4=People's Justice|[9])","(Sg:5=Protector of the Commonwealth|[9])","(Sg:6=Arbiter|[9])","(Sg:6=Counsellor|[9])","(Sg:7=Director|[9])","(Sg:7=Personnel Manager|[9])","(Sg:7=Supervisor|[9])"],
    		fieldI: ["Adjudicator","Judge","Arbiter"],
    		fieldJ: ["(Sg<5=[2]|deprogramming)","(Sg<5=[2]|brainwashing)","(Sg<5=[2]|brain wipe)","(Sg<5=[2]|re-education)","(Sg<5=[2]|community service)","(Sg<3=vitrification|[2])","(Sg:7=reduction in salary|[2])"],
    		fieldK: ["(Se<7=death|throat-cutting)","slow death","(Sg<1=drawing and quartering|immurement)","penal servitude","death of personality","brain wipe"],
    		fieldL: ["Addressing the court","On being dragged from the courtroom","With bulging eyes","With a certain dignity","Struggling with the guards","Visibly appalled","Clearly terrified","Shaking with fear"],
    		fieldM: ["prisoner","felon","miscreant","guilty party"],
    		fieldN: ["murmured","yelled","screamed","shouted","said","shrieked"],
    		fieldO: ["amuse","enrage","anger","tickle","entertain","bewilder","confuse","puzzle"],
    		fieldP: ["lively","eager","exuberant","festive","excited","feverish","frantic"],
    		fieldQ: ["crowd","rabble","throng","mob","(Sg:1=courtiers|[9])","(Sg:4=Party members|[9])","(Sg>4=media|[9])","(Sg:7=executives|[9])"],
    		fieldR: ["crowd","rabble","throng","mob"],
    		sentences: ["@s, @d.@c: Local >1 2 the capture of [GNN_NamesPirates], the 3 4 who has 5 shipping in this and nearby systems 6 7. The 8, @W, sentenced @n0 to {1. 3 the 4 5, '[GNN_PirateInsult]', which only served to 6 the 7 8.","@s, @d.@c: A {7 9 of >}1 looked on as [GNN_NamesPirates] was today found guilty on all counts. Summing up, 8 @W called the prisoner 'a 3 4, who has 5 local shipping 6 7'. {3, @n0 5, '[GNN_PirateInsult]', which seemed to 6 @n1. Traders' Guild representatives }2 @n1 as @n0 was sentenced to {1."]
    	},
    	GNN_C:{
    		fieldA: ["(X GNN_serious1)"],
    		fieldB: ["(Sg:0=tribespeople|[2])","(Sg:0=warriors|[2])","(Sg:1=nobles|[2])","(Sg:1=peasants|[2])","(Sg:3=fanatics|[2])","(Sg:4=Party members|[2])","(Sg:7=executives|[2])","(Si:human=colonists|[2])","media","inhabitants","citizens"],
    		fieldC: ["offended","transgressed","broke","violated","flouted","outraged"],
    		fieldD: ["(Sg!4=religious precepts|[4])","laws","customs","mores","morality","traditions","norms","codes of behaviour","conventions"],
    		fieldE: ["touching","looking at","speaking to","smiling at","winking at","kicking","shouting at","eating","whistling at","singing to","whistling near","tickling","abusing","insulting","(Sg!4=denying the sanctity of|[5])","(Sg:4=oppressing|[5])","coughing near","sneezing within earshot of","laughing at","soiling","ogling"],
    		fieldF: ["frozen","pickled","(Sg:1=Royal|[6])","(Sg!4=sacred|[6])","(Sg!4=holy|[6])","unwashed","veiled","blue","white","green","purple","cross-eyed","one-eyed","three-eyed","drunken","sleeping","preserved","painted","(Sg<4=low-caste|[6])","(Sg<4=high-caste|[6])"],
    		fieldG: ["(Sg!4=priest|[7])","(Sg!4=priestess|[7])","(Sg!4=idol|[7])","(Sg!4=divinity|[7])","(Sg!4=fetish|[7])","goat","monkey","shrew","chicken","poet","treeoid","bat","Elder","ant","opossum","sheep","bison","buffalo","pig","ferret","weasel","gibbon","baboon","porcupine","pachyderm","(Sg:2=courtier|[7])","(Sg:4=senior Party member|[7])","(Sg:7=member of the Board|[7])"],
    		fieldH: ["(X GNN_rumour1)"],
    		fieldI: ["twelve","twenty-four","(X GNN_few2)"],
    		fieldJ: ["hours","days"],
    		fieldK: ["(X GNN_mob1)"],
    		fieldL: ["an apology","the ambassador's resignation","the ambassador's head","compensation for mental anguish","'an end to Co-operative brutality'","the withdrawal of Co-operative forces from the system","atonement","nothing less than the breakup of the Co-operative","the ambassador's surrender","justice"],
    		fieldM: ["political reputations","delicate trade negotiations","diplomatic careers","planetary honour and pride","the fates of worlds"],
    		fieldN: ["(X GNN_ending1)"],
    		fieldO: ["scandal has erupted following the arrival of"],
    		fieldP: ["the new Co-operative ambassador to"],
    		fieldQ: ["Although the ambassador's staff have denied the allegations, calling them"],
    		fieldR: ["the Co-operative embassy has been surrounded by"],
    		sentences: ["A 1 {6 (Si:human=[GNN_Names]|[GNN_NamesOther])}, a @h from @s, as {7} @S. Local 2 claim that @n 3 @s 4 by 5 a 6 7. @n's staff deny the allegations, calling them '8'. Nevertheless, for the last 9 {1, 9 2 of protestors demanding 3. 4 hang in the balance5","(Si:human=[GNN_Names]|[GNN_NamesOther]), a @h from @s and {7} @S, is today at the centre of a 1 scandal. {2 of local }2 have surrounded the embassy, claiming that @n 3 @s 4 by 5 a 6 7. {8} '8', angry voices are demanding {3. 4 are at stake here5"],
    		custom: [0x0],
    		splitRules: []
    	},
    	GNN_D:{
    		fieldA: ["(X GNN_react1)"],
    		fieldB: ["(X GNN_claims1)"],
    		fieldC: ["(X GNN_fail1)"],
    		fieldD: ["(X GNN_P005)"],
    		fieldE: ["a number of","several","three","four","five","six","seven","eight","nine","ten","eleven","twelve","more than a dozen","more than fifteen","more than twenty","an estimated twenty-two","more than two dozen","dozens of","a great many"],
    		fieldF: ["(X GNN_ships2)"],
    		fieldG: ["ranking GalCop officer","GalCop commander","Viper squadron leader","GalCop co-ordinator"],
    		fieldH: ["we are doing the best we can within a very limited budget","we put our lives on the line every day","we do not shirk our duty","we simply do not have sufficient forces available","our own losses were considerable","our pilots are severely overstretched","we cannot work miracles","this attack was unprecedented in scale","we are not to blame here"],
    		fieldI: ["levelled accusations that","claimed that","presented evidence which purported to show that","displayed evidence that","suggested that"],
    		fieldJ: ["(Sg:1=crown officers|[1])","(Sg:1=nobles|[1])","(Sg:3=state police|[1])","(Sg:3=security|[1])","(Sg:4=Party members|[1])","(Sg:7=executives|[1])","(Sg:7=salarymen|[1])","(Sg:7=accountants|[1])","officials","administrators","agents"],
    		fieldK: ["delayed","misused","misappropriated","stolen","failed to provide","siphoned off","purloined","embezzled"],
    		fieldL: ["funds","moneys","resources","supplies","assets","stores","reserves","finances"],
    		fieldM: ["required by","intended for","needed by","urgently needed by","desperately needed for","which rightfully belonged to"],
    		fieldN: ["system patrols","Viper patrols","system police","GalCop forces","Co-operative forces","local Viper pilots"],
    		fieldO: ["at this time","at this moment","right now","For the moment","currently","at this point","just now","presently,","as things stand","given the circumstances","with so many of our members lost,"],
    		fieldP: ["who is to blame","who is at fault","who is responsible","who is culpable","where the fault lies","what the problem is"],
    		fieldQ: ["want a fighting chance","need all parties to work together","want to prevent this tragedy from repeating itself","need everyone to do their job"],
    		fieldR: ["are still unaccounted for","cannot be accounted for","are listed as 'overdue'","are missing, presumed destroyed","cannot be located","have disappeared from the system","are missing: hopefully both jumped out safely"],
    		sentences: ["@s, @d.@c: GalCop _1 2 that they 3 a 4, (X GNN_P001) 5 >6 (X GNN_P002). [GNN_Names], the 7, said, '+8,' and 9 @s {1 had 2 3 4 5. (X GNN_P003) [GNN_Names] said, '+6 we don't care 7: we just 8.' (X GNN_P004) the }6 '[GNN_NamesShips]' and '[GNN_NamesShips]' {9.","@s, @d.@c: [GNN_Names], the local 7, has 9 @s {1 have 2 3 4 5. Planetary representatives }_1 @n's statement, issuing their own 2 that {5 }3 a recent 4, which resulted in the destruction of 5 >6 across the system. Merchants' Guild representative [GNN_Names] said, '{+6 we don't care 7: we just 8.' Since the attack, the }6 '[GNN_NamesShips]' and '[GNN_NamesShips]' {9."]
    	},
    	GNN_TraderCharacter:{
    		fieldA: ["affected(B3+)","annoying","big","bohemian(B1+)","burly","cantankerous","chaotic(B0+)","childlike","cold","cosmopolitan(B1+)","dirt-encrusted","discreet","eloquent","famous","fashionable","fearless","flabby","fractured","funny","furious","gentle","greasy(B0+)","greedy","grim(B1+)","grinning(B1+)","grumpy","honourable(B1+)","lively","magnificent(B1+)","mean-spirited","memorable","miserly","misty(B0+)","mitochondrial","modest","moronic","most difficult","mysterious","nearly blind(B0+)","old","one-eyed(B0+)","paternal","pathetic","pompous(B1+)","psychotic(B1+)","raspy(B0+)","ravishing","reactionary(B0+)","respectable(B1+)","resplendent","righteous","rough","rude(B1+)","rum","salty(B0+)","shabby","slow","small","smelly(B0+)","statesmanlike(B1+)","stoic","stormy","tattered(B0+)","well-known(B1+)","worldly(B1+)"],
    		fieldB: [" and (B0=[5]|[4]) of [6]"],
    		fieldC: ["(D50=Junior Chief|[5])","Chief Scientist(B3+)","Director(B3+)","Executive Chief(B3+)","Senior Chief(B3+)","Senior Coordinator(B3+)"],
    		fieldD: ["(B1=[3]|Design Specialist)","(B1=[3]|Sales Manager)","(D50=Junior Chief|[5])","Operating [5]","Trade (D50=[5]|Coordinator)"],
    		fieldE: ["Assistant(B2+)","Attendant(B2+)","Engineer(B2+)","Manager(B2+)"],
    		fieldF: ["[8]","Amber [7]","AMS [7]","B.AT Inc","Betaex [7]","Borland [7]","Citek [7]","Citex [7]","Citgoo Express","Clifford [7]","Conestrip [7]","Connex [7]","Dalmore [7]","Daltlane [7]","deVane [7]","Dingi [7]","ETS [7]","Faulcon [7]","FreshFoods Inc","Fujio [7]","FullGrip [7]","Grupo Langostaides Azules","Huginkiss [7]","Hydrotec [7]","Inditech [7]","InterDrew [7]","Joover [7]","KMC [7]","Lave Fried Trumble Inc","Leysson [7]","Lifetec [7]","Ligoos [7]","Lucky Vole Farms","Mana [7]","Milford [7]","Monu Pharma","Nano [7]","NoVidio [7]","OO-Haul [7]","Oops Deliveries","PIn-tel Limited","PlaneOptics [7]","Plummer [7]","Ret Vesla Clothings","Saltlane [7]","Silvercon [7]","Siretex [7]","Stimtatex [7]","Subtech [7]","Takahara [7]","Texacoo Fuel [7]","the KitiTec Ltd","the Onix Inc","the Oomoo [7]","the Weyland-Yutani Corporation","Warfeld [7]","Wencoo [7]","Xenophob [7]","ZA Brew Ltd"],
    		fieldG: ["(X GNN_company2)"],
    		fieldH: ["Balder [9]","Emerson [9]","Palmer [9]","Greening [9]","Parker [9]","Nomuhare [9]"],
    		fieldI: ["and Sons Ltd","Inc","and Balder [7]","and Emerson [7]","and Palmer [7]","and Greening [7]","and Parker [7]","and Partners"],
    		fieldJ: ["co-owner of","commandeering","Commander of","holder of","operating","owner of","patron of","piloting","skipper of","taskmaster of"],
    		fieldK: ["compact (D50=[3]|[4])","escorted (D50=[3]|[4])","(B2=fast [4]|heavy [3])","finely crafted [3]","guarded [3]","(B2=un|heavily )escorted (D50=[3]|[4])","light escorted (D50=[3]|[4])","light guarded (D50=[3]|[4])","light (B1=[4]|[5])","(B3=experimental|maneuverable) (D50=[4]|[5])","medium (D50=escorted [4]|guarded [3])","medium [4]","(B2=small [5]|slim [4])"],
    		fieldL: ["(B3=Python|Anaconda) [6]","Python [6]","Boa [6]","Boa II [6]","Boa Class Cruiser","(B3=Ferdelance|Anaconda) [6]","Python [6]"],
    		fieldM: ["Cobra Mk III [7]","Ferdelance [7]","Moray Medical Boat [7]","Moray Star Boat [7]","Cobra Mk III [7]"],
    		fieldN: ["Adder(B2+) [7]","Asp(B2+) [7]","Cobra Mk I(B2+) [7]","Gecko(B2+) [8]","Krait(B2+) [8]","Mamba(B2+) [8]","Sidewinder(B2+) [8]","Cobra Mk I(B2+) [7]","Adder(B2+) [7]"],
    		fieldO: ["(B3=liner|barge)","(B3=yacht|cargo ship)","(B3=cruiser|cargo shuttle)","craft","cruiser","(B3=yacht|ferry)","(B2=ore ship|cruiser)","scientific vessel","schooner","solar-sail","starship","(B3=cargo steamer|tradeship)","transport","vessel"],
    		fieldP: ["(B3=yacht|cargo shuttle)","craft","(B3=merchant ship|ferry)","(B3=scientific|privateer) ship","skiff","sloop","scow","(B3=prototype|scout ship)","(B2=skiff|shuttle)"],
    		fieldQ: ["craft","privateer ship","skiff","sloop","scow","scout ship"],
    		fieldR: [],
    		sentences: ["@XCaptain @W, a 1 @h from @s(D30=[2]|), {1 '[GNN_NamesShips]', a 2."]
    	}
    };
    this.irregularNouns = {
    	bison:"bison",
    	carp:"carp",
    	genie:"genii",
    	gold:"gold",
    	mouse:"mice",
    	oni:"oni",
    	ox:"oxen",
    	seraph:"seraphim",
    	shrimp:"shrimp",
    	squid:"squid",
    	trout:"trout"
    };
    this.irregularVerbs = {
    	arise:["arise","arises","arose","arisen"],
    	awake:["awake","awakes","awoke","awoken"],
    	backslide:["backslide","backslides","backslid","backslid"],
    	be:["be","is","was","been"],
    	bear:["bear","bears","bore","born"],
    	beat:["beat","beats","beat","beaten"],
    	become:["become","becomes","became","become"],
    	begin:["begin","begins","began","begun"],
    	bend:["bend","bends","bent","bent"],
    	bet:["bet","bets","bet","betted"],
    	bid:["bid","bids","bid","bid"],
    	bind:["bind","binds","bound","bound"],
    	bite:["bite","bites","bit","bitten"],
    	bleed:["bleed","bleeds","bled","bled"],
    	blow:["blow","blows","blew","blown"],
    	"break":["break","breaks","broke","broken"],
    	breed:["breed","breeds","bred","bred"],
    	bring:["bring","brings","brought","brought"],
    	browbeat:["browbeat","browbeats","browbeat","browbeaten"],
    	build:["build","builds","built","built"],
    	burst:["burst","bursts","burst","burst"],
    	buy:["buy","buys","bought","bought"],
    	cast:["cast","casts","cast","cast"],
    	"catch":["catch","catches","caught","caught"],
    	choose:["choose","chooses","chose","chosen"],
    	cling:["cling","clings","clung","clung"],
    	come:["come","comes","came","come"],
    	cost:["cost","costs","cost","cost"],
    	creep:["creep","creeps","crept","crept"],
    	crossbreed:["crossbreed","crossbreeds","crossbred","crossbred"],
    	cut:["cut","cuts","cut","cut"],
    	daydream:["daydream","daydreams","daydreamt","daydreamt"],
    	deal:["deal","deals","dealt","dealt"],
    	dig:["dig","digs","dug","dug"],
    	dive:["dive","dives","dove","dived"],
    	"do":["do","does","did","done"],
    	draw:["draw","draws","drew","drawn"],
    	dream:["dream","dreams","dreamt","dreamt"],
    	drink:["drink","drinks","drank","drunk"],
    	drive:["drive","drives","drove","driven"],
    	eat:["eat","eats","ate","eaten"],
    	fall:["fall","falls","fell","fallen"],
    	"feast on":["feast on","feasts on","feasted upon","feasted upon"],
    	feed:["feed","feeds","fed","fed"],
    	feel:["feel","feels","felt","felt"],
    	fight:["fight","fights","fought","fought"],
    	find:["find","finds","found","found"],
    	fit:["fit","fits","fitted","fitted"],
    	flee:["flee","flees","fled","fled"],
    	fling:["fling","flings","flung","flung"],
    	fly:["fly","flies","flew","flown"],
    	forbid:["forbid","forbids","forbade","forbidden"],
    	forecast:["forecast","forecasts","forecast","forecast"],
    	foresee:["foresee","foresees","foresaw","foreseen"],
    	foretell:["foretell","foretells","foretold","foretold"],
    	forget:["forget","forgets","forgot","forgotten"],
    	forgive:["forgive","forgives","forgave","forgiven"],
    	forsake:["forsake","forsakes","forsook","forsaken"],
    	freeze:["freeze","freezes","froze","frozen"],
    	frostbite:["frostbite","frostbites","frostbit","frostbitten"],
    	fry:["fry","fries","fried","fried"],
    	get:["get","gets","got","gotten"],
    	give:["give","gives","gave","given"],
    	go:["go","goes","went","gone"],
    	grind:["grind","grinds","ground","ground"],
    	grow:["grow","grows","grew","grown"],
    	handwrite:["handwrite","handwrites","handwrote","handwritten"],
    	hang:["hang","hangs","hung","hung"],
    	have:["have","have","had","had"],
    	hear:["hear","hears","heard","heard"],
    	hew:["hew","hews","hewed","hewed"],
    	hide:["hide","hides","hid","hidden"],
    	hit:["hit","hit","hit","hit"],
    	hold:["hold","holds","held","held"],
    	hurt:["hurt","hurts","hurt","hurt"],
    	inbreed:["inbreed","inbreeds","inbred","inbred"],
    	inlay:["inlay","inlays","inlaid","inlaid"],
    	input:["input","inputs","input","input"],
    	keep:["keep","keeps","kept","kept"],
    	kneel:["kneel","kneels","knelt","knelt"],
    	know:["know","knows","knew","known"],
    	lay:["lay","lays","laid","laid"],
    	lead:["lead","leads","led","led"],
    	leave:["leave","leaves","left","left"],
    	lend:["lend","lends","lent","lent"],
    	let:["let","lets","let","let"],
    	lie:["lie","lies","lied","lied"],
    	light:["light","lights","lit","lit"],
    	lose:["lose","loses","lost","lost"],
    	make:["make","makes","made","made"],
    	mean:["mean","means","meant","meant"],
    	meet:["meet","meets","met","met"],
    	miscast:["miscast","miscasts","miscast","miscast"],
    	misdeal:["misdeal","misdeals","misdealt","misdealt"],
    	misdo:["misdo","misdoes","misdid","misdone"],
    	mishear:["mishear","mishears","misheard","misheard"],
    	mislay:["mislay","mislays","mislaid","mislaid"],
    	mislead:["mislead","misleads","misled","misled"],
    	misread:["misread","misreads","misread","misread"],
    	misspend:["misspend","misspends","misspent","misspent"],
    	mistake:["mistake","mistakes","mistook","mistaken"],
    	misteach:["misteach","misteachs","mistaught","mistaught"],
    	misunderstand:["misunderstand","misunderstands","misunderstood","misunderstood"],
    	miswrite:["miswrite","miswrites","miswrote","miswritten"],
    	offset:["offset","offsets","offset","offset"],
    	outbid:["outbid","outbids","outbid","outbid"],
    	outbreed:["outbreed","outbreeds","outbred","outbred"],
    	outdo:["outdo","outdoes","outdid","outdone"],
    	outdraw:["outdraw","outdraws","outdrew","outdrawn"],
    	outdrink:["outdrink","outdrinks","outdrank","outdrunk"],
    	outdrive:["outdrive","outdrives","outdrove","outdriven"],
    	outfight:["outfight","outfights","outfought","outfought"],
    	outfly:["outfly","outflies","outflew","outflown"],
    	outgrow:["outgrow","outgrows","outgrew","outgrown"],
    	outride:["outride","outrides","outrode","outridden"],
    	outrun:["outrun","outruns","outran","outrun"],
    	outsell:["outsell","outsells","outsold","outsold"],
    	outshoot:["outshoot","outshoots","outshot","outshot"],
    	outsit:["outsit","outsits","outsat","outsat"],
    	outspeak:["outspeak","outspeaks","outspoke","outspoken"],
    	outspeed:["outspeed","outspeeds","outsped","outsped"],
    	outswear:["outswear","outswears","outswore","outsworn"],
    	outthink:["outthink","outthinks","outthought","outthought"],
    	outthrow:["outthrow","outthrows","outthrew","outthrown"],
    	overbid:["overbid","overbids","overbid","overbid"],
    	overbuild:["overbuild","overbuilds","overbuilt","overbuilt"],
    	overbuy:["overbuy","overbuys","overbought","overbought"],
    	overcome:["overcome","overcomes","overcame","overcome"],
    	overdo:["overdo","overdoes","overdid","overdone"],
    	overdraw:["overdraw","overdraws","overdrew","overdrawn"],
    	overdrink:["overdrink","overdrinks","overdrank","overdrunk"],
    	overfeed:["overfeed","overfeeds","overfed","overfed"],
    	overhang:["overhang","overhangs","overhung","overhung"],
    	overhear:["overhear","overhears","overheard","overheard"],
    	overlay:["overlay","overlays","overlaid","overlaid"],
    	overpay:["overpay","overpays","overpaid","overpaid"],
    	override:["override","overrides","overrode","overridden"],
    	overrun:["overrun","overruns","overran","overrun"],
    	oversee:["oversee","oversees","oversaw","overseen"],
    	oversell:["oversell","oversells","oversold","oversold"],
    	overshoot:["overshoot","overshoots","overshot","overshot"],
    	overtake:["overtake","overtakes","overtook","overtaken"],
    	overthink:["overthink","overthinks","overthought","overthought"],
    	overthrow:["overthrow","overthrows","overthrew","overthrown"],
    	partake:["partake","partakes","partook","partaken"],
    	pay:["pay","pays","paid","paid"],
    	plead:["plead","pleads","pleaded","pleaded"],
    	prebuild:["prebuild","prebuilds","prebuilt","prebuilt"],
    	premake:["premake","premakes","premade","premade"],
    	prepay:["prepay","prepays","prepaid","prepaid"],
    	presell:["presell","presells","presold","presold"],
    	preset:["preset","presets","preset","preset"],
    	proofread:["proofread","proofreads","proofread","proofread"],
    	prove:["prove","proves","proved","proven"],
    	put:["put","puts","put","put"],
    	quit:["quit","quits","quit","quit"],
    	read:["read","reads","read","read"],
    	reawake:["reawake","reawakes","reawoke","reawaken"],
    	rebid:["rebid","rebids","rebid","rebid"],
    	rebind:["rebind","rebinds","rebound","rebound"],
    	rebuild:["rebuild","rebuilds","rebuilt","rebuilt"],
    	recast:["recast","recasts","recast","recast"],
    	recut:["recut","recuts","recut","recut"],
    	redeal:["redeal","redeals","redealt","redealt"],
    	redo:["redo","redoes","redid","redone"],
    	redraw:["redraw","redraw","redrew","redrawn"],
    	refit:["refit","refits","refitted","refitted"],
    	regrind:["regrind","regrinds","reground","reground"],
    	regrow:["regrow","regrows","regrew","regrown"],
    	rehang:["rehang","rehangs","rehung","rehung"],
    	rehear:["rehear","rehears","reheard","reheard"],
    	relight:["relight","relights","relit","relit"],
    	remake:["remake","remakes","remade","remade"],
    	rend:["rend","rends","rent","rent"],
    	repay:["repay","repays","repaid","repaid"],
    	reread:["reread","rereads","reread","reread"],
    	rerun:["rerun","reruns","reran","rerun"],
    	resell:["resell","resells","resold","resold"],
    	resend:["resend","resends","resent","resent"],
    	reset:["reset","resets","reset","reset"],
    	resew:["resew","resews","resewed","resewn"],
    	retake:["retake","retakes","retook","retaken"],
    	reteach:["reteach","reteaches","retaught","retaught"],
    	retear:["retear","retears","retore","retorn"],
    	retell:["retell","retells","retold","retold"],
    	rethink:["rethink","rethinks","rethought","rethought"],
    	retread:["retread","retreads","retread","retread"],
    	retrofit:["retrofit","retrofits","retrofitted","retrofitted"],
    	rewake:["rewake","rewakes","rewoke","rewaken"],
    	rewear:["rewear","rewears","rewore","reworn"],
    	reweave:["reweave","reweaves","rewove","rewoven"],
    	rewin:["rewin","rewins","rewon","rewon"],
    	rewind:["rewind","rewinds","rewound","rewound"],
    	rewrite:["rewrite","rewrites","rewrote","rewritten"],
    	rid:["rid","rids","rid","rid"],
    	ride:["ride","rides","rode","ridden"],
    	ring:["ring","rings","rang","rung"],
    	rip:["rip","rips","ripped","ripped"],
    	rise:["rise","rises","rose","risen"],
    	run:["run","runs","ran","run"],
    	saw:["saw","saws","sawed","sawed"],
    	say:["say","says","said","said"],
    	see:["see","sees","saw","seen"],
    	seek:["seek","seeks","sought","sought"],
    	sell:["sell","sells","sold","sold"],
    	send:["send","sends","sent","sent"],
    	set:["set","sets","set","set"],
    	sew:["sew","sews","sewed","sewn"],
    	shake:["shake","shakes","shook","shaken"],
    	shed:["shed","sheds","shed","shed"],
    	shit:["shit","shits","shit","shit"],
    	shoot:["shoot","shoots","shot","shot"],
    	show:["show","shows","showed","shown"],
    	shrink:["shrink","shrinks","shrank","shrunk"],
    	shut:["shut","shuts","shut","shut"],
    	sing:["sing","sings","sang","sung"],
    	sink:["sink","sinks","sunk","sunk"],
    	sit:["sit","sits","sat","sat"],
    	sleep:["sleep","sleeps","slept","slept"],
    	slide:["slide","slides","slid","slid"],
    	sling:["sling","slings","slung","slung"],
    	slink:["slink","slinks","slinked","slinked"],
    	slit:["slit","slits","slit","slit"],
    	smell:["smell","smells","smelled","smelled"],
    	sneak:["sneak","sneaks","sneaked","sneaked"],
    	sow:["sow","sows","sowed","sowed"],
    	speak:["speak","speaks","spoke","spoken"],
    	speed:["speed","speeds","speeded","speeded"],
    	spell:["spell","spells","spelled","spelled"],
    	spend:["spend","spends","spent","spent"],
    	spill:["spill","spills","spilled","spilled"],
    	spin:["spin","spins","spun","spun"],
    	spit:["spit","spits","spat","spat"],
    	split:["split","splits","split","split"],
    	spoil:["spoil","spoils","spoiled","spoiled"],
    	spread:["spread","spreads","spread","spread"],
    	spring:["spring","springs","sprang","sprung"],
    	stand:["stand","stands","stood","stood"],
    	steal:["steal","steals","stole","stolen"],
    	stick:["stick","sticks","stuck","stuck"],
    	sting:["sting","stings","stung","stung"],
    	stink:["stink","stinks","stunk","stunk"],
    	strike :["strike","strikes","struck","struck"],
    	string:["string","strings","strung","strung"],
    	strive:["strive","strives","strove","striven"],
    	sublet:["sublet","sublets","sublet","sublet"],
    	sunburn:["sunburn","sunburns","sunburned","sunburned"],
    	swear:["swear","swears","swore","sworn"],
    	sweat:["sweat","sweats","sweated","sweated"],
    	sweep:["sweep","sweeps","swept","swept"],
    	swell:["swell","swells","swelled","swelled"],
    	swim:["swim","swims","swam","swum"],
    	swing:["swing","swings","swung","swung"],
    	take:["take","takes","took","taken"],
    	teach:["teach","teaches","taught","taught"],
    	tear:["tear","tear","tore","torn"],
    	tell:["tell","tells","told","told"],
    	think:["think","thinks","thought","thought"],
    	"throw":["throw","throws","threw","thrown"],
    	thrust:["thrust","thrusts","thrust","thrust"],
    	tread:["tread","treads","trod","trodden"],
    	"try":["try","tries","tried","tried"],
    	unbend:["unbend","unbends","unbent","unbent"],
    	unbind:["unbind","unbind","unbound","unbound"],
    	unclothe:["unclothe","unclothes","unclothed","unclothed"],
    	underbid:["underbid","underbids","underbid","underbid"],
    	undercut:["undercut","undercuts","undercut","undercut"],
    	underfeed:["underfeed","underfeeds","underfed","underfed"],
    	undergo:["undergo","undergoes","underwent","undergone"],
    	underlie:["underlie","underlies","underlay","underlain"],
    	undersell:["undersell","undersells","undersold","undersold"],
    	understand:["understand","understands","understood","understood"],
    	undertake:["undertake","undertakes","undertook","undertaken"],
    	underwrite:["underwrite","underwrites","underwrote","underwritten"],
    	undo:["undo","undoes","undid","undone"],
    	unfreeze:["unfreeze","unfreezes","unfroze","unfrozen"],
    	unhang:["unhang","unhangs","unhung","unhung"],
    	unhide:["unhide","unhides","unhid","unhidden"],
    	unsling:["unsling","unslings","unslung","unslung"],
    	unspin:["unspin","unspins","unspun","unspun"],
    	unstick:["unstick","unsticks","unstuck","unstuck"],
    	unstring:["unstring","unstrings","unstrung","unstrung"],
    	unweave:["unweave","unweaves","unwove","unwoven"],
    	unwind:["unwind","unwinds","unwound","unwound"],
    	uphold:["uphold","upholds","upheld","upheld"],
    	upset:["upset","upsets","upset","upset"],
    	wake:["wake","wakes","woke","woken"],
    	wear:["wear","wears","wore","worn"],
    	weave:["weave","weaves","wove","woven"],
    	weep:["weep","weeps","wept","wept"],
    	wet:["wet","wets","wet","wet"],
    	win:["win","wins","won","won"],
    	wind:["wind","winds","wound","wound"],
    	withdraw:["withdraw","withdraws","withdrew","withdrawn"],
    	withhold:["withhold","withholds","withheld","withheld"],
    	withstand:["withstand","withstands","withstood","withstood"],
    	wring:["wring","wrings","wrung","wrung"],
    	write:["write","writes","wrote","written"]
    };
    this.superlatives = {
    	best:1,
    	biggest:1,
    	bulkiest:1,
    	greatest:1,
    	highest:1,
    	largest:1,
    	least:1,
    	littlest:1,
    	lowest:1,
    	max:1,
    	maximal:1,
    	merest:1,
    	minimal:1,
    	most:1,
    	mostest:1,
    	outside:1,
    	paramount:1,
    	slightest:1,
    	smallest:1,
    	superlative:1,
    	supreme:1,
    	tiniest:1,
    	top:1,
    	topmost:1,
    	ultimate:1,
    	utmost:1,
    	uttermost:1
    };
    }).call(this);