From 9aadc546d257a1da4d55fbb26ce5ecb354d32cb8 Mon Sep 17 00:00:00 2001
From: Svornost <11434-svornost@users.noreply.gitgud.io>
Date: Wed, 11 Nov 2020 01:43:49 -0800
Subject: [PATCH] Use the batch art renderer for slave reports to avoid style
 recalcs, and don't bother initializing jQuery objects to append
 standardSlaveReport since we know it's going to return a DOM node anyway.

---
 src/endWeek/brothelReport.js                  |  8 +---
 src/endWeek/clinicReport.js                   | 12 ++----
 src/endWeek/masterSuiteReport.js              |  8 +---
 src/endWeek/reports/arcadeReport.js           |  8 ++--
 src/endWeek/reports/cellblockReport.js        |  8 +---
 src/endWeek/reports/clubReport.js             |  8 +---
 src/endWeek/reports/dairyReport.js            |  8 +---
 src/endWeek/reports/nurseryReport.js          | 17 ++-------
 src/endWeek/reports/penthouseReport.js        | 37 ++++++++++++-------
 src/endWeek/reports/spaReport.js              |  8 +---
 src/endWeek/saLiveWithHG.js                   |  4 --
 src/endWeek/saSharedVariables.js              |  2 +
 src/endWeek/schoolroomReport.js               | 12 ++----
 src/endWeek/servantsQuartersReport.js         | 12 ++----
 src/endWeek/slaveAssignmentReport.js          | 10 +++++
 src/endWeek/standardSlaveReport.js            | 11 ++++++
 .../farmyard/reports/farmyardReport.js        | 16 ++------
 17 files changed, 82 insertions(+), 107 deletions(-)

diff --git a/src/endWeek/brothelReport.js b/src/endWeek/brothelReport.js
index 7cc803a01a6..53c2735599d 100644
--- a/src/endWeek/brothelReport.js
+++ b/src/endWeek/brothelReport.js
@@ -259,9 +259,7 @@ App.EndWeek.brothelReport = function() {
 		tired(slave);
 		if (V.showEWD !== 0) {
 			const madamEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", madamEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(madamEntry, slave);
 			madamEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			App.Events.addNode(
 				madamEntry,
@@ -333,9 +331,7 @@ App.EndWeek.brothelReport = function() {
 			if (V.showEWD !== 0) {
 				const {He} = getPronouns(slave);
 				const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-				if (V.seeImages && V.seeReportImages) {
-					App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-				}
+				App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 				slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 				r = [];
 				r.push(App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name"));
diff --git a/src/endWeek/clinicReport.js b/src/endWeek/clinicReport.js
index 3fe91a528fc..6246921be24 100644
--- a/src/endWeek/clinicReport.js
+++ b/src/endWeek/clinicReport.js
@@ -244,12 +244,10 @@ App.EndWeek.clinicReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const nurseEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", nurseEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(nurseEntry, slave);
 			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));
+			nurseEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			App.SlaveAssignment.standardSlaveReport(slave, true);
 		}
@@ -376,9 +374,7 @@ App.EndWeek.clinicReport = function() {
 
 		if (V.showEWD !== 0) {
 			const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> `);
 			if (slave.choosesOwnAssignment === 2) {
@@ -389,7 +385,7 @@ App.EndWeek.clinicReport = function() {
 			const patientContent = App.UI.DOM.appendNewElement("div", slaveEntry, '', "indent");
 			$(patientContent).append(`${He} ${App.SlaveAssignment.rest(slave)} `);
 			$(patientContent).append(remainReason);
-			$(slaveEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
+			slaveEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			// discard return values silently
 			App.SlaveAssignment.choosesOwnJob(slave);
diff --git a/src/endWeek/masterSuiteReport.js b/src/endWeek/masterSuiteReport.js
index 1e27e3ab63d..4678dac4dbf 100644
--- a/src/endWeek/masterSuiteReport.js
+++ b/src/endWeek/masterSuiteReport.js
@@ -428,18 +428,14 @@ App.EndWeek.masterSuiteReport = function() {
 	if (S.Concubine) {
 		tired(S.Concubine);
 		const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-		if (V.seeImages && V.seeReportImages) {
-			App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(S.Concubine, 0, 0), ["imageRef", "tinyImg"]);
-		}
+		App.SlaveAssignment.appendSlaveArt(slaveEntry, S.Concubine);
 		slaveEntry.append(App.EndWeek.favoriteIcon(S.Concubine), " ");
 		$(slaveEntry).append(concubineText(), commonText(S.Concubine));
 	}
 
 	for (const slave of slaves) {
 		const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-		if (V.seeImages && V.seeReportImages) {
-			App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-		}
+		App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 		slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 		$(slaveEntry).append(nonConcubineText(slave), commonText(slave));
 	}
diff --git a/src/endWeek/reports/arcadeReport.js b/src/endWeek/reports/arcadeReport.js
index 4b7455f76a7..10c07796e88 100644
--- a/src/endWeek/reports/arcadeReport.js
+++ b/src/endWeek/reports/arcadeReport.js
@@ -80,9 +80,7 @@ App.EndWeek.arcadeReport = function() {
 		if (V.showEWD !== 0) {
 			const {He} = getPronouns(slave);
 			const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			r = [];
 			r.push(App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name"));
@@ -175,12 +173,12 @@ App.EndWeek.arcadeReport = function() {
 		if (slave.inflation > 0) {
 			deflate(slave);
 		}
+		App.Events.addNode(el, r, "div", "indent");
 		if (V.showEWD !== 0) {
-			r.push(App.SlaveAssignment.standardSlaveReport(slave, false));
+			el.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			App.SlaveAssignment.standardSlaveReport(slave, true);
 		}
-		App.Events.addNode(el, r, "div", "indent");
 	}
 
 	if (slavesLength + V.fuckdolls > 0) {
diff --git a/src/endWeek/reports/cellblockReport.js b/src/endWeek/reports/cellblockReport.js
index 1a271223b22..9ca2d1e6c1f 100644
--- a/src/endWeek/reports/cellblockReport.js
+++ b/src/endWeek/reports/cellblockReport.js
@@ -172,9 +172,7 @@ App.EndWeek.cellblockReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const wardenessEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", wardenessEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(wardenessEntry, slave);
 			wardenessEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			App.Events.addNode(
 				wardenessEntry,
@@ -293,9 +291,7 @@ App.EndWeek.cellblockReport = function() {
 
 		if (V.showEWD !== 0) {
 			const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			r = [];
 			r.push(App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name"));
diff --git a/src/endWeek/reports/clubReport.js b/src/endWeek/reports/clubReport.js
index 8a02eab58ae..43fc5b9da18 100644
--- a/src/endWeek/reports/clubReport.js
+++ b/src/endWeek/reports/clubReport.js
@@ -142,9 +142,7 @@ App.EndWeek.clubReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const DJEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", DJEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(DJEntry, slave);
 			DJEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			App.Events.addNode(
 				DJEntry,
@@ -196,9 +194,7 @@ App.EndWeek.clubReport = function() {
 
 			if (V.showEWD !== 0) {
 				const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-				if (V.seeImages && V.seeReportImages) {
-					App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-				}
+				App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 				slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 				r = [];
 				r.push(App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name"));
diff --git a/src/endWeek/reports/dairyReport.js b/src/endWeek/reports/dairyReport.js
index 78b75d9d633..bf6bd684437 100644
--- a/src/endWeek/reports/dairyReport.js
+++ b/src/endWeek/reports/dairyReport.js
@@ -365,9 +365,7 @@ App.EndWeek.dairyReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const milkMaidEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", milkMaidEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(milkMaidEntry, slave);
 			milkMaidEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			App.Events.addNode(
 				milkMaidEntry,
@@ -490,9 +488,7 @@ App.EndWeek.dairyReport = function() {
 		cumWeek += milkResults.cum;
 		if (V.showEWD !== 0) {
 			const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			r = [];
 			r.push(App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name"));
diff --git a/src/endWeek/reports/nurseryReport.js b/src/endWeek/reports/nurseryReport.js
index 13d315fe65c..aee524cb6f5 100644
--- a/src/endWeek/reports/nurseryReport.js
+++ b/src/endWeek/reports/nurseryReport.js
@@ -135,19 +135,14 @@ App.Facilities.Nursery.nurseryReport = function nurseryReport() {
 	}
 
 	if (S.Matron) {
-		/** @type {App.Entity.SlaveState} */
 		const slave = S.Matron;
 
 		if (V.showEWD !== 0) {
 			const matronEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", matronEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
-
+			App.SlaveAssignment.appendSlaveArt(matronEntry, slave);
 			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));
+			matronEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			App.SlaveAssignment.standardSlaveReport(slave, true);
 		}
@@ -200,11 +195,7 @@ App.Facilities.Nursery.nurseryReport = function nurseryReport() {
 		if (V.showEWD) {
 			const {He} = getPronouns(slave);
 			const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
-
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class="slave-name">${SlaveFullName(slave)}</span> `);
 
@@ -218,7 +209,7 @@ App.Facilities.Nursery.nurseryReport = function nurseryReport() {
 
 			$(nannyContent).append(`${He} ${App.SlaveAssignment.nanny(slave, matronBonus)}`);	// FIXME: nanny() takes one argument
 
-			$(slaveEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
+			slaveEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {	// silently discard return values
 			App.SlaveAssignment.nanny(slave, matronBonus);	// FIXME: nanny() takes one argument
 			App.SlaveAssignment.standardSlaveReport(slave, true);
diff --git a/src/endWeek/reports/penthouseReport.js b/src/endWeek/reports/penthouseReport.js
index da7f65c6ead..4fe45ac6892 100644
--- a/src/endWeek/reports/penthouseReport.js
+++ b/src/endWeek/reports/penthouseReport.js
@@ -1,38 +1,49 @@
 App.EndWeek.penthouseReport = function() {
 	const el = document.createElement("p");
-	let r;
 
 	const HGSuiteSlaves = App.Utils.jobForAssignment(Job.HEADGIRLSUITE).employees();
+	const hgSlave = HGSuiteSlaves.length > 0 ? HGSuiteSlaves[0] : null;
 	const HGTrainSlavesIDs = slavesToTrain();
 
+	// penthouse images are larger and on the right (for some reason), so we need to initialize a second batch renderer instead of using the global SA Report one
+	let penthouseArtRenderer = null;
+	if (V.seeImages && V.seeReportImages) {
+		const penthouseArtSlaveIDs = V.slaves.filter(s => assignmentVisible(s)).map(s => s.ID);
+		if (hgSlave) {
+			penthouseArtSlaveIDs.push(hgSlave.ID);
+		}
+		penthouseArtRenderer = new App.Art.SlaveArtBatch(penthouseArtSlaveIDs, 2);
+		el.append(penthouseArtRenderer.writePreamble());
+	}
+
 	for (const slave of V.slaves) {
 		if (assignmentVisible(slave)) {
-			r = [];
 			const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
+			if (penthouseArtRenderer) {
+				App.UI.DOM.appendNewElement("div", slaveEntry, penthouseArtRenderer.render(slave), ["imageRef", "medImg"]);
 			}
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
-			r.push(fullReport(slave));
-			App.Events.addNode(el, r, "p");
+			slaveEntry.append(fullReport(slave));
 
-			if (slave.ID === V.HeadGirlID && HGSuiteSlaves.length > 0) {
-				/* We found the Head Girl, now let's find her slave */
-				const hgSlave = getSlave(HGSuiteSlaves[0].ID);
+			if (slave.ID === V.HeadGirlID && hgSlave) {
+				/* Output the HG's slave immediately after the hg */
 				const {He2, he2} = getPronouns(hgSlave).appendSuffix("2");
-				r = [];
-				if (hgSlave.assignment !== "live with your Head Girl") {
+				const r = [];
+				if (hgSlave.assignment !== Job.HEADGIRLSUITE) {
 					r.push(`<span class="red">${hgSlave.slaveName} had been assigned to live with your Head Girl, but this week ${he2} was assigned to ${hgSlave.assignment}. ${He2} has been released to your penthouse for reassignment.</span>`);
-					removeJob(hgSlave, "live with your Head Girl");
+					removeJob(hgSlave, Job.HEADGIRLSUITE);
 				} else {
 					r.push(App.UI.DOM.makeElement("span", SlaveFullName(hgSlave), "slave-name"));
 					if (hgSlave.choosesOwnAssignment === 2) {
 						r.push(App.SlaveAssignment.choosesOwnJob(hgSlave));
 						r.push(He2);
 					}
+					if (penthouseArtRenderer) {
+						r.push(App.UI.DOM.makeElement("div", penthouseArtRenderer.render(hgSlave), ["imageRef", "medImg"]));
+					}
 					r.push(App.SlaveAssignment.liveWithHG(hgSlave));
 				}
-				App.Events.addNode(el, r, "p");
+				App.Events.addNode(el, r, "div", "slave-report");
 			}
 		}
 	}
diff --git a/src/endWeek/reports/spaReport.js b/src/endWeek/reports/spaReport.js
index 69b44f7ee26..d1b9eee8843 100644
--- a/src/endWeek/reports/spaReport.js
+++ b/src/endWeek/reports/spaReport.js
@@ -287,9 +287,7 @@ App.EndWeek.spaReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const attendantEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", attendantEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(attendantEntry, slave);
 			attendantEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			App.Events.addNode(
 				attendantEntry,
@@ -374,9 +372,7 @@ App.EndWeek.spaReport = function() {
 
 		if (V.showEWD !== 0) {
 			const slaveEntry = App.UI.DOM.appendNewElement("div", el, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			r = [];
 			r.push(App.UI.DOM.makeElement("span", SlaveFullName(slave), "slave-name"));
diff --git a/src/endWeek/saLiveWithHG.js b/src/endWeek/saLiveWithHG.js
index f8b898cb6e7..694ee34223f 100644
--- a/src/endWeek/saLiveWithHG.js
+++ b/src/endWeek/saLiveWithHG.js
@@ -49,10 +49,6 @@ App.SlaveAssignment.liveWithHG = (function() {
 		penetrativeUse = 0;
 		cervixPump = 0;
 
-		if (V.seeImages && V.seeReportImages) {
-			App.UI.DOM.appendNewElement("div", el, App.Art.SlaveArtElement(slave, 2, 0), ["imageRef", "medImg"]);
-		}
-
 		HGSetsDiet(slave, S.HeadGirl);
 		if (V.HGSuiteHormones !== 0) {
 			HGSetsHormones(slave, S.HeadGirl);
diff --git a/src/endWeek/saSharedVariables.js b/src/endWeek/saSharedVariables.js
index 8fc356b6559..81608508ffe 100644
--- a/src/endWeek/saSharedVariables.js
+++ b/src/endWeek/saSharedVariables.js
@@ -34,6 +34,8 @@ App.EndWeek.SASharedVariables = class {
 		 * @type {Map<number, Array<number>>} - key is sub target, value is list of sub slaves (by ID) assigned to that target
 		 */
 		this.subSlaveMap = new Map();
+		/** Slave art manager */
+		this.slaveArt = null;
 	}
 
 	/**
diff --git a/src/endWeek/schoolroomReport.js b/src/endWeek/schoolroomReport.js
index 2fcb706c0e0..5d315659318 100644
--- a/src/endWeek/schoolroomReport.js
+++ b/src/endWeek/schoolroomReport.js
@@ -150,12 +150,10 @@ App.EndWeek.schoolroomReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const schoolteacherEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", schoolteacherEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(schoolteacherEntry, slave);
 			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));
+			schoolteacherEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			App.SlaveAssignment.standardSlaveReport(slave, true);
 		}
@@ -225,9 +223,7 @@ App.EndWeek.schoolroomReport = function() {
 		if (V.showEWD !== 0) {
 			const {He} = getPronouns(slave);
 			const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> `);
 			if (slave.choosesOwnAssignment === 2) {
@@ -243,7 +239,7 @@ App.EndWeek.schoolroomReport = function() {
 			}
 			const studentContent = App.UI.DOM.appendNewElement("div", slaveEntry, '', "indent");
 			$(studentContent).append(`${He} ${App.SlaveAssignment.takeClasses(slave)}`);
-			$(slaveEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
+			slaveEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			// discard return values silently
 			App.SlaveAssignment.choosesOwnJob(slave);
diff --git a/src/endWeek/servantsQuartersReport.js b/src/endWeek/servantsQuartersReport.js
index 2a31dba3895..ed62fd97435 100644
--- a/src/endWeek/servantsQuartersReport.js
+++ b/src/endWeek/servantsQuartersReport.js
@@ -209,12 +209,10 @@ App.EndWeek.servantsQuartersReport = function() {
 		/* apply following SA passages to facility leader */
 		if (V.showEWD !== 0) {
 			const stewardessEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", stewardessEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(stewardessEntry, slave);
 			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));
+			stewardessEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			App.SlaveAssignment.standardSlaveReport(slave, true);
 		}
@@ -284,9 +282,7 @@ App.EndWeek.servantsQuartersReport = function() {
 		if (V.showEWD !== 0) {
 			const {He} = getPronouns(slave);
 			const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-			}
+			App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 			slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 			$(slaveEntry).append(`<span class='slave-name'>${SlaveFullName(slave)}</span> `);
 			if (slave.choosesOwnAssignment === 2) {
@@ -303,7 +299,7 @@ App.EndWeek.servantsQuartersReport = function() {
 				SQMilk += milkResults.milk;
 				SQMilkSale += milkResults.milkSale;
 			}
-			$(slaveEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
+			slaveEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 		} else {
 			// discard return values silently
 			App.SlaveAssignment.choosesOwnJob(slave);
diff --git a/src/endWeek/slaveAssignmentReport.js b/src/endWeek/slaveAssignmentReport.js
index 73cf86303a4..50d790cfc37 100644
--- a/src/endWeek/slaveAssignmentReport.js
+++ b/src/endWeek/slaveAssignmentReport.js
@@ -232,6 +232,16 @@ App.EndWeek.slaveAssignmentReport = function() {
 		}
 	}
 
+	// initialize slave art
+	if (V.seeImages && V.seeReportImages) {
+		// agents and partners are not drawn; penthouse partners and the head girl's slave will be drawn via a different mechanism (since they are larger and right-aligned)
+		const undrawnJobs = [Job.AGENT, Job.AGENTPARTNER, ...App.Entity.facilities.penthouse.jobsNames, Job.HEADGIRLSUITE];
+		const drawnSlaveIDs = V.slaves.filter(s => !undrawnJobs.includes(s.assignment)).map(s => s.ID);
+		// this batch renderer object will be accessible to all the facility reports
+		App.EndWeek.saVars.slaveArt = new App.Art.SlaveArtBatch(drawnSlaveIDs, 0);
+		res.append(App.EndWeek.saVars.slaveArt.writePreamble());
+	}
+
 	/**
 	 * Accordion
 	 * @version 0.7RC
diff --git a/src/endWeek/standardSlaveReport.js b/src/endWeek/standardSlaveReport.js
index 233c87928ff..b2792a7f077 100644
--- a/src/endWeek/standardSlaveReport.js
+++ b/src/endWeek/standardSlaveReport.js
@@ -35,3 +35,14 @@ App.SlaveAssignment.individualSlaveReport = function(slave) {
 		App.SlaveAssignment.rivalries(slave),
 	];
 };
+
+/**
+ * Render slave assignment report art
+ * @param {ParentNode} node
+ * @param {App.Entity.SlaveState} slave
+ */
+App.SlaveAssignment.appendSlaveArt = function(node, slave) {
+	if (V.seeImages && V.seeReportImages) {
+		App.UI.DOM.appendNewElement("div", node, App.EndWeek.saVars.slaveArt.render(slave), ["imageRef", "tinyImg"]);
+	}
+};
diff --git a/src/facilities/farmyard/reports/farmyardReport.js b/src/facilities/farmyard/reports/farmyardReport.js
index 7d646bf9f79..defb1d0e849 100644
--- a/src/facilities/farmyard/reports/farmyardReport.js
+++ b/src/facilities/farmyard/reports/farmyardReport.js
@@ -254,14 +254,10 @@ App.Facilities.Farmyard.farmyardReport = function farmyardReport() {
 
 		if (V.showEWD) {
 			const farmerEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-
-			if (V.seeImages && V.seeReportImages) {
-				App.UI.DOM.appendNewElement("div", farmerEntry, App.Art.SlaveArtElement(Farmer, 0, 0), ["imageRef", "tinyImg"]);
-			}
-
+			App.SlaveAssignment.appendSlaveArt(farmerEntry, Farmer);
 			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));
+			farmerEntry.append(App.SlaveAssignment.standardSlaveReport(Farmer, false));
 		} else {
 			App.SlaveAssignment.standardSlaveReport(Farmer, true);
 		}
@@ -353,11 +349,7 @@ App.Facilities.Farmyard.farmyardReport = function farmyardReport() {
 
 			if (V.showEWD) {
 				const slaveEntry = App.UI.DOM.appendNewElement("div", frag, '', "slave-report");
-
-				if (V.seeImages && V.seeReportImages) {
-					App.UI.DOM.appendNewElement("div", slaveEntry, App.Art.SlaveArtElement(slave, 0, 0), ["imageRef", "tinyImg"]);
-				}
-
+				App.SlaveAssignment.appendSlaveArt(slaveEntry, slave);
 				slaveEntry.append(App.EndWeek.favoriteIcon(slave), " ");
 				$(slaveEntry).append(`<span class="slave-name">${SlaveFullName(slave)}</span> `);
 
@@ -379,7 +371,7 @@ App.Facilities.Farmyard.farmyardReport = function farmyardReport() {
 				const farmhandContent = App.UI.DOM.appendNewElement("div", slaveEntry, '', "indent");
 
 				$(farmhandContent).append(App.SlaveAssignment.workTheFarm(slave));
-				$(slaveEntry).append(App.SlaveAssignment.standardSlaveReport(slave, false));
+				slaveEntry.append(App.SlaveAssignment.standardSlaveReport(slave, false));
 			} else {	// silently discard return values
 				App.SlaveAssignment.workTheFarm(slave);
 				App.SlaveAssignment.standardSlaveReport(slave, true);
-- 
GitLab