code:
:: Research Lab [nobr]

<<switch $temp>>

<<case 0>>

	<<set $nextButton to "Back", $nextLink to "Manage Arcology">>

	//You switch one of the screens in your office to the feed from research facility.//

[[Decomission facility|Manage Arcology][$researchLab.built to "false",$researchLab.hired to 0,$helots += $researchLab.menials,$researchLab.menials to 0,$researchLab.research to "none",$researchLab.manufacture to "none",$researchLab.productionTime to 0]] //Warning! This will cancel all projects, remove all staff and shut down this facility.//

[[Purchase cybernetics|Research Lab][$temp to 1]]

	__Personnel__

	<<if $researchLab.aiModule == 1>>
		[[Buy and install research module|Research Lab][$cash -= 35000, $researchLab.aiModule to 2]] //This module enables your assistant to assist staff and direct menials assigned to your research facility, increasing efficiency. It costs ¤35000//

	<</if>>
	<<if ($researchLab.hired + $researchLab.menials) == 0>>
		//Facility is currently unstaffed.//
	<<else>>
		//You have
		<<if $researchLab.hired == 1>>
			one scientist
		<<elseif $researchLab.hired > 1>>
			$researchLab.hired scientists
		<</if>>
		<<if $researchLab.menials != 0>> and<</if>>
		<<if $researchLab.menials == 0>>
		<<elseif $researchLab.menials == 1>>
			one menial slave
		<<elseif $researchLab.menials > 1>>
			$researchLab.menials menials
		<</if>>
		working in your lab.
		<<if $researchLab.aiModule != 0>>Occasionally you hear voice of your assistant as it helps direct and organize work.<</if>>//
	<</if>>

	 Currently, this facility can employ $researchLab.maxSpace people.
	<<if $researchLab.maxSpace == 5>>
		[[Expand facility|Research Lab][$cash -= Math.trunc(5000*$upgradeMultiplierArcology), $researchLab.maxSpace to 10]]
		//Costs ¤<<print Math.trunc(5000*$upgradeMultiplierArcology)>>//
	<<elseif $researchLab.maxSpace == 10>>
		[[Expand facility|Research Lab][$cash -= Math.trunc(5000*$upgradeMultiplierArcology), $researchLab.maxSpace to 20]]
		//Costs ¤<<print Math.trunc(10000*$upgradeMultiplierArcology)>>//
	<<elseif $researchLab.maxSpace == 20>>
		[[Expand facility|Research Lab][$cash -= Math.trunc(5000*$upgradeMultiplierArcology), $researchLab.maxSpace to 30]]
		//Costs ¤<<print Math.trunc(15000*$upgradeMultiplierArcology)>>//
	<<elseif $researchLab.maxSpace == 30>>
		[[Expand facility|Research Lab][$cash -= Math.trunc(5000*$upgradeMultiplierArcology), $researchLab.maxSpace to 40]]
		//Costs ¤<<print Math.trunc(20000*$upgradeMultiplierArcology)>>//
	<<elseif $researchLab.maxSpace == 40>>
		[[Expand facility|Research Lab][$cash -= Math.trunc(5000*$upgradeMultiplierArcology), $researchLab.maxSpace to 50]]
		//Costs ¤<<print Math.trunc(25000*$upgradeMultiplierArcology)>>//
	<<elseif $researchLab.maxSpace == 50>>
		//Facility is fully expanded.//
	<</if>>

	<<if ($researchLab.hired + $researchLab.menials) < $researchLab.maxSpace>>
		Hire [[x1|Research Lab][$researchLab.hired += 1,$cash -= 5000]]
		<<if ($researchLab.maxSpace - ($researchLab.hired + $researchLab.menials)) >= 5>>
			| [[x5|Research Lab][$researchLab.hired += 5,$cash -= 25000]]
		<</if>>
		<<if ($researchLab.maxSpace - ($researchLab.hired + $researchLab.menials)) >= 10>>
			| [[x10|Research Lab][$researchLab.hired += 10,$cash -= 50000]]
		<</if>>
		scientists.

		    //Each scientist will require an initial fee of ¤5000 and incur ¤300 weekly.//

		 <<if $helots > 0>>
			Assign [[x1|Research Lab][$researchLab.menials += 1,$helots -= 1]]
			<<if ($researchLab.maxSpace - ($researchLab.menials + $researchLab.menials)) >= 5 && $helots >= 5>>
				| [[x5|Research Lab][$researchLab.menials += 5,$helots -= 5]]
			<</if>>
			<<if ($researchLab.maxSpace - ($researchLab.menials + $researchLab.menials)) >= 10 && $helots >= 10>>
				| [[x10|Research Lab][$researchLab.menials += 10,$helots -= 10]]
			<</if>>
			  menial slaves to lab.

		<<else>>You do not own any <<if $researchLab.menials != 0>>unassigned <</if>>menial slaves.

		<</if>>
		   //Using menial slaves is much cheaper than hiring scientists, but they are less effective. ¤100 per slave each week.//

	<<else>>
		   //Facility is fully staffed.//
	<</if>>

	<<if $researchLab.hired > 0>>
		Fire [[x1|Research Lab][$researchLab.hired -= 1]]
		<<if $researchLab.hired >= 5>>
			| [[x5|Research Lab][$researchLab.hired -= 5]]
		<</if>>
		<<if $researchLab.hired >= 10>>
			| [[x10|Research Lab][$researchLab.hired -= 10]]
		<</if>>
		| [[All|Research Lab][$researchLab.hired to 0]]
		scientists.
	<</if>>
	<<if $researchLab.menials > 0>>

		Dismiss [[x1|Research Lab][$researchLab.menials -= 1,$helots += 1]]
		<<if $researchLab.menials >= 5>>
			| [[x5|Research Lab][$researchLab.menials -= 5,$helots += 5]]
		<</if>>
		<<if $researchLab.menials >= 10>>
			| [[x10|Research Lab][$researchLab.menials -= 10,$helots += 10]]
		<</if>>
		| [[All|Research Lab][$helots += $researchLab.menials,$researchLab.menials to 0]]
		menial slaves.
	<</if>>

	__Research__

	<<if $researchLab.research != "none">>
		//Your lab staff is currently researching @@color:yellow;$researchLab.research@@.//
	<<elseif $researchLab.manufacture != "none">>
		//Your lab staff is currently busy with other projects.//
	<<else>>
		//No research active.//

		<<if $researchLab.basicPLimbInterface == 0 && $stockpile.basicPLimbInterface > 0>>

			[[Reverse engineer basic prosthetics interface|Research Lab][$researchLab.productionTime to 80,$researchLab.research to "Basic prosthetics interface"]]
		<</if>>
		<<if $researchLab.basicPLimbInterface != 0 && $researchLab.advPLimbInterface == 0 && $stockpile.advPLimbInterface > 0>>

			[[Reverse engineer advanced prosthetics interface|Research Lab][$researchLab.productionTime to 120,$researchLab.research to "Advanced prosthetics interface"]]
		<</if>>
		<<if $researchLab.basicPLimb == 0 && $stockpile.basicPLimb > 0>>

			[[Reverse engineer basic prosthetic limbs|Research Lab][$researchLab.productionTime to 80,$researchLab.research to "Basic prosthetic limbs"]]
		<</if>>
		<<if $researchLab.advSexPLimb == 0 && $stockpile.advSexPLimb > 0>>

			[[Reverse engineer advanced sex limbs|Research Lab][$stockpile.advSexPLimb -= 1,$researchLab.productionTime to 100,$researchLab.research to "Advanced sex limbs"]]
		<</if>>
		<<if $researchLab.advGracePLimb == 0 && $stockpile.advGracePLimb > 0>>

			[[Reverse engineer advanced beauty limbs|Research Lab][$stockpile.advGracePLimb -= 1,$researchLab.productionTime to 100,$researchLab.research to "Advanced beauty limbs"]]
		<</if>>
		<<if $researchLab.advCombatPLimb == 0 && $stockpile.advCombatPLimb > 0>>

			[[Reverse engineer advanced combat limbs|Research Lab][$stockpile.advCombatPLimb -= 1,$researchLab.productionTime to 100,$researchLab.research to "Advanced combat limbs"]]
		<</if>>
		<<if $researchLab.cyberneticPLimb == 0 && $researchLab.advPLimbInterface == 1 && ($researchLab.advGracePLimb + $researchLab.advGracePLimb + $researchLab.advCombatPLimb) >= 1>>

			[[Develop cybernetic limbs|Research Lab][$researchLab.productionTime to 300,$researchLab.research to "Cybernetic limbs"]]
		<</if>>
		<<if $researchLab.ocularImplant == 0 && $stockpile.ocularImplant > 0>>

			[[Reverse engineer ocular implants|Research Lab][$stockpile.ocularImplant -= 1,$researchLab.productionTime to 100,$researchLab.research to "Ocular implants"]]
		<</if>>
		<<if $researchLab.erectileImplant == 0 && $stockpile.erectileImplant > 0>>

			[[Reverse engineer erectile implant|Research Lab][$stockpile.erectileImplant -= 1,$researchLab.productionTime to 100,$researchLab.research to "Erectile implant"]]
		<</if>>
	<</if>>

	__Manufacture__

	<<if $researchLab.research != "none">>
		//Your lab staff is currently busy with research.//
	<<elseif $researchLab.manufacture != "none">>
		//Your lab staff is currently building @@color:yellow;$researchLab.manufacture@@.//
	<<else>>
		//No projects currently active.//

		<<if $researchLab.basicPLimbInterface == 1>>

			[[Build basic prosthetics interface|Research Lab][$researchLab.productionTime to 50,$researchLab.manufacture to "Basic prosthetics interface"]]
		<</if>>
		<<if $researchLab.advPLimbInterface == 1>>

			[[Build advanced prosthetics interface|Research Lab][$researchLab.productionTime to 80,$researchLab.manufacture to "Advanced prosthetics interface"]]
		<</if>>
		<<if $researchLab.basicPLimb == 1>>

			[[Build basic prosthetic limbs|Research Lab][$researchLab.productionTime to 20,$researchLab.manufacture to "Basic prosthetic limbs"]]
		<</if>>
		<<if $researchLab.advSexPLimb == 1>>

			[[Build advanced sex limbs|Research Lab][$researchLab.productionTime to 100,$researchLab.manufacture to "Advanced sex limbs"]]
		<</if>>
		<<if $researchLab.advGracePLimb == 1>>

			[[Build advanced beauty limbs|Research Lab][$researchLab.productionTime to 100,$researchLab.manufacture to "Advanced beauty limbs"]]
		<</if>>
		<<if $researchLab.advCombatPLimb == 1>>

			[[Build advanced combat limbs|Research Lab][$researchLab.productionTime to 100,$researchLab.manufacture to "Advanced combat limbs"]]
		<</if>>
		<<if $researchLab.cyberneticPLimb == 1>>

			[[Build cybernetic limbs|Research Lab][$researchLab.productionTime to 150,$researchLab.manufacture to "Cybernetic limbs"]]
		<</if>>
		<<if $researchLab.ocularImplant == 1>>

			[[Build ocular implants|Research Lab][$researchLab.productionTime to 80,$researchLab.manufacture to "Ocular implants"]]
		<</if>>
		<<if $researchLab.erectileImplant == 1>>

			[[Build Erectile implant|Research Lab][$researchLab.productionTime to 50,$researchLab.manufacture to "Erectile implant"]]
		<</if>>
	<</if>>

<<case 1>>
	<<set $temp to 0>>
	<<set $nextLink to "Research Lab">>
	//You contact representative of one of the larger cybernetics companies and inquired about their products.
 This is what they have to offer://

	__Hardware__

	[[Basic prosthetics interface|Research Lab][$temp to 1, $cash -= 25000, $stockpile.basicPLimbInterface += 1]] //Costs ¤25000. Currently have: $stockpile.basicPLimbInterface//

	[[Advanced prosthetics interface|Research Lab][$temp to 1, $cash -= 60000, $stockpile.advPLimbInterface += 1]] //Costs ¤60000. Currently have: $stockpile.advPLimbInterface//

	[[Basic prosthetic limbs|Research Lab][$temp to 1, $cash -= 15000, $stockpile.basicPLimb += 1]] //Costs ¤15000. Currently have: $stockpile.basicPLimb//

	[[Advanced sex limbs|Research Lab][$temp to 1, $cash -= 30000, $stockpile.advSexPLimb += 1]] //Costs ¤30000. Currently have: $stockpile.advSexPLimb//

	[[Advanced beauty limbs|Research Lab][$temp to 1, $cash -= 30000, $stockpile.advGracePLimb += 1]] //Costs ¤30000. Currently have: $stockpile.advGracePLimb//

	[[Advanced combat limbs|Research Lab][$temp to 1, $cash -= 30000, $stockpile.advCombatPLimb += 1]] //Costs ¤30000. Currently have: $stockpile.advCombatPLimb//

	[[Ocular implants|Research Lab][$temp to 1, $cash -= 35000, $stockpile.ocularImplant += 1]] //Costs ¤35000. Currently have: $stockpile.ocularImplant//

	/*[[Erectile implant|Research Lab][$temp to 1, $cash -= 25000, $stockpile.erectileImplant += 1]] //Costs ¤25000. Currently have: $stockpile.erectileImplant//*/

__Schematics__

	<<if $researchLab.basicPLimbInterface != 1 && $researchLab.research != "Basic prosthetics interface">>
		[[Basic prosthetics interface|Research Lab][$temp to 1, $cash -= 85000, $researchLab.basicPLimbInterface to 1]] //Costs ¤85000.//

	<</if>>
	<<if $researchLab.advPLimbInterface != 1 && $researchLab.research != "Advanced prosthetics interface">>
	[[Advanced prosthetics interface|Research Lab][$temp to 1, $cash -= 260000, $researchLab.advPLimbInterface to 1]] //Costs ¤260000.//

	<</if>>
	<<if $researchLab.basicPLimb != 1 && $researchLab.research != "Basic prosthetic limbs">>
	[[Basic prosthetic limbs|Research Lab][$temp to 1, $cash -= 60000, $researchLab.basicPLimb to 1]] //Costs ¤60000.//

	<</if>>
	<<if $researchLab.advSexPLimb != 1 && $researchLab.research != "Advanced sex limbs">>
	[[Advanced sex limbs|Research Lab][$temp to 1, $cash -= 120000, $researchLab.advSexPLimb to 1]] //Costs ¤30000.//

	<</if>>
	<<if $researchLab.advGracePLimb != 1 && $researchLab.research != "Advanced beauty limbs">>
	[[Advanced beauty limbs|Research Lab][$temp to 1, $cash -= 120000, $researchLab.advGracePLimb to 1]] //Costs ¤30000.//

	<</if>>
	<<if $researchLab.advCombatPLimb != 1 && $researchLab.research != "Advanced combat limbs">>
	[[Advanced combat limbs|Research Lab][$temp to 1, $cash -= 120000, $researchLab.advCombatPLimb to 1]] //Costs ¤30000.//

	<</if>>
	<<if $researchLab.ocularImplant != 1 && $researchLab.research != "Ocular implants">>
	[[Ocular implants|Research Lab][$temp to 1, $cash -= 160000, $researchLab.ocularImplant to 1]] //Costs ¤35000.//

	<</if>>
	/*<<if $researchLab.erectileImplant != 1 && $researchLab.research != "Erectile implant">>
	[[Erectile implant|Research Lab][$temp to 1, $cash -= 95000, $researchLab.erectileImplant to 1]] //Costs ¤95000.//
	<</if>>*/

<</switch>>


code:
:: accordionJS.tw [script]
/* Accordion 000-250-006 */

/*
 * We're making changes to the DOM, so we need to make them *after* everything has been generated
 * Sticking this all in postdisplay calls reduces the chance of there being a timing conflict
 *   with other scripts, since anything poking the DOM here will be done last
 *
 * Dev Note: The accordion mod should be able to turn *anything* into an accordion. This iteration
 *   is configured tightly for the end of week report runs, but it shouldn't be that hard to adapt for
 *   other uses, like character bios. For now, I'll see what other extra-long passages of cosmetic text
 *   might benefit.
 *
 * 000-250-006 03092017
*/

postdisplay["doAccordionSet"] = function (content) {
    if (variables().useAccordion == 1) {
        Array.prototype.slice.call(document.querySelectorAll('.macro-include'))
        .forEach(function(element) {
            element.classList.add('accHidden');
        });
    }
}

postdisplay["doAccordion"] = function (content) {
    var acc = document.getElementsByClassName("accordion");
    var i;

    for (i = 0; i < acc.length; i += 1) {
        acc[i].onclick = function () {
            this.classList.toggle("active");
            var panel = this.nextElementSibling;
            if (panel.style.maxHeight) {
                panel.style.maxHeight = null;
            } else {
                panel.style.maxHeight = panel.scrollHeight + "px";
            }
        };
    }
};

repo_name: deswes/fc


code:
:: 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);
}


code:
:: EconomyJS [script]

window.LivingRule = Object.freeze({LUXURIOUS: 'luxurious', NORMAL: 'normal', SPARSE: 'sparse'});
window.Job = Object.freeze({
	DAIRY: 'work in the dairy', MASTER_SUITE: 'serve in the master suite', CONCUBINE: 'be your concubine',
	BABY_FACTORY: 'labor in the production line', BROTHEL: 'work in the brothel'});

window.getSlaveCost = function(s) {
	if(!s) { return 0; }
	// Data duplicated from Cost Report
	var cost = 0;
	var rulesCost = State.variables.rulesCost;
	var foodCost = State.variables.foodCost;
	var drugsCost = State.variables.drugsCost;

	// Living expenses
	if(s.livingRules === LivingRule.LUXURIOUS) {
		cost += rulesCost * (s.relationship >= 4 ? 3 : 4);
	} else if(s.livingRules == LivingRule.NORMAL) {
		cost += rulesCost * 2;
	} else {
		cost += rulesCost;
	}

	// Food
	cost += foodCost * 4;
	switch(s.diet) {
		case 'fattening': case 'muscle building':
			cost += foodCost;
			break;
		case 'restricted': case 'slimming':
			cost -= foodCost;
	}
	if(s.weight > 50) {
		cost += foodCost;
	} else if(s.weight < -50) {
		cost -= foodCost;
	}
	if(s.drugs === 'appetite suppressors') {
		cost -= foodCost;
	}
	if(s.lactation > 0) {
		cost += foodCost * (1 + s.lactation * (1 + Math.trunc(s.boobs/10000)));
	}
	if(s.preg > 5) {
		if(s.assignment === Job.DAIRY && State.variables.dairyFeedersSetting > 0) {
			// Extra feeding costs to support pregnancy are covered by dairy feeders.
			// TODO: Include them here anyway?
		} else if((s.assignment === Job.MASTER_SUITE || s.assignment === Job.CONCUBINE)
			&& State.variables.masterSuiteUpgradePregnancy === 1) {
			// Extra feeding costs to support pregnancy are covered by master suite luxuries.
			// TODO: Include them here anyway?
		} else {
			cost += foodCost * s.pregType * (s.pregControl === 'speed up' ? 3 : 1);
		}
	}
	if(s.diet === 'XX' || s.diet === 'XY') {
		cost += 25;
	} else if(s.diet === 'XXY') {
		cost += 75;
	}

	// Accessibility costs
	if(State.variables.boobAccessibility !== 1 && s.boobs > 7500
		&& (s.assignment != Job.DAIRY || State.variables.dairyRestraintsSetting < 2)) {
		cost += 50;
	}
	if(State.variables.pregAccessibility !== 1
		&& ((s.preg > 30 && s.pregType >= 2) || (s.preg > 20 && s.pregType >= 10) || (s.preg > 10 && s.pregType >= 20) || s.bellyImplant >= 10000)
		&& s.assignment != Job.BABY_FACTORY) {
		cost += 100;
	}
	if(State.variables.dickAccessibility != 1 && s.dick > 45) {
		cost += 50;
	}
	if(State.variables.ballsAccessibility != 1 && s.balls > 90) {
		cost += 50;
	}
	if(State.variables.buttAccessibility != 1 && s.butt > 15) {
		cost += 50;
	}
	if(!canSee(s)) {
		cost += 50;
	} else if(s.eyes <= -1) {
		cost += 25;
	} else if(s.eyewear === 'blurring glasses' || s.eyewear === 'blurring contacts') {
		cost += 25;
	}
	if(s.amp !== 0) {
		if(s.amp === 1) {
			cost += rulesCost;
		} else {
			cost += rulesCost / 2;
		}
	} else if(!canWalk(s)) {
		cost += rulesCost;
	}

	// Maintenance
	if(s.boobs > 10000 && s.boobsImplantType === 1) {
		cost += 50;
	}
	if(s.butt > 10 && s.buttImplantType === 1) {
		cost += 50;
	}
	if(s.preg > 25 && s.universalRulesBirthing === 1) {
		cost += 50;
	}

	// Retirement account
	if(State.variables.CitizenRetirement === 1) {
		cost += 250;
	}

	// Enemas
	if(s.inflation === 3) {
		switch(s.inflationType) {
		case "water":
			cost += 100;
			break;
		case "curative":
		case "aphrodisiac":
		case "tightener":
			cost += (100 + (drugsCost * 2));
			break;
		}
	} else if(s.inflation === 2) {
		switch(s.inflationType) {
		case "water":
			cost += 50;
			break;
		case "curative":
		case "aphrodisiac":
		case "tightener":
			cost += (50 + (drugsCost * 2));
			break;
		}
	} else if(s.inflation === 1) {
		switch(s.inflationType) {
		case "water":
			cost += 25;
			break;
		case "curative":
		case "aphrodisiac":
		case "tightener":
			cost += (25 + (drugsCost * 2));
			break;
		}
	}

	// Drugs
	if(s.drugs === 'anti-aging cream') {
		cost += drugsCost * 10;
	} else if(s.drugs === 'female hormone injections' || s.drugs === 'male hormone injections') {
		cost += drugsCost * 5;
	} else if(s.drugs != 'no drugs') {
		cost += drugsCost + 2;
	}
	if(s.curatives > 0) {
		cost += drugsCost * (1 + s.curatives);
	}
	if(s.aphrodisiacs > 0) {
		cost += drugsCost * s.aphrodisiacs;
	}
	if(s.hormones !== 0) {
		cost += Math.trunc(drugsCost * Math.abs(s.hormones) * 0.5);
	}
	if(s.preg === -1 && isFertile(s)) {
		cost += Math.trunc(drugsCost * 0.5);
	}

	// Promotion costs
	if(State.variables.studio === 1) {
		if(s.pornFameSpending > 0) {
			cost += s.pornFameSpending;
		}
	}

	if(isNaN(cost)) {
		throw new Error('Cost calculation for slave ' + s.slaveName + ' (' + s.ID + ') failed.');
	}
	return cost;
};

window.getSlaveStatisticData = function(s, facility) {
	if(!s || !facility) {
		// Base data, even without facility
		return {
			ID: s.ID, slaveName: s.slaveName, customLabel: s.customLabel,
			income: 0, adsIncome: 0, rep: 0, cost: getSlaveCost(s),
			customers: 0 /* brothel, club, ... */
		};
	}

	if(!facility.income) {
		facility.income = new Map();
	}

	if(facility.income.has(s.ID)) {
		return facility.income.get(s.ID);
	} else {
		var data = {
			ID: s.ID, slaveName: s.slaveName, customLabel: s.customLabel,
			income: 0, adsIncome: 0, rep: 0, cost: getSlaveCost(s),
			customers: 0 /* brothel, club, ... */
		};
		facility.income.set(s.ID, data);
		return data;
	}
};

window.initFacilityStatistics = function(facility) {
	facility = facility || {};
	facility.adsIncome = 0;
	facility.maintenance = 0;
	facility.totalIncome = 0;
	facility.totalExpenses = 0;
	facility.profit = 0;
	facility.income = new Map();
	return facility;
}

Number.prototype.toFixedHTML = function() {
	return Number.prototype.toFixed.apply(this, arguments).replace(/\.0+$/, '$&');
}


code:
:: StoryJS [script]

/*config.history.tracking = false;*/
window.variableAsNumber = function(x, defaultValue, minValue, maxValue) {
	x = Number(x)
	if (x != x) {//NaN
		return defaultValue || 0;//In case the default value was not supplied.
	}
	if (x < minValue) {//Works even if minValue is undefined.
		return minValue;
	}
	if (x > maxValue) {//Works even if maxValue is undefined.
		return maxValue;
	}
	return x;
};
window.isSexuallyPure = function(slave) {
	if (!slave) {
		return null;
	}
	if (slave.vagina < 1 && slave.anus < 1 && !slave.analCount && !slave.vaginalCount && !slave.oralCount) {
		return true;
	} else {
		return false;
	}
};
if (typeof interpolate == "undefined") {
	var interpolate = function(x0,y0,x1,y1,x) {
		if(x <= x0) {
			return y0;
		} else if(x >= x1) {
			return y1;
		} else {
			return (x - x0) * ((y1 - y0) / (x1 - x0)) + y0;
		}
	};
	window.interpolate = interpolate;
}
config.history.maxStates = 1;

config.saves.autosave = "autosave";
window.isFullyPotent = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.dick > 0 && slave.balls > 0 && slave.hormones <= 0) {
		return true;
	} else {
		return false;
	}
};

/* mousetrap v1.5.3 craig.is/killing/mice */
(function(C,r,g){function t(a,b,h){a.addEventListener?a.addEventListener(b,h,!1):a.attachEvent("on"+b,h)}function x(a){if("keypress"==a.type){var b=String.fromCharCode(a.which);a.shiftKey||(b=b.toLowerCase());return b}return l[a.which]?l[a.which]:p[a.which]?p[a.which]:String.fromCharCode(a.which).toLowerCase()}function D(a){var b=[];a.shiftKey&&b.push("shift");a.altKey&&b.push("alt");a.ctrlKey&&b.push("ctrl");a.metaKey&&b.push("meta");return b}function u(a){return"shift"==a||"ctrl"==a||"alt"==a||
"meta"==a}function y(a,b){var h,c,e,g=[];h=a;"+"===h?h=["+"]:(h=h.replace(/\+{2}/g,"+plus"),h=h.split("+"));for(e=0;e<h.length;++e)c=h[e],z[c]&&(c=z[c]),b&&"keypress"!=b&&A[c]&&(c=A[c],g.push("shift")),u(c)&&g.push(c);h=c;e=b;if(!e){if(!k){k={};for(var m in l)95<m&&112>m||l.hasOwnProperty(m)&&(k[l[m]]=m)}e=k[h]?"keydown":"keypress"}"keypress"==e&&g.length&&(e="keydown");return{key:c,modifiers:g,action:e}}function B(a,b){return null===a||a===r?!1:a===b?!0:B(a.parentNode,b)}function c(a){function b(a){a=
a||{};var b=!1,n;for(n in q)a[n]?b=!0:q[n]=0;b||(v=!1)}function h(a,b,n,f,c,h){var g,e,l=[],m=n.type;if(!d._callbacks[a])return[];"keyup"==m&&u(a)&&(b=[a]);for(g=0;g<d._callbacks[a].length;++g)if(e=d._callbacks[a][g],(f||!e.seq||q[e.seq]==e.level)&&m==e.action){var k;(k="keypress"==m&&!n.metaKey&&!n.ctrlKey)||(k=e.modifiers,k=b.sort().join(",")===k.sort().join(","));k&&(k=f&&e.seq==f&&e.level==h,(!f&&e.combo==c||k)&&d._callbacks[a].splice(g,1),l.push(e))}return l}function g(a,b,n,f){d.stopCallback(b,
b.target||b.srcElement,n,f)||!1!==a(b,n)||(b.preventDefault?b.preventDefault():b.returnValue=!1,b.stopPropagation?b.stopPropagation():b.cancelBubble=!0)}function e(a){"number"!==typeof a.which&&(a.which=a.keyCode);var b=x(a);b&&("keyup"==a.type&&w===b?w=!1:d.handleKey(b,D(a),a))}function l(a,c,n,f){function e(c){return function(){v=c;++q[a];clearTimeout(k);k=setTimeout(b,1E3)}}function h(c){g(n,c,a);"keyup"!==f&&(w=x(c));setTimeout(b,10)}for(var d=q[a]=0;d<c.length;++d){var p=d+1===c.length?h:e(f||
y(c[d+1]).action);m(c[d],p,f,a,d)}}function m(a,b,c,f,e){d._directMap[a+":"+c]=b;a=a.replace(/\s+/g," ");var g=a.split(" ");1<g.length?l(a,g,b,c):(c=y(a,c),d._callbacks[c.key]=d._callbacks[c.key]||[],h(c.key,c.modifiers,{type:c.action},f,a,e),d._callbacks[c.key][f?"unshift":"push"]({callback:b,modifiers:c.modifiers,action:c.action,seq:f,level:e,combo:a}))}var d=this;a=a||r;if(!(d instanceof c))return new c(a);d.target=a;d._callbacks={};d._directMap={};var q={},k,w=!1,p=!1,v=!1;d._handleKey=function(a,
c,e){var f=h(a,c,e),d;c={};var k=0,l=!1;for(d=0;d<f.length;++d)f[d].seq&&(k=Math.max(k,f[d].level));for(d=0;d<f.length;++d)f[d].seq?f[d].level==k&&(l=!0,c[f[d].seq]=1,g(f[d].callback,e,f[d].combo,f[d].seq)):l||g(f[d].callback,e,f[d].combo);f="keypress"==e.type&&p;e.type!=v||u(a)||f||b(c);p=l&&"keydown"==e.type};d._bindMultiple=function(a,b,c){for(var d=0;d<a.length;++d)m(a[d],b,c)};t(a,"keypress",e);t(a,"keydown",e);t(a,"keyup",e)}var l={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",
20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"ins",46:"del",91:"meta",93:"meta",224:"meta"},p={106:"*",107:"+",109:"-",110:".",111:"/",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},A={"~":"`","!":"1","@":"2","#":"3",$:"4","%":"5","^":"6","&":"7","*":"8","(":"9",")":"0",_:"-","+":"=",":":";",'"':"'","<":",",">":".","?":"/","|":"\\"},z={option:"alt",command:"meta","return":"enter",
escape:"esc",plus:"+",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?"meta":"ctrl"},k;for(g=1;20>g;++g)l[111+g]="f"+g;for(g=0;9>=g;++g)l[g+96]=g;c.prototype.bind=function(a,b,c){a=a instanceof Array?a:[a];this._bindMultiple.call(this,a,b,c);return this};c.prototype.unbind=function(a,b){return this.bind.call(this,a,function(){},b)};c.prototype.trigger=function(a,b){if(this._directMap[a+":"+b])this._directMap[a+":"+b]({},a);return this};c.prototype.reset=function(){this._callbacks={};this._directMap=
{};return this};c.prototype.stopCallback=function(a,b){return-1<(" "+b.className+" ").indexOf(" mousetrap ")||B(b,this.target)?!1:"INPUT"==b.tagName||"SELECT"==b.tagName||"TEXTAREA"==b.tagName||b.isContentEditable};c.prototype.handleKey=function(){return this._handleKey.apply(this,arguments)};c.init=function(){var a=c(r),b;for(b in a)"_"!==b.charAt(0)&&(c[b]=function(b){return function(){return a[b].apply(a,arguments)}}(b))};c.init();C.Mousetrap=c;"undefined"!==typeof module&&module.exports&&(module.exports=
c);"function"===typeof define&&define.amd&&define(function(){return c})})(window,document);

Mousetrap.bind("enter", function () {
	$("#story-caption #endWeekButton a.macro-link").trigger("click");
});
Mousetrap.bind("space", function () {
	$("#story-caption #nextButton a.macro-link").trigger("click");
});
Mousetrap.bind("c", function () {
	$("#story-caption #manageArcology a.macro-link").trigger("click");
});
Mousetrap.bind("p", function () {
	$("#story-caption #managePenthouse a.macro-link").trigger("click");
});
Mousetrap.bind("left", function () {
	$("#prevSlave a.macro-link").trigger("click");
	$("#prevRule a.macro-link").trigger("click");
});
Mousetrap.bind("q", function () {
	$("#prevSlave a.macro-link").trigger("click");
	$("#prevRule a.macro-link").trigger("click");
});
Mousetrap.bind("shift+left", function () {
	$("#firstRule a.macro-link").trigger("click");
});
Mousetrap.bind("shift+q", function () {
	$("#firstRule a.macro-link").trigger("click");
});
Mousetrap.bind("right", function () {
	$("#nextSlave a.macro-link").trigger("click");
	$("#nextRule a.macro-link").trigger("click");
});
Mousetrap.bind("shift+right", function () {
	$("#lastRule a.macro-link").trigger("click");
});
Mousetrap.bind("e", function () {
	$("#nextSlave a.macro-link").trigger("click");
	$("#nextRule a.macro-link").trigger("click");
});
Mousetrap.bind("shift+e", function () {
	$("#lastRule a.macro-link").trigger("click");
});
Mousetrap.bind("f", function () {
	$("#walkpast a.macro-link").trigger("click");
});
Mousetrap.bind("h", function () {
	$("#manageHG a.macro-link").trigger("click");
});
Mousetrap.bind("s", function () {
	$("#buySlaves a.macro-link").trigger("click");
});
Mousetrap.bind("a", function () {
	$("#managePA a.macro-link").trigger("click");
});
Mousetrap.bind("b", function () {
	$("#manageBG a.macro-link").trigger("click");
});
Mousetrap.bind("r", function () {
	$("#manageRecruiter a.macro-link").trigger("click");
});
Mousetrap.bind("o", function () {
	$("#story-caption #optionsButton a.macro-link").trigger("click");
});
Mousetrap.bind("y", function () {
	$("#story-caption #policyButton a.macro-link").trigger("click");
});
Mousetrap.bind("f", function () {
	$("#story-caption #FSButton a.macro-link").trigger("click");
});
Mousetrap.bind("l", function () {
	$("#story-caption #LanguageButton a.macro-link").trigger("click");
});
Mousetrap.bind("t", function () {
	$("#story-caption #PAOButton a.macro-link").trigger("click");
});
Mousetrap.bind("u", function () {
	$("#story-caption #URButton a.macro-link").trigger("click");
});
Mousetrap.bind("w", function () {
	$("#story-caption #WARButton a.macro-link").trigger("click");
});

/**
 * BoobGenerator namespace.
 */
if (typeof BoobGenerator == "undefined") {
	var BoobGenerator = {
		rollBreast: function (modif) {
			var volume = [0, 300, 500, 650, 800, 1000, 1200, 1400, 1600, 1800, 2050, 2300, 2600, 2900, 3250, 3600, 3950, 4300, 4700, 5100, 5500, 5900];
			var volume_dist = [90000, 470000, 720000, 840000, 908574, 947759, 970151, 982946, 990258, 994436, 996824, 998188, 998968, 999414, 999669, 999814, 999897, 999945, 999972, 999987, 999995, 1000000];
			var randomRoll = Math.floor(Math.random() * 1000000) + 1
			var actualSize = 0
			while (randomRoll > volume_dist[actualSize]) {
				actualSize = actualSize + 1
			}
			var minorSizeAdjustment = 0
			if (Math.random()<.5) {
				minorSizeAdjustment = (Math.floor(Math.random() * 2) + 1) * 50
			}
			var volResult = volume[actualSize] + minorSizeAdjustment + modif
			if (volResult < 0) {volResult = 0}
			return volResult
		}
	};
	// Raise namespace scope to Global.
	window.BoobGenerator = BoobGenerator;
};

/**
 * Slave checker namespace.
 */
if (typeof SlaveStatsChecker == "undefined") {
	var SlaveStatsChecker = {
		checkForLisp: function (slave) {
				/* Begin mod section: toggle whether slaves lisp. */
				if (SugarCube.State.variables.disableLisping == 1) {
					return false;
				}
				/* End mod section: toggle whether slaves lisp. */
				return ((slave.lips > 70) || (slave.lipsPiercing + slave.tonguePiercing > 2))
			}
	};
	// Raise namespace scope to Global.
	window.SlaveStatsChecker = SlaveStatsChecker;
};

if (typeof FertilityAge == "undefined") {
	var FertilityAge = {
		setAge: function (age) {
			age = Number(age)
				if (age != age) {
					return 13;
				} else {
				return age
			}
		}
	};
	// Raise namespace scope to Global.
	window.FertilityAge = FertilityAge;
};

window.canGetPregnant = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.pubertyXX == 0){
		return false;
	} else if (slave.physicalAge >= 47) {
		return false;
	} else if (slave.inflation != 0) {
		return false;
	} else if (slave.bellyImplant != 0) {
		return false;
	} else if (slave.preg != 0) {
		return false;
	} else if ((slave.mpreg == 1) && (canDoAnal(slave) == true)) {
		return true;
	} else if (slave.ovaries != 1) {
		return false;
	} else if (canDoVaginal(slave) == false) {
		return false;
	} else {
		return true;
	}
};

window.isFertile = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.pubertyXX == 0) {
		return false;
	} else if (slave.physicalAge >= 47) {
		return false;
	} else if (slave.inflation != 0) {
		return false;
	} else if (slave.bellyImplant != 0) {
		return false;
	} else if (slave.preg > 0) {
		return false;
	} else if (slave.preg < -1) {
		return false;
	} else if (slave.mpreg == 1) {
		return true;
	} else if (slave.ovaries != 1) {
		return false;
	} else {
		return true;
	}
};

window.canBreed = function(slave1, slave2) {
	if (slave1.eggType == slave2.ballType) {
		return true;
	} else {
		return false;
	}
};

//hyperpreg size 2
window.hyperBellyTwo = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 30 && slave.pregType >= 20) {
		return true;
	} else if (slave.bellyImplant >= 32000) {
		return true;
	} else {
		return false;
	}
};

window.hyperPregBellyTwo = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 30 && slave.pregType >= 20) {
		return true;
	} else {
		return false;
	}
};

//hyperpreg size 1
window.hyperBellyOne = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 20 && slave.pregType >= 20) {
		return true;
	} else if (slave.preg > 30 && slave.pregType >= 10) {
		return true;
	} else if (slave.bellyImplant >= 16000) {
		return true;
	} else {
		return false;
	}
};

window.hyperPregBellyOne = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 20 && slave.pregType >= 20) {
		return true;
	} else if (slave.preg > 30 && slave.pregType >= 10) {
		return true;
	} else {
		return false;
	}
};

//full term belly
window.hugeBelly = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 0 && slave.pregType >= 20) {
		return true;
	} else if (slave.preg > 10 && slave.pregType >= 10) {
		return true;
	} else if (slave.preg > 30) {
		return true;
	} else if (slave.inflation >= 3) {
		return true;
	} else if (slave.bellyImplant >= 8000) {
		return true;
	} else {
		return false;
	}
};

window.hugeBellyPreg = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 0 && slave.pregType >= 20) {
		return true;
	} else if (slave.preg > 10 && slave.pregType >= 10) {
		return true;
	} else if (slave.preg > 30) {
		return true;
	} else {
		return false;
	}
};

//is the slave's belly big enough to get in the way
window.bigBellyPreg = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.preg > 0 && slave.pregType >= 20) {
		return true;
	} else if (slave.preg > 10 && slave.pregType >= 10) {
		return true;
	} else if (slave.preg > 20) {
		return true;
	} else {
		return false;
	}
};

window.bigBelly = function(slave) {
	if (!slave) {
		return null;
	} else if (bigBellyPreg(slave) == true) {
		return true;
	} else if (slave.inflation > 2) {
		return true;
	} else if (slave.bellyImplant > 8000) {
		return true;
	} else {
		return false;
	}
};

window.canAchieveErection = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.dick < 7 && slave.dick > 0 && (slave.balls > 0 ? slave.hormones <= 0 : slave.hormones < 0)) {
		return true;
	} else {
		return false;
	}
};

window.canPenetrate = function(slave) {
	if (!slave) {
		return null;
	} else if (canAchieveErection(slave) == false) {
		return false;
	} else if (slave.dickAccessory == "chastity") {
		return false;
	} else if (slave.dickAccessory == "combined chastity") {
		return false;
	} else if (slave.dick > 7) {
		return false;
	}
	return true;
};

window.canSee = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.eyes > -2) {
		return true;
	} else {
		return false;
	}
};

window.canWalk = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.amp == 1)  {
		return false;
	} else if (slave.boobs > 9000+(slave.muscles*100) && slave.physicalAge >= 18) {
		return false;
	} else if (slave.boobs > 5000+(slave.muscles*10) && slave.physicalAge <= 3) {
		return false;
	} else if (slave.boobs > 7000+(slave.muscles*20) && slave.physicalAge <= 12) {
		return false;
	} else if (slave.boobs > 9000+(slave.muscles*50) && slave.physicalAge < 18) {
		return false;
	} else if (slave.dick >= 15+(slave.muscles*.2) && slave.physicalAge <= 3) {
		return false;
	} else if (slave.dick >= 30+(slave.muscles*.3) && slave.physicalAge <= 12) {
		return false;
	} else if (slave.dick >= 68+(slave.muscles*.4)) {
		return false;
	} else if (slave.balls >= 30+(slave.muscles*.3) && slave.physicalAge <= 3) {
		return false;
	} else if (slave.balls >= 60+(slave.muscles*.5) && slave.physicalAge <= 12) {
		return false;
	} else if (slave.balls >= 90+(slave.muscles*.7)) {
		return false;
	} else if (slave.butt > 10 && slave.physicalAge <= 3) {
		return false;
	} else if (slave.butt > 14 && slave.physicalAge <= 12) {
		return false;
	} else if (slave.preg > 20 && slave.physicalAge >= 13 && slave.pregType >= 20 && slave.height < 150) {
		return false;
	} else if (slave.preg > 30 && slave.physicalAge >= 13 && slave.pregType >= 20 && (!slave.height >= 185 || !slave.muscles > 1)) {
		return false;
	} else if (slave.preg > 20 && slave.physicalAge <= 3 && slave.pregType >= 10) {
		return false;
	} else if (slave.preg > 20 && slave.physicalAge <= 12 && slave.pregType >= 20) {
		return false;
	} else if (slave.bellyImplant > 31000+(slave.muscles*100) && slave.physicalAge >= 18) {
		return false;
	} else if (slave.bellyImplant > 31000+(slave.muscles*80) && slave.physicalAge >= 13) {
		return false;
	} else if (slave.bellyImplant > 12000+(slave.muscles*50) && slave.physicalAge <= 3) {
		return false;
	} else if (slave.bellyImplant > 16000+(slave.muscles*20) && slave.physicalAge <= 12) {
		return false;
	} else if (slave.heels == 0) {
		return true;
	} else if (slave.shoes == "heels") {
		return true;
	} else if (slave.shoes == "extreme heels") {
		return true;
	} else if (slave.shoes == "boots") {
		return true;
	} else {
		return false;
	}
};

window.canTalk = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.accent > 2)  {
		return false;
	} else if (slave.voice == 0) {
		return false;
	} else if (slave.lips > 95) {
		return false;
	} else {
		return true;
	}
};

window.canDoAnal = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.vaginalAccessory == "anal chastity") {
		return false;
	} else if (slave.dickAccessory == "anal chastity") {
		return false;
	} else if (slave.vaginalAccessory == "combined chastity") {
		return false;
	} else if (slave.dickAccessory == "combined chastity") {
		return false;
	}
	return true;
};

window.canDoVaginal = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.vagina < 0) {
		return false;
	} else if (slave.vaginalAccessory == "chastity belt") {
		return false;
	} else if (slave.vaginalAccessory == "combined chastity") {
		return false;
	}
	return true;
};

window.tooBigBreasts = function(slave){
	if (!slave) {
		return null;
	} else if (slave.boobs > 9000+(slave.muscles*100) && slave.physicalAge >= 18) {
		return true;
	} else if (slave.boobs > 5000+(slave.muscles*10) && slave.physicalAge <= 3) {
		return true;
	} else if (slave.boobs > 7000+(slave.muscles*20) && slave.physicalAge <= 12) {
		return true;
	} else if (slave.boobs > 9000+(slave.muscles*50) && slave.physicalAge < 18) {
		return true;
	} else {
		return false;
	}
};

window.tooBigBelly = function(slave){
	if (!slave) {
		return null;
	} else if (slave.preg > 20 && slave.physicalAge >= 18 && slave.pregType >= 20 && slave.height < 150) {
		return true;
	} else if (slave.preg > 30 && slave.physicalAge >= 18 && slave.pregType >= 20 && (!slave.height >= 185 || !slave.muscles > 1)) {
		return true;
	} else if (slave.preg > 20 && slave.physicalAge <= 3 && slave.pregType >= 10) {
		return true;
	} else if (slave.preg > 20 && slave.physicalAge <= 12 && slave.pregType >= 20) {
		return true;
	} else if (slave.bellyImplant > 31000+(slave.muscles*100) && slave.physicalAge >= 18) {
		return true;
	} else if (slave.bellyImplant > 31000+(slave.muscles*80) && slave.physicalAge >= 13) {
		return true;
	} else if (slave.bellyImplant > 12000+(slave.muscles*20) && slave.physicalAge <= 3) {
		return true;
	} else if (slave.bellyImplant > 16000+(slave.muscles*50) && slave.physicalAge <= 12) {
		return true;
	} else {
		return false;
	}
};

window.tooBigBalls = function(slave){
	if (!slave) {
		return null;
	} else if (slave.balls >= 30+(slave.muscles*.3) && slave.physicalAge <= 3) {
		return true;
	} else if (slave.balls >= 60+(slave.muscles*.5) && slave.physicalAge <= 12) {
		return true;
	} else if (slave.balls >= 90+(slave.muscles*.7)) {
		return true;
	} else {
		return false;
	}
};

window.tooBigDick = function(slave){
	if (!slave) {
		return null;
	} else if (slave.dick >= 15+(slave.muscles*.2) && slave.physicalAge <= 3) {
		return true;
	} else if (slave.dick >= 30+(slave.muscles*.3) && slave.physicalAge <= 12) {
		return true;
	} else if (slave.dick >= 68+(slave.muscles*.4)) {
		return true;
	} else {
		return false;
	}
};

window.tooBigButt = function(slave){
	if (!slave) {
		return null;
	} else if (slave.butt > 10 && slave.physicalAge <= 3) {
		return true;
	} else if (slave.butt > 14 && slave.physicalAge <= 12) {
		return true;
	} else {
		return false;
	}
};

/*
window.sameTParent = function(slave1, slave2) {
	if ((slave1.mother == slave2.father || slave1.father == slave2.mother) && (slave1.mother != 0 && slave1.mother != -2 && slave1.father != 0 && slave1.father != -2)) {
		return true; //testtest catches the case if a mother is a father or a father a mother
	} else {
		return false;
	}
};
*/

// testtest catches the case if a mother is a father or a father a mother
window.sameTParent = function(slave1, slave2) {
	if (slave1.mother == slave2.father && slave1.father == slave2.mother && slave1.mother != 0 && slave1.mother != -2 && slave1.father != 0 && slave1.father != -2 && slave1.mother != slave1.father) {
		return 2;
	} else if ((slave1.mother == slave2.father || slave1.father == slave2.mother) && slave1.mother != 0 && slave1.mother != -2 && slave2.mother != 0 && slave2.mother != -2 && slave1.mother != slave1.father) {
		return 3;
	} else {
		return 0;
	}
};

window.sameDad = function(slave1, slave2){
	if ((slave1.father == slave2.father) && (slave1.father != 0 && slave1.father != -2)) {
		return true;
	} else {
		return false;
	}
};

window.sameMom = function(slave1, slave2){
	if ((slave1.mother == slave2.mother) && (slave1.mother != 0 && slave1.mother != -2)) {
		return true;
	} else {
		return false;
	}
};

window.areTwins = function(slave1, slave2) {
	if (sameDad(slave1, slave2) == false) {
		return false;
	} else if (sameMom(slave1, slave2) == false) {
		return false;
	} else if (slave1.actualAge == slave2.actualAge && slave1.birthWeek == slave2.birthWeek) {
		return true;
	} else {
		return false;
	}
};

/*
//3 = half-sisters, 2 = sisters, 1 = twins, 0 = not related
window.areSisters = function(c1, c2) {
	if(c1.ID == c2.ID) {
		return 0;
	}
	var sib = 4;
	if(sameMom(c1, c2)) {
		sib -= 1;
	}
	if(sameDad(c1, c2)) {
	   sib -=1;
	}
	if (sib == 2 && c1.actualAge == c2.actualAge && c1.birthWeek == c2.birthWeek) {
		sib -= 1;
	}
	if(sib == 4) {
		return 0
	} else {
		return sib;
	}
}
*/

window.areSisters = function(slave1, slave2) {
	if (slave1.ID == slave2.ID) {
		return 0; //you are not your own sister
	} else if ((slave1.father != 0 && slave1.father != -2) || (slave1.mother != 0 && slave1.mother != -2)) {
		if (sameDad(slave1, slave2) == false && sameMom(slave1, slave2) == true) {
			return 3; //half sisters
		} else if (sameDad(slave1, slave2) == true && sameMom(slave1, slave2) == false) {
			return 3; //half sisters
		} else if (sameTParent(slave1, slave2) == 3) {
			return 3; //half sisters
		} else if (sameTParent(slave1, slave2) == 2) {
			return 2; //sisters
		} else if (sameDad(slave1, slave2) == true && sameMom(slave1, slave2) == true) {
			if (slave1.actualAge == slave2.actualAge && slave1.birthWeek == slave2.birthWeek) {
				return 1; //twins
			} else {
				return 2; //sisters
			}
		} else {
			return 0; //not related
		}
	} else {
		return 0; //not related
	}
};

window.totalRelatives = function(slave) {
	var relatives = 0;
	if (slave.mother > 0) {
		relatives += 1
	}
	if (slave.father > 0) {
		relatives += 1
	}
	if (slave.daughters > 0) {
		relatives += slave.daughters
	}
	if (slave.sisters > 0) {
		relatives += slave.sisters
	}
	return relatives
};

window.mutualChildren = function(slave1, slave2, slaves) {
	return slaves.filter(function(s) { return s.ID != slave1.ID && s.ID != slave2.ID && ((s.mother == slave1.ID && s.father == slave2.ID) || (s.mother == slave2.ID && s.father == slave1.ID)); }).length;
}

if (typeof DairyRestraintsSetting == "undefined") {
	var DairyRestraintsSetting = {
		setSetting: function (setting) {
			setting = Number(setting)
			return setting
		}
	};
	// Raise namespace scope to Global.
	window.DairyRestraintsSetting = DairyRestraintsSetting;
};

window.isSlaveAvailable = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.assignment == "be your agent") {
		return false;
	} else if (slave.assignment == "live with your agent") {
		return false;
	} else if (slave.assignment == "work in the dairy" && DairyRestraintsSetting >= 2) {
		return false;
	} else {
		return true;
	}
};

window.relationTargetWord = function(slave) {
	if (!slave) {
		return null;
	} else if (slave.relation == "daughter") {
		return "mother";
	} else if (slave.relation == "mother") {
		return "daughter";
	}
	return slave.relation;
};

window.ruleApplied = function(slave, ID) {
	if (!slave) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	} else {
		for(var d=0; d < slave.currentRules.length; ++d){
			if(slave.currentRules[d] == ID){
				return true;
			}
		}return false;
	}
};

window.ruleAssignment = function(applyAssignment, assignment) {
	for(var d=0; d < applyAssignment.length; ++d){
		if(applyAssignment[d] == assignment){

			return true;
		}
	}return false;
};

window.ruleFacility = function(applyFacility, facility) {
	for(var d=0; d < applyFacility.length; ++d){
		if(applyFacility[d] == facility){
			return true;
		}
	}return false;
};

window.ruleExcludeSlaveFacility = function(rule, slave) {
	if (!slave) {
		return null;
	}else if (!rule) {
		return null;
	}else if (!rule.excludeFacility) {
		return false;
	} else {
		for(var d=0; d < rule.excludeFacility.length; ++d){
			if(rule.excludeFacility[d] == "hgsuite"){
				if(slave.assignment == "live with your Head Girl" ){
					return true;
				}
				else if(slave.assignment == "be your Head Girl"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "arcade"){
				if (slave.assignment == "be confined in the arcade" ){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "mastersuite"){
				if(slave.assignment == "serve in the master suite" ){
					return true;
				}
				else if(slave.assignment == "be your Concubine"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "clinic"){
				if(slave.assignment == "get treatment in the clinic" ){
					return true;
				}
				else if(slave.assignment == "be the Nurse"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "spa"){
				if(slave.assignment == "rest in the spa" ){
					return true;
				}
				else if(slave.assignment == "be the Attendant"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "brothel"){
				if(slave.assignment == "work in the brothel" ){
					return true;
				}
				else if(slave.assignment == "be the Madam"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "club"){
				if(slave.assignment == "serve in the club" ){
					return true;
				}
				else if(slave.assignment == "be the DJ"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "dairy"){
				if (slave.assignment == "work in the dairy"){
					return true;
				}
				else if(slave.assignment == "be the Milkmaid"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "servantsquarters"){
				if(slave.assignment == "work as a servant"){
					return true;
				}
				else if(slave.assignment == "be the Stewardess"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "schoolroom"){
				if(slave.assignment == "learn in the schoolroom" ){
					return true;
				}
				else if(slave.assignment == "be the Schoolteacher"){
					return true;
				}
			}
			else if(rule.excludeFacility[d] == "cellblock"){
				if(slave.assignment == "be confined in the cellblock" ){
					return true;
				}
				else if(slave.assignment == "be the Wardeness"){
					return true;
				}
			}
		}
	}
};

window.ruleAppliedToSlaveFacility = function(rule, slave) {
	if (!slave) {
		return null;
	}else if (!rule) {
		return null;
	}else if (!rule.facility) {
		return false;
	} else {
		for(var d=0; d < rule.facility.length; ++d){
			if(rule.facility[d] == "hgsuite"){
				if(slave.assignment == "live with your Head Girl" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be your Head Girl")){
					return true;
				}
			}
			else if(rule.facility[d] == "arcade"){
				if(slave.assignment == "be confined in the arcade" ){
					return true;
				}
			}
			else if(rule.facility[d] == "mastersuite"){
				if(slave.assignment == "serve in the master suite" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be your Concubine")){
					return true;
				}
			}
			else if(rule.facility[d] == "clinic"){
				if(slave.assignment == "get treatment in the clinic" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Nurse")){
					return true;
				}
			}
			else if(rule.facility[d] == "spa"){
				if(slave.assignment == "rest in the spa" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Attendant")){
					return true;
				}
			}
			else if(rule.facility[d] == "brothel"){
				if(slave.assignment == "work in the brothel" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Madam")){
					return true;
				}
			}
			else if(rule.facility[d] == "club"){
				if(slave.assignment == "serve in the club" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the DJ")){
					return true;
				}
			}
			else if(rule.facility[d] == "dairy"){
				if (slave.assignment == "work in the dairy"){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Milkmaid")){
					return true;
				}
			}
			else if(rule.facility[d] == "servantsquarters"){
				if(slave.assignment == "work as a servant" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Stewardess")){
					return true;
				}
			}
			else if(rule.facility[d] == "schoolroom"){
				if(slave.assignment == "learn in the schoolroom" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Schoolteacher")){
					return true;
				}
			}
			else if(rule.facility[d] == "cellblock"){
				if(slave.assignment == "be confined in the cellblock" ){
					return true;
				}
				else if((rule.excludeSpecialSlaves != true) && (slave.assignment == "be the Wardeness")){
					return true;
				}
			}
		}return false;
	}
};

window.ruleSlaveSelected = function(slave, rule) {
	if (!slave) {
		return null;
	}else if (!rule) {
		return null;
	}else if (!rule.selectedSlaves) {
		return false;
	} else {
		for(var d=0; d < rule.selectedSlaves.length; ++d){
			if(slave.ID == rule.selectedSlaves[d]){
				return true;
			}
		}return false;
	}
};

window.ruleSlaveExcluded = function(slave, rule) {
	if (!slave) {
		return null;
	}else if (!rule) {
		return null;
	}else if (!rule.excludedSlaves) {
		return false;
	} else {
		for(var d=0; d < rule.excludedSlaves.length; ++d){
			if(slave.ID == rule.excludedSlaves[d]){
				return true;
			}
		}return false;
	}
};
window.hasSurgeryRule = function(slave, rules) {
	if (!slave) {
		return false;
	}else if (!rules) {
		return false;
	}else if (!slave.currentRules) {
		return false;
	}else {
		for(var d=rules.length-1; d >= 0; --d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].autoSurgery > 0){
						return true;
					}
				}
			}
		}return false;
	}
};

window.lastPregRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return false;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].preg == -1){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.hasHColorRule = function(slave, rules) {
	if (!slave) {
		return false;
	}else if (!rules) {
		return false;
	}else if (!slave.currentRules) {
		return false;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].hColor != "no default setting"){
						return true;
					}
				}
			}
		}return false;
	}
};

window.hasHStyleRule = function(slave, rules) {
	if (!slave) {
		return false;
	}else if (!rules) {
		return false;
	}else if (!slave.currentRules) {
		return false;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].hStyle != "no default setting"){
						return true;
					}
				}
			}
		}return false;
	}
};

window.hasEyeColorRule = function(slave, rules) {
	if (!slave) {
		return false;
	}else if (!rules) {
		return false;
	}else if (!slave.currentRules) {
		return false;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].hStyle != "no default setting"){
						return true;
					}
				}
			}
		}return false;
	}
};

window.lastEyeWearRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].eyewear != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastEyeColorRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].eyeColor != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastMakeupRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].makeup != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastNailsRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].nails != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastHColorRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].hColor != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastHStyleRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].hStyle != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastHLengthRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].hLength != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastPubicHColorRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].pubicHColor != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastPubicHStyleRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].pubicHStyle != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastUnderArmHColorRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].underArmHColor != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastUnderArmHStyleRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].underArmHStyle != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastNipplesPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].nipplesPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastAreolaePiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].areolaePiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastClitPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].clitPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastClitSettingRule = function(slave, rules) {
    if (!slave) {
        return null;
    }else if (!rules) {
        return null;
    }else if (!slave.currentRules) {
        return null;
    }else {
        for(var d=rules.length-1; d >= 0;--d){
            for(var e=0; e < slave.currentRules.length;++e){
                if(slave.currentRules[e] == rules[d].ID){
                    if (rules[d].clitSetting != "no default setting"){
                        return rules[d];
                    }
                }
            }
        }return null;
    }
};
window.lastClitSettingXYRule = function(slave, rules) {
    if (!slave) {
        return null;
    }else if (!rules) {
        return null;
    }else if (!slave.currentRules) {
        return null;
    }else {
        for(var d=rules.length-1; d >= 0;--d){
            for(var e=0; e < slave.currentRules.length;++e){
                if(slave.currentRules[e] == rules[d].ID){
                    if (rules[d].clitSettingXY != "no default setting"){
                        return rules[d];
                    }
                }
            }
        }return null;
    }
};
window.lastClitSettingXXRule = function(slave, rules) {
    if (!slave) {
        return null;
    }else if (!rules) {
        return null;
    }else if (!slave.currentRules) {
        return null;
    }else {
        for(var d=rules.length-1; d >= 0;--d){
            for(var e=0; e < slave.currentRules.length;++e){
                if(slave.currentRules[e] == rules[d].ID){
                    if (rules[d].clitSettingXX != "no default setting"){
                        return rules[d];
                    }
                }
            }
        }return null;
    }
};
window.lastClitSettingEnergyRule = function(slave, rules) {
    if (!slave) {
        return null;
    }else if (!rules) {
        return null;
    }else if (!slave.currentRules) {
        return null;
    }else {
        for(var d=rules.length-1; d >= 0;--d){
            for(var e=0; e < slave.currentRules.length;++e){
                if(slave.currentRules[e] == rules[d].ID){
                    if (rules[d].clitSettingEnergy != "no default setting"){
                        return rules[d];
                    }
                }
            }
        }return null;
    }
};
window.lastVaginaPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].vaginaPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastDickPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].dickPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastAnusPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].anusPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastLipsPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].lipsPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastTonguePiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].tonguePiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastEarPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].earPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastEyebrowPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].earPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastNosePiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].nosePiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastNavelPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].navelPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastCorsetPiercingRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].corsetPiercing != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastBoobsTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].boobsTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastButtTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].buttTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastVaginaTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].vaginaTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastDickTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].dickTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastAnusTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].anusTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastLipsTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].lipsTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastShouldersTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].shouldersTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastArmsTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].armsTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastLegsTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].legsTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastStampTatRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].stampTat != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.lastLactationSurgeryRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			if (!rules[d].surgery) {
				return null;
			}
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].surgery.lactation != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastLipSurgeryRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			if (!rules[d].surgery) {
				return null;
			}
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].surgery.lips != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastBoobSurgeryRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			if (!rules[d].surgery) {
				return null;
			}
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].surgery.boobs != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};
window.lastButtSurgeryRule = function(slave, rules) {
	if (!slave) {
		return null;
	}else if (!rules) {
		return null;
	}else if (!slave.currentRules) {
		return null;
	}else {
		for(var d=rules.length-1; d >= 0;--d){
			if (!rules[d].surgery) {
				return null;
			}
			for(var e=0; e < slave.currentRules.length;++e){
				if(slave.currentRules[e] == rules[d].ID){
					if (rules[d].surgery.butt != "no default setting"){
						return rules[d];
					}
				}
			}
		}return null;
	}
};

window.checkThresholds = function(number, rule) {
	if (!rule) {
		return null;
	} else {
		if ((rule.thresholdUpper != "none") && (rule.thresholdLower != "none")){
			if (!rule.eqLower && !rule.eqUpper){
				if((number < rule.thresholdUpper) && (number > rule.thresholdLower)){
					return true;
				}
			}
			else if (rule.eqLower && !rule.eqUpper){
				if((number < rule.thresholdUpper) && (number >= rule.thresholdLower)){
					return true;
				}
			}
			else if (!rule.eqLower && rule.eqUpper){
				if((number <= rule.thresholdUpper) && (number > rule.thresholdLower)){
					return true;
				}
			}
			else {
				if((number <= rule.thresholdUpper) && (number >= rule.thresholdLower)){
					return true;
				}
			}
		}
		else if (rule.thresholdUpper != "none"){
			if (!rule.eqUpper) {
				if(number < rule.thresholdUpper){
					return true;
				}
			}
			else{
				if(number <= rule.thresholdUpper){
					return true;
				}
			}
		}
		else if (rule.thresholdLower != "none"){
			if (!rule.eqLower) {
				if(number > rule.thresholdLower){
					return true;
				}
			}
			else{
				if(number >= rule.thresholdLower){
					return true;
				}
			}
		}return false;
	}
};

window.removeFromArray = function(arr, val) {
	for (var i = 0; i < arr.length; i++)
		if (val == arr[i])
			return arr.splice(i,1);
	return null;
};

window.milkAmount = function(slave) {
	var milk;
	var calcs;
	if (!slave) {
		return null;
	} else {
		calcs = slave.boobs-slave.boobsImplant
		if (calcs > 20000) {
			milk = (118+((calcs-20000)/400))
		} else if (calcs > 10000) {
			milk = (78+((calcs-10000)/300))
		} else if (calcs > 5000) {
			milk = (53+((calcs-5000)/200))
		} else if (calcs > 2000) {
			milk = (29+((calcs-2000)/125))
		} else if (calcs > 800) {
			milk = (16+((calcs-800)/80))
		} else {
			milk = (8+((calcs-400)/50))
		}
		if (slave.lactation == 2) {
			milk *= 1.2
		}
		milk += (milk*((slave.devotion-50)/200))
		if (slave.boobsImplant > 200) {
			milk *= 0.9
		}
		calcs = slave.hormones
		if (slave.balls != 0 && calcs > -2) {
			calcs -= 1
		} else if (slave.ovaries != 1 && calcs < 2) {
			calcs += 1
		}
		milk *= (1+(calcs*0.1))
		milk *= (1+(slave.preg/100))
		milk *= (1+(slave.health/50))
		milk *= (1+(slave.weight/500))
		milk *= (1+(slave.lactationAdaptation/500))
		milk = Math.trunc(milk)
		milk = Math.clamp(milk,1,1000000000000000000)
		return milk
	}
};

window.cumAmount = function(slave) {
	var cum = 0;
	var calcs = 0;
	if (!slave) {
		return null;
	} else {
		if (slave.drugs == "testicle enhancement") {
			cum = ((slave.balls*3.5)+1)
		} else if (slave.drugs == "hyper testicle enhancement") {
			cum = ((slave.balls*5)+1)
		} else {
			cum = ((slave.balls*2.5)+1)
		}
		if (slave.prostateImplant == 1) {
			cum *= 1.2
		}
		if (slave.diet == "cum production") {
			cum *= 1.2
		}
		calcs = slave.hormones
		cum *= (1-(calcs*0.1))
		if (slave.scrotum == 0) {
			cum *= 0.8
		}
		if (slave.devotion > 50) {
			cum += (cum*(slave.devotion/100))
		} else if (slave.devotion < -50) {
			cum += (cum*(slave.devotion/100))
		}
		if (slave.health > 50) {
			cum += (cum*(slave.health/50))
		} else if (slave.health < -50) {
			cum += (cum*(slave.health/50))
		}
		if (slave.prostate == 0) {
			cum *= 0.2 // being generous here
		}
		cum = Math.trunc(cum)
		cum = Math.clamp(cum,1,1000000000000000000)
		return cum
	}
};

window.randomRelatedSlave = function(slave, filterFunction) {
  if(!slave || !SugarCube) { return undefined; }
  if(typeof filterFunction !==  'function') { filterFunction = function(s, index, array) { return true; }; }
  return SugarCube.State.variables.slaves.filter(filterFunction).shuffle().find(function(s, index, array) {return areSisters(slave, s) || s.mother == slave.ID || s.father == slave.ID || slave.ID == s.mother || slave.ID == s.father; })
}

window.randomRelatedAvailableSlave = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return isSlaveAvailable(s); });
}

window.randomSister = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return areSisters(slave, s); });
}

window.randomTwinSister = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return areSisters(slave, s) == 1; });
}

window.randomAvailableSister = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return isSlaveAvailable(s) && areSisters(slave, s); });
}

window.randomAvailableTwinSister = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return isSlaveAvailable(s) && areSisters(slave, s) == 1; });
}

window.randomDaughter = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return s.mother == slave.ID || s.father == slave.ID; });
}

window.randomAvailableDaughter = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return isSlaveAvailable(s) && (s.mother == slave.ID || s.father == slave.ID); });
}

window.randomParent = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return s.ID == slave.mother || s.ID == slave.father; });
}

window.randomAvailableParent = function(slave) {
	return randomRelatedSlave(slave, function(s, index, array) { return isSlaveAvailable(s) && (s.ID == slave.mother || s.ID == slave.father); });
}

window.totalPlayerRelatives = function(pc) {
	var relatives = 0;
	if (pc.mother > 0) {
		relatives += 1
	}
	if (pc.father > 0) {
		relatives += 1
	}
	if (pc.daughters > 0) {
		relatives += pc.daughters
	}
	if (pc.sisters > 0) {
		relatives += pc.sisters
	}
	return relatives
};

window.ngUpdateGenePool = function(genePool) {
  var transferredSlaveIds = (SugarCube.State.variables.slaves || [])
    .filter(function(s) { return s.ID >= 1200000; })
    .map(function(s) { return s.ID - 1200000; });
  return (genePool || [])
    .filter(function(s) { return transferredSlaveIds.indexOf(s.ID) >= 0; })
    .map(function(s) {
      var result = jQuery.extend(true, {}, s);
      result.ID += 1200000;
      return result;
    });
}

window.toJson = function(obj) {
    var jsontext = JSON.stringify(obj);
    jsontext = jsontext.replace(/^{/,"");
    jsontext = jsontext.replace(/}$/,"");
    return jsontext;
};


code:
:: textboxJS [script]

/* Nicked off greyelf, works for <<replace>> textboxes */
window.setReplaceTextboxMaxLength = function (storyVarName, maxLength) {
	var textboxId = '#textbox-' + Util.slugify(storyVarName);
	$(textboxId)
			.attr('maxlength', maxLength)
			.css({
				'min-width' : 'initial',
				width       : maxLength + 'em',
				padding		: '3px 2px'
			});
};

/* Nicked off TheMadExile, works for non-<<replace>> textboxes */
window.setTextboxMaxLength = function (storyVarName, maxLength) {
	var textboxId = '#textbox-' + Util.slugify(storyVarName);
	postdisplay[textboxId + '-maxlength'] = function (taskName) {
		delete postdisplay[taskName];
		$(textboxId)
			.attr('maxlength', maxLength)
			.css({
				'min-width' : 'initial',
				width       : maxLength + 'em',
				padding		: '3px 2px'
			});
	};
};


code:
:: UtilJS [script]

if(!Array.prototype.findIndex) {
	Array.prototype.findIndex = function(predicate) {
		if (this == null) {
			throw new TypeError('Array.prototype.find called on null or undefined');
		}
		if (typeof predicate !== 'function') {
			throw new TypeError('predicate must be a function');
		}
		var list = Object(this);
		var length = list.length >>> 0;
		var thisArg = arguments[1];
		var value;

		for (var i = 0; i < length; i++) {
			value = list[i];
			if (predicate.call(thisArg, value, i, list)) {
				return i;
			}
		}
		return -1;
	};
};

/*
A categorizer is used to "slice" a value range into distinct categories in an efficient manner.

--- Example ---
Original SugarCube code
<<if _Slave.muscles > 95>>
	Musc++
<<elseif _Slave.muscles > 30>>
	Musc+
<<elseif _Slave.muscles > 5>>
	Toned
<<elseif _Slave.muscles > -6>>
<<elseif _Slave.muscles > -31>>
	@@color:red;weak@@
<<elseif _Slave.muscles > -96>>
	@@color:red;weak+@@
<<else>>
	@@color:red;weak++@@
<</if>>

As a categorizer
<<if ndef $cats>><<set $cats = {}>><</if>>
<<if ndef $cats.muscleCat>>
	<!-- This only gets set once, skipping much of the code evaluation, and can be set outside of the code in an "init" passage for further optimization -->
	<<set $cats.muscleCat = new Categorizer([96, 'Musc++'], [31, 'Musc+'], [6, 'Toned'], [-5, ''], [-30, '@@color:red;weak@@'], [-95, '@@color:red;weak+@@'], [-Infinity, '@@color:red;weak++@@'])>>
<</if>>
<<print $cats.muscleCat.cat(_Slave.muscles)>>
*/
window.Categorizer = function() {
	this.cats = Array.prototype.slice.call(arguments)
		.filter(function(e, i, a) {
			return e instanceof Array && e.length == 2 && typeof e[0] === 'number' && !isNaN(e[0])
				&& a.findIndex(function(val) { return e[0] === val[0]; }) === i; /* uniqueness test */ })
		.sort(function(a, b) { return b[0] - a[0]; /* reverse sort */ });
};
window.Categorizer.prototype.cat = function(val, def) {
	if(typeof val !== 'number' || isNaN(val)) {
		return def;
	}
	var result = this.cats.find(function(e) { return val >= e[0]; });
	return result ? result[1] : def;
};


code:
:: Abort

<<set $nextButton = "Back">>\
<<set $nextLink = "Slave Interact">>\
<<nobr>>
The remote surgery makes aborting a pregnancy quick and efficient. $activeSlave.slaveName is
<<if $activeSlave.fetish == "pregnancy">>
	@@color:red;fundamentally broken.@@ Her entire concept of self and sexuality was wrapped up in the life growing within her, and now it is gone.
	<<set  $activeSlave.fetish to "mindbroken">>
<<elseif $activeSlave.devotion < -50>>
	@@color:mediumorchid;filled with violent, consuming hatred@@. Even though she knew her baby was destined for a slave orphanage, it seems she cared for it and views you as its killer. She is @@color:gold;terrified of your power@@ over her body.
	<<set  $activeSlave.trust -= 10>>
	<<set  $activeSlave.devotion -= 25>>
<<elseif $activeSlave.devotion < -20>>
	@@color:mediumorchid;afflicted by desperate, inconsolable sobbing@@. Even though she knew her baby was destined for a slave orphanage, it seems she cared for it. She is @@color:gold;terrified of your power@@ over her body.
	<<set  $activeSlave.trust -= 10>>
	<<set  $activeSlave.devotion -= 10>>
<<elseif $activeSlave.devotion <= 20>>
	@@color:mediumorchid;consumed by muted weeping and enduring sorrow@@. Even though she knew her baby was destined for a slave orphanage, it seems she cared for it. She is @@color:gold;terrified of your power@@ over her body.
	<<set  $activeSlave.trust -= 10>>
	<<set  $activeSlave.devotion -= 5>>
<<elseif $activeSlave.devotion <= 50>>
	dully obedient. She has been broken to slave life so thoroughly that even this is neither surprising nor affecting. She is @@color:gold;terrified of your power@@ over her body.
	<<set  $activeSlave.trust -= 10>>
<<else>>
	@@color:hotpink;pleased by this stark development@@, since she is so attentive to your will. She also expects she'll be able to fuck better now.
	<<set  $activeSlave.devotion += 4>>
<</if>>

<<set _currentRule to lastPregRule($activeSlave,$defaultRules)>>

<<if ($activeSlave.assignmentVisible == 1) && (_currentRule != null)>><<set $activeSlave.preg = -1>><<else>><<set $activeSlave.preg = 0>><</if>>
<<if $activeSlave.reservedChildren > 0>>
	<<set $reservedChildren -= $activeSlave.reservedChildren>>
<</if>>
<<set $activeSlave.pregType = 0>>
<<set $activeSlave.pregSource = 0>>
<</nobr>>