Index: shadows/split.recipe
===================================================================
--- shadows/split.recipe	(revision 6781)
+++ shadows/split.recipe	(working copy)
@@ -5,6 +5,7 @@
 shadow: StyleSheetLayout.tiddler
 shadow: StyleSheetLocale.tiddler
 shadow: StyleSheetPrint.tiddler
+shadow: SystemSettings.tiddler
 shadow: PageTemplate.tiddler
 shadow: ViewTemplate.tiddler
 shadow: EditTemplate.tiddler
Index: shadows/SystemSettings.tiddler
===================================================================
--- shadows/SystemSettings.tiddler	(revision 0)
+++ shadows/SystemSettings.tiddler	(revision 0)
@@ -0,0 +1,30 @@
+<div title="SystemSettings">
+<pre>chkRegExpSearch: false
+chkCaseSensitiveSearch: false
+chkIncrementalSearch: true
+chkAnimate_cookie: false
+chkSaveBackups: true
+chkAutoSave: false
+chkGenerateAnRssFeed: false
+chkSaveEmptyTemplate: false
+chkOpenInNewWindow: true
+chkToggleLinks: false
+chkHttpReadOnly: true
+chkForceMinorUpdate: false
+chkConfirmDelete: true
+chkInsertTabs: false
+chkUsePreForStorage: true
+chkDisplayInstrumentation: false
+txtBackupFolder: 
+txtEditorFocus: text
+txtMainTab_cookie: More
+txtMoreTab_cookie: Missing
+txtMaxEditRows: 30
+txtFileSystemCharSet: UTF-8
+txtTheme: 
+txtUserName: YourName
+chkSliderOptionsPanel_cookie: true
+chkBackstage_cookie: false
+chkSideBarTabs_cookie: true
+</pre>
+</div>
\ No newline at end of file
Index: js/TiddlyWiki.js
===================================================================
--- js/TiddlyWiki.js	(revision 6781)
+++ js/TiddlyWiki.js	(working copy)
@@ -151,7 +151,7 @@
 	return textOut.join("");
 };
 
-TiddlyWiki.prototype.slicesRE = /(?:^([\'\/]{0,2})~?([\.\w]+)\:\1\s*([^\n]+)\s*$)|(?:^\|([\'\/]{0,2})~?([\.\w]+)\:?\4\|\s*([^\|\n]+)\s*\|$)/gm;
+TiddlyWiki.prototype.slicesRE = /(?:^([\'\/]{0,2})~?([\.\w]+)\:\1[\t\x20]*([^\n]*)[\t\x20]*$)|(?:^\|([\'\/]{0,2})~?([\.\w]+)\:?\4\|[\t\x20]*([^\|\n]*)[\t\x20]*\|$)/gm;
 
 // @internal
 TiddlyWiki.prototype.calcAllSlices = function(title)
Index: js/main.js
===================================================================
--- js/main.js	(revision 6781)
+++ js/main.js	(working copy)
@@ -33,13 +33,13 @@
 	story = new Story("tiddlerDisplay","tiddler");
 	addEvent(document,"click",Popup.onDocumentClick);
 	saveTest();
-	loadOptionsCookie();
 	for(var s=0; s<config.notifyTiddlers.length; s++)
 		store.addNotification(config.notifyTiddlers[s].name,config.notifyTiddlers[s].notify);
 	t1 = new Date();
 	loadShadowTiddlers();
 	t2 = new Date();
 	store.loadFromDiv("storeArea","store",true);
+	loadOptionsCookie();
 	t3 = new Date();
 	invokeParamifier(params,"onload");
 	t4 = new Date();
Index: js/Options.js
===================================================================
--- js/Options.js	(revision 6781)
+++ js/Options.js	(working copy)
@@ -4,8 +4,8 @@
 
 config.optionHandlers = {
 	'txt': {
-		get: function(name) {return encodeCookie(config.options[name].toString());},
-		set: function(name,value) {config.options[name] = decodeCookie(value);}
+		get: function(name) {return config.options[name].toString();},
+		set: function(name,value) {config.options[name] = value;}
 	},
 	'chk': {
 		get: function(name) {return config.options[name] ? "true" : "false";},
@@ -13,10 +13,20 @@
 	}
 };
 
-function loadOptionsCookie()
+//# Loads up config.options from cookies and SystemSettings
+function initialiseOptions()
 {
 	if(safeMode)
 		return;
+	loadSystemSettings();
+	loadCookies();
+}
+// Deprecated name for backwards compatibility
+var loadOptionsCookie = initialiseOptions;
+
+function loadCookies()
+{
+	var cookies = {};
 	var cookies = document.cookie.split(";");
 	for(var c=0; c<cookies.length; c++) {
 		var p = cookies[c].indexOf("=");
@@ -24,29 +34,86 @@
 			var name = cookies[c].substr(0,p).trim();
 			var value = cookies[c].substr(p+1).trim();
 			var optType = name.substr(0,3);
-			if(config.optionHandlers[optType] && config.optionHandlers[optType].set)
-				config.optionHandlers[optType].set(name,value);
+			if(config.optionSource[name] == 'cookie' && config.optionHandlers[optType] && config.optionHandlers[optType].set)
+				config.optionHandlers[optType].set(name,decodeCookie(value));
 		}
 	}
 }
 
-function saveOptionCookie(name)
+function loadSystemSettings()
 {
+	var settings = store.calcAllSlices("SystemSettings");
+	for(var key in settings) {
+		var splitPos = key.indexOf('_');
+		var name = key;
+		var source = "setting";
+		if(splitPos !== -1) {
+			source = key.substr(splitPos+1);
+			name = key.substr(0,splitPos);
+		}
+		optType = name.substr(0,3);
+		if(config.optionHandlers[optType] && config.optionHandlers[optType].set) {
+			config.optionHandlers[optType].set(name,settings[key]);
+		}
+		config.optionSource[name] = source;
+	}
+}
+
+function onSystemSettingsChange()
+{
+	if(!startingUp) {
+		loadSystemSettings();
+	}
+}
+
+// Saves the named option in a cookie or SystemSettings as appropriate
+function saveOption(name)
+{
 	if(safeMode)
 		return;
+	if(config.optionSource[name] == 'cookie')
+		saveCookie(name);
+	else
+		saveSystemSetting(name);
+}
+// Deprecated names for backwards compatibility
+var saveOptionCookie = saveOption;
+
+function saveCookie(name)
+{
 	var c = name + "=";
 	var optType = name.substr(0,3);
 	if(config.optionHandlers[optType] && config.optionHandlers[optType].get)
-		c += config.optionHandlers[optType].get(name);
+		c += encodeCookie(config.optionHandlers[optType].get(name));
 	c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";
 	document.cookie = c;
 }
 
+function saveSystemSetting(name)
+{
+	var s = "";
+	for(var key in config.options) {
+		s += key;
+		if(config.optionSource[key] && config.optionSource[key] != "setting") {
+			s += "_" + config.optionSource[key];
+		}
+		var optType = key.substr(0,3);
+		var value = "";
+		if(config.optionHandlers[optType] && config.optionHandlers[optType].get)
+			value = config.optionHandlers[optType].get(key);
+		s += ": " + value + "\n";
+	}
+	store.saveTiddler("SystemSettings","SystemSettings",s,"System",new Date());
+	autoSaveChanges();
+}
+
+//# Flatten cookies to ANSI character set by substituting html character entities for non-ANSI characters
 function encodeCookie(s)
 {
 	return escape(convertUnicodeToHtmlEntities(s));
 }
 
+//# Decode any html character entities to their unicode equivalent
 function decodeCookie(s)
 {
 	s = unescape(s);
Index: js/Config.js
===================================================================
--- js/Config.js	(revision 6781)
+++ js/Config.js	(working copy)
@@ -63,6 +63,13 @@
 	};
 config.optionsDesc = {};
 
+//# config.optionSource["chkAnimate"] can be:
+//# 	cookie: the option gets stored in a cookie, with the default value coming from SystemSettings
+//#		volatile: the option isn't persisted at all, and reverts to the default specified in SystemSettings when the document is reloaded
+//#		setting: the option is stored in the SystemSettings tiddler
+//#	The default is "setting"
+config.optionSource = {};
+
 // Default tiddler templates
 var DEFAULT_VIEW_TEMPLATE = 1;
 var DEFAULT_EDIT_TEMPLATE = 2;
Index: js/Lingo.js
===================================================================
--- js/Lingo.js	(revision 6781)
+++ js/Lingo.js	(working copy)
@@ -462,6 +462,7 @@
 	StyleSheetLayout: "This shadow tiddler contains CSS definitions related to the layout of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler",
 	StyleSheetLocale: "This shadow tiddler contains CSS definitions related to the translation locale",
 	StyleSheetPrint: "This shadow tiddler contains CSS definitions for printing",
+	SystemSettings: "This tiddler is used to store configuration options for this TiddlyWiki document",
 	TabAll: "This shadow tiddler contains the contents of the 'All' tab in the right-hand sidebar",
 	TabMore: "This shadow tiddler contains the contents of the 'More' tab in the right-hand sidebar",
 	TabMoreMissing: "This shadow tiddler contains the contents of the 'Missing' tab in the right-hand sidebar",
@@ -472,4 +473,3 @@
 	ToolbarCommands: "This shadow tiddler determines which commands are shown in tiddler toolbars",
 	ViewTemplate: "The HTML template in this shadow tiddler determines how tiddlers look"
 	});
-
Index: js/Refresh.js
===================================================================
--- js/Refresh.js	(revision 6781)
+++ js/Refresh.js	(working copy)
@@ -4,6 +4,7 @@
 
 //# List of notification functions to be called when certain tiddlers are changed or deleted
 config.notifyTiddlers = [
+	{name: "SystemSettings", notify: onSystemSettingsChange},
 	{name: "StyleSheetLayout", notify: refreshStyles},
 	{name: "StyleSheetColors", notify: refreshStyles},
 	{name: "StyleSheet", notify: refreshStyles},

