Back to Index Page generated: Nov 12, 2024, 11:02:04 PM

Expansion Galactic Registry

Content

Warnings

  1. http://wiki.alioth.net/index.php/Galactic%20Registry -> 404 Not Found
  2. Low hanging fuit: Information URL exists...

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Shows system information for the current galactic sector. Shows system information for the current galactic sector.
Identifier oolite.oxp.phkb.GalacticRegistry oolite.oxp.phkb.GalacticRegistry
Title Galactic Registry Galactic Registry
Category Ambience Ambience
Author phkb phkb
Version 5.9.1 5.9.1
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://wiki.alioth.net/index.php/GalCop_Galactic_Registry n/a
Download URL https://wiki.alioth.net/img_auth.php/d/d4/GalCopGalacticRegistry_5.9.1.oxz n/a
License CC-BY-NC-SA 3.0 CC-BY-NC-SA 3.0
File Size n/a
Upload date 1710158235

Documentation

readme.txt

GalCop Galactic Registry
By Nick Rogers

With thanks to Okti for his code for the Gal Navy locations.

Overview
========
This OXP aims to provide pilots with data relating to their current sector, and provide tools pilots can use to better understand the galaxy they work in. This expansion adds a new interface screen, the "GalCop galactic registry", which had the following sub-options:

1. Regions: Each sector has a number of galactic regions, and this menu allows pilots to see all named regions and display their location.
2. Spacelanes: There are a number of spacelanes in each section, largely related to trade routes. This menu will list each of the different spacelanes defined in the current galactic sector, and allow you to display each route on the galactic chart.
3. TechLevel: This menu allows pilots to highlight all systems of a particular techlevel, and (if the Advanced Navigational Array is installed) to automatically plot a course to the closest one.
4. Government Types: This menu allows pilots to highlight all systems of government type, and (if the Advanced Navigational Array is installed) to automatically plot a course to the closest one.
5. Economy: This menu allows pilots to highlight all systems of a particular economy, and (if the Advanced Navigational Array is installed) to automatically plot a course to the closest one.
6. Galactic Navy Sector Commands: If you have the GalNavy OXP installed, this option will become available. This will highlight each system that is home to a GalNavy sector command, and (if the Advanced Navigational Array is installed) allow you to automatically plot a course to the closest one.
7. GalCop Sector HQ: This menu allows pilots to highlight the GalCop Sector HQ system in the sector.
8. Full system list: This function will list all systems in the sector. The list can be sorted by name, tech level, government type or economy type. Additionally, two systems can be selected from the list, and then the details of these two systems can be displayed along with a galactic map showing the route between them. 
9. Search registry: This function will take any text input and search all planetary descriptions for that criteria.

For any of the defined sections you have the option of keeping the information displayed on all system maps. When the section is selected, choose the "Set as permanent display" option to turn this on, and "Unset permanent display" to turn it off.

Notes about the 'Search Registry' function
------------------------------------------
The Search registry function will take all entered criteria and find any system where all the criteria are matched to at least one property.

The following properties will be searched:
- Planetary description
- Inhabitants description
- Government description
- Economy description
- Techlevel
- Productivity
- Population 
- Radius (ie Planet radius)

Some examples of search criteria:
"tl8+ ind prod>30000"
    Will find any industrial system with a TL of 8 or greater, and with a productivity of more than 30000.
"feline anarchy pop<3"
    Will find any Anarchy system with feline inhabitants and a population less than 3 billion. In Galaxy 1, there are two systems that will be found for this search: Erbiti and Orrira.
"tl6 tedious"
    Will find any TL6 system with 'tedious' in the planetary description. In Galaxy 1, there is only one system that will be found for this search: Aleusqu.
"frog agri tl7"
    Will find any agricultural-type (poor, mainly, average or rich) TL7 system, inhabited by frogs. In Galaxy 1, there are three systems that will be found for this search: Isinor, Rebia, and Teanrebi.
"human poet|wolf tl8+|industrial"
    Will find any system inhabited by humans or humanoids, AND where either "poet" OR "wolf" is mentioned in the description, AND has either a TL greater than or equal to 8 OR is an industrial-type economy.
    
Installation
============
After installing the OXP no additional set up is required. The "GalCop galactic registry" will be available whenever you dock.

3rd Party interface
===================
It's possible for other OXP's to add their own planet lists to the registry. The following is an example of the interface code:

	var data = {
		name: "My systems",
		markerColor:"whiteColor", 
		markerShape:"MARKER_DIAMOND",
		listType: "unconnected",
		systems:[
            {name:"System list 1", markerColor:"redColor", markerShape:"MARKER_X", systemIDList:[1,2,3,4,5]},
            {name:"System list 2", systemIDList:[6,7,8,9,10]},
            {name:"System list 3", systemIDList:[11,12,13,14,15]}
        ]
	};
    worldScripts.GalacticRegistry.$addCustomSystemList(data);

In new main menu item will be displayed, called "My systems". When you select that item, there will be 3 subsections inside, "System list 1", "System list 2", and "System list 3". "System list 1" has overriden the default markerColor and markerShape settings.

Full data definition:
    name:               The text to appear on the main menu.
    markerColor:        The color specifier to use when marking planets on the map. 
                        If not specified, will default to "whiteColor".
    markerShape:        The shape to use for the planet markers. Must be one of MARKER_X, MARKER_PLUS, MARKER_SQUARE, MARKER_DIAMOND.
                        If not specified, will default to "MARKER_DIAMOND".
    startMarkerShape:   The marker shape to use at the start of the path (path list type only) (defaults to "MARKER_SQUARE")
    endMarkerShape:     The marker shape to use at the end of the path (path list type only) (defaults to "MARKER_DIAMOND")
    listType:           Can be one of the following:
                        unconnected: all systems in the list are unconnected, and will be marked individually on the map. 
                            This is the default setting when "listType" is not specified.
                        region: all systems in the list are connected, and all possible connections between them will be highlighted on the map.
                            The systems themselves will not have markers.
                        path: each system in the list represents one point on a defined path, and only the links between consecutive items will be highlighted on the map.
                            The first and last system in the list will have map markers.
    linkColor:          The color specifier to use when highlighting links on the map. 
                        If not specified, this will default to "greenColor".
    systems:            An array of dictionary items to be shown. The ID's must be in the current galaxy.
                        The dictionary format is:
						name:				The name of this list of systems that will appear on the menu and on the title when selected
						markerColor: 		The color to use for any markers in this list (unconnected list type only) (overrides the parent markerColor)
						markerShape: 		The shape to use for any markers in this list (unconnected list type only) (overrides the parent markerShape)
	  					startMarkerShape: 	The shape to use at the start of a path (for path list types only) (overrides the parent startMarkerShape)
	  					endMarkerShape: 	The shape to use at the end of a path (for path list types only) (overrides the parent endMarkerShape)
						linkColor:			The color specified to be used for all links on the map (path and region list types only) (overrides the parent linkColor)
						systemIDList: 		an array of system ID's that define this list

Note: The list of custom items will be reset whenever the player enters a new galaxy. OXP's will need to re-add their data after a galactic jump. The best time to do this is during the "shipDockedWithStation" world event.

Adding an entry with the same name as an existing item will overwrite existing data with the new data.

License
=======
This OXP is released under the Creative Commons Attribution - Non-Commercial - Share Alike 3.0 license. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/

Galaxy image from http://simpleicon.com/solar_system.html

Discussion
==========
This OXP is discussed at this forum link: http://aegidian.org/bb/viewtopic.php?f=4&t=17893

Version History
===============
5.9.1
- Fixed bug when searching using < or > with tl.

5.9
- Fixed issues arising from accessing registry while in flight.
- Added ability to search for systems based on radius (ie planet radius).

5.8 
- Fixed issue where second selected system in the Full System List was not showing government, TL or economy in all circumstances.

5.7
- Fixed spelling error in region "The Siege Worlds".

5.6
- Added ability to search for government or economy based on the numeric value (eg gov>2).
- Added ability to search for techlevel using form "tl>8".

5.5
- Added ability to search for systems based on productivity or population.

5.4
- Fixed spelling mistake in code.
- Added features available in Oolite 1.91ff.
- Adjusted brightness of background overlay image, which couldn't be seen in Oolite 1.90.

5.3
- Made compatible with "SW Economy".

5.2
- Fixed some potential referencing errors on mission screens.

5.1
- Spacelane system lists are no longer sorted, so the planet list will be in path order.

5.0
- Re-engineered the internal structures so that all base criteria are now using the same data structures as the custom lists. Custom lists can now have multiple subsets defined within them.
- Custom lists now have the ability to be made a permanent display on the chart.
- Unconnected lists (that is, a series of unconnected planets) can now be made a permanent display on the chart.
- The 'Search registry' function can now do +/- searches on techlevel.
- The 'Search registry' function can now do an "OR" search, using the "|" bar separator. This allows for more complex search queries like "human poet|wolf tl8+|industrial", which translates to "find any system inhabited by humans or humanoids, AND where "poet" OR "wolf" is mentioned in the description, AND has either a TL greater than or equal to 8 OR an industrial-type economy"

4.4
- The 'Search registry' function will now also search government description, economy description, inhabitants description and techlevel. 
- Added a "New search" menu to the Search registry results screen.

4.3
- Bug fixes.

4.2
- Added ability for spacelanes and regions to be shown permanently on any chart.
- Fixed issue where showing the system list of a region would keep the system map visible.
- Moved some menu item text into descriptions.plist.
- Code refactoring and cleanup.

4.1
- Player's current route was always showing the shortest route on the map, even if the quickest route had been selected on the F6 screen.

4.0
- Made compatible with OXP's that change the system.concealment property.
- Added interface to allow 3rd party OXP's to add their own planet lists, regions and paths.

3.3
- When setting a course to a target system, F7 screen will now display the new destination.

3.2
- Added GalCop HQ system to the menu (used by Bounty System OXP, and Email System OXP).
- Added a "search" facility where planetary descriptions can be searched for entered criteria.
- Code refactoring.

3.1
- Removed debug log entries.

3.0
- Added a "Full system list", which lists all system names, and allows sorting by name, tech level, government or economy type. Also has ability to select two systems and show route between the two, as well as other system details.
- Removed redundant header from all system lists.

2.0
- Added ability to view a list of planet names for any given sub-section of the chart.
- Added markers to the start and end of spacelanes.

1.6
- Fixed issue with HUD not becoming visible again after use.

1.5
- Changed "==" comparisons to "===" for performance improvements.
- Fixed issue with the paging for TechLevels.

1.4 
- Updated check for "Allow Big GUI".
- Fixed issue where the interface screen wasn't being added when docking at a new station.

1.3
- Improved menu unsability by auto selecting the next item in the menu.
- Updated screenID's to enable BGS background sounds.
- Renamed background overlay image to prevent possibility of future duplication.
- Toned down overlay image.
- Code refactoring.

1.2
- Removed unnecessary link to "Display Current Course".
- Fixed issue where current course was always showing with the shortest plot.

1.1
- Small tweaks to menu text.
- Smugglers chart markers now removed from various Galactic Registry screens to make the image clearer.

1.0
- Initial release

Equipment

Name Visible Cost [deci-credits] Tech-Level
Advanced Navigational Array Tool no 100 1+

Ships

This expansion declares no ships. This may be related to warnings.

Models

This expansion declares no models. This may be related to warnings.

Scripts

Path
Scripts/galactic_registry.js
"use strict";
this.name        = "GalacticRegistry";
this.author      = "phkb";
this.copyright   = "2017 phkb";
this.description = "Shows various details about the current galactic sector.";
this.license     = "CC BY-NC-SA 3.0";

this._disabled = false;
this._regionColor = "greenColor";
this._techLevelColor = "greenColor";
this._governmentColor = ["0.5 0.0 0.7",	"0.7 0.5 0.3", "0.0 1.0 0.3", "1.0 0.8 0.1", "1.0 0.0 0.0", "0.1 0.5 1.0", "0.7 0.7 0.7", "0.7 1.0 1.0"];
this._economyColor = ["1.0 1.0 0.0", "0.875 1.0 0.0", "0.75 1.0 0.0", "0.625 1.0 0.0", "0.5 1.0 0.0", "0.375 1.0 0.0", "0.25 1.0 0.0", "0.125 1.0 0.0"];
this._markedRegions = [];
this._markedPlanets = [];
this._permanentRegions = [];
this._permanentLanes = [];
this._explorersClub = false;
this._smugglers = false;
this._menuColor = "orangeColor";
this._itemColor = "yellowColor";
this._disabledColor = "darkGrayColor";
this._altColor = "greenColor";
this._menu = 0;
this._item = 0;
this._page = 0;
this._removeANATool = false;
this._holdDestination = -1;
this._lastChoice = [];
this._spaceLaneStart = -1;
this._spaceLaneEnd = -1;
this._select1 = -1;
this._select2 = -1;
this._selectLast = 2;
this._sortType = 0;
this._search = "";
this._searchMax = false;
this._pageLength = 16;
this._custom = [];
this._permanentChartData = {regions:[], paths:[], systems:[]};
this._setItem;
this._exitTo = "";
this._notice = false;

//-------------------------------------------------------------------------------------------------------------
// Interface to add a custom planet list to the registry
// data is dictionary with the following properties:
//    name: 			The text to appear on the menu.
//    markerColor: 		The default color specifier to use when marking planets on the map. Default is "whiteColor".
//    markerShape: 		The default shape to use for the planet markers. Must be one of MARKER_X, MARKER_PLUS, MARKER_SQUARE, MARKER_DIAMOND.
//	  startMarkerShape: The shape to use at the start of a path (for path list types only)
//	  endMarkerShape: 	The shape to use at the end of a path (for path list types only)
//	  linkColor:		The default color specifier to use for any links defined on the map (path and region list types only)
//    listType:			Can be one of the following: unconnected, path, region
//						unconnected		each system is marked individually, with no connections between them
//						path			each system in the list marks one point of a path, with connections between each
//										only the start and end systems will be marked with this type
//						region			each system is connected to each other system (within 7ly) in the list
//										systems will not be individually marked with this type
//						Note: for "path" and "region", only connections 7ly or less in length will be marked
//    systems: 			An array of dictionary objects that detail the systems to be shown
//						name:				The name of this list of systems that will appear on the menu and on the title when selected
//						markerColor: 		The color to use for any markers in this list (overrides the parent markerColor)
//						markerShape: 		The shape to use for any markers in this list (overrides the parent markerShape)
//	  					startMarkerShape: 	The shape to use at the start of a path (for path list types only) (overrides the parent startMarkerShape)
//	  					endMarkerShape: 	The shape to use at the end of a path (for path list types only) (overrides the parent endMarkerShape)
//						linkColor:			The color specified to be used for all links on the map (path and region list types only) (overrides the parent linkColor)
//						systemIDList: 		an array of system ID's that define this list
//
this.$addCustomSystemList = function $addCustomSystemList(data) {
	this.$addSystemList(data);
}

//-------------------------------------------------------------------------------------------------------------
this.$addSystemList = function $addSystemList(data, coreID) {
	var markers = ["MARKER_X", "MARKER_PLUS", "MARKER_SQUARE", "MARKER_DIAMOND"];
	var listTypes = ["unconnected", "region", "path"];

	if (data.hasOwnProperty("name") === false || data.name === "") {
		throw "Invalid settings: name must be supplied.";
	}

	// if the name already exists in the data, remove it so we can re-add it.
	for (var i = this._custom.length - 1; i >= 0; i--) {
		if (this._custom[i].name === data.name) {
			this._custom.splice(i, 1);
			break;
		}
	}

	if (data.hasOwnProperty("listType") === false) data.listType = "unconnected";
	if (listTypes.indexOf(data.listType) === -1) {
		throw "Invalid settings: invalid listType specified. Must be unconnected, region, or path";
	}

	if (data.hasOwnProperty("markerColor") === false) data.markerColor = "whiteColor";

	if (data.hasOwnProperty("markerShape") === false) data.markerShape = "MARKER_DIAMOND";
	if (markers.indexOf(data.markerShape) === -1) {
		throw "Invalid settings: invalid markerShape specified (" + data.markerShape + ").";
	}
	if (data.hasOwnProperty("startMarkerShape") === true) {
		if (markers.indexOf(data.startMarkerShape) === -1) {
			throw "Invalid settings: invalid startMarkerShape specified (" + data.startMarkerShape + ").";
		}
	} else {
		if (data.listType === "path") {
			data.startMarkerShape = "MARKER_SQUARE";
		}
	}
	if (data.hasOwnProperty("endMarkerShape") === true) {
		if (markers.indexOf(data.endMarkerShape) === -1) {
			throw "Invalid settings: invalid endMarkerShape specified (" + data.endMarkerShape + ").";
		}
	} else {
		if (data.listType === "path") {
			data.endMarkerShape = "MARKER_DIAMOND";
		}
	}

	if (data.hasOwnProperty("systems") === true) {
		var valid = false;
		if (Array.isArray(data.systems)) valid = true; // we're ok
		if (typeof data.systems[0] === "object") {
			if (data.systems[0].hasOwnProperty("name") && data.systems[0].hasOwnProperty("systemIDList")) valid = true
			// give each system data element a (mostly) unique id
			for (var i = 0; i < data.systems.length; i++) {
				data.systems[i].id = data.name + "|" + data.systems[i].name
				if (data.systems[i].hasOwnProperty("linkColor") === false && data.hasOwnProperty("linkColor")) {
					data.systems[i].linkColor = data.linkColor;
				}
				if (data.systems[i].hasOwnProperty("markerShape") === false && data.hasOwnProperty("markerShape")) {
					data.systems[i].markerShape = data.markerShape;
				}
				if (data.systems[i].hasOwnProperty("markerColor") === false && data.hasOwnProperty("markerColor")) {
					data.systems[i].markerColor = data.markerColor;
				}
				if (data.listType == "path") {
					if (data.systems[i].hasOwnProperty("endMarkerShape") === false && data.hasOwnProperty("endMarkerShape")) {
						data.systems[i].endMarkerShape = data.endMarkerShape;
					}
					if (data.systems[i].hasOwnProperty("startMarkerShape") === false && data.hasOwnProperty("startMarkerShape")) {
						data.systems[i].startMarkerShape = data.startMarkerShape;
					}
				}
			}
		}
		if (valid == false) throw "Invalid settings: systems must be supplied, and must be an array or dictionaries.";
	} else {
		throw "Invalid settings: systems array not set.";
	}
	if (data.systems.length === 0) {
		throw "Invalid settings: no system ID's found in the systems array.";
	}
	
	if (coreID && coreID > 0) {
		this._custom.splice(coreID - 1, 0, data);
	} else {
		this._custom.push(data);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$addCoreData = function $addCoreData() {

	// regions
	var data = {
		name: "[gr_regions_menu]",
		linkColor:this._regionColor, 
		listType: "region",
		systems:[]
	};
	var regions = this.$getRegionData();
	for (var i = 0; i < regions.length; i++) {
		data.systems.push({name:regions[i].name, systemIDList:regions[i].data})
	}
	this.$addSystemList(data, 1);

	// spacelanes
	var data = {
		name: "[gr_spacelanes_menu]",
		listType: "path",
		startMarkerShape:"MARKER_SQUARE",
		endMarkerShape:"MARKER_DIAMOND",
		systems:[]
	};
	var lanes = this.$getSpacelanes();
	for (var i = 0; i < lanes.length; i++) {
		data.systems.push({name:lanes[i].name, markerColor:lanes[i].color, linkColor:lanes[i].color, systemIDList:lanes[i].data})
	}
	this.$addSystemList(data, 2);

	// techlevel
	var data = {
		name: "[gr_techlevel_menu]",
		markerColor:this._techLevelColor, 
		markerShape:"MARKER_DIAMOND",
		listType: "unconnected",
		systems:[]
	};
	var maxlevel = this.$getMaxTechLevel();
	for (var i = 0; i <= maxlevel; i++) {
		data.systems.push({name:"TechLevel " + (i+1), systemIDList:this.$getSystemsByTechLevel(i)});
	}
	this.$addSystemList(data, 3);

	// government
	var data = {
		name: "[gr_govtype_menu]",
		listType: "unconnected",
		systems:[]
	};
	for (var i = 0; i <= 7; i++) {
		data.systems.push({name:this.$governmentDescriptionPlural(i), markerColor:this._governmentColor[i], systemIDList:this.$getSystemsByGovernment(i)})
	}
	this.$addSystemList(data, 4);

	// economy
	var data = {
		name: "[gr_ecotype_menu]",
		listType: "unconnected",
		systems:[]
	};
	for (var i = 0; i <= 7; i++) {
		data.systems.push({name:this.$economyDescription(i), markerColor:this._economyColor[i], systemIDList:this.$getSystemsByEconomy(i)})
	}
	this.$addSystemList(data, 5);

	// galcop hq
	var data = {
		name: "[gr_galcophq_menu]",
		listType: "unconnected",
		systems:[{name:"[gr_galcophq_menu]", markerColor:"whiteColor", systemIDList:this.$galCopHQSystem()}]
	};
	this.$addSystemList(data, 6);

	// add the galactic navy sector commands for this sector
	if (worldScripts["GalNavy"]) {
		this.$addCustomSystemList({name:expandDescription("[gr_galnavy_menu]"), systems:[{name:"Galactic Navy", systemIDList:this.$galNavySectorCommands()}]});
	}
}

//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function() {

	for (var i = 0; i < 60; i++) this._lastChoice.push("");

	if (worldScripts["Explorers Club"]) this._explorersClub = true;
	if (worldScripts["Smugglers_Illegal"]) this._smugglers = true;

	// add a mission screen exception to Xenon UI
	if (worldScripts.XenonUI) {
		var wx = worldScripts.XenonUI;
		wx.$addMissionScreenException("oolite-galacticregistry-regions-map");
		wx.$addMissionScreenException("oolite-galacticregistry-lanes-map");
		wx.$addMissionScreenException("oolite-galacticregistry-techlevel-map");
		wx.$addMissionScreenException("oolite-galacticregistry-government-map");
		wx.$addMissionScreenException("oolite-galacticregistry-economy-map");
		wx.$addMissionScreenException("oolite-galacticregistry-custom-map");
		wx.$addMissionScreenException("oolite-galacticregistry-selected-map");
		wx.$addMissionScreenException("oolite-galacticregistry-galcophq-map");
		wx.$addMissionScreenException("oolite-galacticregistry-searchresults-map");
	}
	// add a mission screen exception to Xenon Redux UI
	if (worldScripts.XenonReduxUI) {
		var wxr = worldScripts.XenonReduxUI;
		wxr.$addMissionScreenException("oolite-galacticregistry-regions-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-lanes-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-techlevel-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-government-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-economy-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-custom-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-selected-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-galcophq-map");
		wxr.$addMissionScreenException("oolite-galacticregistry-searchresults-map");
	}

	if (missionVariables.GalacticRegistry_PermanentRegions) {
		this._permanentRegions = JSON.parse(missionVariables.GalacticRegistry_PermanentRegions);
		delete missionVariables.GalacticRegistry_PermanentRegions;
	}
	if (missionVariables.GalacticRegistry_PermanentLanes) {
		this._permanentLanes = JSON.parse(missionVariables.GalacticRegistry_PermanentLanes);
		delete missionVariables.GalacticRegistry_PermanentLanes;
	}
	this.$removeHistoricPermanentMarkers();

	if (missionVariables.GalacticRegistry_PermenantChartData || missionVariables.GalacticRegistry_PermanentChartData) {
		if (missionVariables.GalacticRegistry_PermenantChartData) {
			this._permanentChartData = JSON.parse(missionVariables.GalacticRegistry_PermenantChartData);
		}
		if (missionVariables.GalacticRegistry_PermanentChartData) {
			this._permanentChartData = JSON.parse(missionVariables.GalacticRegistry_PermanentChartData);
		}
		delete missionVariables.GalacticRegistry_PermenantChartData;
		delete missionVariables.GalacticRegistry_PermanentChartData;
	}

	this.$addCoreData();

	if (oolite.compareVersion("1.91") <= 0) {
		setExtraGuiScreenKeys(this.name, {
			guiScreen:"GUI_SCREEN_LONG_RANGE_CHART", 
			registerKeys:{"key1":[{key:"g",mod1:true}]}, 
			callback:this.$setupMissionPage.bind(this)
		});
		setExtraGuiScreenKeys(this.name, {
			guiScreen:"GUI_SCREEN_SHORT_RANGE_CHART", 
			registerKeys:{"key1":[{key:"g",mod1:true}]}, 
			callback:this.$setupMissionPage.bind(this)
		});

		if (worldScripts.ContextualHelp) {
			worldScripts.ContextualHelp.$addHelpTextToGuiScreen(this.name, "GUI_SCREEN_LONG_RANGE_CHART", "\nPress Ctrl-G on this screen to open the Galactic Registry.");
			worldScripts.ContextualHelp.$addHelpTextToGuiScreen(this.name, "GUI_SCREEN_SHORT_RANGE_CHART", "\nPress Ctrl-G on this screen to open the Galactic Registry.");
		}

	} //else {
		this.$initInterface(player.ship.dockedStation);
		//this._notice = true;
	//}
}

//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function() {
	if (this._permanentChartData) {
		missionVariables.GalacticRegistry_PermanentChartData = JSON.stringify(this._permanentChartData);
	} else {
		if (missionVariables.GalacticRegistry_PermanentChartData) delete missionVariables.GalacticRegistry_PermanentChartData;
	}
}

//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function(station) {
	this.$initInterface(station);
}

//-------------------------------------------------------------------------------------------------------------
this.guiScreenChanged = function(to, from) {
	if (from === "GUI_SCREEN_MISSION" && this._screenActive) {
		this._screenActive = false;
		player.ship.hudHidden = false;
		if (this._removeANATool === true) {
			// remove the ANA tool if it was installed
			player.ship.removeEquipment("EQ_ANA_TOOL");
			this._removeANATool = false;
		}
		if (this._holdDestination >= 0) {
			player.ship.targetSystem = this._holdDestination;
			this._holdDestination = -1;
		}
		if (this._smugglers) worldScripts.Smugglers_Illegal.$markSystems();
	}
	// clean up all the marks on the chart
	if (guiScreen != "GUI_SCREEN_MISSION" && guiScreen != "GUI_SCREEN_INTERFACES") {
		this.$removeChartData();
	}
	if ((to == "GUI_SCREEN_LONG_RANGE_CHART" || to == "GUI_SCREEN_SHORT_RANGE_CHART") && this._notice == false) {
		this._notice = true;
		player.consoleMessage("Press Ctrl-G to access the Galactic Registry", 5);
	}
}

//-------------------------------------------------------------------------------------------------------------
this.shipWillEnterWitchspace = function(cause) {
	if (cause === "galactic jump") {
		// clean up any permanent chart markers
		var regions = this._permanentChartData.regions;
		if (regions && regions.length > 0) {
			for (var i = regions.length - 1; i >= 0; i--) {
				this.$removePermanentRegion(regions[i].id);
			}
		}
		var paths = this._permanentChartData.paths;
		if (paths && paths.length > 0) {
			for (var i = paths.length - 1; i >= 0; i--) {
				this.$removePermanentPath(paths[i].id);
			}
		}
		var sys = this._permanentChartData.systems;
		if (sys && sys.length > 0) {
			for (var i = sys.length - 1; i >= 0; i--) {
				this.$removePermanentSystems(sys[i].id);
			}
		}
		this._permanentChartData = {regions:[], paths:[], systems:[]};
	}
}

//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function(galaxyNumber) {
	// reset the custom array, so that there is no chance of displaying misleading info
	this._custom.length = 0;
	this.$addCoreData();
}

//-------------------------------------------------------------------------------------------------------------
this.$initInterface = function $initInterface(station) {
	station.setInterface(this.name,{
		title:"GalCop galactic registry",
		category:"Informational",
		summary:"Accesses system data for the current galactic sector.",
		callback:this.$setupMissionPage.bind(this)
	});
}

//-------------------------------------------------------------------------------------------------------------
this.$setupMissionPage = function $setupMissionPage(key) {
	if (this._explorersClub) this.$hideExplorersClub();
	this._lastChoice = []; // reset all last choices
	this._menu = 0;
	this._page = 0;
	this._exitTo = "GUI_SCREEN_INTERFACES";
	if (key == "key1") this._exitTo = "GUI_SCREEN_SHORT_RANGE_CHART";
	this.$showMissionPage();
}

//-------------------------------------------------------------------------------------------------------------
this.$showMissionPage = function $showMissionPage() {
	function compareName(a, b) {
		if (a.name < b.name) return -1;
		if (a.name > b.name) return 1;
		return 0;
	}
	function compareTL(a, b) {
		if (a.techlevel < b.techlevel) return -1;
		if (a.techlevel > b.techlevel) return 1;
		if (a.name < b.name) return -1;
		if (a.name > b.name) return 1;
		return 0;
	}
	function compareEco(a, b) {
		if (a.economy < b.economy) return -1;
		if (a.economy > b.economy) return 1;
		if (a.name < b.name) return -1;
		if (a.name > b.name) return 1;
		return 0;
	}
	function compareGov(a, b) {
		if (a.government < b.government) return -1;
		if (a.government > b.government) return 1;
		if (a.name < b.name) return -1;
		if (a.name > b.name) return 1;
		return 0;
	}
	
	if (this._smugglers) this.$hideSmugglers();

	var curChoices = {};
	var p = player.ship;
	var def = "";
	var text = "";
	var pagesize = 8;
	this._pageLength = 16;
	var zeroMap = (worldScripts.ZeroMap ? true : false);

	if (zeroMap && worldScripts.BountySystem_MostWanted && worldScripts.BountySystem_MostWanted._unconcealmentActive === true) {
		if (this._retry) this._retry.stop();
		log(this.name, "starting retry of missionpage");
		this._retry = new Timer(this, this.$showMissionPage, 0.25, 0);
		return;
	}

	if (zeroMap) worldScripts.ZeroMap._hideGUIScreen();

	var bg = "LONG_RANGE_CHART_SHORTEST";
	
	// in order to show connecting lines on the map, we need to make sure the player either has the ANA, or if not that, then a piece of equipment that can provide the same service
	if (player.ship.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === false) {
		player.ship.awardEquipment("EQ_ANA_TOOL");
		this._removeANATool = true;
		// if we've had to award the ANA tool to display lines between systems, then we don't want to give the player a free route planner
		// turn off the player's destination while we display these screens
		if (player.ship.docked) {
			this._holdDestination = p.targetSystem;
			p.targetSystem = system.ID;
		}
	} else {
		// otherwise, we have the array, so we can add the current course to any display, if it's not already there
		if (p.routeMode === "OPTIMIZED_BY_TIME") bg = "LONG_RANGE_CHART_QUICKEST";
	}

	if (this._removeANATool === false) pagesize = 6;

	if (this.$isBigGuiActive() === false) p.hudHidden = true;
	this._screenActive = true;

	this.$removeChartData();

	switch (this._menu) {
		case 0: // main menu
			{
				text = "Welcome to the GalCop galactic registry. Select the area you want to browse:";

				curChoices["11_FULLLIST"] = {text:"[gr_fulllist_menu]", color:this._menuColor};
				curChoices["12_SEARCH"] = {text:"[gr_search_menu]", color:this._menuColor};
				if (this._custom.length > 0) {
					for (var i = 0; i < this._custom.length; i++) {
						var item = this._custom[i];
						curChoices["10_CUSTOM~" + (i < 10 ? "0" : "") + i] = {text:expandDescription(item.name), color:this._menuColor};
					}
				}
				curChoices["99_EXIT"] = {text:"[gr_exit_menu]", color:this._itemColor};

				def = "99_EXIT";

				var opts = {
					screenID: "oolite-galacticregistry-intro-map",
					title: "Galactic Registry - Main Menu",
					allowInterrupt: true,
					overlay:{name:"galreg-solar_system.png", height:546},
					exitScreen: this._exitTo,
					choices: curChoices,
					initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
					message: text
				};
				break;
			}
		case 8: // full list
			{
				var syslist = SystemInfo.filteredSystems(this, function(other) {return (!other.concealment || other.concealment <= 100);});
				var rows = 16;
				
				switch (this._sortType) {
					case 0:
						syslist.sort(compareName);
						break;
					case 1: 
						syslist.sort(compareTL);
						break;
					case 2:
						syslist.sort(compareGov);
						break;
					case 3:
						syslist.sort(compareEco);
						break;
				}

				text = this.$padTextRight("", 2.1) + 
					this.$padTextRight("Name", 7) + 
					this.$padTextRight("TL", 3) + 
					this.$padTextRight("Government", 10) +
					"Economy\n";

				var maxpage = Math.ceil(syslist.length / rows);
				var end = ((this._page * rows) + rows);
				var itemcount = 0;
				if (end > syslist.length) end = syslist.length;
				for (var i = (this._page * rows); i < end; i++) {
					curChoices["40_SYSLIST_" + (i < 10 ? "00" : (i < 100 ? "0" : "")) + i + "~" + syslist[i].systemID] =
						{text:this.$padTextRight((this._select1 === syslist[i].systemID || this._select2 === syslist[i].systemID ? "•" : ""), 2) + 
							this.$padTextRight(syslist[i].name, 7) + 
							this.$padTextRight(((!syslist[i].concealment || syslist[i].concealment === 0) ? syslist[i].techlevel + 1 : "??"), 3) + 
							this.$padTextRight(((!syslist[i].concealment || syslist[i].concealment === 0) ? this.$governmentDescription(syslist[i].government) : "??"), 10) + 
							((!syslist[i].concealment || syslist[i].concealment === 0) ? this.$economyDescription(syslist[i].economy) : "??"), 
						alignment:"LEFT", color:this._itemColor};
					itemcount += 1;
				}

				curChoices["94_SPACER"] = "";
				for (var i = 0; i < (rows - itemcount); i++) {
					curChoices["94_SPACER_" + i] = "";
				}

				if (maxpage > 1 && this._page < (maxpage - 1)) {
					curChoices["95_NEXT"] = {text:"[gr_nextpage]", color:this._menuColor};
				} else {
					curChoices["95_NEXT"] = {text:"[gr_nextpage]", color:this._disabledColor, unselectable:true};
				}
				if (this._page > 0) {
					curChoices["96_PREV"] = {text:"[gr_prevpage]", color:this._menuColor};
				} else {
					curChoices["96_PREV"] = {text:"[gr_prevpage]", color:this._disabledColor, unselectable:true};
				}

				curChoices["97_1_SORT_NAME"] = {text:"[gr_sort_name]", color:(this._sortType === 0 ? this._disabledColor : this._menuColor), unselectable:(this._sortType === 0 ? true : false)};
				curChoices["97_2_SORT_TL"] = {text:"[gr_sort_tl]", color:(this._sortType === 1 ? this._disabledColor : this._menuColor), unselectable:(this._sortType === 1 ? true : false)};
				curChoices["97_3_SORT_GOV"] = {text:"[gr_sort_gov]", color:(this._sortType === 2 ? this._disabledColor : this._menuColor), unselectable:(this._sortType === 2 ? true : false)};
				curChoices["97_4_SORT_ECO"] = {text:"[gr_sort_eco]", color:(this._sortType === 3 ? this._disabledColor : this._menuColor), unselectable:(this._sortType === 3 ? true : false)};

				var sys1 = "(none)";
				var sys2 = "(none)";
				if (this._select1 >= 0) sys1 = System.systemNameForID(this._select1);
				if (this._selectLast === 2) sys1 = "• " + sys1;
				if (this._select2 >= 0) sys2 = System.systemNameForID(this._select2);
				if (this._selectLast === 1) sys2 = " •" + sys2;

				curChoices["97_9_SELECTED"]	 = {text:expandDescription("[gr_view_selected]", {select1:sys1, select2:sys2}), color:(this._select1 === -1 || this._select2 === -1 ? this._disabledColor : this._menuColor), unselectable:(this._select1 === -1 || this._select2 === -1 ? true : false)};

				def = "98_EXIT";
				curChoices["98_EXIT"] = {text:"[gr_exit_menu]", color:this._exitColor};

				var opts = {
					screenID: "oolite-galacticregistry-fulllist-map",
					title: "System List" + (maxpage > 1 ? ": Page " + (this._page + 1) + " of " + maxpage : ""),
					overlay:{name:"galreg-solar_system.png", height:546},
					allowInterrupt: true,
					exitScreen: this._exitTo,
					choices: curChoices,
					initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
					message: text
				};
				break;
			}

		case 9: // selected systems
			{
				mission.markSystem({system:this._select1, markerColor:"greenColor", markerShape:"MARKER_SQUARE", name:"galreg_marked"});
				this._markedPlanets.push(this._select1);
				mission.markSystem({system:this._select2, markerColor:"cyanColor", markerShape:"MARKER_SQUARE", name:"galreg_marked"});
				this._markedPlanets.push(this._select2);

				var data1 = this.$getSystemData(this._select1);
				var data2 = this.$getSystemData(this._select2);
				var conceal1 = System.infoForSystem(galaxyNumber, this._select1).concealment;
				var conceal2 = System.infoForSystem(galaxyNumber, this._select2).concealment;

				if (p.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === true) {
					var rt = System.infoForSystem(galaxyNumber, this._select1).routeToSystem(System.infoForSystem(galaxyNumber, this._select2), p.routeMode);
					if (rt && rt.route.length > 1) {
						for (var i = 0; i < rt.route.length - 1; i++) {
							if (rt.route[i] < rt.route[i + 1]) {
								SystemInfo.setInterstellarProperty(galaxyNumber, rt.route[i], rt.route[i + 1], 2, "link_color", "whiteColor", "galreg_region");
								this._markedRegions.push({id1:rt.route[i], id2:rt.route[i + 1]});
							} else {
								SystemInfo.setInterstellarProperty(galaxyNumber, rt.route[i + 1], rt.route[i], 2, "link_color", "whiteColor", "galreg_region");
								this._markedRegions.push({id1:rt.route[i + 1], id2:rt.route[i]});
							}
						}
					}
				}

				var govs = new Array();
				for (var i = 0; i < 8 ; i++)
					govs.push(String.fromCharCode(i));
				this.ecos = new Array();
				for (i = 0; i < 8 ; i++) {
					this.ecos.push(String.fromCharCode(23 - i));
				}
				var spc = String.fromCharCode(31);

				text = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; 

				text += this.$padTextRight(
					data1.name + ((!conceal1 || conceal1 === 0) ? " (" + spc + govs[data1.government] + spc + ecos[data1.economy] + spc + "TL" + spc + data1.techLevel + ")" : ""), 15.5) + 
					data2.name + ((!conceal2 || conceal2 === 0) ? " (" + spc + govs[data2.government] + spc + ecos[data2.economy] + spc + "TL" + spc + data2.techLevel + ")" : "") + "\n";
				text += this.$padTextRight(((!conceal1 || conceal1 === 0) ? data1.population + " " + data1.inhabitants : ""), 15.5) + 
					((!conceal2 || conceal2 === 0) ? data2.population + " " + data2.inhabitants : "") + "\n";
				text += this.$padTextRight(((!conceal1 || conceal1 === 0) ? "Prod: " + data1.productivity + " M₢, Radius: " + data1.radius + " km" : ""), 15.5) + 
					((!conceal2 || conceal2 === 0) ? "Prod: " + data2.productivity + " M₢, Radius: " + data2.radius + " km" : "") + "\n\n";

				if (rt) {
					text += "Distance between systems: " + rt.distance.toFixed(1) + " ly / " + 
						rt.time.toFixed(1) + " " + (rt.time > 0.95 && rt.time < 1.05 ? expandDescription("[sysdata-route-hours%0]") : expandDescription("[sysdata-route-hours%1]"))  + " / " + 
						(rt.route.length - 1) + " " + (rt.route.length === 2 ? expandDescription("[sysdata-route-jumps%0]") : expandDescription("[sysdata-route-jumps%1]"));
				} else {
					text += "Distance between systems: " + System.infoForSystem(galaxyNumber, this._select1).distanceToSystem(System.infoForSystem(galaxyNumber, this._select2)) + " ly";
				}

				if (p.hasEquipmentProviding("EQ_ADVANCED_NAVIGATIONAL_ARRAY") === true) {
					var rt1 = system.info.routeToSystem(System.infoForSystem(galaxyNumber, this._select1), p.routeMode);
					if (rt1 && rt1.route.length > 1) {
						var rtText = rt1.distance.toFixed(1) + " ly / " + 
						rt1.time.toFixed(1) + " " + (rt1.time > 0.95 && rt1.time < 1.05 ? expandDescription("[sysdata-route-hours%0]") : expandDescription("[sysdata-route-hours%1]"))  + " / " + 
						(rt1.route.length - 1) + " " + (rt1.route.length === 2 ? expandDescription("[sysdata-route-jumps%0]") : expandDescription("[sysdata-route-jumps%1]"));
						curChoices["50_SETCOURSE~" + this._select1] = {text:expandDescription("[gr_setcourse3]", {select:System.systemNameForID(this._select1), details:rtText}), color:"greenColor"};
					} else {
						var rtText = system.info.distanceToSystem(System.infoForSystem(galaxyNumber, this._select1)).toFixed(1) + " ly";
						curChoices["50_SETCOURSE~" + this._select1] = {text:expandDescription("[gr_nocourse]", {select:System.systemNameForID(this._select1), details:rtText}), color:"greenColor", unselectable:true};
					}
					var rt2 = system.info.routeToSystem(System.infoForSystem(galaxyNumber, this._select2), p.routeMode);
					if (rt2 && rt2.route.length > 1) {
						var rtText = rt2.distance.toFixed(1) + " ly / " + 
						rt2.time.toFixed(1) + " " + (rt2.time > 0.95 && rt2.time < 1.05 ? expandDescription("[sysdata-route-hours%0]") : expandDescription("[sysdata-route-hours%1]"))  + " / " + 
						(rt2.route.length - 1) + " " + (rt2.route.length === 2 ? expandDescription("[sysdata-route-jumps%0]") : expandDescription("[sysdata-route-jumps%1]"));	
						curChoices["50_SETCOURSE~" + this._select2] = {text:expandDescription("[gr_setcourse3]", {select:System.systemNameForID(this._select2), details:rtText}), color:"cyanColor"};
					} else {
						var rtText = system.info.distanceToSystem(System.infoForSystem(galaxyNumber, this._select2)).toFixed(1) + " ly";
						curChoices["50_SETCOURSE~" + this._select2] = {text:expandDescription("[gr_nocourse]", {select:System.systemNameForID(this._select2), details:rtText}), color:"cyanColor", unselectable:true};
					}
				}

				curChoices["97_EXIT"] = {text:"[gr_exit_menu]", color:this._itemColor};
				def = "97_EXIT";

				var opts = {
					screenID: "oolite-galacticregistry-selected-map",
					title: "Galactic Registry - Selected Systems",
					backgroundSpecial: bg,
					overlay:{name:"galreg-solar_system.png", height:546},
					allowInterrupt: true,
					exitScreen: this._exitTo,
					choices: curChoices,
					initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
					message: text
				};
				break;
			}

		case 10: // search results map
			{
				this._pageLength = 255;
				var planets = this.$searchSystems();
				var closest = this.$getClosestSystemFromList(planets);

				for (var i = 0; i < planets.length; i++) {
					mission.markSystem({system:planets[i].systemID, markerColor:"cyanColor", markerShape:"MARKER_DIAMOND", name:"galreg_marked"});
					this._markedPlanets.push(planets[i].systemID);
				}

				curChoices["17_SEARCHRESULTS-X"] = {text:"[gr_showsystems0]", unselectable:false, color:this._altColor};

				if (this._removeANATool === false) {
					if (closest != -1) curChoices["50_SETCOURSE~" + closest] = {text:expandDescription("[gr_setcourse1]", {select:System.systemNameForID(closest)}), color:this._menuColor};
				}

				text = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nFound " + planets.length + " system" + (planets.length > 1 ? "s" : "") + ".  Search criteria: " + this._search.join(" ");

				curChoices["97_SEARCH_AGAIN"] = {text:"[gr_search_again]", color:this._itemColor};
				curChoices["98_EXIT"] = {text:"[gr_exit_menu]", color:this._itemColor};
				def = "98_EXIT";

				var opts = {
					screenID: "oolite-galacticregistry-searchresults-map",
					title: "Galactic Registry - Search Results",
					backgroundSpecial: bg,
					overlay:{name:"galreg-solar_system.png", height:546},
					allowInterrupt: true,
					exitScreen: this._exitTo,
					choices: curChoices,
					initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
					message: text
				};
				break;
			}
		case 17: // search results sys list
			{
				this._pageLength = 22;
				var planets = this.$searchSystems();
				planets.sort(compareName);
				var closest = this.$getClosestSystemFromList(planets);

				text = (this._searchMax === false ? "Found " + planets.length + " system" + (planets.length > 1 ? "s" : "") + ".  " : "") + "Search criteria: " + this._search.join(" ") + "\n" + (this._searchMax === true ? "Note: More than 66 systems found - Only 66 systems shown" : "") + "\n";
				
				text += this.$formatSystemList(planets);

				curChoices["17_SEARCHRESULTS"] = {text:"[gr_showmap0]", color:this._altColor};

				if (this._removeANATool === false) {
					if (closest != -1) curChoices["50_SETCOURSE~" + closest] = {text:expandDescription("[gr_setcourse1]", {select:System.systemNameForID(closest)}), color:this._menuColor};
				}

				curChoices["97_SEARCH_AGAIN"] = {text:"[gr_search_again]", color:this._itemColor};
				curChoices["98_EXIT"] = {text:"[gr_exit_menu]", color:this._itemColor};
				def = "98_EXIT";

				var opts = {
					screenID: "oolite-galacticregistry-searchsystemslist-map",
					title: "Galactic Registry - Search Results",
					allowInterrupt: true,
					exitScreen: this._exitTo,
					choices: curChoices,
					initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
					message: text
				};
				break;
			}
	}

	if (this._menu >= 20) {
		var cust = this._menu - 20;
		var sub = false;
		if (cust >= 20) {
			cust -= 20;
			sub = true;
		}
		var custItem = this._custom[cust];
		this._setItem = custItem.systems[this._item];
		var planets = custItem.systems[this._item].systemIDList;
		def = "98_EXIT";

		if (sub === false) {
			var closest = this.$getClosestSystemFromList(planets);

			switch (custItem.listType) {
				case "unconnected": // (default)
					var colr = custItem.systems[this._item].markerColor;
					var shape = custItem.systems[this._item].markerShape;

					for (var i = 0; i < planets.length; i++) {
						var s = System.infoForSystem(galaxyNumber, planets[i]);
						if (!s.concealment || s.concealment <= 100) {
							mission.markSystem({system:planets[i], markerColor:colr, markerShape:shape, name:"galreg_marked", markerScale:1.0});
							this._markedPlanets.push(planets[i]);
						}
					}
					break;
				case "region": 
					var colr = custItem.systems[this._item].linkColor
					for (var j = 0; j < planets.length; j++) {
						for (var k = 0; k < planets.length; k++) {
							if (j != k && planets[j] < planets[k]) {
								this._markedRegions.push({id1:planets[j], id2:planets[k]});
								SystemInfo.setInterstellarProperty(galaxyNumber, planets[j], planets[k], 2, "link_color", colr, "galreg_region");
							}
						}
					}
					break;
				case "path":
					var colr = custItem.systems[this._item].linkColor

					for (var j = 0; j < planets.length - 1; j++) {
						var s1 = System.infoForSystem(galaxyNumber, planets[j]);
						var c1 = s1.concealment;
						if (!c1) c1 = 0;
						var s2 = System.infoForSystem(galaxyNumber, planets[j + 1]);
						var c2 = s2.concealment;
						if (!c2) c2 = 0;
						if (c1 <= 100 && c2 <= 100 && s1.distanceToSystem(s2) <= 7) {
							if (planets[j] < planets[j + 1]) {
								SystemInfo.setInterstellarProperty(galaxyNumber, planets[j], planets[j + 1], 2, "link_color", colr, "galreg_region");
								this._markedRegions.push({id1:planets[j], id2:planets[j + 1]});
							} else {
								SystemInfo.setInterstellarProperty(galaxyNumber, planets[j + 1], planets[j], 2, "link_color", colr, "galreg_region");
								this._markedRegions.push({id1:planets[j + 1], id2:planets[j]});
							}
						}
					}
					// mark the end points on the route
					colr = custItem.systems[this._item].markerColor

					var c1 = System.infoForSystem(galaxyNumber, planets[0]).concealment;
					if (!c1 || c1 <= 100) {
						mission.markSystem({system:planets[0], name:"galreg_marked", markerShape:custItem.systems[this._item].startMarkerShape, markerColor:colr, markerScale:1.5});
						this._spaceLaneStart = planets[0];
					}
					var c2 = System.infoForSystem(galaxyNumber, planets[planets.length - 1]).concealment;
					if (!c2 || c2 <= 100) {
						mission.markSystem({system:planets[planets.length - 1], name:"galreg_marked", markerShape:custItem.systems[this._item].endMarkerShape, markerColor:colr, markerScale:1.5});
						this._spaceLaneEnd = planets[planets.length - 1];
					}
					break;
			}

			var opts = {
				screenID: "oolite-galacticregistry-custom-map",
				title: "Galactic Registry - " + expandDescription(custItem.systems[this._item].name),
				backgroundSpecial: bg,
				overlay:{name:"galreg-solar_system.png", height:546},
				allowInterrupt: true,
				exitScreen: this._exitTo,
				initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
				message: text
			};

		} else {
			var syslist = [];
			for (var i = 0; i < planets.length; i++) {
				var s = System.infoForSystem(galaxyNumber, planets[i]);
				syslist.push(s);
			}
			// only sort the non-path lists
			if (custItem.listType != "path") {
				syslist.sort(compareName);
				planets.sort(compareName);
			}
			var closest = this.$getClosestSystemFromList(planets);

			text = this.$formatSystemList(syslist);

			var opts = {
				screenID: "oolite-galacticregistry-customsystemslist-map",
				title: "Galactic Registry - " + expandDescription(custItem.systems[this._item].name),
				overlay:{name:"galreg-solar_system.png", height:546},
				allowInterrupt: true,
				exitScreen: this._exitTo,
				initialChoicesKey: (this._lastChoice[this._menu] != "" ? this._lastChoice[this._menu] : def),
				message: text
			};
		}

		var holdpagesize = pagesize;

		var maxpage = Math.ceil(custItem.systems.length / pagesize);
		// if we have three pages to display, we need to reduce the page size because the middle page will need a "Next" plus a "Back" item
		// which will reduce the actual space for techelevel items
		if (maxpage > 1) { //  && pagesize === 7
			pagesize -= 1;
			maxpage = Math.ceil(custItem.systems.length / pagesize);
		}
		
		var end = ((this._page * pagesize) + pagesize);
		if (end > custItem.systems.length) end = custItem.systems.length;

		for (var i = (this._page * pagesize); i < end; i++) {
			if (this._item === i) {
				if (sub === false) {
					curChoices["20_CUSTOM!" + (cust < 10 ? "0" : "") + cust + "~" + (i < 10 ? "0" : "") + i + "-X"] = {text:expandDescription("[gr_showsystems1]", {name:custItem.systems[i].name}), unselectable:false, color:this._altColor};
				} else {
					curChoices["20_CUSTOM!" + (cust < 10 ? "0" : "") + cust + "~" + (i < 10 ? "0" : "") + i] = {text:expandDescription("[gr_showmap1]", {name:custItem.systems[i].name}), unselectable:false, color:this._altColor};
				}
			} else {
				curChoices["20_CUSTOM!" + (cust < 10 ? "0" : "") + cust + "~" + (i < 10 ? "0" : "") + i] = {text:custItem.systems[i].name, color:this._menuColor};
			}
		}

		if (this._removeANATool === false) {
			if (closest != -1 && player.ship.docked) curChoices["50_SETCOURSE~" + closest] = {text:expandDescription("[gr_setcourse1]", {select:System.systemNameForID(closest)}), color:this._itemColor};
			switch (custItem.listType) {
				case "unconnected":
					curChoices["94U_PERMANENT"] = {text:(this.$checkPermanentSystems(this._setItem.id) ? "[gr_unset_permanent]" : "[gr_set_permanent]"), color:this._itemColor};
					break;
				case "region":
					curChoices["94R_PERMANENT"] = {text:(this.$checkPermanentRegions(this._setItem.id) ? "[gr_unset_permanent]" : "[gr_set_permanent]"), color:this._itemColor};
					break;
				case "path":
					curChoices["94P_PERMANENT"] = {text:(this.$checkPermanentPaths(this._setItem.id) ? "[gr_unset_permanent]" : "[gr_set_permanent]"), color:this._itemColor};
					break;
			}
		}

		if (maxpage > 1) {
			if (this._page < (maxpage - 1)) {
				curChoices["95_NEXT"] = {text:"[gr_nextpage]", color:this._itemColor};
			} else {
				curChoices["95_NEXT"] = {text:"[gr_nextpage]", color:this._disabledColor, unselectable:true};
			}
			if (this._page > 0) {
				curChoices["96_PREV"] = {text:"[gr_prevpage]", color:this._itemColor};
			} else {
				curChoices["96_NEXT"] = {text:"[gr_prevpage]", color:this._disabledColor, unselectable:true};
			}
		}

		curChoices["98_EXIT"] = {text:"[gr_exit_menu]", color:this._itemColor};

		pagesize = holdpagesize;
		opts.choices = curChoices;
	}

	if (zeroMap) worldScripts.ZeroMap._showAll(galaxyNumber);

	mission.runScreen(opts, this.$screenHandler, this);
}

//-------------------------------------------------------------------------------------------------------------
this.$screenHandler = function $screenHandler(choice) {
	if (this._holdDestination >= 0) {
		player.ship.targetSystem = this._holdDestination;
		this._holdDestination = -1;
	}

	if (!choice) return;

	this._lastChoice[this._menu] = choice;
	
	switch (choice) {
		case "11_FULLLIST":
			this._menu = 8;
			this._item = 0;
			this._page = 0;
			break;
		case "12_SEARCH":
			this.$getSearchPhrase();
			return;
		case "94U_PERMANENT": // systems
			if (this.$checkPermanentSystems(this._setItem.id)) {
				this.$removePermanentSystems(this._setItem.id);
			} else {
				this._permanentChartData.systems.push({
					id:this._setItem.id, 
					markerShape:this._setItem.markerShape, 
					markerColor:this._setItem.markerColor, 
					markerScale:1.0,
					systemIDList:this._setItem.systemIDList
				});
			}
			break;
		case "94P_PERMANENT":
			if (this.$checkPermanentPaths(this._setItem.id)) {
				this.$removePermanentPath(this._setItem.id);
				this.$removePermanentSystems(this._setItem.id);
			} else {
				this._permanentChartData.paths.push({
					id:this._setItem.id,
					linkColor: this._setItem.linkColor,
					systemIDList: this._setItem.systemIDList
				});
				this._permanentChartData.systems.push({
					id:this._setItem.id,
					markerShape:this._setItem.startMarkerShape,
					markerColor:this._setItem.markerColor,
					markerScale:1.5,
					systemIDList:[this._setItem.systemIDList[0]]
				});
				this._permanentChartData.systems.push({
					id:this._setItem.id,
					markerShape:this._setItem.endMarkerShape,
					markerColor:this._setItem.markerColor,
					markerScale:1.5,
					systemIDList:[this._setItem.systemIDList[this._setItem.systemIDList.length - 1]]
				});
			}
			break;
		case "94R_PERMANENT":
			if (this.$checkPermanentRegions(this._setItem.id)) {
				this.$removePermanentRegion(this._setItem.id);
			} else {
				this._permanentChartData.regions.push({
					id:this._setItem.id,
					linkColor: this._setItem.linkColor,
					systemIDList: this._setItem.systemIDList
				});
			}
			break;
		case "95_NEXT":
			this._page += 1;
			break;
		case "96_PREV":
			this._page -= 1;
			break;
		case "97_1_SORT_NAME":
			this._sortType = 0;
			break;
		case "97_2_SORT_TL":
			this._sortType = 1;
			break;
		case "97_3_SORT_GOV":
			this._sortType = 2;
			break;
		case "97_4_SORT_ECO":
			this._sortType = 3;
			break;
		case "97_9_SELECTED":
			this._menu = 9;
			break;
		case "97_EXIT":
			this._menu = 8;
			break;
		case "98_EXIT":
			this._menu = 0;
			break;
		case "97_SEARCH_AGAIN":
			this._menu = this.$getSearchPhrase();
			return;
		case "17_SEARCHRESULTS":
			this._menu = 10;
			this._lastChoice[this._menu] = "17_SEARCHRESULTS-X";
			break;
		case "17_SEARCHRESULTS-X":
			this._menu = 17;
			this._lastChoice[this._menu] = "17_SEARCHRESULTS";
			break;
	}

	if (choice.indexOf("10_CUSTOM~") >= 0) {
		var custIndex = parseInt(choice.substring(choice.indexOf("~") + 1), 10);
		this._menu = custIndex + 20;
		this._item = 0;
		this._page = 0;
	}
	if (choice.indexOf("20_CUSTOM") >= 0) {
		var menuIndex = parseInt(choice.substring(choice.indexOf("!") + 1), 10);
		this._menu = menuIndex + 20;
		var itemIndex = parseInt(choice.substring(choice.indexOf("~") + 1), 10);
		this._item = itemIndex;
		if (choice.indexOf("-X") === -1) {
			this._lastChoice[this._menu] = choice + "-X";
		} else {
			this._menu = menuIndex + 40;
			this._lastChoice[this._menu] = choice.replace("-X", "");
		}
	}

	if (choice.indexOf("40_SYSLIST") >= 0) {
		var sys = parseInt(choice.substring(choice.indexOf("~") + 1), 10);
		if (this._selectLast === 2) {
			this._select1 = sys;
			this._selectLast = 1;
		} else {
			this._select2 = sys;
			this._selectLast = 2;
		}
	}
	if (choice.indexOf("50_SETCOURSE") >= 0) {
		player.ship.targetSystem = parseInt(choice.substring(choice.indexOf("~") + 1), 10);
		player.ship.infoSystem = player.ship.targetSystem;
		player.consoleMessage("Course set for " + System.systemNameForID(player.ship.targetSystem));
		this._lastChoice[this._menu] = "";
	}

	if (choice != "99_EXIT") this.$showMissionPage();
}

//-------------------------------------------------------------------------------------------------------------
// prompts the user for search criteria
this.$getSearchPhrase = function $getSearchPhrase() {
	
	var text = "Enter the words you'd like to search for, with each word separated by a space. The words will be looked for in the planet's " +
		"description, government type, economy type, inhabitants description and techelevel. " + 
		"All words will need to find a match in one of the descriptions in order to include that system in the search results.\n\n" +
		"For example, entering 'feline anarchy' would find any Anarchy systems populated by felines.\n\n" +
		"Entering 'tl7- tedious prod<15000' would find any TechLevel 7 or less systems that have 'tedious' in the planetary description and a productivity less than 15000 MCr.\n\n" + 
		"Entering 'human pop<4.0 tl8+|industrial' would final any system populated with less than 4.0 billion humans or humanoids and with either a TechLevel of 8 or more, or any of the industrial economies.\n\n" +
		"Entering a blank value will abort the search and return to the main menu. Entered words must be a minimum of three characters in length.";

	var opts = {
		screenID: "oolite-galacticregistry-searchphrase-map",
		title: "Enter search criteria",
		allowInterrupt: false,
		exitScreen: "GUI_SCREEN_INTERFACES",
		overlay: {name:"galreg-solar_system.png", height:546},
		message: text,
		textEntry: true
	};
	mission.runScreen(opts,this.$extractSearchWords, this);
}

//-------------------------------------------------------------------------------------------------------------
// parses the input from the setLogSize screen
this.$extractSearchWords = function $extractSearchWords(param) {
	this._menu = 10;
	if (param === "") {
		this._menu = 0; 
	} else {
		this._search = param.toLowerCase().split(" ");
		for (var i = this._search.length - 1; i >= 0; i--) {
			if (this._search[i].trim() === "" || this._search[i].length <= 2) this._search.splice(i, 1);
		}
		if (this._search.length === 0) this._menu = 0;
	}
	this.$showMissionPage();
}

//-------------------------------------------------------------------------------------------------------------
// returns a 3-column list of planets, formatted for display
this.$formatSystemList = function $formatSystemList(list) {
	var govs = new Array();
	for (var i = 0; i < 8 ; i++)
		govs.push(String.fromCharCode(i));
	this.ecos = new Array();
	for (i = 0; i < 8 ; i++) {
		this.ecos.push(String.fromCharCode(23 - i));
	}
	var spc = String.fromCharCode(31);
	
	var lines = [];
	for (var i = 0; i < this._pageLength; i++) lines.push("");
	var point = 0;
	var p = player.ship;
	
	var colwidth = 31;
	if (list.length > this._pageLength) colwidth = 15;
	if (list.length > (this._pageLength * 2)) colwidth = 10.2;

	for (var i = 0; i < list.length; i++) {
		if (isNaN(list[i])) {
			var sys = list[i];
		} else {
			var sys = System.infoForSystem(galaxyNumber, list[i]);
		}
		var item = sys.name + ((!sys.concealment || sys.concealment === 0) ? " (" + govs[sys.government] + spc + ecos[sys.economy] + spc + "TL" + (sys.techlevel + 1) + ")" : "");

		lines[point] += this.$padTextRight(item, colwidth);
		point += 1;
		if (point === lines.length) point = 0;
	}
	var result = "";
	for (var i = 0; i < lines.length; i++) {
		result += lines[i] + "\n";
	}
	return result;
}

//-------------------------------------------------------------------------------------------------------------
this.$getClosestSystemFromList = function $getClosestSystemFromList(planets) {
	var dist = 0;
	var min_dist = 200;
	var closest = -1;
	var maxlevel = this.$getMaxTechLevel();
	var chk = -1;
	for (var i = 0; i < planets.length; i++) {
		if (isNaN(planets[i])) {
			chk = planets[i].systemID;
		} else {
			chk = planets[i];
		}
		var s = System.infoForSystem(galaxyNumber, chk);
		if (!s.concealment || s.concealment <= 100) {
			var dist = this.$getDistanceToPlanet(chk);
			if (dist < min_dist) {closest = chk; min_dist = dist;}
		}
	}
	return closest;
}

//-------------------------------------------------------------------------------------------------------------
this.$getRegionData = function $getRegionData() {
	var info = [];
	switch (galaxyNumber) {
		case 0:
			info = [{name:"Xexedi Cluster", data:[43,101,141,250,197,140,48,37,58,64,188,111]},
					{name:"Galcenter G1", data:[167,249,131,42,93,100,139,21,230,62]},
					{name:"Teraed Region", data:[221,185,99,241,84,120,191,121,60]},
					{name:"The Pulsar Worlds", data:[102,18,51,246,218,8,114,215,158,49]},
					{name:"The Tortuga Expanse", data:[213,59,142,174,223,238]},
					{name:"The Devil's Triangle", data:[20,148,181]},
					{name:"The Iron Stars", data:[3,128,94,153,132,26,196,146,234]},
					{name:"The Old Worlds", data:[129,255,55,46,147,7,39]}];
			break;
		case 1:
			info = [{name:"The Qucedi Bottleneck", data:[159,111,157,16,139,34,248,205,59]},
					{name:"The Equilibrium", data:[156,92,61]},
					{name:"Redline Stars", data:[231,215,147,108,140,249,189,65,204]},
					{name:"Kob's Ladder", data:[29,13,97,102,149,124,81,20,123]},
					{name:"The Teonan Web", data:[32,42,26,114,202,55,142,50,69,18,36,146,251]},
					{name:"Fiddler's Green", data:[10,2,224,172,70,120,181,76,104,7,194]},
					{name:"The Zaedvera Pocket", data:[87,134,38,185,155,62,227,175,235,44,220,192]},
					{name:"Galcenter G2", data:[242,91,167,115,178,113,226,57,94,19,33]},
					{name:"The Citadel of Chaos", data:[100,229,37,5]},
					{name:"The Fertile Cresent", data:[47,0,217,213,190,135,30,137,254,64,110,225]}];
			break;
		case 2:
			info = [{name:"The Outer Reach", data:[100,18,149,62,201,223,52,145]},
					{name:"The Prodigal Suns", data:[206,133]},
					{name:"The Inner Reach", data:[54,161,185,118,121,186,232,165,129]},
					{name:"The Sidewinder Expanse", data:[40,184,36,99,210,35,61,90,51]},
					{name:"Galcenter G3", data:[234,49,239,22,228,175,110,140,5,56,177,150,26,58]},
					{name:"The Starbridge Cluster", data:[192,207,134,244,60,107,173,215,64,119,168,114,227,19,205,94,88,101,241,82,236,32,46,248]},
					{name:"The Yeon Pass", data:[170,231,127,45,27,108,247,199]}];
			break;
		case 3:
			info = [{name:"Foundry's Reach", data:[184,86,163,116,230,167,94,36,159,12,57,65,35,55,228]},
					{name:"The Unified Democratic Star League", data:[234,125,245,181,73,82,117,37,237,53,74,38]},
					{name:"The Parallel Accord", data:[99,63,51,102,31,20,44,215,158,92,224,231,220,110,68,151,248,79,71,115]},
					{name:"Galcenter G4", data:[222,65,137,144,101,45,105,148,95,49,34,10,54,30,119,103,241]}];
			break;
		case 4:
			info = [{name:"The Gates of Damocles", data:[84,66,58,49,71,125,78,242]},
					{name:"The Siege Worlds", data:[31,127,134,44,198,37,63,95,219]},
					{name:"Galcenter G5", data:[3,47,111,181,231,35,122,180,102,24,19,69,156,60,1,230,112,28]},
					{name:"Galcon Bombard", data:[151,86,133,123,36,98,223]},
					{name:"The Steel Halo", data:[55,128,72,185,126,100,109]},
					{name:"The Tetiri Conclave", data:[205,7,161,70,173,137,191,140]}];
			break;
		case 5:
			info = [{name:"The Anener Commonwealth", data:[32,56,47,160,242,167,129,12]},
					{name:"The Rabian Spur", data:[88,184,196,8,3,84,236,111,214]},
					{name:"The Iron Alliance", data:[177,185,106,44,245,171,156,113,14,146,249,230,134,205,216,82]},
					{name:"The Rimward Industrial Sector", data:[116,178,154,45,204,163,120,7,251,72,132,137,255,90,149,241,153,141,95,218,212,198]},
					{name:"The Jaws of Cerberus", data:[121,203,31,30,74,126,234]},
					{name:"The Isaanus Syndicate", data:[240,140,159,77,66,10,118,186,46]},
					{name:"The Lost Worlds", data:[41,202,55,33]},
					{name:"The Anenbian Confederacy", data:[172,208,201,87,168,2,39,246,83,42,35,65,114,224,23]},
					{name:"The Raonbe Cluster", data:[22,98,53,229,248,139,16,102,130]},
					{name:"The Centreward Industrial Sector", data:[37,75,127,6,189,89,17,1,161,250,147,67,60,138,252,155,233,225,86,254,71,0,58,210,69,4,223,144,19,206,150,194,182,5,200]},
					{name:"Galcenter G6", data:[176,99,174,85,237,133,213,107,187,40,164,215,117,79,9,232,50,110,81,195,183]}];
			break;
		case 6:
			info = [{name:"GALCOP Central Intelligence Sector", data:[18,234,117,49,1]},
					{name:"The Isare Pact", data:[124,51,172,81,102,204]},
					{name:"Galcenter G7", data:[215,111,181,41,39,65,44,236,150,193,247,202,72,37,179,133]},
					{name:"The Kleptocratic Swathe", data:[187,77,53,100,240,107,174]},
					{name:"The Rubicon Crossroad", data:[186,110,97,248,15,134]},
					{name:"The Five Point Trade Barrier", data:[137,153,27,228,139]}];
			break;
		case 7:
			info = [{name:"Beggars' Loop", data:[242,170,87,115,150,62,240,186,34,196,185,11,253,166,132,90,134,160]},
					{name:"The Ladle", data:[52,223,247,144,67]},
					{name:"The Far Arm Star Cluster", data:[203,255,161,98,16,20,84,107]},
					{name:"The Riven Hitachi Senate", data:[6,81,250,65,169,232,105,80,75,40,59,252,153,72,10,219,231,200,208,86]},
					{name:"Galcenter G8", data:[135,73,193,120,127,7,102,184,172,177,210,70,130,123,38,175,23,233,39,168,64,104,41,125,45,110,201,241,154]},
					{name:"The Unified Tech-Core", data:[216,13,147,137,9,211,88,171,2,215]}];
			break;
	}
	return info;
}

//-------------------------------------------------------------------------------------------------------------
// loads the spacelane array with data for the current galaxy
this.$getSpacelanes = function $getSpacelanes() {
	var data = [];
	switch (galaxyNumber) {
		case 0:
			data = [{name:"Spaceway L1", color:"0.0 1.0 1.0 0.5", data:[141,250,111,186,50,73,35,188,250]},
					{name:"Spaceway L2", color:"1.0 1.0 0.0 0.5", data:[7,129,227,73,89,222,29,93,42,131]},
					{name:"Spaceway L3", color:"whiteColor", data:[131,62,150,198,36,28,16,221,99]},
					{name:"Spaceway L4", color:"0.824 0.412 0.118 1.0", data:[99,241,86,126,18,246]}];
			break;
		case 1:
			data = [{name:"Spaceway L1", color:"0.0 1.0 1.0 0.5", data:[82,23,188,23,54,74,122,57,115,178,45]},
					{name:"Spaceway L2", color:"redColor", data:[45,144,189,140,65,48,204,193,221,236,66,58,88,127]},
					{name:"Spaceway L3", color:"1.0 1.0 0.0 0.5", data:[127,109,42,114,202]},
					{name:"The Tomoka Run", color:"greenColor", data:[127,207,136,6,24,53,78,48]},
					{name:"The Maorin Pass", color:"whiteColor", data:[205,59,100,9,156,92,61,41,179,189]},
					{name:"Erlage Corridor 'Butchers Row'", color:"0.824 0.412 0.118 1.0", data:[113,115,57,94,29]}];
			break;
		case 2:
			data = [{name:"Spaceway L1", color:"0.0 1.0 1.0 0.5", data:[38,182,246,91,22,140,5,56,177,150,26,75,144,209,17,218]},
					{name:"Spaceway L2", color:"redColor", data:[50,65,79,154,38,139,189,135,42]},
					{name:"Triskelion Conduit", color:"whiteColor", data:[205,241,101,132,6,180,164,70,10,85,81,225,81,85,10,70,202,53]},
					{name:"Chancers Alley", color:"0.824 0.412 0.118 1.0", data:[140,58,152,76,77,97,168]},
					{name:"Glasnost Corridor", color:"greenColor", data:[106,250,245,160,245,22]},
					{name:"Broken Circle", color:"1.0 1.0 0.0 0.5", data:[118,161,54,165,129,186]}];
			break;
		case 3:
			data = [{name:"Sunspan Pass", color:"greenColor", data:[116,230,167,48,210,36,150,84,240,193,223,118,197,135,85,154,213,162,166,213]},
					{name:"Sanctuary's Way", color:"0.0 1.0 1.0 0.5", data:[16,42,172,40,80,65,144,105,119,208,189,1,174,146,100,233]},
					{name:"Spaceway L1", color:"0.824 0.412 0.118 1.0", data:[50,239,103,108,103,177,17,177,103,45,105,137,95,54,77,76,21,2,249,113,141,113,97]},
					{name:"Supply Line 1 'Freedom'", color:"whiteColor", data:[209,33,62,25,134,58,138,191,78,57,242,234,245,181,82,117,53,74,38]},
					{name:"Supply Line 2 'Unity'", color:"1.0 1.0 0.0 0.5", data:[71,79,68,110,220,158,215,63,44,66,146,174,1,4,121,145,142,6,142,11,7,161,140]},
					{name:"The Esonlear Cakewalk", color:"redColor", data:[7,32,232,216,60]}];
			break;
		case 4:
			data = [{name:"Spaceway L1", color:"0.824 0.412 0.118 1.0", data:[41,216,112,230,28,102,181,35,180,24,19,156,1,45,79,172,169]},
					{name:"Spaceway L2", color:"whiteColor", data:[140,137,173,70,7,253,243,135,193,225,184,150,115,201,189,227,226,221,57,202,135,202,57,221,226,227,189,115,11,54,158,175,85,178,204,12,215,212,158]},
					{name:"Spaceway L3 'The Great Wheel'", color:"greenColor", data:[194,8,210,41,222,183,254,149,130,108,82,92,29,121,34,183]},
					{name:"The Lesser Wheel", color:"redColor", data:[114,118,2,116,244,248,65,146,153,10,99,91,200,244]},
					{name:"The Extrinsic Reach", color:"blueColor", data:[120,9,233,104,136,129,139,163,61]},
					{name:"The Serenic Arc", color:"1.0 1.0 0.0 0.5", data:[249,16,20,39,93,207,131,74,182,252,188,40,146,153,146,40,188,252,182,166,53,221,220,225]},
					{name:"The Zalexe Loop", color:"0.0 1.0 1.0 0.5", data:[30,89,87,89,152,170,88,194,77,246,106,190,208,167]}];
			break;
		case 5:
			data = [{name:"Spaceway L1", color:"0.824 0.412 0.118 1.0", data:[84,3,8,88,206,136,144,13,92,99,85,133,40,215,115,83,246,39,35,114]},
					{name:"Spaceway L2", color:"1.0 1.0 0.0 0.5", data:[169,51,80,103,243,98,102,16,109,101,67,142,60,209,233,112,225,131,210,12,150,91]},
					{name:"The Centreward Span", color:"whiteColor", data:[104,54,162,148,211,6,181,17,108,28]},
					{name:"The Rimward Arc", color:"0.0 1.0 1.0 0.5", data:[156,113,14,216,82,177,116,154,120,50,232,124,215]},
					{name:"Remlock Road", color:"redColor", data:[10,77,159,226,31,203,30,234,240,234,140,159]}];
			break;
		case 6:
			data = [{name:"Spaceway L1", color:"0.0 1.0 1.0 0.5", data:[103,58,253,65,39,44,236,150,247,193,179,133,215,95,109]},
					{name:"The Road", color:"whiteColor", data:[194,73,146,239,86,74,199,23,138,18,234,244,166,152,162,242,184]},
					{name:"Far Rift Reach", color:"0.824 0.412 0.118 1.0", data:[218,130,125,205,79,191,17,178]},
					{name:"The Isisian Detour", color:"1.0 1.0 0.0 0.5", data:[211,7,163,67,209,250,19,239]},
					{name:"The Quandixe Connection", color:"redColor", data:[46,36,212,187,53,107,174]}];
			break;
		case 7:
			data = [{name:"Spaceway L1 'The Nemorican Arc'", color:"whiteColor", data:[114,12,241,39,23,38,123,130,167,63,136,8,44,91,56,62,186,93,32,61,244,243,116,46,157,230,151,213,198,148,49,76,203,255,161,98,53,1,145,33]},
					{name:"Spaceway L2", color:"0.0 1.0 1.0 0.5", data:[215,2,211,9,13,147,216,225,21,218,71,206,236,190,18,26,152,51,209,24,174,82,179,173,30,251,233,125,45,41,104,110,73,135,117,55]},
					{name:"Centreward Flight", color:"1.0 1.0 0.0 0.5", data:[126,6,81,65,169,232,252]},
					{name:"The Hitachi Trade Annex", color:"0.824 0.412 0.118 1.0", data:[75,219,248,117]},
					{name:"Rimward Decamp", color:"redColor", data:[10,72,219,248,117]}];
			break;
	}
	return data;
}

//-------------------------------------------------------------------------------------------------------------
// returns true if a HUD with allowBigGUI is enabled, otherwise false
this.$isBigGuiActive = function $isBigGuiActive() {
	if (oolite.compareVersion("1.83") <= 0) {
		return player.ship.hudAllowsBigGui;
	} else {
		var bigGuiHUD = ["XenonHUD.plist", "coluber_hud_ch01-dock.plist"]; 	// until there is a property we can check, I'll be listing HUD's that have the allow_big_gui property set here
		if (bigGuiHUD.indexOf(player.ship.hud) >= 0) {
			return true;
		} else {
			return false;
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
// turns off any explorer club markers
this.$hideExplorersClub = function $hideExplorersClub() {
	for (var i = 0; i < 256; i++) {
		mission.unmarkSystem({system:i, name:"exclubmap"});
	}
}

//-------------------------------------------------------------------------------------------------------------
// turns off any smugglers markers
this.$hideSmugglers = function $hideSmugglers() {
	var w = worldScripts.Smugglers_Illegal;
	// clear out existing marks
	for (var i = 0; i < w._markedSystems.length; i++) {
		mission.unmarkSystem({system:w._markedSystems[i], name:"illegalgoods"});
	}

	// reset the array
	w._markedSystems = [];
}

//-------------------------------------------------------------------------------------------------------------
// removes any region, lane or planetary markers from the chart
this.$removeChartData = function $removeChartData() {
	for (var i = 0; i < this._markedRegions.length; i++) {
		SystemInfo.setInterstellarProperty(galaxyNumber, this._markedRegions[i].id1, this._markedRegions[i].id2, 2, "link_color", "galreg_region");
	}
	this._markedRegions = [];
	for (var i = 0; i < this._markedPlanets.length; i++) {
		mission.unmarkSystem({system:this._markedPlanets[i], name:"galreg_marked"});
	}
	if (this._spaceLaneStart >= 0) mission.unmarkSystem({system:this._spaceLaneStart, name:"galreg_marked"});
	if (this._spaceLaneEnd >= 0) mission.unmarkSystem({system:this._spaceLaneEnd, name:"galreg_marked"});
	this._spaceLaneStart = -1;
	this._spaceLaneEnd = -1;
	this._markedPlanets = [];
	this.$reapplyPermanentInfo();
}

//-------------------------------------------------------------------------------------------------------------
this.$reapplyPermanentInfo = function $reapplyPermanentInfo() {
	var i = 0;
	var j = 0;
	var k = 0;
	if (this._permanentChartData) {
		if (this._permanentChartData.regions && this._permanentChartData.regions.length > 0) {
			var regions = this._permanentChartData.regions;
			for (i = 0; i < regions.length; i++) {
				if (regions[i].systemIDList && regions[i].systemIDList.length > 0) {
					var dta = regions[i].systemIDList;
					for (j = 0; j < dta.length; j++) {
						for (k = 0; k < dta.length; k++) {
							if (j != k && dta[j] < dta[k]) {
								SystemInfo.setInterstellarProperty(galaxyNumber, dta[j], dta[k], 2, "link_color", regions[i].linkColor, "galreg_region");
							}
						}
					}
				}
			}
		}
		if (this._permanentChartData.paths && this._permanentChartData.paths.length > 0) {
			var paths = this._permanentChartData.paths;
			for (i = 0; i < paths.length; i++) {
				var colr = paths[i].linkColor;
				var planets = paths[i].systemIDList;
				for (var j = 0; j < planets.length - 1; j++) {
					var s1 = System.infoForSystem(galaxyNumber, planets[j]);
					var c1 = s1.concealment;
					if (!c1) c1 = 0;
					var s2 = System.infoForSystem(galaxyNumber, planets[j + 1]);
					var c2 = s2.concealment;
					if (!c2) c2 = 0;
					if (c1 <= 100 && c2 <= 100 && s1.distanceToSystem(s2) <= 7) {
						if (planets[j] < planets[j + 1]) {
							SystemInfo.setInterstellarProperty(galaxyNumber, planets[j], planets[j + 1], 2, "link_color", colr, "galreg_region");
							this._markedRegions.push({id1:planets[j], id2:planets[j + 1]});
						} else {
							SystemInfo.setInterstellarProperty(galaxyNumber, planets[j + 1], planets[j], 2, "link_color", colr, "galreg_region");
							this._markedRegions.push({id1:planets[j + 1], id2:planets[j]});
						}
					}
				}
			}
		}
		if (this._permanentChartData.systems && this._permanentChartData.systems.length > 0) {
			var syslist = this._permanentChartData.systems;
			for (i = 0; i < syslist.length; i++) {
				if (syslist[i].systemIDList && syslist[i].systemIDList.length > 0) {
					var dta = syslist[i].systemIDList;
					for (j = 0; j < dta.length; j++) {
						mission.markSystem({system:dta[j], name:"galreg_marked", markerShape:syslist[i].markerShape, markerColor:syslist[i].markerColor, markerScale:syslist[i].markerScale});
					}
				}
			}
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
// gets the maximum techlevel for the sector
this.$getMaxTechLevel = function $getMaxTechLevel() {
	var tl = 0;
	for (var i = 0; i <= 255; i++) {
		var info = System.infoForSystem(galaxyNumber, i);
		if (info.techlevel > tl) tl = info.techlevel;
	}
	return tl;
}

//-------------------------------------------------------------------------------------------------------------
// returns a list of planets of a particular government type (0-7)
this.$getSystemsByGovernment = function $getSystemsByGovernment(govType) {
	var govs = SystemInfo.filteredSystems(this, function(other) {
		return (other.government === govType && (!other.concealment || other.concealment === 0));
	});
	var list = [];
	for (var i = 0; i < govs.length; i++) {
		list.push(govs[i].systemID);
	}
	return list;	
}

//-------------------------------------------------------------------------------------------------------------
// returns a list of planets of a particular techlevel
this.$getSystemsByTechLevel = function $getSystemsByTechLevel(techLevel) {
	var tl = SystemInfo.filteredSystems(this, function(other) {
		return (other.techlevel === techLevel && (!other.concealment || other.concealment === 0));
	});
	var list = [];
	for (var i = 0; i < tl.length; i++) {
		list.push(tl[i].systemID);
	}
	return list;	
}

//-------------------------------------------------------------------------------------------------------------
// returns a list of planets of a particular economy
this.$getSystemsByEconomy = function $getSystemsByEconomy(economy) {
	var ecos = SystemInfo.filteredSystems(this, function(other) {
		return (other.economy === economy && (!other.concealment || other.concealment === 0));
	});
	var list = [];
	for (var i = 0; i < ecos.length; i++) {
		list.push(ecos[i].systemID);
	}
	return list;	
}

//-------------------------------------------------------------------------------------------------------------
this.$governmentDescription = function $governmentDescription(gov) {
	switch (gov) {
		case 0: return "Anarchy";
		case 1: return "Feudal";
		case 2: return "Multi-Government";
		case 3: return "Dictatorship";
		case 4: return "Communist";
		case 5: return "Confederacy";
		case 6: return "Democracy";
		case 7: return "Corporate State";
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$governmentDescriptionPlural = function $governmentDescriptionPlural(gov) {
	switch (gov) {
		case 0: return "Anarchies";
		case 1: return "Feudals";
		case 2: return "Multi-Governments";
		case 3: return "Dictatorships";
		case 4: return "Communists";
		case 5: return "Confederacies";
		case 6: return "Democracies";
		case 7: return "Corporate States";
	}
}

//-------------------------------------------------------------------------------------------------------------
this.$economyDescription = function $economyDescription(eco) {
	if (worldScripts["market_tweak.js"]) {
		switch (eco) {
			case 0: return "Extreme Industrial";
			case 1: return "Strong Industrial";
			case 2: return "Common Industrial";
			case 3: return "Mainly Industrial";
			case 4: return "Mainly Agricultural";
			case 5: return "Common Agricultural";
			case 6: return "Strong Agricultural";
			case 7: return "Extreme Agricultural";
		}
	} else {
		switch (eco) {
			case 0: return "Rich Industrial";
			case 1: return "Average Industrial";
			case 2: return "Poor Industrial";
			case 3: return "Mainly Industrial";
			case 4: return "Mainly Agricultural";
			case 5: return "Rich Agricultural";
			case 6: return "Average Agricultural";
			case 7: return "Poor Agricultural";
		}
	}
}

//-------------------------------------------------------------------------------------------------------------
// returns planet ID for galcop HQ (returned as an array)
this.$galCopHQSystem = function $galCopHQSystem() {
	var galCopHQ = [7, 33, 26, 49, 102, 85, 202, 184];			// galcop hq locations in each sector
	return [galCopHQ[galaxyNumber]];
}

//-------------------------------------------------------------------------------------------------------------
// returns list of planet ID's where gal navy sector commands reside
this.$galNavySectorCommands = function $galNavySectorCommands() {
	var data = new Array
	switch(galaxyNumber){
		case 0:
			data = new Array(24, 193, 154, 188, 125, 109, 249, 150, 80, 175, 120, 220, 158, 15);
			break;
		case 1:
			data = new Array(248, 135, 106, 82, 150, 182, 33, 48, 227, 96, 127, 202, 243, 170);
			break;
		case 2:
			data = new Array(31, 165, 245, 84, 36, 21, 26, 139, 251, 205, 223, 204, 17, 247);
			break;
		case 3:
			data = new Array(39, 221, 188, 86, 9, 57, 186, 237, 49, 103, 254, 66, 140, 110);
			break;
		case 4:
			data = new Array(249, 71, 57, 144, 198, 153, 204, 73, 102, 222, 29, 233, 152, 190);
			break;
		case 5:
			data = new Array(151, 227, 6, 51, 60, 129, 8, 53, 85, 120, 208, 220, 146, 66);
			break;
		case 6:
			data = new Array(214, 161, 250, 127, 23, 154, 234, 24, 55, 64, 231, 140, 202, 35);
			break;
		case 7:
			data = new Array(26, 218, 9, 174, 156, 251, 75, 136, 184, 87, 212, 116, 98, 55);
			break;
	}
	return data;
}

//-------------------------------------------------------------------------------------------------------------
// returns the distance to a particular planet
this.$getDistanceToPlanet = function $getDistanceToPlanet(sysID) {
	if (sysID < 0 || sysID > 255) return 0;
	var dist = 200;
	var route = System.infoForSystem(galaxyNumber, system.ID).routeToSystem(System.infoForSystem(galaxyNumber, sysID), "OPTIMIZED_BY_JUMPS");
	if (route) dist = route.distance;
	return dist;
}

//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextRight = function $padTextRight(currentText, desiredLength, leftSwitch) {
	if (currentText == null) currentText = "";
	var hairSpace = String.fromCharCode(31);
	var ellip = "…";
	var currentLength = defaultFont.measureString(currentText);
	var hairSpaceLength = defaultFont.measureString(hairSpace);
	// calculate number needed to fill remaining length
	var padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
	if (padsNeeded < 1)	{
		// text is too long for column, so start pulling characters off
		var tmp = currentText;
		do {
			tmp = tmp.substring(0, tmp.length - 2) + ellip;
			if (tmp === ellip) break;
		} while (defaultFont.measureString(tmp) > desiredLength);
		currentLength = defaultFont.measureString(tmp);
		padsNeeded = Math.floor((desiredLength - currentLength) / hairSpaceLength);
		currentText = tmp;
	}
	// quick way of generating a repeated string of that number
	if (!leftSwitch || leftSwitch === false) {
		return currentText + new Array(padsNeeded).join(hairSpace);
	} else {
		return new Array(padsNeeded).join(hairSpace) + currentText;
	}
}

//-------------------------------------------------------------------------------------------------------------
// appends space to currentText to the specified length in 'em'
this.$padTextLeft = function $padTextLeft(currentText, desiredLength) {
	return this.$padTextRight(currentText, desiredLength, true);
}

//-------------------------------------------------------------------------------------------------------------
this.$getSystemData = function $getSystemData(sysID) {
	var sys = System.infoForSystem(galaxyNumber, sysID);
    var data = {};
	if (!sys.concealment || sys.concealment === 0) { 
		data["name"] = sys.name;
		data["economy"] = sys.economy;
		data["government"] = sys.government;
		data["techLevel"] = sys.techlevel;
		data["population"] = expandDescription("[sysdata-pop-value]", {population:sys.population});
		data["inhabitants"] = sys.inhabitants;
		data["productivity"] = sys.productivity;
		data["radius"] = sys.radius;
	} else {
		if (sys.concealment > 100) {
			data["name"] = "??";
		} else {
			data["name"] = sys.name;
		}
		data["economy"] = "??";
		data["government"] = "??";
		data["techLevel"] = "??";
		data["population"] = "??";
		data["inhabitants"] = "??";
		data["productivity"] = "??";
		data["radius"] = "??";
	}
    return data;
}

//-------------------------------------------------------------------------------------------------------------
// returns a list of sysInfos which match search criteria
this.$searchSystems = function $searchSystems() {
	this._searchMax = false;

	var list = SystemInfo.filteredSystems(this, function(other) { 
		var result = false; // set initial value to false, so if we fail the concealment check, the result will be false
		if (!other.concealment || other.concealment === 0) {
			var gtlt = [">=", "<=", ">", "<"];
			result = true; // but now we're going to assume a true result, and look for reasons to fail it.
			var w = worldScripts.GalacticRegistry._search
			var desc = other.description.toLowerCase();
			var govd = this.$governmentDescription(other.government).toLowerCase();
			var ecod = this.$economyDescription(other.economy).toLowerCase();
			var inhd = other.inhabitants.toLowerCase();
			for (var i = 0; i < w.length; i++) {
				var or_w = null;
				var word = w[i];
				var or_loop = 0;
				var or_check = true;
				var check = false;
				// check for the or "|" switch
				if (word.indexOf("|") >= 0) {
					or_w = word.toLowerCase().split("|");
					word = or_w[or_loop];
				}
				do {
					if (desc.indexOf(word) >= 0) check = true;
					if (govd.indexOf(word) >= 0) check = true;
					if (ecod.indexOf(word) >= 0) check = true;
					if (inhd.indexOf(word) >= 0) check = true;
					if (word.indexOf("gov") == 0 || word.indexOf("eco") == 0 || word.indexOf("pop") == 0 || word.indexOf("prod") == 0 || word.indexOf("tl") == 0 || word.indexOf("rad") == 0) {
						var val = -1.0;
						var chk = 0.0;
						if (word.indexOf("gov") == 0) chk = other.government;
						if (word.indexOf("eco") == 0) chk = other.economy;
						if (word.indexOf("pop") == 0) chk = other.population / 10;
						if (word.indexOf("prod") == 0) chk = other.productivity;
						if (word.indexOf("tl") == 0) chk = other.techlevel + 1; // checking for format of tl>8
						if (word.indexOf("rad") == 0) chk = other.radius;
						for (var j = 0; j < gtlt.length; j++) {
							if (word.indexOf(gtlt[j]) >= 0) {
								val = parseFloat(word.split(gtlt[j])[1]);
								if (!isNaN(val)) {
									switch (j) {
										case 0: 
											if (chk >= val) check = true;
											break;
										case 1:
											if (chk <= val) check = true;
											break;
										case 2:
											if (chk > val) check = true;
											break;
										case 3:
											if (chk < val) check = true;
											break;
									}
								}
								break;
							}
						}
					}
					if (word.indexOf("tl") == 0) { // checking for format tl8+
						// first check for a straight 1-1 test (eg tl8)
						if (word + " " == "tl" + (other.techlevel + 1).toString() + " ") check = true;
						// if that fails, lets do the +/- checks
						if (check == false) {
							var checkTL = 0;
							var dir = 0;
							// parse the input to get an integer version of the request TL and the direction we'll be testing
							if (word.indexOf("+") > 0) {checkTL = parseInt(word.substring(2, word.indexOf("+")), 10); dir = 1;}
							if (word.indexOf("-") > 0) {checkTL = parseInt(word.substring(2, word.indexOf("-")), 10); dir = -1;}
							if (checkTL > 0) {
								if (dir == 1 && (other.techlevel + 1) >= checkTL) check = true;
								if (dir == -1 && (other.techlevel + 1) <= checkTL) check = true;
							}
						}
					} 
					if (or_w) {
						or_loop ++;
						if (or_loop > or_w.length - 1) {
							or_check = false;
						} else {
							word = or_w[or_loop];
						}
					} else {
						or_check = false;
					}
				} while (or_check == true);
				if (check == false) result = check;
			}
		}
		return result;
	});
	if (list.length > (this._pageLength * 3)) {
		this._searchMax = true;
		for (var i = list.length - 1; i >= (this._pageLength * 3); i--) {
			list.splice(i, 1);
		}
	}
	return list;
}

//-------------------------------------------------------------------------------------------------------------
// returns true if "id" is one of the current permanent regions, otherwise false
this.$checkPermanentRegions = function $checkPermanentRegions(id) {
	if (!this._permanentChartData || !this._permanentChartData.regions) return false;
	var regions = this._permanentChartData.regions;
	for (var i = 0; i < regions.length; i++) {
		if (regions[i].id === id) return true;
	}
	return false;
}

//-------------------------------------------------------------------------------------------------------------
// removes a region from the permanent list
this.$removePermanentRegion = function $removePermanentRegion(id) {
	if (!this._permanentChartData || !this._permanentChartData.regions) return;
	var regions = this._permanentChartData.regions;
	for (var i = 0; i < regions.length; i++) {
		if (regions[i].id === id) {
			var dta = regions[i].systemIDList;
			for (var j = 0; j < dta.length; j++) {
				for (var k = 0; k < dta.length; k++) {
					if (j != k && dta[j] < dta[k]) {
						SystemInfo.setInterstellarProperty(galaxyNumber, dta[j], dta[k], 2, "link_color", "galreg_region");
					}
				}
			}
			regions.splice(i, 1);
			return;
		};
	}
}

//-------------------------------------------------------------------------------------------------------------
// returns true if "id" is one of the current permanent paths, otherwise false
this.$checkPermanentPaths = function $checkPermanentPaths(id) {
	if (!this._permanentChartData || !this._permanentChartData.paths) return false;
	var paths = this._permanentChartData.paths;
	for (var i = 0; i < paths.length; i++) {
		if (paths[i].id === id) return true;
	}
	return false;
}

//-------------------------------------------------------------------------------------------------------------
// removes a region from the permanent list
this.$removePermanentPath = function $removePermanentPath(id) {
	if (!this._permanentChartData || !this._permanentChartData.paths) return;
	var paths = this._permanentChartData.paths;
	for (var i = 0; i < paths.length; i++) {
		if (paths[i].id === id) {
			var dta = paths[i].systemIDList;
			for (var j = 0; j < dta.length; j++) {
				for (var k = 0; k < dta.length; k++) {
					if (j != k && dta[j] < dta[k]) {
						SystemInfo.setInterstellarProperty(galaxyNumber, dta[j], dta[k], 2, "link_color", "galreg_region");
					}
				}
			}
			paths.splice(i, 1);
			return;
		};
	}
}

//-------------------------------------------------------------------------------------------------------------
// returns true if "id" is one of the current permanent systems, otherwise false
this.$checkPermanentSystems = function $checkPermanentSystems(id) {
	if (!this._permanentChartData || !this._permanentChartData.systems) return false;
	var syslist = this._permanentChartData.systems;
	for (var i = 0; i < syslist.length; i++) {
		if (syslist[i].id === id) return true;
	}
	return false;
}

//-------------------------------------------------------------------------------------------------------------
// removes a list of systems from the permanent list
this.$removePermanentSystems = function $removePermanentSystems(id) {
	if (!this._permanentChartData || !this._permanentChartData.systems) return;
	var syslist = this._permanentChartData.systems;
	for (var i = syslist.length - 1; i >= 0; i--) {
		if (syslist[i].id === id) {
			var dta = syslist[i].systemIDList;
			for (var j = 0; j < dta.length; j++) {
				mission.unmarkSystem({system:dta[j], name:"galreg_marked"});
			}
			syslist.splice(i, 1);
		};
	}
}

//-------------------------------------------------------------------------------------------------------------
// removes any stored historic permanent markers/properties
this.$removeHistoricPermanentMarkers = function $removeHistoricPermanentMarkers() {
	// remove an permanent markings
	var i = 0;
	var j = 0;
	var k = 0;
	if (this._permanentRegions.length > 0) {
		var regions = this.$getRegionData();
		for (i = 0; i < this._permanentRegions.length; i++) {
			var dta = regions[this._permanentRegions[i]].data;
			for (j = 0; j < dta.length; j++) {
				for (k = 0; k < dta.length; k++) {
					if (j != k && dta[j] < dta[k]) {
						SystemInfo.setInterstellarProperty(galaxyNumber, dta[j], dta[k], 2, "link_color", "galreg_region");
					}
				}
			}
		}
	}
	if (this._permanentLanes.length > 0) {
		var lanes = this.$getSpacelanes();
		for (i = 0; i < this._permanentLanes.length; i++) {
			var lane = lanes[this._permanentLanes[i]];
			var dta = lane.data;
			for (j = 0; j < dta.length - 1; j++) {
				var c1 = System.infoForSystem(galaxyNumber, dta[j]).concealment;
				if (!c1) c1 = 0;
				var c2 = System.infoForSystem(galaxyNumber, dta[j + 1]).concealment;
				if (!c2) c2 = 0;
				if (c1 <= 100 && c2 <= 100) {
					if (dta[j] < dta[j + 1]) {
						SystemInfo.setInterstellarProperty(galaxyNumber, dta[j], dta[j + 1], 2, "link_color", "galreg_region");
					} else {
						SystemInfo.setInterstellarProperty(galaxyNumber, dta[j + 1], dta[j], 2, "link_color", "galreg_region");
					}
				}
			}
		}
		for (var i = mission.markedSystems.length - 1; i >= 0; i--) {
			if (mission.markedSystems[i].name.indexOf(this.name) >= 0 || mission.markedSystems[i].name.indexOf("galreg_marked") >= 0) 
				mission.unmarkSystem({system:mission.markedSystems[i].system, name:mission.markedSystems[i].name});
		}
	}
	this._permanentRegions.length = 0;
	this._permanentLanes.length = 0;
	delete this._permanentRegions;
	delete this._permanentLanes;
}
Scripts/galactic_registry_conditions.js
"use strict";
this.name        = "GalacticRegistry_Conditions";
this.author      = "phkb";
this.copyright   = "2015 phkb";
this.description = "Condition script for Galactic Registry equipment";
this.license     = "CC BY-NC-SA 3.0";

//-------------------------------------------------------------------------------------------------------------
this.allowAwardEquipment = function(equipment, ship, context) {
	if (context == "scripted") return true;
	return false;
}