From 20afda162110df94bec5c9ed8ba9ab7c02a30013 Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@gmail.com>
Date: Fri, 25 Sep 2020 15:18:35 +0200
Subject: [PATCH] add favorites system

---
 js/003-data/gameVariableData.js               |  1 +
 src/002-config/mousetrapConfig.js             |  4 +-
 src/endWeek/clinicReport.js                   |  2 +
 src/endWeek/masterSuiteReport.js              |  2 +
 src/endWeek/reports/nurseryReport.js          |  2 +
 src/endWeek/schoolroomReport.js               |  2 +
 src/endWeek/servantsQuartersReport.js         |  2 +
 src/endWeek/slaveAssignmentReport.js          | 11 ++++
 .../farmyard/reports/farmyardReport.js        |  2 +
 src/gui/css/mainStyleSheet.css                | 25 +++++++-
 src/interaction/slaveInteract.js              | 62 +++++++++++++++++++
 src/js/slaveListing.js                        | 25 ++++++--
 src/js/utilsDOM.js                            |  2 +-
 src/uncategorized/arcadeReport.tw             |  1 +
 src/uncategorized/brothelReport.tw            |  2 +
 src/uncategorized/cellblockReport.tw          |  2 +
 src/uncategorized/clubReport.tw               |  2 +
 src/uncategorized/dairyReport.tw              |  2 +
 src/uncategorized/penthouseReport.tw          |  4 +-
 src/uncategorized/slaveInteract.tw            | 29 +--------
 src/uncategorized/spaReport.tw                |  2 +
 21 files changed, 149 insertions(+), 37 deletions(-)

diff --git a/js/003-data/gameVariableData.js b/js/003-data/gameVariableData.js
index 8943bfd57f2..abab64bd930 100644
--- a/js/003-data/gameVariableData.js
+++ b/js/003-data/gameVariableData.js
@@ -1378,6 +1378,7 @@ App.Data.resetOnNGPlus = {
 	 * @type {Object.<number, string>}
 	 */
 	choosesOwnAssignmentText: {},
+	favorites: []
 };
 
 App.Data.ignoreGameStateVariables = [
diff --git a/src/002-config/mousetrapConfig.js b/src/002-config/mousetrapConfig.js
index d0bc8f6dba1..d1e1836a15d 100644
--- a/src/002-config/mousetrapConfig.js
+++ b/src/002-config/mousetrapConfig.js
@@ -276,12 +276,12 @@ App.UI.Hotkeys.add("nextLink", {
 });
 App.UI.Hotkeys.add("prev-slave", {
 	callback: function() {
-		$("#prev-slave a.macro-link").trigger("click");
+		$("#prev-slave a").trigger("click");
 	}, combinations: ["left", "q"], uiName: "Previous Slave"
 });
 App.UI.Hotkeys.add("next-slave", {
 	callback: function() {
-		$("#next-slave a.macro-link").trigger("click");
+		$("#next-slave a").trigger("click");
 	}, combinations: ["right", "e"], uiName: "Next Slave"
 });
 App.UI.Hotkeys.add("prev-child", {
diff --git a/src/endWeek/clinicReport.js b/src/endWeek/clinicReport.js
index 50332b58843..a098ec4070d 100644
--- a/src/endWeek/clinicReport.js
+++ b/src/endWeek/clinicReport.js
@@ -247,6 +247,7 @@ App.EndWeek.clinicReport = function() {
 			if (V.seeImages && V.seeReportImages) {
 				App.UI.DOM.appendNewElement("div", nurseEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
+			nurseEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(nurseEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> is serving as the clinical nurse.`);
 			$(nurseEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
@@ -380,6 +381,7 @@ App.EndWeek.clinicReport = function() {
 			if (V.seeImages && V.seeReportImages) {
 				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
+			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> `);
 			if (slave.choosesOwnAssignment === 2) {
 				$(slaveEntry).append(App.SlaveAssignment.choosesOwnJob(slave));
diff --git a/src/endWeek/masterSuiteReport.js b/src/endWeek/masterSuiteReport.js
index 20e78be18cf..1424117c0a0 100644
--- a/src/endWeek/masterSuiteReport.js
+++ b/src/endWeek/masterSuiteReport.js
@@ -437,6 +437,7 @@ App.EndWeek.masterSuiteReport = function() {
 		if (V.seeImages && V.seeReportImages) {
 			App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(S.Concubine, 0, 0), ["imageRef", "tinyImg"]);
 		}
+		slaveEntry.append(App.EndWeek.favoriteIcon(S.Concubine), " ");
 		$(slaveEntry).append(concubineText(), commonText(S.Concubine));
 	}
 
@@ -445,6 +446,7 @@ App.EndWeek.masterSuiteReport = function() {
 		if (V.seeImages && V.seeReportImages) {
 			App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 		}
+		slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 		$(slaveEntry).append(nonConcubineText(slave), commonText(slave));
 	}
 
diff --git a/src/endWeek/reports/nurseryReport.js b/src/endWeek/reports/nurseryReport.js
index cef8907e539..9d9bfdb6df6 100644
--- a/src/endWeek/reports/nurseryReport.js
+++ b/src/endWeek/reports/nurseryReport.js
@@ -155,6 +155,7 @@ App.Facilities.Nursery.nurseryReport = function nurseryReport() {
 				App.UI.DOM.appendNewElement("div", matronEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
 
+			matronEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(matronEntry).append(`<span class="slave-name">${SlaveFullName(slave)}</span> is serving as your Matron.`);
 			$(matronEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
@@ -219,6 +220,7 @@ App.Facilities.Nursery.nurseryReport = function nurseryReport() {
 				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
 
+			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class="slave-name">${SlaveFullName(slave)}</span> `);
 
 			if (slave.choosesOwnAssignment === 2) {
diff --git a/src/endWeek/schoolroomReport.js b/src/endWeek/schoolroomReport.js
index 2f6588cc9d0..c42cf4e6009 100644
--- a/src/endWeek/schoolroomReport.js
+++ b/src/endWeek/schoolroomReport.js
@@ -153,6 +153,7 @@ App.EndWeek.schoolroomReport = function() {
 			if (V.seeImages && V.seeReportImages) {
 				App.UI.DOM.appendNewElement("div", schoolteacherEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
+			schoolteacherEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(schoolteacherEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> is serving as your Schoolteacher.`);
 			$(schoolteacherEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
@@ -229,6 +230,7 @@ App.EndWeek.schoolroomReport = function() {
 			if (V.seeImages && V.seeReportImages) {
 				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
+			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> `);
 			if (slave.choosesOwnAssignment === 2) {
 				$(slaveEntry).append(App.SlaveAssignment.choosesOwnJob(slave));
diff --git a/src/endWeek/servantsQuartersReport.js b/src/endWeek/servantsQuartersReport.js
index 2c45c6d9de3..8567aec2ada 100644
--- a/src/endWeek/servantsQuartersReport.js
+++ b/src/endWeek/servantsQuartersReport.js
@@ -214,6 +214,7 @@ App.EndWeek.servantsQuartersReport = function() {
 			if (V.seeImages && V.seeReportImages) {
 				App.UI.DOM.appendNewElement("div", stewardessEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
+			stewardessEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(stewardessEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> is serving as your Stewardess.`);
 			$(stewardessEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
@@ -291,6 +292,7 @@ App.EndWeek.servantsQuartersReport = function() {
 			if (V.seeImages && V.seeReportImages) {
 				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 			}
+			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> `);
 			if (slave.choosesOwnAssignment === 2) {
 				$(slaveEntry).append(App.SlaveAssignment.choosesOwnJob(slave));
diff --git a/src/endWeek/slaveAssignmentReport.js b/src/endWeek/slaveAssignmentReport.js
index ce8b3338e49..6e8ccc46121 100644
--- a/src/endWeek/slaveAssignmentReport.js
+++ b/src/endWeek/slaveAssignmentReport.js
@@ -822,3 +822,14 @@ App.EndWeek.slaveAssignmentReport = function() {
 		warningLine.appendChild(document.createTextNode("."));
 	}
 };
+
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {Node}
+ */
+App.EndWeek.favoriteIcon = function(slave) {
+	if (V.favorites.includes(slave.ID)) {
+		return App.UI.DOM.makeElement("span", String.fromCharCode(0xe800), ["icons", "favorite"]);
+	}
+	return document.createDocumentFragment();
+};
diff --git a/src/facilities/farmyard/reports/farmyardReport.js b/src/facilities/farmyard/reports/farmyardReport.js
index 47f1c0ccc9c..ec07120e28e 100644
--- a/src/facilities/farmyard/reports/farmyardReport.js
+++ b/src/facilities/farmyard/reports/farmyardReport.js
@@ -278,6 +278,7 @@ App.Facilities.Farmyard.farmyardReport = function farmyardReport() {
 				App.UI.DOM.appendNewElement("div", farmerEntry, App.Art.SlaveArtElement(Farmer, 0, 0), ["imageRef", "tinyImg"]);
 			}
 
+			farmerEntry.append(App.EndWeek.favoriteIcon(Farmer), " ");
 			$(farmerEntry).append(`<span class="slave-name">${SlaveFullName(Farmer)}</span> is serving as the Farmer.`);
 			$(farmerEntry).append(App.SlaveAssignment.standardSlaveReport(Farmer, false));
 		} else {
@@ -384,6 +385,7 @@ App.Facilities.Farmyard.farmyardReport = function farmyardReport() {
 					App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
 				}
 
+				slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 				$(slaveEntry).append(`<span class="slave-name">${SlaveFullName(slave)}</span> `);
 
 				if (slave.choosesOwnAssignment === 2) {
diff --git a/src/gui/css/mainStyleSheet.css b/src/gui/css/mainStyleSheet.css
index 8099da85308..b6aa6ab2a00 100644
--- a/src/gui/css/mainStyleSheet.css
+++ b/src/gui/css/mainStyleSheet.css
@@ -356,7 +356,7 @@ h3 + p {
 	color: red;
 }
 
-div.center {
+div.center, p.center {
 	margin-left: auto;
 	margin-right: auto;
 	text-align: center;
@@ -388,7 +388,30 @@ div.flex-container {
 	text-indent: 0;
 }
 
+/* make cheat textboxes fit in sidebar */
 #story-caption input {
 	min-width: 0;
 	width: calc(100% - 0.8em - 2px);
 }
+
+/* slave interact navigation */
+.adjacent-slave {
+	font-weight: bold;
+}
+.interact-name {
+	margin: 0 2em;
+}
+
+.icons {
+	font-family: 'tme-fa-icons';
+}
+
+.favorite, .favorite:hover {
+	color: yellow;
+	text-decoration: none;
+}
+
+.not-favorite, .not-favorite:hover {
+	color: grey;
+	text-decoration: none;
+}
diff --git a/src/interaction/slaveInteract.js b/src/interaction/slaveInteract.js
index 6ccd07c9d1d..fe2bd9a5f94 100644
--- a/src/interaction/slaveInteract.js
+++ b/src/interaction/slaveInteract.js
@@ -26,6 +26,68 @@ App.UI.SlaveInteract.placeInLine = function(slave) {
 	return [slaveList[prevIndex].ID, slaveList[nextIndex].ID];
 };
 
+/**
+ * @param {App.Entity.SlaveState} slave
+ * @returns {HTMLParagraphElement}
+ */
+App.UI.SlaveInteract.navigation = function(slave) {
+	const p = document.createElement("p");
+	p.classList.add("center");
+
+	if (V.cheatMode) {
+		const div = document.createElement("div");
+		div.classList.add("note");
+		div.append(App.UI.DOM.passageLink("Cheat Edit Slave", "MOD_Edit Slave Cheat", () => { V.cheater = 1; }),
+			" | ",
+			App.UI.DOM.passageLink("Cheat Edit Slave Alternative", "MOD_Edit Slave Cheat New", () => { V.cheater = 1; }));
+		p.append(div);
+	}
+
+	App.UI.DOM.appendNewElement("span", p, App.UI.Hotkeys.hotkeys("prev-slave"), "hotkey");
+	const prevSpan = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Prev", "Slave Interact",
+		() => { V.activeSlave = getSlave(App.UI.SlaveInteract.placeInLine(slave)[0]); }), "adjacent-slave");
+	prevSpan.id = "prev-slave";
+	p.append(" ", prevSpan);
+
+	const centerSpan = document.createElement("span");
+	centerSpan.classList.add("interact-name");
+
+	App.UI.DOM.appendNewElement("span", centerSpan, slave.slaveName, "slave-name");
+
+	const favSpan = document.createElement("span");
+	favSpan.id = "fav-span";
+	favSpan.append(favLink());
+
+	centerSpan.append(" ", favSpan);
+	p.append(centerSpan);
+
+	const nextSpan = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Next", "Slave Interact",
+		() => { V.activeSlave = getSlave(App.UI.SlaveInteract.placeInLine(slave)[1]); }), "adjacent-slave");
+	nextSpan.id = "next-slave";
+	p.append(nextSpan, " ");
+	App.UI.DOM.appendNewElement("span", p, App.UI.Hotkeys.hotkeys("next-slave"), "hotkey");
+
+	return p;
+
+	function favLink() {
+		if (V.favorites.includes(slave.ID)) {
+			const link = App.UI.DOM.link(String.fromCharCode(0xe800), () => {
+				V.favorites.delete(slave.ID);
+				App.UI.DOM.replace("#fav-span", favLink());
+			});
+			link.classList.add("icons", "favorite");
+			return link;
+		} else {
+			const link = App.UI.DOM.link(String.fromCharCode(0xe801), () => {
+				V.favorites.push(slave.ID);
+				App.UI.DOM.replace("#fav-span", favLink());
+			});
+			link.classList.add("icons", "not-favorite");
+			return link;
+		}
+	}
+};
+
 /**
  * @param {App.Entity.SlaveState} slave
  * @returns {Node}
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index 378e04ff952..3c0eb404892 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -522,16 +522,21 @@ App.UI.SlaveList.SlaveInteract = {};
 
 /**
  * @param {App.Entity.SlaveState} slave
- * @returns {HTMLElement}
+ * @returns {DocumentFragment|HTMLElement}
  */
 App.UI.SlaveList.SlaveInteract.stdInteract = function(slave) {
-	return App.UI.DOM.passageLink(SlaveFullName(slave), 'Slave Interact', () => {
+	const link = App.UI.DOM.passageLink(SlaveFullName(slave), "Slave Interact", () => {
 		App.UI.SlaveList.ScrollPosition.record();
 		V.activeSlave = slave;
 	});
+	if (V.favorites.includes(slave.ID)) {
+		return App.UI.DOM.combineNodes(
+			App.UI.DOM.makeElement("span", String.fromCharCode(0xe800), ["icons", "favorite"]),
+			" ", link);
+	}
+	return link;
 };
 
-
 /**
  * @param {App.Entity.SlaveState} slave
  * @returns {DocumentFragment|HTMLElement}
@@ -994,10 +999,16 @@ App.UI.SlaveList.penthousePage = function() {
 			penthouseSlavesIDs.push(S.Bodyguard.ID);
 		}
 		SlaveSort.IDs(penthouseSlavesIDs);
-		return makeTabDesc('all', `All${V.useSlaveSummaryTabs > 0 ? ` (${penthouseSlavesIDs.length})` : ""}`,
+		return makeTabDesc("all", `All${V.useSlaveSummaryTabs > 0 ? ` (${penthouseSlavesIDs.length})` : ""}`,
 			App.UI.SlaveList.render(penthouseSlavesIDs, [], App.UI.SlaveList.SlaveInteract.penthouseInteract));
 	}
 
+	function favorites() {
+		SlaveSort.IDs(V.favorites);
+		return makeTabDesc("favorites", `Favorites${V.useSlaveSummaryTabs > 0 ? ` (${V.favorites.length})` : ""}`,
+			App.UI.SlaveList.render(V.favorites, [], App.UI.SlaveList.SlaveInteract.penthouseInteract));
+	}
+
 	let fragment = document.createDocumentFragment();
 
 	if (V.positionMainLinks >= 0) {
@@ -1013,13 +1024,17 @@ App.UI.SlaveList.penthousePage = function() {
 
 	// Overview tab
 	if (V.useSlaveSummaryOverviewTab) {
-		tabs.push(makeTabDesc('overview', "Special Roles", overviewTabContent()));
+		tabs.push(makeTabDesc("overview", "Special Roles", overviewTabContent()));
 	}
 
 	if (V.useSlaveSummaryTabs === 0) {
 		tabs.push(allTab());
 	}
 
+	if (V.favorites.length > 0 || V.useSlaveSummaryTabs === 0) {
+		tabs.push(favorites());
+	}
+
 	// tabs for each assignment
 	for (const jn of ph.jobsNames) {
 		const slaves = _slavesForJob(jn);
diff --git a/src/js/utilsDOM.js b/src/js/utilsDOM.js
index 0996959a4dc..76b9f1099bf 100644
--- a/src/js/utilsDOM.js
+++ b/src/js/utilsDOM.js
@@ -188,7 +188,7 @@ App.Utils.passageElement = function(passage) {
 };
 
 /**
- * @param {(Node|string)[]} content
+ * @param {(Node|string)} content
  * @returns {DocumentFragment}
  */
 App.UI.DOM.combineNodes = function(...content) {
diff --git a/src/uncategorized/arcadeReport.tw b/src/uncategorized/arcadeReport.tw
index 92d94086e63..d8cd8080b89 100644
--- a/src/uncategorized/arcadeReport.tw
+++ b/src/uncategorized/arcadeReport.tw
@@ -71,6 +71,7 @@
 			</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_slave)>>
 		<span class='slave-name'><<= SlaveFullName(_slave)>></span>
 		<<if _slave.choosesOwnAssignment == 2>>
 			<<= App.SlaveAssignment.choosesOwnJob(_slave)>>
diff --git a/src/uncategorized/brothelReport.tw b/src/uncategorized/brothelReport.tw
index e010651d5f5..73f506b673a 100644
--- a/src/uncategorized/brothelReport.tw
+++ b/src/uncategorized/brothelReport.tw
@@ -191,6 +191,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_S.Madam)>>
 		<span class="slave-name"><<= SlaveFullName(_S.Madam)>></span> is serving as the Madam.
 		<br>&nbsp;&nbsp;&nbsp;
 		<<= App.SlaveAssignment.choosesOwnClothes(_S.Madam)>>
@@ -276,6 +277,7 @@
 			</div>
 			<</if>>
 			/* 000-250-006 */
+			<<includeDOM App.EndWeek.favoriteIcon(_slave)>>
 			<span class="slave-name"><<= SlaveFullName(_slave)>></span>
 			<<if _slave.choosesOwnAssignment == 2>>
 				<<= App.SlaveAssignment.choosesOwnJob(_slave)>>
diff --git a/src/uncategorized/cellblockReport.tw b/src/uncategorized/cellblockReport.tw
index 988393a3ba8..6427ebeaad4 100644
--- a/src/uncategorized/cellblockReport.tw
+++ b/src/uncategorized/cellblockReport.tw
@@ -135,6 +135,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon($slaves[$i])>>
 		<span class='slave-name'><<= SlaveFullName($slaves[$i])>></span> is serving as the Wardeness in $cellblockName.
 		<br>&nbsp;&nbsp;&nbsp;&nbsp;
 		<<= App.SlaveAssignment.choosesOwnClothes($slaves[$i])>>
@@ -252,6 +253,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_slave)>>
 		<span class='slave-name'><<= SlaveFullName(_slave)>></span>
 		<<if _slave.choosesOwnAssignment == 2>>
 			<<= App.SlaveAssignment.choosesOwnJob(_slave)>>
diff --git a/src/uncategorized/clubReport.tw b/src/uncategorized/clubReport.tw
index 6bc9c1b6cc8..be8d7bf0b2b 100644
--- a/src/uncategorized/clubReport.tw
+++ b/src/uncategorized/clubReport.tw
@@ -115,6 +115,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_S.DJ)>>
 		<span class='slave-name'><<= SlaveFullName(_S.DJ)>></span> is performing as the DJ in $clubName.
 		<br>&nbsp;&nbsp;&nbsp;
 		<<= App.SlaveAssignment.choosesOwnClothes(_S.DJ)>>
@@ -186,6 +187,7 @@
 			</div>
 			<</if>>
 			/* 000-250-006 */
+			<<includeDOM App.EndWeek.favoriteIcon(_slave)>>
 			<span class='slave-name'><<= SlaveFullName(_slave)>></span>
 			<<if _slave.choosesOwnAssignment == 2>>
 				<<= App.SlaveAssignment.choosesOwnJob(_slave)>>
diff --git a/src/uncategorized/dairyReport.tw b/src/uncategorized/dairyReport.tw
index 1ac86d5a22b..102454f267d 100644
--- a/src/uncategorized/dairyReport.tw
+++ b/src/uncategorized/dairyReport.tw
@@ -305,6 +305,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_S.Milkmaid)>>
 		<span class='slave-name'><<= SlaveFullName(_S.Milkmaid)>></span> is serving as your Milkmaid.
 		<br>&nbsp;&nbsp;&nbsp;
 		<<= App.SlaveAssignment.choosesOwnClothes(_S.Milkmaid)>>
@@ -413,6 +414,7 @@
 		<<else>>
 			is serving as a cow in $dairyName.
 		<</if>>
+		<<includeDOM App.EndWeek.favoriteIcon(_slave)>>
 		<br>&nbsp;&nbsp;&nbsp;&nbsp;$He <<= App.SlaveAssignment.getMilked(_slave)>>
 		<br>&nbsp;&nbsp;&nbsp;
 		<<include "SA rules">>
diff --git a/src/uncategorized/penthouseReport.tw b/src/uncategorized/penthouseReport.tw
index f2817f9ac92..7ef58944bda 100644
--- a/src/uncategorized/penthouseReport.tw
+++ b/src/uncategorized/penthouseReport.tw
@@ -6,7 +6,9 @@
 
 <<for $i = 0; $i < _SL; $i++>>
 	<<if assignmentVisible($slaves[$i])>>
-		<div><span class='slave-name'><<= SlaveFullName($slaves[$i])>></span>
+		<div>
+		<<includeDOM App.EndWeek.favoriteIcon($slaves[$i])>>
+		<span class='slave-name'><<= SlaveFullName($slaves[$i])>></span>
 		<<if $slaves[$i].choosesOwnAssignment == 2>>
 			<<= App.SlaveAssignment.choosesOwnJob($slaves[$i])>>
 			$He
diff --git a/src/uncategorized/slaveInteract.tw b/src/uncategorized/slaveInteract.tw
index 90d552b63c2..901901cf4d3 100644
--- a/src/uncategorized/slaveInteract.tw
+++ b/src/uncategorized/slaveInteract.tw
@@ -52,33 +52,8 @@
 	<<set $encyclopedia = "Gender">>
 <</if>>
 
-<<set _slavesInLine = App.UI.SlaveInteract.placeInLine(getSlave($AS))>>
-
-<p align="center">
-	<<if $cheatMode == 1>>
-		<div style="font-style:italic">
-			[[Cheat Edit Slave|MOD_Edit Slave Cheat][$cheater = 1]] |
-			[[Cheat Edit Slave Alternative|MOD_Edit Slave Cheat New][$cheater = 1]]
-		</div>
-	<</if>>
-	<span class="hotkey">
-		<<print App.UI.Hotkeys.hotkeys("prev-slave")>>
-	</span>
-	<span id="prev-slave" style="font-weight:bold">
-		<<link "Prev" "Slave Interact">><<set $activeSlave = getSlave(_slavesInLine[0])>><</link>>
-	</span>
-	&nbsp;&nbsp;&nbsp;&nbsp;
-	<span class='slave-name'>
-		<<= getSlave($AS).slaveName>>
-	</span>
-	&nbsp;&nbsp;&nbsp;&nbsp;
-	<span id="next-slave" style="font-weight:bold">
-		<<link "Next" "Slave Interact">><<set $activeSlave = getSlave(_slavesInLine[1])>><</link>>
-	</span>
-	<span class="hotkey">
-		<<print App.UI.Hotkeys.hotkeys("next-slave")>>
-	</span>
-</p>
+<<includeDOM App.UI.SlaveInteract.navigation(getSlave($AS))>>
+
 <div class="tab-bar">
 	<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Description'), jQuery('#LSD').empty().append(App.Desc.longSlave(getSlave(V.AS)))" id="tab Description">Description</button>
 	<button class="tab-links" onclick="App.UI.tabBar.openTab(event, 'Modify')" id="tab Modify">Modify</button>
diff --git a/src/uncategorized/spaReport.tw b/src/uncategorized/spaReport.tw
index 0d86282ac2f..d9e4bdad4ad 100644
--- a/src/uncategorized/spaReport.tw
+++ b/src/uncategorized/spaReport.tw
@@ -227,6 +227,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_S.Attendant)>>
 		<span class='slave-name'><<= SlaveFullName(_S.Attendant)>></span> is serving as the Attendant in $spaName.
 		<br>&nbsp;&nbsp;&nbsp;
 		<<= App.SlaveAssignment.choosesOwnClothes(_S.Attendant)>>
@@ -319,6 +320,7 @@
 		</div>
 		<</if>>
 		/* 000-250-006 */
+		<<includeDOM App.EndWeek.favoriteIcon(_slave)>>
 		<span class='slave-name'><<= SlaveFullName(_slave)>></span>
 		<<if _slave.choosesOwnAssignment == 2>>
 			<<= App.SlaveAssignment.choosesOwnJob(_slave)>>
-- 
GitLab