diff --git a/src/js/betterRA.tw b/src/js/betterRA.tw
deleted file mode 100644
index 18c6f084a28501a3e6443347ceda205108d805b9..0000000000000000000000000000000000000000
--- a/src/js/betterRA.tw
+++ /dev/null
@@ -1,318 +0,0 @@
-:: BetterRA_JS [script]
-//Imported to pregmod from unknown author added this to original FC at some point (0.9.5.4). I don't write this by myself (pregmodfan).
-
-// Implements a Top Down Operator Precedence parser, also know as a Pratt
-// parser, after its "inventor", Vaughan Pratt.  The one implemented here
-// closely follows what's presented here,
-//     * http://javascript.crockford.com/tdop/tdop.html
-// by Douglas Crockford.  He uses that parser in JSLint.  Other relevant
-// resources on the interweb
-//     * http://effbot.org/zone/simple-top-down-parsing.htm
-//     * http://eli.thegreenplace.net/2010/01/02/top-down-operator-precedence-parsing
-//     * http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
-//     * https://higherlogics.blogspot.gr/2009/11/extensible-statically-typed-pratt.html
-//     * https://github.com/fholm/Vaughan
-// included here mostly as bookmarks for potential future reference.
-//
-// With regards to the lexer, I mostly copied
-//     * http://eli.thegreenplace.net/2013/06/25/regex-based-lexical-analysis-in-python-and-javascript/
-// not without changes though.
-//
-// Other useful things, to complement my lacking JavaScript knowledge were
-//     * https://plainjs.com/javascript/utilities/merge-two-javascript-objects-19/
-//     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
-// Some I actually use, some I do not
-
-
-function panic(index, msg) {
-    throw {index: index, message: msg};
-}
-
-function escapeRegExp(s){
-    return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
-}
-
-
-var Lexer = function(skipWhitespace) {
-    this.rules = [];
-    this.index = 0;
-    this.buffer = "";
-    this.skipWhitespace = skipWhitespace ? /\S/ : null;
-}
-
-Lexer.prototype.addRule = function(id, defn) {
-    var pattern = (defn && defn.pattern) || escapeRegExp(id);
-    this.rules.push({
-        id: id,
-        pattern: new RegExp('^' + pattern)
-    });
-}
-
-Lexer.prototype.feed = function(buffer) {
-    this.buffer = buffer;
-    this.index = 0;
-}
-
-Lexer.prototype.nextInterestingChar = function() {
-    if (this.skipWhitespace) {
-        var match = this.skipWhitespace.exec(this.buffer.substr(this.index));
-        return match ? this.index + match.index
-                     : this.buffer.length;
-    }
-    return this.index;
-}
-
-Lexer.prototype.next = function() {
-    this.index = this.nextInterestingChar();
-
-    if (this.index >= this.buffer.length)
-        return { done: true };
-
-    for (var i = 0; i < this.rules.length; ++i) {
-        var rule = this.rules[i],
-            match = rule.pattern.exec(this.buffer.substr(this.index));
-        if (match) {
-            var token = {
-                id: rule.id,
-                value: match[0],
-                index: this.index,
-            };
-            this.index += token.value.length;
-            return { done: false, value: token };
-        }
-    }
-
-    panic(this.index, "illegal character");
-}
-
-
-
-var BaseSymbol = {
-    lbp: 0,
-    nud: function() { panic(this.index, "Undefined"); },
-    led: function() { panic(this.index, "Missing operator"); }
-};
-
-var Parser = function(eofToken) {
-    this.lexer = new Lexer(true);
-    this.currentSymbol = null;
-
-    this.eofToken = eofToken;
-    this.symbolTable = {
-        [this.eofToken]: Object.create(BaseSymbol, {id: {value: this.eofToken}})
-    };
-}
-
-Parser.prototype.addSymbol = function(id, defn) {
-    var s = this.symbolTable[id];
-    if (s) {
-        if (defn && defn.lbp !== undefined && defn.lbp >= s.lbp) s.lbp = defn.lbp;
-        if (defn && defn.nud !== undefined) s.nud = defn.nud;
-        if (defn && defn.led !== undefined) s.led = defn.led;
-    } else {
-        s = Object.create(BaseSymbol);
-        s.id = id;
-        if (defn && defn.lbp !== undefined) s.lbp = defn.lbp;
-        if (defn && defn.nud) s.nud = defn.nud;
-        if (defn && defn.led) s.led = defn.led;
-        this.symbolTable[id] = s;
-        this.lexer.addRule(id, defn);
-    }
-    return this;
-}
-
-Parser.prototype.addInfix = function(id, lbp, callback) {
-    this.addSymbol(id, {
-        lbp: lbp,
-        led: function(p, left) { return callback(this, left, p.parse(lbp)); }
-    });
-    return this;
-}
-
-Parser.prototype.addInfixR = function(id, lbp, callback) {
-    this.addSymbol(id, {
-        lbp: lbp,
-        led: function(p, left) { return callback(this, left, p.parse(lbp-1)); }
-    });
-    return this;
-}
-
-Parser.prototype.addPrefix = function(id, callback) {
-    this.addSymbol(id, {
-        // FIXME: is the rbp (in parse) always 70?
-        nud: function (p) { return callback(p.parse(70)); }
-    });
-    return this;
-}
-
-Parser.prototype.advance = function(id) {
-    if (id && this.currentSymbol.id !== id)
-        panic(this.currentSymbol.index, "expected '" + id + "'");
-
-    var iter = this.lexer.next(),
-        token = iter.value;
-    if (iter.done)
-        token = {
-            id: this.eofToken,
-            value: "",
-            index: this.lexer.buffer.length
-        };
-
-    var symbol = this.symbolTable[iter.done ? this.eofToken : token.id];
-    if (!symbol)
-        panic(token.index, "unknown token " + token.id);
-
-    var newSymbol = Object.create(symbol);
-    newSymbol.value = token.value;
-    newSymbol.index = token.index;
-    return this.currentSymbol = newSymbol;
-}
-
-Parser.prototype.parse = function(rbp) {
-    var symbol = this.currentSymbol;
-    this.advance();
-    var left = symbol.nud(this);
-
-    rbp = rbp || 0;
-    while (rbp < this.currentSymbol.lbp) {
-        symbol = this.currentSymbol;
-        this.advance();
-        left = symbol.led(this, left);
-    }
-    return left;
-}
-
-Parser.prototype.parseString = function(string) {
-    this.lexer.feed(string);
-    this.advance();  // "kickstart" the lexer
-    return this.parse();
-}
-
-
-
-var BaseExpression = {
-    check: function(env) { panic("Wrong!"); },
-    eval: function(env) { panic("Do no know how to eval " + this); }
-};
-
-var DeferredEvalParserBuilder = function(eofToken) {
-    this.parser = new Parser(eofToken);
-}
-
-DeferredEvalParserBuilder.prototype.addSymbol = function(id, extra) {
-    this.parser.addSymbol(id, extra);
-    return this;
-}
-
-DeferredEvalParserBuilder.prototype.addInfix = function(id, lbp, func) {
-    this.parser.addInfix(id, lbp, function(symbol, left, right) {
-        var expr = Object.create(BaseExpression);
-        expr.first = left;
-        expr.second = right;
-        expr.eval = function(env) {
-            return func(this.first.eval(env), this.second.eval(env));
-        };
-        return expr;
-    });
-    return this;
-}
-
-DeferredEvalParserBuilder.prototype.addInfixR = function(id, lbp, func) {
-    this.parser.addInfixR(id, lbp, function(symbol, left, right) {
-        var expr = Object.create(BaseExpression);
-        expr.first = left;
-        expr.second = right;
-        expr.eval = function(env) {
-            return func(this.first.eval(env), this.second.eval(env));
-        };
-        return expr;
-    });
-    return this;
-}
-
-DeferredEvalParserBuilder.prototype.addPrefix = function(id, func) {
-    this.parser.addPrefix(id, function (symbol) {
-        var expr = Object.create(BaseExpression);
-        expr.val = symbol;
-        expr.eval = function(env) { return func(this.val.eval(env)); };
-        return expr;
-    });
-    return this;
-}
-
-
-var op = {
-    add: function(a, b) { return a + b; },
-    sub: function(a, b) { return a - b; },
-    mul: function(a, b) { return a * b; },
-    div: function(a, b) { return a / b; },
-    pow: function(a, b) { return Math.pow(a, b); },  // for completeness
-
-    neg: function(a) { return -a; },
-
-    lt: function(a, b) { return a < b; },
-    le: function(a, b) { return a <= b; },
-    gt: function(a, b) { return a > b; },
-    ge: function(a, b) { return a >= b; },
-    eq: function(a, b) { return a === b; },
-    neq: function(a, b) { return a !== b; },
-
-    not: function(a) { return !a; },
-    or: function(a, b) { return a || b; },
-    and: function(a, b) { return a && b; },
-};
-
-var parserBuilder = new DeferredEvalParserBuilder('(end)')
-    .addSymbol('(int)', {
-        pattern: '\\d+',
-        nud: function() {
-            var expr = Object.create(BaseExpression);
-            expr.val = parseInt(this.value);
-            expr.eval = function() { return this.val; };
-            return expr;
-        }
-    })
-    .addSymbol('(name)', {
-        pattern: '[a-zA-Z]\\w*',
-        nud: function(p) {
-            var expr = Object.create(BaseExpression);
-            expr.name = this.value;
-            expr.eval = function(env) { return env[this.name]; };
-            return expr;
-        }
-    })
-
-    .addInfix("+", 50,  op.add)
-    .addInfix("-", 50,  op.sub)
-    .addInfix("*", 60,  op.mul)
-    .addInfix("/", 60,  op.div)
-    .addInfixR("^", 70, op.pow)
-
-    .addPrefix("-", op.neg)
-
-    .addInfix("<=", 30, op.le)
-    .addInfix("<",  30, op.lt)
-    .addInfix(">=", 30, op.ge)
-    .addInfix(">",  30, op.gt)
-    .addInfix("!=", 30, op.neq)
-    .addInfix('=',  30, op.eq)
-
-    .addPrefix("!", op.not)
-    .addInfix('||', 30, op.or)
-    .addInfix('&&', 30, op.and)
-
-    .addSymbol(")")
-    .addSymbol("(", {
-        nud: function(p) {
-            var expr = p.parse(0);
-            p.advance(")");
-            return expr;
-        }
-    });
-
-window.parser = parserBuilder.parser;
-window.parseAndEvaluate = function(text, env) {
-    var expr = parser.parseString(text);
-    return expr.eval(env);
-}
-
diff --git a/src/js/raSelectorJS.tw b/src/js/raSelectorJS.tw
new file mode 100644
index 0000000000000000000000000000000000000000..b5590a99ea39a91444d61e7f9f66696b250cf442
--- /dev/null
+++ b/src/js/raSelectorJS.tw
@@ -0,0 +1,70 @@
+:: RA Selector JS [script]
+
+window.growAdvSelector = function(slave, rule) {
+
+	var ret = "";
+	var setd = 0;
+
+	if ((rule.breastSize == "small" && slave.boobs < 350) ||
+		(rule.breastSize == "c-cup" && slave.boobs < 550) ||
+		(rule.breastSize == "f-cup" && slave.boobs < 1100) ||
+		(rule.breastSize == "k-cup" && slave.boobs < 2150) ||
+		(rule.breastSize == "p-cup" && slave.boobs < 3700) ||
+		(rule.breastSize == "unlimited" && slave.boobs < 24000))	
+	{ 
+		slave.drugs = "breast injections"; 
+		ret = slave.slaveName + "'s boobs could be bigger, so she's been put on breast injections.";
+		return ret;
+	}
+	
+	if ((rule.buttSize == "small" && slave.butt < 1) ||
+		(rule.buttSize == "plump" && slave.butt < 3) ||
+		(rule.buttSize == "huge" && slave.butt < 4) ||
+		(rule.buttSize == "enormous" && slave.butt < 6) ||
+		(rule.buttSize == "unlimited" && slave.butt < 19))	
+	{ 
+		slave.drugs = "butt injections"; 
+		ret = slave.slaveName + "'s butt could be bigger, so she's been put on butt injections.";
+		return ret;
+	}
+
+	if ((rule.ballSize == "small" && slave.balls < 2) ||
+		(rule.ballSize == "big" && slave.balls < 4) ||
+		(rule.ballSize == "huge" && slave.balls < 6) ||
+		(rule.ballSize == "unlimited" && slave.balls < 9))	
+	{ 
+		slave.drugs = "testicle enhancement"; 
+		ret = slave.slaveName + "'s balls aren't large enough, so she's been put on testicle enhancement.";
+		return ret;
+	}
+
+	if ((rule.penisSize == "small" && slave.dick < 2) ||
+		(rule.penisSize == "big" && slave.dick < 4) ||
+		(rule.penisSize == "huge" && slave.dick < 6) ||
+		(rule.penisSize == "unlimited" && slave.dick < 12))	
+	{ 
+		slave.drugs = "penis enhancement"; 
+		ret = slave.slaveName + "'s dick aren't large enough, so she's been put on penis enhancement.";
+		return ret;
+	}
+
+	if ((rule.lipSize == "normal" && slave.lips < 15) ||
+		(rule.lipSize == "pretty" && slave.lips < 30) ||
+		(rule.lipSize == "plush" && slave.lips < 55) ||
+		(rule.lipSize == "huge" && slave.lips < 85) ||
+		(rule.lipSize == "facepussy" && slave.lips < 99))	
+	{ 
+		slave.drugs = "lip injections"; 
+		ret = slave.slaveName + "'s lips aren't large enough, so she's been put on lips enhancement.";
+		return ret;
+	}
+
+	if (slave.drugs != "no drugs")
+	{
+		slave.drugs = "no drugs";
+		ret = slave.slaveName + " has reached growth targets and has been taken off growth injections.";
+	}
+
+	return ret;
+
+}
\ No newline at end of file
diff --git a/src/js/rbuttonJS.tw b/src/js/rbuttonJS.tw
new file mode 100644
index 0000000000000000000000000000000000000000..e0ef1586c17d5dbc846ccc901e6e274d03f546cf
--- /dev/null
+++ b/src/js/rbuttonJS.tw
@@ -0,0 +1,108 @@
+:: rbuttonJS [script]
+/* This is modifed radiobutton macro, for automatic checked state setup*/
+/* Usage (be sure to use quotes around parameters): 
+
+	<<rbutton "$variable" "value">>	
+Or:
+	<<rbutton "$variable" "value" "HTML_element_ID" "Text to replace with, inside html element with ID from previous parameter. <br> HTML tags allowed.">> 
+
+Group of radiobutton will be created based on variable name. Checked state will be setted up if variable contain value matched with second parameter. Full form of macro call can be used to display extended description of selected value.
+*/
+
+Macro.add('rbutton', {
+	handler() {
+	    if (this.args.length < 2) {
+		const errors = [];
+		if (this.args.length < 1) { errors.push('variable name'); }
+		if (this.args.length < 2) { errors.push('checked value'); }
+		return this.error(`no ${errors.join(' or ')} specified`);
+	    }
+
+	    // Ensure that the variable name argument is a string.
+	    if (typeof this.args[0] !== 'string') {
+		return this.error('variable name argument is not a string');
+	    }
+
+	    const varName = this.args[0].trim();
+
+	    // Try to ensure that we receive the variable's name (incl. sigil), not its value.
+	    if (varName[0] !== '$' && varName[0] !== '_') {
+		return this.error(`variable name "${this.args[0]}" is missing its sigil ($ or _)`);
+	    }
+
+	    const initValue	 = Wikifier.getValue(this.args[0]);
+	    const varId      = Util.slugify(varName);
+	    const checkValue = this.args[1];
+	    const el         = document.createElement('input');
+
+	    var replaceID = "";
+	    var replaceText = "";
+	    if (typeof this.args[2] === 'string') {
+			replaceID = this.args[2];
+	    }
+	    if (typeof this.args[3] === 'string') {
+			replaceText = this.args[3];
+	    }
+
+		
+	    
+	    /*
+		Setup and initialize the group counter.
+	    */
+	    if (!TempState.hasOwnProperty(this.name)) {
+		TempState[this.name] = {};
+	    }
+
+	    if (!TempState[this.name].hasOwnProperty(varId)) {
+		TempState[this.name][varId] = 0;
+	    }
+
+	    /*
+		Setup and append the input element to the output buffer.
+	    */
+	    jQuery(el)
+		.attr({
+		    id       : `${this.name}-${varId}-${TempState[this.name][varId]++}`,
+		    name     : `${this.name}-${varId}`,
+		    type     : 'radio',
+		    tabindex : 0 // for accessiblity
+		})
+		.addClass(`macro-${this.name}`)
+		.on('change', function () {
+		    if (this.checked) {
+			Wikifier.setValue(varName, checkValue);
+
+			if (replaceID.length > 0 && replaceText.length > 0){
+
+				var replaceEl = document.getElementById(replaceID);
+				//alert (replaceEl);
+				if (replaceEl != null) {
+					replaceEl.innerHTML = replaceText;
+					}
+
+				}
+		    }
+		})
+		.ready (function () {
+			//alert ("DOM finished");
+			if (el.checked && replaceID.length > 0 && replaceText.length > 0){
+
+				var replaceEl = document.getElementById(replaceID);
+				//alert (replaceEl);
+				if (replaceEl != null) {
+					replaceEl.innerHTML = replaceText;
+				}
+
+			}
+		})
+		.appendTo(this.output);
+
+	    /*
+		Set the story variable to the checked value and the input element to checked, if requested.
+	    */
+	    if (initValue == checkValue) {
+		el.checked = true;
+		Wikifier.setValue(varName, checkValue);
+	    }
+	}
+    });
diff --git a/src/npc/exportSlave.tw b/src/npc/exportSlave.tw
index fc791eba7887fa0efb093783069fd8fcee673b97..bd8e80ac13a4252f22ebd243477ebde940e3a53d 100644
--- a/src/npc/exportSlave.tw
+++ b/src/npc/exportSlave.tw
@@ -9,3 +9,9 @@
 <<if (ndef $activeSlave.currentRules) || ($activeSlave.currentRules.length < 1)>><<set _currentRules = "[]">><<else>><<set _currentRules = "$activeSlave.currentRules">><</if>>
 
 slaveName: "$activeSlave.slaveName", slaveSurname: "$activeSlave.slaveName", birthName: "$activeSlave.birthName", birthSurname: "$activeSlave.birthSurname", genes: "$activeSlave.genes", weekAcquired: 1, origin: "$activeSlave.origin", career: "$activeSlave.career", ID: $activeSlave.ID, pornFame: $activeSlave.pornFame, pornFameSpending: $activeSlave.pornFameSpending, prestige: $activeSlave.prestige, prestigeDesc: "$activeSlave.prestigeDesc", recruiter: 0, relation: 0, relationTarget: 0, relationship: 0, relationshipTarget: 0, rivalry: 0, rivalryTarget: 0, subTarget: 0, choosesOwnAssignment: 0, assignment: "rest", assignmentVisible: 1, sentence: 0, training: 0, toyHole: "all her holes", indenture: -1, indentureRestrictions: 0, birthWeek: $activeSlave.birthWeek, age: $activeSlave.age, ageImplant: $activeSlave.ageImplant, health: $activeSlave.health, minorInjury: 0, trust: $activeSlave.trust, oldTrust: $activeSlave.trust, devotion: $activeSlave.devotion, oldDevotion: $activeSlave.devotion, weight: $activeSlave.weight, muscles: $activeSlave.muscles, height: $activeSlave.height, heightImplant: $activeSlave.heightImplant, nationality: "$activeSlave.nationality", race: "$activeSlave.race", markings: "none", eyes: 1, eyeColor: "$activeSlave.eyeColor", eyewear: "none", hColor: "$activeSlave.hColor", pubicHColor: "$activeSlave.pubicHColor", skin: "$activeSlave.skin", hLength: $activeSlave.hLength, hStyle: "$activeSlave.hStyle", pubicHStyle: "$activeSlave.pubicHStyle", waist: $activeSlave.waist, corsetPiercing: 0, amp: $activeSlave.amp, heels: $activeSlave.heels, voice: $activeSlave.voice, voiceImplant: $activeSlave.voiceImplant, accent: $activeSlave.accent, shoulders: $activeSlave.shoulders, shouldersImplant: $activeSlave.shouldersImplant, boobs: $activeSlave.boobs, boobsImplant: $activeSlave.boobsImplant, boobsImplantType: $activeSlave.boobsImplantType, boobShape: "normal", nipples: "$activeSlave.nipples",  nipplesPiercing: $activeSlave.nipplesPiercing, areolae: $activeSlave.areolae, areolaePiercing: $activeSlave.areolaePiercing, boobsTat: "$activeSlave.boobsTat", lactation: $activeSlave.lactation, lactationAdaptation: 0, milk: 0, cum: 0, hips: $activeSlave.hips, hipsImplant: $activeSlave.hipsImplant, butt: $activeSlave.butt, buttImplant: $activeSlave.buttImplant, buttImplantType: $activeSlave.buttImplantType, buttTat: "$activeSlave.buttTat", face: $activeSlave.face, faceImplant: $activeSlave.faceImplant, faceShape: "normal", lips: $activeSlave.lips, lipsImplant: $activeSlave.lipsImplant, lipsPiercing: $activeSlave.lipsPiercing, lipsTat: "$activeSlave.lipsTat", teeth: "$activeSlave.teeth", tonguePiercing: $activeSlave.tonguePiercing, vagina: $activeSlave.vagina, vaginaLube: $activeSlave.vaginaLube, vaginaPiercing: $activeSlave.vaginaPiercing, vaginaTat: "$activeSlave.vaginaTat", preg: $activeSlave.preg, pregSource: 0, pregType: 0, labor: 0, births: $activeSlave.births, cSec: 0, bellyAccessory: "none", labia: $activeSlave.labia, clit: $activeSlave.clit, clitPiercing: $activeSlave.clitPiercing, clitSetting: "$activeSlave.clitSetting", foreskin: 0, anus: $activeSlave.anus, dick: $activeSlave.dick, analArea: 1, dickPiercing: $activeSlave.dickPiercing, dickTat: "$activeSlave.dickTat", balls: $activeSlave.balls, scrotum: 0, ovaries: $activeSlave.ovaries, anusPiercing: $activeSlave.anusPiercing, anusTat: "$activeSlave.anusTat", makeup: $activeSlave.makeup, nails: $activeSlave.nails, brand: "$activeSlave.brand", brandLocation: "$activeSlave.brandLocation", earPiercing: $activeSlave.earPiercing, nosePiercing: $activeSlave.nosePiercing, eyebrowPiercing: $activeSlave.eyebrowPiercing, navelPiercing: $activeSlave.navelPiercing, shouldersTat: "$activeSlave.shouldersTat", armsTat: "$activeSlave.armsTat", legsTat: "$activeSlave.legsTat", backTat: "$activeSlave.backTat", stampTat: "$activeSlave.stampTat", vaginalSkill: $activeSlave.vaginalSkill, oralSkill: $activeSlave.oralSkill, analSkill: $activeSlave.analSkill, whoreSkill: $activeSlave.whoreSkill, entertainSkill: $activeSlave.entertainSkill, combatSkill: $activeSlave.combatSkill, livingRules: "$activeSlave.livingRules", speechRules: "$activeSlave.speechRules", releaseRules: "$activeSlave.releaseRules", relationshipRules: "$activeSlave.relationshipRules", standardPunishment: "situational", standardReward: "situational", useRulesAssistant: 1, diet: "$activeSlave.diet", dietCum: $activeSlave.dietCum, dietMilk: $activeSlave.dietMilk, tired: 0, hormones: 0, drugs: "$activeSlave.drugs", curatives: 0, chem: 0, aphrodisiacs: 0, addict: $activeSlave.addict, fuckdoll: $activeSlave.fuckdoll, choosesOwnClothes: 0, clothes: "$activeSlave.clothes", collar: "$activeSlave.collar", shoes: "$activeSlave.shoes", vaginalAccessory: "none", dickAccessory: "none", buttplug: "none", intelligence: $activeSlave.intelligence,  intelligenceImplant: $activeSlave.intelligenceImplant, energy: $activeSlave.energy, attrXX: $activeSlave.attrXX, attrXY: $activeSlave.attrXY, attrKnown: $activeSlave.attrKnown, fetish: "$activeSlave.fetish", fetishStrength: $activeSlave.fetishStrength, fetishKnown: $activeSlave.fetishKnown, behavioralFlaw: "$activeSlave.behavioralFlaw", behavioralQuirk: "none", sexualFlaw: "$activeSlave.sexualFlaw", sexualQuirk: "none", oralCount: 0, vaginalCount: 0, analCount: 0, mammaryCount: 0, penetrativeCount: 0, pitKills: 0, customTat: "$activeSlave.customTat", customLabel: "", customDesc: "$activeSlave.customDesc", customImage: 0, currentRules: _currentRules, actualAge: $activeSlave.actualAge, visualAge: $activeSlave.visualAge, physicalAge: $activeSlave.physicalAge, bellyTat: "$activeSlave.bellyTat", induce: 0, mpreg: $activeSlave.mpreg, inflation: 0, inflationType: "none", inflationMethod: 0, milkSource: 0, cumSource: 0, burst: 0, bellyImplant: $activeSlave.bellyImplant, bellySag: $activeSlave.bellySag, bellyPain: 0, cervixImplant: $activeSlave.cervixImplant, birthsTotal: $activeSlave.birthsTotal, pubertyXX: $activeSlave.pubertyXX, pubertyAgeXX: $activeSlave.pubertyAgeXX, pubertyXY: $activeSlave.pubertyXY, pubertyAgeXY: $activeSlave.pubertyAgeXY, scars: $activeSlave.scars, breedingMark: 0, underArmHStyle: "waxed", underArmHColor: "$activeSlave.underArmHColor", bodySwap: $activeSlave.bodySwap, father: 0, mother: 0, daughters: 0, sisters: 0, canRecruit: 0, HGExclude: 0, ballType: "$activeSlave.ballType", eggType: "$activeSlave.eggType", reservedChildren: 0, choosesOwnChastity: 0, pregControl: "none", readyLimbs: [], ageAdjust: $activeSlave.ageAdjust, bald: $activeSlave.bald, origBodyOwner: "", death: "", hormoneBalance: $activeSlave.hormoneBalance
+
+<br><br><br> __Direct JSON export method__: <br><br>
+
+
+<<set _jsonText = toJson($activeSlave)>>
+_jsonText
diff --git a/src/uncategorized/rulesAssistant.tw b/src/uncategorized/rulesAssistant.tw
index 4c434726399b4429de83bbac992541f892ae9dfa..8eafebd4a20b9d52afc258f5450b2339f142ac62 100644
--- a/src/uncategorized/rulesAssistant.tw
+++ b/src/uncategorized/rulesAssistant.tw
@@ -303,7 +303,7 @@ __Rule $r Automatic Activation__
 	<<timed 50ms>>
 	<<replace "#activation">>
 		(custom): <br>
-		//Sir, I'm afraid the condition you have given me is too complex to display in the usual interface.//
+		//Sir, I'm afraid the condition you have given me is too complex to display in the usual interface.//<br>
 		<<textinput "_customCondition" _customCondition>>
 			<<set _customConditionOld = _customCondition>>
 			<<RAChangeSave>>
@@ -1380,6 +1380,8 @@ Growth hormones for healthy slaves:
 	''as large as will allow a normal life.''
 <<elseif $currentRule.growth == "unlimited">>
 	''no limits.''
+<<elseif $currentRule.growth == "advSelect">>
+	''advanced selection for individual body parts.''
 <<else>>
 	''no default setting.''
 <</if>>
@@ -1420,6 +1422,16 @@ Growth hormones for healthy slaves:
 	<<RAChangeApply>>
 <</link>>
 |
+<<link "Advanced Selection">>
+	<<set $currentRule.growth = "advSelect">>
+	<<RAChangeGrowth>>
+	<<RAChangeSave>>
+	<<RAChangeApply>>
+	<<script>>
+	document.getElementById("bodySize").style.display = "inline";
+	<</script>>
+<</link>>
+|
 <<link "None">>
 	<<set $currentRule.growth = "none">>
 	<<RAChangeGrowth>>
@@ -1427,8 +1439,62 @@ Growth hormones for healthy slaves:
 	<<RAChangeApply>>
 <</link>>
 
+<br>
+<div id = "bodySize" style = "display:none">
+Please select desired body parts sizes (growth only) <br>
+Breasts: 
+No growth <<rbutton "$currentRule.breastSize" "none">> | 
+Girlish <<rbutton "$currentRule.breastSize" "small">> |
+C-cup <<rbutton "$currentRule.breastSize" "c-cup">> |
+F-cup <<rbutton "$currentRule.breastSize" "f-cup">> | 
+K-cup <<rbutton "$currentRule.breastSize" "k-cup">> | 
+P-cup <<rbutton "$currentRule.breastSize" "p-cup">> | 
+Unlimited <<rbutton "$currentRule.breastSize" "unlimited">>
+<br>
+
+Butt: 
+No growth <<rbutton "$currentRule.buttSize" "none">> | 
+Small <<rbutton "$currentRule.buttSize" "small">> |
+Plump <<rbutton "$currentRule.buttSize" "plump">> |
+Huge <<rbutton "$currentRule.buttSize" "huge">> | 
+Enormous <<rbutton "$currentRule.buttSize" "enormous">> | 
+Unlimited <<rbutton "$currentRule.buttSize" "unlimited">>
 <br>
 
+Lips: 
+No growth <<rbutton "$currentRule.lipSize" "none">> | 
+Normal <<rbutton "$currentRule.lipSize" "normal">> |
+Pretty <<rbutton "$currentRule.lipSize" "pretty">> |
+Plush <<rbutton "$currentRule.lipSize" "plush">> | 
+Huge <<rbutton "$currentRule.lipSize" "huge">> | 
+Facepussy <<rbutton "$currentRule.lipSize" "facepussy">>
+<br>
+
+Balls: 
+No growth <<rbutton "$currentRule.ballSize" "none">> | 
+Normal <<rbutton "$currentRule.ballSize" "small">> |
+Big <<rbutton "$currentRule.ballSize" "big">> |
+Huge <<rbutton "$currentRule.ballSize" "huge">> | 
+Unlimited <<rbutton "$currentRule.ballSize" "unlimited">>
+<br>
+
+Penis: 
+No growth <<rbutton "$currentRule.penisSize" "none">> | 
+Normal <<rbutton "$currentRule.penisSize" "small">> |
+Big <<rbutton "$currentRule.penisSize" "big">> |
+Huge <<rbutton "$currentRule.penisSize" "huge">> | 
+Unlimited <<rbutton "$currentRule.penisSize" "unlimited">>
+<br>
+
+
+</div>
+<<timed 40ms>>
+	<<if $currentRule.growth == "advSelect">>
+		<<script>>
+		document.getElementById("bodySize").style.display = "inline";
+		<</script>>
+	<</if>>
+<</timed>>
 Health drugs:
 
 <span id = "curatives">
diff --git a/src/utility/raWidgets.tw b/src/utility/raWidgets.tw
index 52a603f78c5666946d73d2e52fe2894245951e95..23d291a53626a2bd0d48542279dea5e43b72a10e 100644
--- a/src/utility/raWidgets.tw
+++ b/src/utility/raWidgets.tw
@@ -2021,12 +2021,17 @@ Growth hormones for healthy slaves:
 	''as large as will allow a normal life.''
 <<elseif $currentRule.growth == "unlimited">>
 	''no limits.''
+<<elseif $currentRule.growth == "advSelect">>
+	''advanced selection for individual body parts.''
 <<elseif $currentRule.growth == "none">>
 	''none.''
 <<else>>
 	''no default setting.''
 <</if>>
 <</replace>>
+<<script>>
+	document.getElementById("bodySize").style.display = "none";
+<</script>>
 <</widget>>
 
 /%
@@ -3840,6 +3845,8 @@ check if a rule attribute, any one, is defined and otherwise skip everything.
 		<<set $args[0].drugs = "no drugs">>
 		<br>$args[0].slaveName has reached growth targets and has been taken off growth injections.
 	<</if>>
+<<elseif (_combinedRule.growth == "advSelect")>>
+	<br><<print growAdvSelector($args[0], _combinedRule)>>
 <<else>>
 	<<if ($args[0].hips > -1) && ($args[0].butt < 6) && ($args[0].butt < ($args[0].boobs/500))>>
 		<<set $args[0].drugs = "butt injections">>