diff --git a/js/artInfrastructure.js b/js/artInfrastructure.js
index 23ed5bea12df4c2f27e169e776ac162e2da982f3..f3df7232e0fa5739205f9e665338a17723c30100 100644
--- a/js/artInfrastructure.js
+++ b/js/artInfrastructure.js
@@ -37,7 +37,7 @@ App.Art.cacheArtData = function() {
 	App.Data.Art.VectorRevamp = makeCache(document.querySelectorAll('[tags="Twine.image"][name^="Art_Vector_Revamp"]'));
 };
 
-App.Art.URLIDMatcher = /url\(#(.*)\)/;
+App.Art.URLIDMatcher = /url\(#(.*)\)/g;
 App.Art.SvgQueue = class {
 	/**
 	 * @param {{trigger:string, action:string, value:string}[]} transformRules - when a 'data-transform' attribute with value "trigger" is seen on an element, perform 'action' with 'value'
@@ -119,9 +119,8 @@ App.Art.SvgQueue = class {
 
 	/** add an SVG from the cache to the render queue
 	 * @param {string} id
-	 * @param {number} [rndID] - optional unique ID which identifies this specific art instance to make internal defs link correctly
 	 */
-	add(id, rndID) {
+	add(id) {
 		const res = this._cache.get(id);
 		let clones = [];
 		if (!res) {
diff --git a/src/art/vector_revamp/vectorRevampedArtControl.js b/src/art/vector_revamp/vectorRevampedArtControl.js
index 58cc49a150f873f0c8768794b3a545e074e17b8f..4949181a7b02b45bc6c9ba0b3bc6ad2509ef3ce9 100644
--- a/src/art/vector_revamp/vectorRevampedArtControl.js
+++ b/src/art/vector_revamp/vectorRevampedArtControl.js
@@ -1407,7 +1407,7 @@ class ClothingControl {
 			};
 		}
 	}
-	
+
 	get ballgown() {
 		this.piecewiseClothing.ballgown = true;
 		return {
@@ -1721,7 +1721,6 @@ class ClothingControl {
 			this.piecewiseClothing.overalls = true;
 			return {
 				bodySettings: {
-					
 				},
 				styleSettings: {
 					top_primary: {fill: pri_col, "fill-opacity": 1},
@@ -1845,8 +1844,8 @@ class ClothingControl {
 			let st_acc = {fill: "#000000", "fill-opacity": 0};
 			if (this.accessories.longStockings || this.accessories.shortStockings) {
 				st_pri = {fill: "#F7F7F7", "fill-opacity": 0.3};
-				st_acc = {fill: "#D20030", "fill-opacity": 1};	
-			}	
+				st_acc = {fill: "#D20030", "fill-opacity": 1};
+			}
 			let sa = "#D20030";
 			let sp = "#F7F7F7";
 			switch (this.slave.shoes) {
@@ -1901,8 +1900,8 @@ class ClothingControl {
 			let st_acc = {fill: "#000000", "fill-opacity": 0};
 			if (this.accessories.longStockings || this.accessories.shortStockings) {
 				st_pri = {fill: "#F7F7F7", "fill-opacity": 0.3};
-				st_acc = {fill: "#D20030", "fill-opacity": 1};	
-			}		
+				st_acc = {fill: "#D20030", "fill-opacity": 1};
+			}
 			let sa = "#F7F7F7";
 			let sp = "#D20030";
 			switch (this.slave.shoes) {
@@ -3070,8 +3069,8 @@ class RevampedArtControl {
 		}
 		if (this.clothingControl.piecewiseClothing.shibari) {
 			const bellySize = [0, 2, 2, 3, 4, 5, 6, 7, 8, 9];
-			let bl = bellySize[this.bellyLevel];			
-			if (this.bellyLevel == 0) {
+			const bl = bellySize[this.bellyLevel];
+			if (this.bellyLevel === 0) {
 				result.push(`Art_Vector_Revamp_Torso_Outfit_Shibari_${this.torsoSize}`);
 			} else {
 				result.push(`Art_Vector_Revamp_Torso_Outfit_Shibari_Belly_${bl}`);
@@ -3085,7 +3084,7 @@ class RevampedArtControl {
 		}
 		if (this.clothingControl.piecewiseClothing.straps) {
 			const bellySize = [0, 0, 0, 3, 4, 5, 5, 5, 5, 5];
-			let bl = bellySize[this.bellyLevel];
+			const bl = bellySize[this.bellyLevel];
 			if (this.bellyLevel <= 2) {
 				result.push(`Art_Vector_Revamp_Torso_Outfit_Straps_Base`);
 				result.push(`Art_Vector_Revamp_Torso_Outfit_Straps_${this.torsoSize}`);
@@ -3251,13 +3250,12 @@ class RevampedArtControl {
 		}
 		return result;
 	}
-	
+
 	get torsoOutfitFrontLayer() {
 		let result = [];
 		if (this.clothingControl.piecewiseClothing.ballgown) {
-			
 			result.push(`Art_Vector_Revamp_Torso_Outfit_Ballgown_Unnatural`);
-			if (this.torsoSize != "Unnatural") {
+			if (this.torsoSize !== "Unnatural") {
 				result.push(`Art_Vector_Revamp_Torso_Outfit_Ballgown_${this.torsoSize}`);
 			}
 			if (this.bellyLevel > 0) {
diff --git a/src/js/rulesAssistantOptions.js b/src/js/rulesAssistantOptions.js
index 61fbc7a9ad2987c34b10b9604b9d764c73b666a8..3e03234e13f6d93c107430ada628b1c4cca68e38 100644
--- a/src/js/rulesAssistantOptions.js
+++ b/src/js/rulesAssistantOptions.js
@@ -808,6 +808,16 @@ App.RA.options = (function() {
 			const v = this.parse(this.numEditor.value);
 			return v === null ? null : App.RA.makeTarget(this.opSelector.value, v);
 		}
+
+		dataEqual(left, right) {
+			// when comparing a plain number to a target, assume equal conditions
+			const xor = (a, b) => (a) ? !(b) : !!(b);
+			if (xor(_.isNumber(left), _.isNumber(right))) {
+				left = _.isNil(left.val) ? left : left.val;
+				right = _.isNil(right.val) ? right : right.val;
+			}
+			return _.isEqual(left, right);
+		}
 	}
 
 	class NumericRangeEditor extends EditorWithShortcuts {
@@ -966,6 +976,16 @@ App.RA.options = (function() {
 			const v = isNaN(n) ? this.numEditor.value : Math.floor(n);                         // return numEditor.value as number if !NaN (should result in realValue being of number)
 			return v === null || v === "" ? null : { cond: this.opSelector.value, val: v };
 		}
+
+		dataEqual(left, right) {
+			// when comparing a plain number to a target, assume equal conditions
+			const xor = (a, b) => (a) ? !(b) : !!(b);
+			if (xor(_.isNumber(left), _.isNumber(right))) {
+				left = _.isNil(left.val) ? left : left.val;
+				right = _.isNil(right.val) ? right : right.val;
+			}
+			return _.isEqual(left, right);
+		}
 	}
 
 	// a way to organize lists with too many elements in subsections