code:
App.Art.hexToRgb = function(hex) {
	hex = hex.replace('#', '');
	let r = parseInt(hex.substring(0, 2), 16);
	let g = parseInt(hex.substring(2, 4), 16);
	let b = parseInt(hex.substring(4, 6), 16);
	return [r/255, g/255, b/255];
};

App.Art.random = function(seed) {
	let x = Math.sin(seed+1) * 10000;
	return x - Math.floor(x);
};

App.Art.getMaterialById = function(scene, id) {
	for (const material of scene.materials) {
		if(material.matId === id) {
			return material;
		}
	}
	return null;
};

App.Art.getMorphById = function(scene, id) {
	for (const morph of scene.models[0].morphs) {
		if(morph.morphId === id) {
			return morph;
		}
	}
	return null;
};

App.Art.getSurfaceById = function(scene, id) {
	for (const figure of scene.models[0].figures) {
		for (const surface of figure.surfaces) {
			if (surface.surfaceId === id) {
				return surface;
			}
		}
	}
	return null;
};

App.Art.getMatIdsBySurface = function(scene, id) {
	for (const figure of scene.models[0].figures) {
		for (const surface of figure.surfaces) {
			if (surface .surfaceId === id) {
				return surface.matIds;
			}
		}
	}
};

App.Art.resetMorphs = function(scene) {
	for (let i =0; i < scene.models[0].morphs.length; i++) {
		scene.models[0].morphs[i].value = App.Art.defaultScene.models[0].morphs[i].value;
	}
};

App.Art.getArtParams = function() {
	let p = {};

	p.hideDick = false;
	p.hideVagina = false;
	p.hideHair = false;
	p.applyNipples = true;
	p.applyPumps = false;
	p.applyExtremeHeels = false;
	p.applyExtremeHeels2 = false;

	return p;
};

App.Art.applyFigures = function(slave, scene, p) {
	let figures = [];

	switch(slave.clothes) {
		case "attractive lingerie":
			figures.push("AS2_Body1", "AS2_Socks");
			p.hideDick = true;
			p.applyNipples = false;
			break;
		case "attractive lingerie for a pregnant woman":
			figures.push("AS2_Babydoll2", "AS2_Pantie", "AS2_Socks_5506");
			p.hideDick = true;
			p.applyNipples = false;
			break;
		case "restrictive latex":
			figures.push("Dark Princess Bodysuit", "Dark Princess Boots");
			p.hideDick = true;
			p.applyNipples = false;
			p.applyPumps = true;
			break;
		case "a slutty klan robe":
			figures.push("Slutty Klan Robe");
			p.hideDick = true;
			p.hideHair = true;
			p.applyNipples = false;
			break;
		case "a klan robe":
			figures.push("Klan Robe");
			p.hideDick = true;
			p.hideHair = true;
			p.applyNipples = false;
			break;
		case "a bunny outfit":
			figures.push("Bunny Suit", "Bunny Gloves", "Bunny Chocker", "Bunny Shoes", "Bunny Stocking", "Bunny Ears");
			p.hideDick = true;
			p.applyNipples = false;
			p.applyPumps = true;
			break;
		case "a penitent nuns habit":
			figures.push("Nun_Outfit");
			p.hideDick = true;
			p.hideHair = true;
			p.applyNipples = false;
			break;
		case "a fallen nuns habit":
			figures.push("NUN OUTFIT", "NUN HAT", "NUN PANTIES", "NUN STOCKINGS");
			p.hideDick = true;
			p.hideHair = true;
			p.applyNipples = false;
			break;
		case "an apron":
			figures.push("Apron");
			p.hideDick = true;
			p.applyNipples = false;
			break;
		case "a burkini":
			figures.push("Burkini");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = true;
			break;
		case "a burqa":
			figures.push("Burqa");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = true;
			break;
		case "harem gauze":
			figures.push("Harem Gauze Shocks", "Harem Gauze Slutty Blouse", "Harem Gauze Underpant", "Harem Gauze Vail");
			p.hideDick = true;
			p.applyNipples = false;
			break;
		case "a mounty outfit":
			figures.push("Mounty Hat", "Mounty Jacket", "Mounty Pants");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = true;
			break;
		case "a hijab and abaya":
			figures.push("Hijab And Abaya");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = true;
			break;
		case "uncomfortable straps":
			figures.push("Uncomfortable Straps", "Uncomfortable Bracelets", "Uncomfortable LegsBracelets");
			p.hideDick = false;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "a toga":
			figures.push("Toga");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a schutzstaffel uniform":
			figures.push("Schutzstaffel Uniform");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a slutty schutzstaffel uniform":
			figures.push("Slutty Schutzstaffel Uniform");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a slave gown":
			figures.push("Slave Gown");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a long qipao":
			figures.push("Long Qipao");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a maternity dress":
			figures.push("Maternity Dress");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a nice nurse outfit":
			figures.push("Nurse Uniform", "Nurse Hat");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a slutty nurse outfit":
			figures.push("Slutty Nurse Bra", "Slutty Nurse Dress", "Slutty Nurse Necklace", "Slutty Nurse Underwear", "Slutty Nurse Boots", "Slutty Nurse Cap");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			p.applyPumps = true;
			break;
		case "a slutty maid outfit":
			figures.push("Slutty Maid Dress", "Slutty Maid Bands", "Slutty Maid Neck Bow", "Slutty Maid Shoes", "Slutty Maid Headband");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			p.applyPumps = true;
			break;
		case "a nice maid outfit":
			figures.push("Maid Band", "Maid Corset", "Maid Collar", "Maid Panty", "Maid Skirt", "Maid Sleeve Left", "Maid Sleeve Right", "Maid Stocking Left", "Maid Stocking Right", "Maid Top");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a police uniform":
			figures.push("Police Cap", "Police Outfit", "Police Shoes", "Police Belt", "Police Gun");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a biyelgee costume":
			figures.push("Biyelgee Dress", "Biyelgee Hat");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a one-piece swimsuit":
			figures.push("Swimsuit");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a sports bra":
			figures.push("Sports Bra");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a striped bra":
			figures.push("Bra");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a sweater":
			figures.push("Sweater");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a sweater and cutoffs":
			figures.push("Sweater", "Cutoffs");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a sweater and panties":
			figures.push("Sweater", "Panties");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a t-shirt":
			figures.push("Shirt");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a t-shirt and jeans":
			figures.push("Shirt", "Jeans");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a t-shirt and panties":
			figures.push("Shirt", "Panties");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a t-shirt and thong":
			figures.push("Shirt", "Thong");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a tank-top":
			figures.push("Tank Top");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a tank-top and panties":
			figures.push("Tank Top", "Panties");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a thong":
			figures.push("Thong");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "a tube top":
			figures.push("Tube Top");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a tube top and thong":
			figures.push("Tube Top", "Thong");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "an oversized t-shirt":
			figures.push("Oversized Shirt");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "an oversized t-shirt and boyshorts":
			figures.push("Oversized Shirt", "Boy Shorts");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "boyshorts":
			figures.push("Boy Shorts");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "panties":
			figures.push("Panties");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "pasties":
			figures.push("Pasties Left", "Pasties Right");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "panties and pasties":
			figures.push("Pasties Left", "Pasties Right", "Panties");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "spats and a tank top":
			figures.push("Spats", "Tank Top");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "sport shorts":
			figures.push("Sports Shorts");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "sport shorts and a sports bra":
			figures.push("Sports Shorts", "Sports Bra");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "sport shorts and a t-shirt":
			figures.push("Sports Shorts", "Shirt");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "stretch pants and a crop-top":
			figures.push("Stretch Pants", "Crop Top");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "leather pants and a tube top":
			figures.push("Leather Pants", "Tube Top");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "leather pants and pasties":
			figures.push("Leather Pants", "Pasties Left", "Pasties Right");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "leather pants":
			figures.push("Leather Pants");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "striped panties":
			figures.push("Panties");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "striped underwear":
			figures.push("Panties");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "cutoffs":
			figures.push("Cutoffs");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "cutoffs and a t-shirt":
			figures.push("Cutoffs", "Shirt");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "jeans":
			figures.push("Jeans");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "a button-up shirt":
			figures.push("Buttonup Shirt");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a button-up shirt and panties":
			figures.push("Buttonup Shirt", "Panties");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a bra":
			figures.push("Bra");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a skimpy loincloth":
			figures.push("Loincloth Skirt");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "battlearmor":
			figures.push("Battle Armor");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = true;
			break;
		case "a scalemail bikini":
			figures.push("Scalemail Bikini");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a mini dress":
			figures.push("Mini Dress");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = false;
			break;
		case "a cybersuit":
			figures.push("Cybersuit");
			p.hideDick = true;
			p.applyNipples = false;
			p.hideHair = true;
			break;
		case "slutty jewelry":
			figures.push("Bangles");
			p.hideDick = true;
			p.applyNipples = true;
			p.hideHair = false;
			break;
		case "a slutty outfit":
			figures.push("Slutty Outfit");
			p.hideDick = false;
			p.applyNipples = false;
			p.hideHair = false;
			break;
	}

	if(slave.chastityAnus && slave.chastityVagina) {
		figures.push("Chastity Belt Base", "Chastity Belt Vaginal Cap with Holes", "Chastity Belt Anal Cap with Hole");
		p.hideDick = true;
	}
	if(!slave.chastityAnus && slave.chastityVagina) {
		figures.push("Chastity Belt Base", "Chastity Belt Vaginal Cap with Holes");
		p.hideDick = true;
	}
	if(slave.chastityAnus && !slave.chastityVagina) {
		figures.push("Chastity Belt Base", "Chastity Belt Anal Cap with Hole");
		p.hideDick = true;
	}

	switch(slave.bellyAccessory) {
		// case "a corset": figures.push("Corset A_80240"); break;
		// case "an extreme corset": figures.push("corset1_112951"); break;
		default: break;
	}

	switch(slave.faceAccessory) {
		case "porcelain mask":
			figures.push("Porcelain Mask");
			break;
	}

	switch(slave.collar) {
		case "preg biometrics":
			figures.push("Pregnancy Collar");
			break;
	}

	switch(slave.shoes) {
		case "extreme heels":
			figures.push("Extreme Heels"); p.applyExtremeHeels = true;
			break;
		case "extreme platform heels":
			figures.push("Extreme Heels 2"); p.applyExtremeHeels2 = true;
			break;
	}

	switch(slave.eyewear) {
		case "glasses":
			figures.push("Glasses");
			break;
	}

	if (!hasLeftArm(slave) && slave.PLimb > 0) {
		figures.push("Amputee Cap Arm Left");
	}
	if (!hasRightArm(slave) && slave.PLimb > 0) {
		figures.push("Amputee Cap Arm Right");
	}

	figures.push("Genesis 8 Female");
	figures.push("Genesis 8 Female Eyelashes");

	if (!p.hideVagina) {
		figures.push("New Genitalia For Victoria 8 - Color Layer");
	}
	if (!p.hideDick) {
		figures.push("Futalicious Shell");
	}

	if (!p.hideHair) {
		switch(slave.hStyle) {
			case "afro": figures.push("Yara Hair"); break;
			case "cornrows": figures.push("HR TIGER BRAIDS G2F"); break;
			case "bun": figures.push("Adia Hair"); break;
			case "neat": figures.push("Samira Hair"); break;
			case "strip": figures.push("Rebel Hair"); break;
			case "tails": figures.push("Kinley Hair G8"); break;
			case "up": figures.push("Pina Hair G8F"); break;
			case "ponytail": figures.push("Ponytail"); break;
			case "braided": figures.push("LLF-MishkaGeBase1"); break;
			case "dreadlocks": figures.push("Dreads"); break;
			case "permed": figures.push("IchigoHair"); break;
			case "curled": figures.push("Havana Hair"); break;
			case "luxurious": figures.push("BaronessHR"); break;
			case "messy bun": figures.push("Krayon Hair"); break;
			case "messy": figures.push("MessyHairG3"); break;
			case "eary": figures.push("GeorginaHair"); break;
			case "undercut": figures.push("Edit Female Hair"); break;
			case "bangs": figures.push("Neko Hair Genesis 8 Female"); break;
			case "hime": figures.push("Nyohair"); break;
			case "drills": figures.push("LLF-BunnyCurls-G3"); break;
			case "bald": break;
			case "shaved": break;
			case "buzzcut": break;
			case "trimmed": break;
			default: break;
		}
	}

	for (let i=0; i < scene.models[0].figures.length; i++) {
		scene.models[0].figures[i].visible = false;
		for (let j =0; j < figures.length; j++) {
			if (scene.models[0].figures[i].figId === figures[j]) {
				scene.models[0].figures[i].visible = true;
			}
		}
	}
};

App.Art.applySurfaces = function(slave, scene, p) {
	let glansFutaliciousShellLayers = [];
	let shaftFutaliciousShellLayers = [];
	let testiclesFutaliciousShellLayers = [];
	let torsoFrontFutaliciousShellLayers = [];
	let torsoMiddleFutaliciousShellLayers = [];
	let torsoBackFutaliciousShellLayers = [];
	let rectumFutaliciousShellLayers = [];
	let torsoFrontLayers = [];
	let torsoMiddleLayers = [];
	let torsoBackLayers = [];
	let genitaliaLayers = [];
	let anusLayers = [];
	let torsoLayers = [];
	let faceLayers = [];
	let lipsLayers = [];
	let earsLayers = [];
	let legsLayers = [];
	let armsLayers = [];
	let eyesocketLayers = [];
	let toenailsLayers = [];
	let fingernailsLayers = [];

	let surfaces = [];

	if ((slave.dick !== 0 || (!(slave.scrotum <= 0 || slave.balls <= 0))) && !p.hideDick) {
		surfaces.push(["Futalicious_Genitalia_G8F_Shaft_Futalicious_Shell", "visible", true]);
		surfaces.push(["Futalicious_Genitalia_G8F_Glans_Futalicious_Shell", "visible", true]);
		surfaces.push(["Futalicious_Genitalia_G8F_Testicles_Futalicious_Shell", "visible", true]);
		surfaces.push(["Futalicious_Genitalia_G8F_Torso_Front_Futalicious_Shell", "visible", true]);
		surfaces.push(["Futalicious_Genitalia_G8F_Torso_Middle_Futalicious_Shell", "visible", true]);
		surfaces.push(["Futalicious_Genitalia_G8F_Torso_Back_Futalicious_Shell", "visible", true]);
		surfaces.push(["Futalicious_Genitalia_G8F_Rectum_Futalicious_Shell", "visible", false]);
		surfaces.push(["Torso_Front", "visible", true]);
		surfaces.push(["Torso_Middle", "visible", true]);
		surfaces.push(["Torso_Back", "visible", true]);

		surfaces.push(["Genitalia", "visible", true]);
		surfaces.push(["Anus", "visible", true]);
		surfaces.push(["new_gens_V8_1840_Genitalia", "visible", true]);
		surfaces.push(["new_gens_V8_1840_Anus", "visible", true]);
	} else {
		surfaces.push(["Futalicious_Genitalia_G8F_Shaft_Futalicious_Shell", "visible", false]);
		surfaces.push(["Futalicious_Genitalia_G8F_Glans_Futalicious_Shell", "visible", false]);
		surfaces.push(["Futalicious_Genitalia_G8F_Testicles_Futalicious_Shell", "visible", false]);
		surfaces.push(["Futalicious_Genitalia_G8F_Torso_Front_Futalicious_Shell", "visible", false]);
		surfaces.push(["Futalicious_Genitalia_G8F_Torso_Middle_Futalicious_Shell", "visible", false]);
		surfaces.push(["Futalicious_Genitalia_G8F_Torso_Back_Futalicious_Shell", "visible", false]);
		surfaces.push(["Futalicious_Genitalia_G8F_Rectum_Futalicious_Shell", "visible", false]);
		surfaces.push(["Torso_Front", "visible", false]);
		surfaces.push(["Torso_Middle", "visible", false]);
		surfaces.push(["Torso_Back", "visible", false]);

		surfaces.push(["Genitalia", "visible", true]);
		surfaces.push(["Anus", "visible", true]);
		surfaces.push(["new_gens_V8_1840_Genitalia", "visible", true]);
		surfaces.push(["new_gens_V8_1840_Anus", "visible", true]);
	}

	let cockSkin;
	let skin;

	let O = App.Art.hexToRgb(skinColorCatcher(slave).skinColor);

	let A = [207/255, 198/255, 195/255];
	let B = [201/255, 157/255, 134/255];
	let C = [174/255, 128/255, 100/255];
	let D = [112/255, 78/255, 62/255];

	let sqAO = (A[0] - O[0])**2 + (A[1] - O[1])**2 + (A[2] - O[2])**2;
	let sqBO = (B[0] - O[0])**2 + (B[1] - O[1])**2 + (B[2] - O[2])**2;
	let sqCO = (C[0] - O[0])**2 + (C[1] - O[1])**2 + (C[2] - O[2])**2;
	let sqDO = (D[0] - O[0])**2 + (D[1] - O[1])**2 + (D[2] - O[2])**2;

	if (sqAO < sqBO && sqAO < sqCO && sqAO < sqDO) {
		skin = "WhiteTone";
		cockSkin = "White";
	} else if (sqBO < sqAO && sqBO < sqCO && sqBO < sqDO) {
		skin = "LightTone";
		cockSkin = "Light";
	} else if (sqCO < sqBO && sqCO < sqAO && sqCO < sqDO) {
		skin = "MidTone";
		cockSkin = "Mid";
	} else if (sqDO < sqBO && sqDO < sqCO && sqDO < sqAO) {
		skin = "DarkTone";
		cockSkin = "Dark";
	}

	glansFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	shaftFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	testiclesFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	torsoFrontFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	torsoMiddleFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	torsoBackFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	rectumFutaliciousShellLayers.push(cockSkin + "Futalicious_Genitalia_G8F_Glans_Futalicious_Shell");
	torsoFrontLayers.push(skin + "Torso", "skindetail_blotches_torso", "skindetail_pores_torso", "skindetail_fine_torso", "skindetail_veins_torso");
	torsoMiddleLayers.push(skin + "Torso", "skindetail_blotches_torso", "skindetail_pores_torso", "skindetail_fine_torso", "skindetail_veins_torso");
	torsoBackLayers.push(skin + "Torso", "skindetail_blotches_torso", "skindetail_pores_torso", "skindetail_fine_torso", "skindetail_veins_torso");
	genitaliaLayers.push(skin + "Genitalia", "skindetail_blotches_torso", "skindetail_pores_torso", "skindetail_fine_torso", "skindetail_veins_torso");
	anusLayers.push(skin + "Anus", "skindetail_blotches_torso", "skindetail_pores_torso", "skindetail_fine_torso", "skindetail_veins_torso");
	torsoLayers.push(skin + "Torso", "skindetail_blotches_torso", "skindetail_pores_torso", "skindetail_fine_torso", "skindetail_veins_torso");
	faceLayers.push(skin + "Face", "skindetail_blotches_face", "skindetail_pores_face", "skindetail_fine_face", "skindetail_veins_face");
	lipsLayers.push(skin + "Lips");
	earsLayers.push(skin + "Ears", "skindetail_blotches_face", "skindetail_pores_face", "skindetail_fine_face", "skindetail_veins_face");
	legsLayers.push(skin + "Legs", "skindetail_blotches_legs", "skindetail_pores_legs", "skindetail_fine_legs", "skindetail_veins_legs");
	armsLayers.push(skin + "Arms", "skindetail_blotches_arms", "skindetail_pores_arms", "skindetail_fine_arms", "skindetail_veins_arms");
	eyesocketLayers.push(skin + "Face");
	toenailsLayers.push(skin + "Toenails");
	fingernailsLayers.push(skin + "Fingernails");

	switch(slave.hStyle) {
		case "buzzcut":
		case "trimmed":
			torsoLayers.push("shaved_torso");
			faceLayers.push("shaved_face");
			break;
		case "bald":
		case "shaved":
		default:
			break;
	}

	switch(slave.eyebrowFullness) {
		case "bald":
		case "shaved":
			break;
		case "pencil-thin":
			faceLayers.push("eyebrow_pencil");
			break;
		case "thin":
			faceLayers.push("eyebrow_thin");
			break;
		case "threaded":
			faceLayers.push("eyebrow_threaded");
			break;
		case "natural":
			faceLayers.push("eyebrow_natural");
			break;
		case "tapered":
			faceLayers.push("eyebrow_tapered");
			break;
		case "thick":
			faceLayers.push("eyebrow_thick");
			break;
		case "bushy":
			faceLayers.push("eyebrow_bushy");
			break;
	}

	switch (slave.makeup) {
		case 1:
			// Nice
			faceLayers.push("makeup_nice_eyes");
			break;
		case 2:
			// Gorgeous
			faceLayers.push("makeup_gorgeous_eyes");
			faceLayers.push("makeup_gorgeous_blush");
			break;
		case 3:
			// Hair coordinated
			faceLayers.push("makeup_nice_eyes");
			break;
		case 4:
			// Slutty
			faceLayers.push("makeup_slutty_eyes");
			faceLayers.push("makeup_slutty_blush");
			break;
		case 5:
			// Neon
			faceLayers.push("makeup_neon_eyes");
			break;
		case 6:
			// Neon hair coordinated
			faceLayers.push("makeup_neon_eyes");
			break;
		case 7:
			// Metallic
			faceLayers.push("makeup_metallic_eyes");
			break;
		case 8:
			// Metallic hair coordinated
			faceLayers.push("makeup_metallic_eyes");
			break;
	}

	let pubicStyle = "";
	switch (slave.pubicHStyle) {
		case "hairless":
		case "waxed":
		case "bald":
			break;
		case "neat":
			pubicStyle = "PubicNeat";
			break;
		case "in a strip":
			pubicStyle = "PubicStrip";
			break;
		case "bushy":
			pubicStyle = "PubicBushy";
			break;
		case "very bushy":
			pubicStyle = "PubicVeryBushy";
			break;
		case "bushy in the front and neat in the rear":
			pubicStyle = "PubicBushyFront";
			break;
		default:
			break;
	}

	if(pubicStyle !== "") {
		torsoLayers.push(pubicStyle);
		genitaliaLayers.push(pubicStyle);
		torsoFrontLayers.push(pubicStyle);
		torsoMiddleLayers.push(pubicStyle);
		torsoFrontFutaliciousShellLayers.push(pubicStyle);
		torsoMiddleFutaliciousShellLayers.push(pubicStyle);
	}

	switch(slave.markings) {
		case "beauty mark":
			torsoLayers.push("skindetail_beauty_marks_torso");
			genitaliaLayers.push("skindetail_beauty_marks_torso");
			faceLayers.push("skindetail_beauty_marks_face");
			armsLayers.push("skindetail_beauty_marks_arms");
			legsLayers.push("skindetail_beauty_marks_legs");
			break;
		case "freckles":
			torsoLayers.push("skindetail_freckles_torso");
			genitaliaLayers.push("skindetail_freckles_torso");
			faceLayers.push("skindetail_freckles_face");
			armsLayers.push("skindetail_freckles_arms");
			legsLayers.push("skindetail_freckles_legs");
			break;
		case "heavily freckled":
			torsoLayers.push("skindetail_heavy_freckles_torso");
			genitaliaLayers.push("skindetail_heavy_freckles_torso");
			faceLayers.push("skindetail_heavy_freckles_face");
			armsLayers.push("skindetail_heavy_freckles_arms");
			legsLayers.push("skindetail_heavy_freckles_legs");
			break;
		case "birthmark":
			torsoLayers.push("skindetail_birthmarks_torso");
	}

	torsoLayers.push("nipple_mask");

	surfaces.push(["Futalicious_Genitalia_G8F_Shaft_Futalicious_Shell", "matIds", shaftFutaliciousShellLayers]);
	surfaces.push(["Futalicious_Genitalia_G8F_Glans_Futalicious_Shell", "matIds", glansFutaliciousShellLayers]);
	surfaces.push(["Futalicious_Genitalia_G8F_Testicles_Futalicious_Shell", "matIds", testiclesFutaliciousShellLayers]);
	surfaces.push(["Futalicious_Genitalia_G8F_Torso_Front_Futalicious_Shell", "matIds", torsoFrontFutaliciousShellLayers]);
	surfaces.push(["Futalicious_Genitalia_G8F_Torso_Middle_Futalicious_Shell", "matIds", torsoMiddleFutaliciousShellLayers]);
	surfaces.push(["Futalicious_Genitalia_G8F_Torso_Back_Futalicious_Shell", "matIds", torsoBackFutaliciousShellLayers]);
	surfaces.push(["Futalicious_Genitalia_G8F_Rectum_Futalicious_Shell", "matIds", rectumFutaliciousShellLayers]);
	surfaces.push(["Torso_Front", "matIds", torsoFrontLayers]);
	surfaces.push(["Torso_Middle", "matIds", torsoMiddleLayers]);
	surfaces.push(["Torso_Back", "matIds", torsoBackLayers]);
	surfaces.push(["Genitalia",	"matIds", genitaliaLayers]);
	surfaces.push(["Anus", "matIds", anusLayers]);
	surfaces.push(["Torso", "matIds", torsoLayers]);
	surfaces.push(["Face", "matIds", faceLayers]);
	surfaces.push(["Lips", "matIds", lipsLayers]);
	surfaces.push(["Ears", "matIds", earsLayers]);
	surfaces.push(["Legs", "matIds", legsLayers]);
	surfaces.push(["Arms", "matIds", armsLayers]);
	surfaces.push(["EyeSocket", "matIds", eyesocketLayers]);
	surfaces.push(["Toenails", "matIds", toenailsLayers]);
	surfaces.push(["Fingernails", "matIds", fingernailsLayers]);

	for (let i=0, count=0; i < scene.models[0].figures.length; i++) {
		for (let j=0; j < scene.models[0].figures[i].surfaces.length; j++, count++) {
			for (let h =0; h < surfaces.length; h++) {
				if (scene.models[0].figures[i].surfaces[j].surfaceId === surfaces[h][0]) {
					scene.models[0].figures[i].surfaces[j][surfaces[h][1]] = surfaces[h][2];
				}
			}
		}
	}
};

App.Art.applyMaterials = function(slave, scene, p) {
	let materials = [];

	let hairColor = App.Art.hexToRgb(extractColor(slave.hColor));
	let lipsColor = App.Art.hexToRgb(skinColorCatcher(slave).lipsColor);
	let areolaColor = App.Art.hexToRgb(skinColorCatcher(slave).areolaColor);

	hairColor = [hairColor[0], hairColor[1], hairColor[2]];

	let makeupColor;
	let makeupOpacity;
	let lipsGloss;

	switch (slave.makeup) {
		case 1:
			// Nice
			makeupColor = "#ff69b4";
			makeupOpacity = 0.5;
			lipsGloss = 25;
			break;
		case 2:
			// Gorgeous
			makeupColor = "#8b008b";
			makeupOpacity = 0.7;
			lipsGloss = 10;
			break;
		case 3:
			// Hair coordinated
			makeupColor = extractColor(slave.hColor);
			makeupOpacity = 0.3;
			lipsGloss = 10;
			break;
		case 4:
			// Slutty
			makeupColor = "#B70000";
			makeupOpacity = 0.8;
			lipsGloss = 5;
			break;
		case 5:
			// Neon
			makeupColor = "#DC143C";
			makeupOpacity = 1;
			lipsGloss = 1;
			break;
		case 6:
			// Neon hair coordinated
			makeupColor = extractColor(slave.hColor);
			makeupOpacity = 1;
			lipsGloss = 1;
			break;
		case 7:
			// Metallic
			makeupColor = "#b22222";
			makeupOpacity = 0.7;
			lipsGloss = 10;
			break;
		case 8:
			// Metallic hair coordinated
			makeupColor = extractColor(slave.hColor);
			makeupOpacity = 0.7;
			lipsGloss = 10;
			break;
		default:
			makeupColor = "#ffffff";
			makeupOpacity = 0;
			lipsGloss = 5;
			break;
	}

	makeupColor = App.Art.hexToRgb(makeupColor);
	lipsColor[0] = makeupColor[0] * makeupOpacity + lipsColor[0] * (1 - makeupOpacity);
	lipsColor[1] = makeupColor[1] * makeupOpacity + lipsColor[1] * (1 - makeupOpacity);
	lipsColor[2] = makeupColor[2] * makeupOpacity + lipsColor[2] * (1 - makeupOpacity);

	let nailColor;
	switch (slave.nails) {
		case 2:
			// color-coordinated with hair
			nailColor = extractColor(slave.hColor);
			break;
		case 4:
			// bright and glittery
			nailColor = "#ff0000";
			break;
		case 5:
			// very long and garish
			nailColor = "#ff0000";
			break;
		case 6:
			// neon
			nailColor = "#DC143C";
			break;
		case 7:
			// color-coordinated neon
			nailColor = extractColor(slave.hColor);
			break;
		case 8:
			// metallic
			nailColor = "#b22222";
			break;
		case 9:
			// color-coordinated metallic
			nailColor = extractColor(slave.hColor);
			break;
		default:
			nailColor = "#ffffff";
			break;
	}

	nailColor = App.Art.hexToRgb(nailColor);

	switch(slave.hStyle) {
		case "afro":
			materials.push(["yara_scalp", "Ka", hairColor]);
			materials.push(["yara_hair", "Ka", hairColor]);
			break;
		case "cornrows":
			materials.push(["tiger_scalp", "Ka", hairColor]);
			materials.push(["tiger_hair", "Ka", hairColor]);
			break;
		case "bun":
			materials.push(["adia_scalp", "Ka", hairColor]);
			materials.push(["adia_hair", "Ka", hairColor]);
			break;
		case "neat":
			materials.push(["samira_scalp", "Ka", hairColor]);
			materials.push(["samira_hair", "Ka", hairColor]);
			break;
		case "strip":
			materials.push(["rebel_scalp", "Ka", hairColor]);
			materials.push(["rebel_hair", "Ka", hairColor]);
			break;
		case "tails":
			materials.push(["kinley_scalp", "Ka", hairColor]);
			materials.push(["kinley_hair_thin_strands", "Ka", hairColor]);
			materials.push(["kinley_hair_long", "Ka", hairColor]);
			materials.push(["kinley_hair_strands", "Ka", hairColor]);
			materials.push(["kinley_hair_base", "Ka", hairColor]);
			materials.push(["kinley_hair_tie", "Ka", hairColor]);
			break;
		case "up":
			materials.push(["pina_scalp", "Ka", hairColor]);
			materials.push(["pina_hair1", "Ka", hairColor]);
			materials.push(["pina_hair2", "Ka", hairColor]);
			break;
		case "ponytail":
			materials.push(["ponytail_scalp", "Ka", hairColor]);
			materials.push(["ponytail_hair1", "Ka", hairColor]);
			materials.push(["ponytail_hair2", "Ka", hairColor]);
			materials.push(["ponytail_hair3", "Ka", hairColor]);
			materials.push(["ponytail_holder", "Ka", hairColor]);
			break;
		case "braided":
			materials.push(["mishka_scalp", "Ka", hairColor]);
			materials.push(["mishka_hair1", "Ka", hairColor]);
			materials.push(["mishka_hair2", "Ka", hairColor]);
			materials.push(["mishka_hair3", "Ka", hairColor]);
			break;
		case "dreadlocks":
			materials.push(["dreads_scalp", "Ka", hairColor]);
			materials.push(["dreads_hair", "Ka", hairColor]);
			break;
		case "permed":
			materials.push(["ichigo_scalp", "Ka", hairColor]);
			materials.push(["ichigo_hair1", "Ka", hairColor]);
			materials.push(["ichigo_hair2", "Ka", hairColor]);
			break;
		case "curled":
			materials.push(["havana_hair", "Ka", hairColor]);
			break;
		case "luxurious":
			materials.push(["baroness_scalp", "Ka", hairColor]);
			materials.push(["baroness_hair", "Ka", hairColor]);
			break;
		case "messy bun":
			materials.push(["krayon_scalp", "Ka", hairColor]);
			materials.push(["krayon_hair1", "Ka", hairColor]);
			materials.push(["krayon_hair2", "Ka", hairColor]);
			materials.push(["krayon_hair3", "Ka", hairColor]);
			materials.push(["krayon_hair4", "Ka", hairColor]);
			break;
		case "messy":
			materials.push(["messy_scalp", "Ka", hairColor]);
			materials.push(["messy_hair", "Ka", hairColor]);
			break;
		case "eary":
			materials.push(["georgina_scalp", "Ka", hairColor]);
			materials.push(["georgina_hair1", "Ka", hairColor]);
			materials.push(["georgina_hair2", "Ka", hairColor]);
			break;
		case "undercut":
			materials.push(["edit_scalp", "Ka", hairColor]);
			materials.push(["edit_hair", "Ka", hairColor]);
			break;
		case "bangs":
			materials.push(["neko_scalp", "Ka", hairColor]);
			materials.push(["neko_hair", "Ka", hairColor]);
			break;
		case "hime":
			materials.push(["nyo_scalp", "Ka", hairColor]);
			materials.push(["nyo_hair", "Ka", hairColor]);
			break;
		case "drills":
			materials.push(["bunny_scalp", "Ka", hairColor]);
			materials.push(["bunny_hair1", "Ka", hairColor]);
			materials.push(["bunny_hair2", "Ka", hairColor]);
			materials.push(["bunny_hair3", "Ka", hairColor]);
			materials.push(["bunny_hair4", "Ka", hairColor]);
			break;
		case "buzzcut":
		case "trimmed":
			materials.push(["shaved_face", "Ka", hairColor]);
			materials.push(["shaved_torso", "Ka", hairColor]);
			break;
		case "bald":
		case "shaved":
		default: break;
	}

	let eyebrowColor = App.Art.hexToRgb(extractColor(slave.eyebrowHColor));

	switch(slave.eyebrowFullness) {
		case "bald":
		case "shaved":
			break;
		case "pencil-thin":
			materials.push(["eyebrow_pencil", "Ka", eyebrowColor]);
			break;
		case "thin":
			materials.push(["eyebrow_thin", "Ka", eyebrowColor]);
			break;
		case "threaded":
			materials.push(["eyebrow_threaded", "Ka", eyebrowColor]);
			break;
		case "natural":
			materials.push(["eyebrow_natural", "Ka", eyebrowColor]);
			break;
		case "tapered":
			materials.push(["eyebrow_tapered", "Ka", eyebrowColor]);
			break;
		case "thick":
			materials.push(["eyebrow_thick", "Ka", eyebrowColor]);
			break;
		case "bushy":
			materials.push(["eyebrow_bushy", "Ka", eyebrowColor]);
			break;
	}

	if(slave.face < -66) {
		materials.push(["Eyelashes", "map_D", "base2/eyelash/EyeLash_0.jpg"]);
	}else if(slave.face < -33) {
		materials.push(["Eyelashes", "map_D", "base2/eyelash/EyeLash_1.jpg"]);
	}else if(slave.face < 0) {
		materials.push(["Eyelashes", "map_D", "base/G8FBaseEyelashes_1006.jpg"]);
	}else if(slave.face < 33) {
		materials.push(["Eyelashes", "map_D", "base2/eyelash/EyeLash_2.jpg"]);
	}else if(slave.face < 66) {
		materials.push(["Eyelashes", "map_D", "base2/eyelash/EyeLash_3.jpg"]);
	}else {
		materials.push(["Eyelashes", "map_D", "base2/eyelash/EyeLash_4.jpg"]);
	}

	let irisColorLeft = App.Art.hexToRgb(extractColor(hasLeftEye(slave) ? extractColor(slave.eye.left.iris) : extractColor("black")));
	let irisColorRight = App.Art.hexToRgb(extractColor(hasRightEye(slave) ? extractColor(slave.eye.right.iris) : extractColor("black")));
	let scleraColorLeft = App.Art.hexToRgb(extractColor(hasLeftEye(slave) ? extractColor(slave.eye.left.sclera) : extractColor("black")));
	let scleraColorRight = App.Art.hexToRgb(extractColor(hasRightEye(slave) ? extractColor(slave.eye.right.sclera) : extractColor("black")));

	materials.push(["Iris_Left", "Ka", [irisColorLeft[0]*2, irisColorLeft[1]*2, irisColorLeft[2]*2]]);
	materials.push(["Iris_Right", "Ka", [irisColorRight[0]*2, irisColorRight[1]*2, irisColorRight[2]*2]]);
	materials.push(["Sclera_Left", "Ka", [scleraColorLeft[0]*0.8, scleraColorLeft[1]*0.8, scleraColorLeft[2]*0.8]]);
	materials.push(["Sclera_Right", "Ka", [scleraColorRight[0]*0.8, scleraColorRight[1]*0.8, scleraColorRight[2]*0.8]]);

	// expected skin color
	let O = App.Art.hexToRgb(skinColorCatcher(slave).skinColor);

	// average color of skintone texture
	let A = [207/255, 198/255, 195/255];
	let B = [201/255, 157/255, 134/255];
	let C = [174/255, 128/255, 100/255];
	let D = [112/255, 78/255, 62/255];

	// find nearest skintone texture
	let sqAO = (A[0] - O[0])**2 + (A[1] - O[1])**2 + (A[2] - O[2])**2;
	let sqBO = (B[0] - O[0])**2 + (B[1] - O[1])**2 + (B[2] - O[2])**2;
	let sqCO = (C[0] - O[0])**2 + (C[1] - O[1])**2 + (C[2] - O[2])**2;
	let sqDO = (D[0] - O[0])**2 + (D[1] - O[1])**2 + (D[2] - O[2])**2;

	// factor to multiply skintone texture to get expected skin color
	let mA = [O[0]/A[0]*0.92, O[1]/A[1]*0.88, O[2]/A[2]*0.88];
	let mB = [O[0]/B[0], O[1]/B[1], O[2]/B[2]];
	let mC = [O[0]/C[0], O[1]/C[1], O[2]/C[2]];
	let mD = [O[0]/D[0], O[1]/D[1], O[2]/D[2]];

	let lA = [lipsColor[0]/A[0], lipsColor[1]/A[1], lipsColor[2]/A[2]];
	let lB = [lipsColor[0]/A[0], lipsColor[1]/A[1], lipsColor[2]/A[2]];
	let lC = [lipsColor[0]/A[0], lipsColor[1]/A[1], lipsColor[2]/A[2]];
	let lD = [lipsColor[0]/A[0], lipsColor[1]/A[1], lipsColor[2]/A[2]];

	if (sqAO < sqBO && sqAO < sqCO && sqAO < sqDO) {
		let S = [4.0, 4.0, 4.0];

		materials.push(["WhiteToneTorso", "Ka", mA]);
		materials.push(["WhiteToneTorso", "Ks", S]);
		materials.push(["WhiteToneArms", "Ka", mA]);
		materials.push(["WhiteToneArms", "Ks", S]);
		materials.push(["WhiteToneLegs", "Ka", mA]);
		materials.push(["WhiteToneLegs", "Ks", S]);
		materials.push(["WhiteToneFace", "Ka", mA]);
		materials.push(["WhiteToneFace", "Ks", S]);
		materials.push(["WhiteToneEars", "Ka", mA]);
		materials.push(["WhiteToneEars", "Ks", S]);
		materials.push(["WhiteToneLips", "Ka", [lA[0]*0.9, lA[1]*0.9, lA[2]*0.9]]);
		materials.push(["WhiteToneLips", "s", lipsGloss]);
		materials.push(["WhiteToneFingernails", "Ka", nailColor]);
		materials.push(["WhiteToneFingernails", "Ks", [1, 1, 1]]);
		materials.push(["WhiteToneToenails", "Ka", nailColor]);
		materials.push(["WhiteToneToenails", "Ks", [1, 1, 1]]);
		materials.push(["WhiteToneAnus", "Ka", mA]);
		materials.push(["WhiteToneAnus", "Ks", S]);
		materials.push(["WhiteToneGenitalia", "Ka", mA]);
		materials.push(["WhiteToneGenitalia", "Ks", S]);
		materials.push(["WhiteFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ka", [mA[0]*0.9, mA[1]*0.9, mA[2]*0.9]]);
		materials.push(["WhiteFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ks", [1, 1, 1]]);
		materials.push(["nipple_mask", "Ka", [areolaColor[0]/A[0], areolaColor[1]/A[1], areolaColor[2]/A[2]]]);
		materials.push(["nipple_mask", "map_Ka", "base2/skin/torso white.jpg"]);
	} else if (sqBO < sqAO && sqBO < sqCO && sqBO < sqDO) {
		let S = [3.0, 3.0, 3.0];

		materials.push(["LightToneTorso", "Ka", mB]);
		materials.push(["LightToneTorso", "Ks", S]);
		materials.push(["LightToneArms", "Ka", mB]);
		materials.push(["LightToneArms", "Ks", S]);
		materials.push(["LightToneLegs", "Ka", mB]);
		materials.push(["LightToneLegs", "Ks", S]);
		materials.push(["LightToneFace", "Ka", mB]);
		materials.push(["LightToneFace", "Ks", S]);
		materials.push(["LightToneEars", "Ka", mB]);
		materials.push(["LightToneEars", "Ks", S]);
		materials.push(["LightToneLips", "Ka", lB]);
		materials.push(["LightToneLips", "s", lipsGloss]);
		materials.push(["LightToneFingernails", "Ka", nailColor]);
		materials.push(["LightToneFingernails", "Ks", [1, 1, 1]]);
		materials.push(["LightToneToenails", "Ka", nailColor]);
		materials.push(["LightToneToenails", "Ks", [1, 1, 1]]);
		materials.push(["LightToneAnus", "Ka", mB]);
		materials.push(["LightToneAnus", "Ks", S]);
		materials.push(["LightToneGenitalia", "Ka", mB]);
		materials.push(["LightToneGenitalia", "Ks", S]);
		materials.push(["LightFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ka", [mB[0]*0.8, mB[1]*0.8, mB[2]*0.8]]);
		materials.push(["LightFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ks", [1, 1, 1]]);
		materials.push(["nipple_mask", "Ka", [areolaColor[0]/B[0], areolaColor[1]/B[1], areolaColor[2]/B[2]]]);
		materials.push(["nipple_mask", "map_Ka", "base2/skin/torso light.jpg"]);
	} else if (sqCO < sqBO && sqCO < sqAO && sqCO < sqDO) {
		let S = [2.0, 2.0, 2.0];

		materials.push(["MidToneTorso", "Ka", mC]);
		materials.push(["MidToneTorso", "Ks", S]);
		materials.push(["MidToneArms", "Ka", mC]);
		materials.push(["MidToneArms", "Ks", S]);
		materials.push(["MidToneLegs", "Ka", mC]);
		materials.push(["MidToneLegs", "Ks", S]);
		materials.push(["MidToneFace", "Ka", mC]);
		materials.push(["MidToneFace", "Ks", S]);
		materials.push(["MidToneEars", "Ka", mC]);
		materials.push(["MidToneEars", "Ks", S]);
		materials.push(["MidToneLips", "Ka", [lC[0]*0.7, lC[1]*0.7, lC[2]*0.7]]);
		materials.push(["MidToneLips", "s", lipsGloss]);
		materials.push(["MidToneFingernails", "Ka", nailColor]);
		materials.push(["MidToneFingernails", "Ks", [1, 1, 1]]);
		materials.push(["MidToneToenails", "Ka", nailColor]);
		materials.push(["MidToneToenails", "Ks", [1, 1, 1]]);
		materials.push(["MidToneAnus", "Ka", mC]);
		materials.push(["MidToneAnus", "Ks", S]);
		materials.push(["MidToneGenitalia", "Ka", mC]);
		materials.push(["MidToneGenitalia", "Ks", S]);
		materials.push(["MidFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ka", [mC[0]*0.65, mC[1]*0.65, mC[2]*0.65]]);
		materials.push(["MidFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ks", [1, 1, 1]]);
		materials.push(["nipple_mask", "Ka", [areolaColor[0]/C[0], areolaColor[1]/C[1], areolaColor[2]/C[2]]]);
		materials.push(["nipple_mask", "map_Ka", "base2/skin/torso mid.jpg"]);
	} else if (sqDO < sqBO && sqDO < sqCO && sqDO < sqAO) {
		let S = [1.0, 1.0, 1.0];

		materials.push(["DarkToneTorso", "Ka", mD]);
		materials.push(["DarkToneTorso", "Ks", S]);
		materials.push(["DarkToneArms", "Ka", mD]);
		materials.push(["DarkToneArms", "Ks", S]);
		materials.push(["DarkToneLegs", "Ka", mD]);
		materials.push(["DarkToneLegs", "Ks", S]);
		materials.push(["DarkToneFace", "Ka", mD]);
		materials.push(["DarkToneFace", "Ks", S]);
		materials.push(["DarkToneEars", "Ka", mD]);
		materials.push(["DarkToneEars", "Ks", S]);
		materials.push(["DarkToneLips", "Ka", [lD[0]*0.7, lD[1]*0.7, lD[2]*0.7]]);
		materials.push(["DarkToneLips", "s", lipsGloss]);
		materials.push(["DarkToneFingernails", "Ka", nailColor]);
		materials.push(["DarkToneFingernails", "Ks", [1, 1, 1]]);
		materials.push(["DarkToneToenails", "Ka", nailColor]);
		materials.push(["DarkToneToenails", "Ks", [1, 1, 1]]);
		materials.push(["DarkToneAnus", "Ka", mD]);
		materials.push(["DarkToneAnus", "Ks", S]);
		materials.push(["DarkToneGenitalia", "Ka", mD]);
		materials.push(["DarkToneGenitalia", "Ks", S]);
		materials.push(["DarkFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ka", [mD[0]*0.85, mD[1]*0.85, mD[2]*0.85]]);
		materials.push(["DarkFutalicious_Genitalia_G8F_Glans_Futalicious_Shell", "Ks", [1, 1, 1]]);
		materials.push(["nipple_mask", "Ka", [areolaColor[0]/D[0], areolaColor[1]/D[1], areolaColor[2]/D[2]]]);
		materials.push(["nipple_mask", "map_Ka", "base2/skin/torso dark.jpg"]);
	}

	let pubicColor = App.Art.hexToRgb(extractColor(slave.pubicHColor));
	switch (slave.pubicHStyle) {
		case "hairless":
		case "waxed":
		case "bald":
			break;
		case "neat":
			materials.push(["PubicNeat", "Ka", pubicColor]);
			break;
		case "in a strip":
			materials.push(["PubicStrip", "Ka", pubicColor]);
			break;
		case "bushy":
			materials.push(["PubicBushy", "Ka", pubicColor]);
			break;
		case "very bushy":
			materials.push(["PubicVeryBushy", "Ka", pubicColor]);
			break;
		case "bushy in the front and neat in the rear":
			materials.push(["PubicBushyFront", "Ka", pubicColor]);
			break;
		default:
			break;
	}

	switch (slave.vaginaLube) {
		case 0:
			materials.push(["new_gens_V8_1840_Genitalia", "s", 50]);
			break;
		case 1:
			materials.push(["new_gens_V8_1840_Genitalia", "s", 25]);
			break;
		case 2:
			materials.push(["new_gens_V8_1840_Genitalia", "s", 10]);
			break;
	}

	let blotchesDetail = 0.5;
	let poresDetail = 0.35;
	let fineDetail = 0.35;
	let veins = 1;

	materials.push(["skindetail_blotches_torso", "d", blotchesDetail]);
	materials.push(["skindetail_blotches_face", "d", blotchesDetail]);
	materials.push(["skindetail_blotches_arms", "d", blotchesDetail]);
	materials.push(["skindetail_blotches_legs", "d", blotchesDetail]);

	materials.push(["skindetail_pores_torso", "d", poresDetail]);
	materials.push(["skindetail_pores_face", "d", poresDetail]);
	materials.push(["skindetail_pores_arms", "d", poresDetail]);
	materials.push(["skindetail_pores_legs", "d", poresDetail]);

	materials.push(["skindetail_fine_torso", "d", fineDetail]);
	materials.push(["skindetail_fine_face", "d", fineDetail]);
	materials.push(["skindetail_fine_arms", "d", fineDetail]);
	materials.push(["skindetail_fine_legs", "d", fineDetail]);

	materials.push(["skindetail_veins_torso", "d", veins]);
	materials.push(["skindetail_veins_face", "d", veins]);
	materials.push(["skindetail_veins_arms", "d", veins]);
	materials.push(["skindetail_veins_legs", "d", veins]);

	switch(slave.markings) {
		case "beauty mark":
			materials.push(["skindetail_beauty_marks_torso", "d", 1]);
			materials.push(["skindetail_beauty_marks_face", "d", 1]);
			materials.push(["skindetail_beauty_marks_arms", "d", 1]);
			materials.push(["skindetail_beauty_marks_legs", "d", 1]);
			break;
		case "freckles":
			materials.push(["skindetail_freckles_torso", "d", 0.7]);
			materials.push(["skindetail_freckles_face", "d", 0.8]);
			materials.push(["skindetail_freckles_arms", "d", 0.7]);
			materials.push(["skindetail_freckles_legs", "d", 0.7]);
			break;
		case "heavily freckled":
			materials.push(["skindetail_heavy_freckles_torso", "d", 0.7]);
			materials.push(["skindetail_heavy_freckles_face", "d", 0.8]);
			materials.push(["skindetail_heavy_freckles_arms", "d", 0.7]);
			materials.push(["skindetail_heavy_freckles_legs", "d", 0.7]);
			break;
		case "birthmark":
			materials.push(["skindetail_birthmarks_torso", "d", 1]);
			materials.push(["skindetail_birthmarks_torso", "Ka", [O[0]+0.2, O[1]+0.2, O[2]+0.2]]);
	}

	let torso = App.Art.getMatIdsBySurface(scene, "Torso")[0];

	if (slave.scar.hasOwnProperty("belly") && slave.scar.belly["c-section"] > 0) {
		materials.push([torso, "map_Kn", "base/Victoria8_Torso_CNM_1002.jpg"]);
	} else {
		materials.push([torso, "map_Kn", "base/Victoria8_Torso_NM_1002.jpg"]);
	}

	if (slave.collar === "preg biometrics") {
		if (slave.preg > 0) {
			materials.push(["pregnancy_collar_screen", "map_Ke", "dummy1"]);
		} else {
			materials.push(["pregnancy_collar_screen", "map_Ke", "dummy0"]);
		}
	}

	if ("glassesColor" in slave) {
		materials.push(["glasses_frame", "Ka", App.Art.hexToRgb(slave.glassesColor)]);
		materials.push(["porcelain_mask_mask", "Ka", App.Art.hexToRgb(slave.glassesColor)]);
	}

	for (let i =0; i < scene.materials.length; i++) {
		for (let j =0; j < materials.length; j++) {
			if (scene.materials[i].matId === materials[j][0]) {
				scene.materials[i][materials[j][1]] = materials[j][2];
			}
		}
	}
};

App.Art.applyMorphs = function(slave, scene, p) {
	let morphs = [];

	function convertRange(sourceMin, sourceMax, targetMin, targetMax, value) {
		return (targetMax-targetMin)/(sourceMax-sourceMin)*(value-sourceMin)+targetMin;
	}

	if (slave.dick !== 0 || (!(slave.scrotum <= 0 || slave.balls <= 0))) {
		morphs.push(["futaGenFix", 1]);
	}

	if (p.applyPumps) {
		morphs.push(["posesHeels", 1]);
	}

	if (p.applyExtremeHeels) {
		morphs.push(["posesExtremeHeels", 1]);
	}

	if (p.applyExtremeHeels2) {
		morphs.push(["posesExtremeHeels2", 1]);
	}

	if(hasBothArms(slave) && hasBothLegs(slave)) {
		if (scene.inspect) {
			morphs.push(["posesInspect", 1]);
			morphs.push(["posesInspectGen", 1]);
		} else if (slave.devotion > 50) {
			morphs.push(["posesHigh", 1]);
		} else if (slave.devotion > -20) {
			morphs.push(["posesMid", 1]);
		} else {
			morphs.push(["posesLow", 1]);
		}
	}

	if (slave.trust < 0) {
		morphs.push(["expressionsFear", Math.abs(slave.trust)/100]);
	} else {
		morphs.push(["expressionsHappy", slave.trust/100]);
	}

	// used for interpolating mixed race based on slave ID
	let races = ["raceWhite", "raceAsian", "raceLatina", "raceBlack", "racePacific", "raceEuropean", "raceAmerindian", "raceSemitic", "raceEastern", "raceAryan", "raceLatina", "raceMalay"];
	let index1 = Math.floor(App.Art.random(slave.ID+1) * races.length);
	let index2 = Math.floor(App.Art.random(slave.ID-1) * (races.length-1));

	switch (slave.race) {
		case "white":
			morphs.push(["raceWhite", 1]); break;
		case "asian":
			morphs.push(["raceAsian", 1]); break;
		case "latina":
			morphs.push(["raceLatina", 1]); break;
		case "black":
			morphs.push(["raceBlack", 1]); break;
		case "pacific islander":
			morphs.push(["racePacific", 1]); break;
		case "southern european":
			morphs.push(["raceEuropean", 1]); break;
		case "amerindian":
			morphs.push(["raceAmerindian", 1]); break;
		case "semitic":
			morphs.push(["raceSemitic", 1]); break;
		case "middle eastern":
			morphs.push(["raceEastern", 1]); break;
		case "indo-aryan":
			morphs.push(["raceAryan", 1]); break;
		case "malay":
			morphs.push(["raceMalay", 1]); break;
		case "mixed race":
			morphs.push([races[index1], 0.5]);
			races.splice(index1, index1);
			morphs.push([races[index2], 0.5]);
			break;
	}
	/*
	switch (slave.race) {
		case "white":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceEurope1", 1]); break;
				case "masculine":
					morphs.push(["raceEurope10", 1]); break;
				case "androgynous":
					morphs.push(["raceEurope15", 1]); break;
				case "cute":
					morphs.push(["raceEurope16", 1]); break;
				case "sensual":
					morphs.push(["raceEurope17", 1]); break;
				case "exotic":
					morphs.push(["raceEurope14", 1]); break;
			} break;
		case "asian":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAsia1", 1]); break;
				case "masculine":
					morphs.push(["raceAsia17", 1]); break;
				case "androgynous":
					morphs.push(["raceAsia10", 1]); break;
				case "cute":
					morphs.push(["raceAsia14", 1]); break;
				case "sensual":
					morphs.push(["raceAsia15", 1]); break;
				case "exotic":
					morphs.push(["raceAsia16", 1]); break;
			} break;
		case "latina":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAfrica4", 1]); break;
				case "masculine":
					morphs.push(["raceAfrica6", 1]); break;
				case "androgynous":
					morphs.push(["raceAfrica1", 1]); break;
				case "cute":
					morphs.push(["raceAfrica5", 1]); break;
				case "sensual":
					morphs.push(["raceAfrica10", 1]); break;
				case "exotic":
					morphs.push(["raceAfrica2", 1]); break;
			} break;
		case "black":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAfrica3", 1]); break;
				case "masculine":
					morphs.push(["raceAfrica6", 1]); break;
				case "androgynous":
					morphs.push(["raceAfrica1", 1]); break;
				case "cute":
					morphs.push(["raceAfrica7", 1]); break;
				case "sensual":
					morphs.push(["raceAfrica8", 1]); break;
				case "exotic":
					morphs.push(["raceAfrica9", 1]); break;
			} break;
		case "pacific islander":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAsia8", 1]); break;
				case "masculine":
					morphs.push(["raceAsia9", 1]); break;
				case "androgynous":
					morphs.push(["raceAsia6", 1]); break;
				case "cute":
					morphs.push(["raceAsia7", 1]); break;
				case "sensual":
					morphs.push(["raceAsia19", 1]); break;
				case "exotic":
					morphs.push(["raceAsia5", 1]); break;
			} break;
		case "southern european":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceEurope11", 1]); break;
				case "masculine":
					morphs.push(["raceEurope12", 1]); break;
				case "androgynous":
					morphs.push(["raceEurope3", 1]); break;
				case "cute":
					morphs.push(["raceEurope2", 1]); break;
				case "sensual":
					morphs.push(["raceEurope18", 1]); break;
				case "exotic":
					morphs.push(["raceEurope13", 1]); break;
			} break;
		case "amerindian":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAfrica4", 1]); break;
				case "masculine":
					morphs.push(["raceAfrica6", 1]); break;
				case "androgynous":
					morphs.push(["raceAfrica1", 1]); break;
				case "cute":
					morphs.push(["raceAfrica5", 1]); break;
				case "sensual":
					morphs.push(["raceAfrica10", 1]); break;
				case "exotic":
					morphs.push(["raceAfrica2", 1]); break;
			} break;
		case "semitic":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAfrica3", 1]); break;
				case "masculine":
					morphs.push(["raceAfrica6", 1]); break;
				case "androgynous":
					morphs.push(["raceAfrica1", 1]); break;
				case "cute":
					morphs.push(["raceAfrica7", 1]); break;
				case "sensual":
					morphs.push(["raceAfrica8", 1]); break;
				case "exotic":
					morphs.push(["raceAfrica9", 1]); break;
			} break;
		case "middle eastern":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceEurope6", 1]); break;
				case "masculine":
					morphs.push(["raceEurope4", 1]); break;
				case "androgynous":
					morphs.push(["raceEurope8", 1]); break;
				case "cute":
					morphs.push(["raceEurope5", 1]); break;
				case "sensual":
					morphs.push(["raceEurope9", 1]); break;
				case "exotic":
					morphs.push(["raceEurope7", 1]); break;
			} break;
		case "indo-aryan":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAsia3", 1]); break;
				case "masculine":
					morphs.push(["raceAsia20", 1]); break;
				case "androgynous":
					morphs.push(["raceAsia18", 1]); break;
				case "cute":
					morphs.push(["raceAsia4", 1]); break;
				case "sensual":
					morphs.push(["raceAsia12", 1]); break;
				case "exotic":
					morphs.push(["raceAsia11", 1]); break;
			} break;
		case "malay":
			switch (slave.faceShape) {
				case "normal":
					morphs.push(["raceAsia2", 1]); break;
				case "masculine":
					morphs.push(["raceAsia13", 1]); break;
				case "androgynous":
					morphs.push(["raceAsia6", 1]); break;
				case "cute":
					morphs.push(["raceAsia7", 1]); break;
				case "sensual":
					morphs.push(["raceAsia19", 1]); break;
				case "exotic":
					morphs.push(["raceAsia5", 1]); break;
			} break;
		case "mixed race":
			//morphs.push([races[index1], 0.5]);
			//races.splice(index1, index1);
			//morphs.push([races[index2], 0.5]);
			break;
	}
*/
	if (slave.lips < 10) {
		morphs.push(["lipsShapeThin", 1]);
	} else if (slave.lips < 20) {
		morphs.push(["lipsShapeNormal", 1]);
	} else if (slave.lips < 40) {
		morphs.push(["lipsShapePretty", 1]);
	} else if (slave.lips < 70) {
		morphs.push(["lipsShapePlush", 1]);
	} else if (slave.lips < 95) {
		morphs.push(["lipsShapeHuge", 1]);
	} else {
		morphs.push(["lipsShapeFacepussy", slave.lips/100]);
	}

	let eyeShape = ["eyeShapeNormal", "eyeShapeWide", "eyeShapeRound", "eyeShapeSmall", "eyeShapeSlit", "eyeShapeCute", "eyeShapeOpen"];
	let eye = Math.floor(App.Art.random(slave.ID+3) * eyeShape.length);
	if (eye > 0) {
		morphs.push(eyeShape[eye], 1);
	}

	let noseShape = ["noseShapeNormal", "noseShapeWide", "noseShapeForward", "noseShapeFlat", "noseShapeTriangular", "noseShapeSmall"];
	let nose = Math.floor(App.Art.random(slave.ID+4) * noseShape.length);
	if (nose > 0) {
		morphs.push(noseShape[nose], 1);
	}

	let foreheadShape = ["foreheadShapeNormal", "foreheadShapeRound", "foreheadShapeSmall"];
	let forehead = Math.floor(App.Art.random(slave.ID+5) * foreheadShape.length);
	if (forehead > 0) {
		morphs.push(foreheadShape[forehead], 1);
	}

	switch (slave.faceShape) {
		case "normal":
			break;
		case "masculine":
			morphs.push(["faceShapeMasculine", 0.6]); break;
		case "androgynous":
			morphs.push(["faceShapeAndrogynous", 0.8]); break;
		case "cute":
			morphs.push(["faceShapeCute", 1]); break;
		case "sensual":
			morphs.push(["faceShapeSensual", 0.8]); break;
		case "exotic":
			morphs.push(["faceShapeExotic", 1]); break;
	}

	if (slave.boobs < 600) {
		morphs.push(["boobShapeSmall", -(slave.boobs-600)/600]);
	} else {
		switch (slave.boobShape) {
			case "normal":
				morphs.push(["boobShapeNormal", ((slave.boobs-600)**(1/3)/17) * (175/slave.height)]); break;
			case "perky":
				morphs.push(["boobShapePerky", ((slave.boobs-600)**(1/3)/30) * (175/slave.height)]); break;
			case "saggy":
				morphs.push(["boobShapeSaggy", ((slave.boobs-600)**(1/3)/28) * (175/slave.height)]); break;
			case "torpedo-shaped":
				morphs.push(["boobShapeTorpedo", ((slave.boobs-600)**(1/3)/8) * (175/slave.height)]); break;
			case "downward-facing":
				morphs.push(["boobShapeDownward", ((slave.boobs-600)**(1/3)/16) * (175/slave.height)]); break;
			case "wide-set":
				morphs.push(["boobShapeWide", ((slave.boobs-600)**(1/3)/9) * (175/slave.height)]); break;
			case "spherical":
				// special case to make nipple work
				if (slave.nipples === "flat" || slave.nipples === "inverted" || !p.applyNipples) {
					morphs.push(["boobShapeSpherical", ((slave.boobs-600)**(1/3)/15) * (175/slave.height)]); break;
				} else {
					morphs.push(["boobShapeSphericalNippleFix", ((slave.boobs-600)**(1/3)/15) * (175/slave.height)]); break;
				}
		}
	}

	if (p.applyNipples) {
		switch (slave.nipples) {
			case "flat":
				break;
			case "huge":
				morphs.push(["nipplesHuge", (slave.boobs**(1/3)/10 + 0.5) * (175/slave.height)]); break;
			case "tiny":
				morphs.push(["nipplesHuge", (slave.boobs**(1/3)/30 + 0.1) * (175/slave.height)]); break;
			case "cute":
				morphs.push(["nipplesHuge", (slave.boobs**(1/3)/20 + 0.25) * (175/slave.height)]); break;
			case "puffy":
				morphs.push(["nipplesPuffy", (slave.boobs**(1/3)/10 + 0.5) * (175/slave.height)]); break;
			case "inverted":
				break;
			case "partially inverted":
				morphs.push(["nipplesPuffy", (slave.boobs**(1/3)/20 + 0.25) * (175/slave.height)]); break;
			case "fuckable":
				morphs.push(["nipplesHuge", (slave.boobs**(1/3)/5 + 0.6) * (175/slave.height)]); break;
		}
	}

	if (slave.foreskin !== 0 && !scene.inspect) {
		morphs.push(["foreskin", 1]);
	}
	if (slave.dick === 0 && !(slave.scrotum <= 0 || slave.balls <= 0)) {
		morphs.push(["dickRemove", 1]);
	} else if (slave.dick !== 0) {
		if (slave.dick <= 8) {
			morphs.push(["dick", (slave.dick * (175/slave.height) / 5.2) -1.05]);
		} else {
			morphs.push(["dick", ((slave.dick - 8) * (175/slave.height) / 2.2) + 0.55]);
		}
	}
	if (slave.vagina === -1) {
		morphs.push(["vaginaRemove", 1]);
	}
	if (slave.scrotum <= 0 || slave.balls <= 1) {
		morphs.push(["ballsRemove", 1]);
	} else {
		if (slave.balls > 1) {
			morphs.push(["balls", convertRange(2, 10, 0, 0.75, slave.balls * (175/slave.height))]);
		}

		if (slave.scrotum > 0) {
			morphs.push(["scrotum", convertRange(1, 10, 0, 2.0, slave.scrotum * (175/slave.height))]);
		}
	}

	morphs.push(["areolae", convertRange(0, 4, -1, 5, slave.areolae)]);
	morphs.push(["shoulders", slave.shoulders/1.2]);
	scene.models[0].transform.scale = slave.height/175; // height by object transform
	if (slave.muscles > 0) {
		morphs.push(["muscles", slave.muscles/33]);
	}

	morphs.push(["belly", slave.belly**(1/3)/24.6]);

	morphs.push(["hips", slave.hips/2]);

	if (slave.butt<=1) {
		morphs.push(["butt", convertRange(0, 1, -1.5, -0.75, slave.butt)]);
	} else {
		morphs.push(["butt", convertRange(2, 20, 0, 3.5, slave.butt)]);
	}

	if (slave.waist > 0) {
		morphs.push(["waist", -slave.waist/100]);
	} else {
		morphs.push(["waist", -slave.waist/50]);
	}

	if (slave.weight >= 0) {
		morphs.push(["weight", slave.weight/75]);
	} else {
		morphs.push(["weightThin", -slave.weight/80]);
	}

	if (slave.visualAge < 20) {
		morphs.push(["physicalAgeYoung", -(slave.visualAge-20)/10]);
	} else {
		morphs.push(["physicalAgeOld", (slave.visualAge-20)/52]);
	}

	if (!hasLeftArm(slave)) {
		morphs.push(["amputeeLeftArm", 1]);
	}
	if (!hasRightArm(slave)) {
		morphs.push(["amputeeRightArm", 1]);
	}
	if (!hasLeftLeg(slave)) {
		morphs.push(["amputeeLeftLeg", 1]);
	}
	if (!hasRightLeg(slave)) {
		morphs.push(["amputeeRightLeg", 1]);
	}

	App.Art.resetMorphs(scene);

	for (let i =0; i < scene.models[0].morphs.length; i++) {
		for (let j =0; j < morphs.length; j++) {
			if (scene.models[0].morphs[i].morphId === morphs[j][0]) {
				scene.models[0].morphs[i].value = morphs[j][1];
			}
		}
	}
};

repo_name: CloudyCoffee/fc

license: mit


code:
///////////////// MORPHS /////////////////
General
	physicalAgeYoung
	physicalAgeOld
	weight
	weightThin
	muscles
	waist
	belly
	hips
	butt
	lips
	shoulders
	areolae
	dick
	balls
	scrotum
	foreskin
	ballsRemove
	dickRemove
	vaginaRemove            - just closes the vagina

amputee
	leftArm
	rightArm
	leftLeg
	rightLeg

boobShape
	small
	normal
	perky
	saggy
	torpedo-shaped          (torpedo)
	downward-facing         (downward)
	wide-set                (wide)
	spherical

nipples
	huge
	puffy

faceShape
	normal
	masculine
	androgynous
	cute
	sensual
	exotic

lips
	thin
	normal
	pretty
	plush
	huge
	facepussy

eyes
	normal
	wide
	round
	cute
	slit
	small
	open

nose
	normal
	wide
	forward
	flat
	triangular
	small

forehead
	normal
	round
	small

expressions
	happy
	fear

race
	white
	asian
	latina
	black
	pacific islander        (pacific)
	southern european       (european)
	amerindian
	semitic
	middle eastern          (eastern)
	indo-aryan              (aryan)
	malay

poses
	high
	mid
	low

///////////////// MATERIALS /////////////////

general
    eye color
    hColor
    makeup
    fingernails

skin color
    pure white		        (Ceridwen)
    ivory		            (Ceridwen)
    white		            (Ceridwen)
    extremely pale		    (Celinette)
    very pale		        (Celinette)
    pale		            (Kimmy)
    extremely fair		    (Kimmy)
    very fair		        (Saffron)
    fair		            (Saffron)
    light		            (FemaleBase)
    light olive		        (FemaleBase)
    tan		                (Reagan)
    olive		            (Kathy)
    bronze		            (Mylou)
    dark olive		        (Adaline)
    dark		            (Daphne)
    light beige		        (Minami)
    beige		            (Tara)
    dark beige		        (Topmodel)
    light brown		        (Topmodel)
    brown		            (Angelica)
    dark brown		        (Angelica)
    black		            (DarkSkin)
    ebony		            (DarkSkin)
    pure black		        (DarkSkin)

dick color
    pure white	            (WhiteFuta)
    ivory	                (WhiteFuta)
    white	                (WhiteFuta)
    extremely pale	        (WhiteFuta)
    very pale	            (WhiteFuta)
    pale	                (WhiteFuta)
    extremely fair      	(WhiteFuta)
    very fair	            (LightFuta)
    fair	                (LightFuta)
    light	                (LightFuta)
    light olive	            (LightFuta)
    tan	                    (MidFuta)
    olive	                (MidFuta)
    bronze	                (MidFuta)
    dark olive          	(MidFuta)
    dark	                (MidFuta)
    light beige	            (MidFuta)
    beige	                (MidFuta)
    dark beige	            (DarkFuta)
    light brown	            (DarkFuta)
    brown	                (DarkFuta)
    dark brown	            (DarkFuta)
    black	                (DarkFuta)
    ebony	                (DarkFuta)
    pure black	            (DarkFuta)

///////////////// MESH /////////////////

General
    genesis8
    vagina
    dick

Hairstyle
	Neat					(Samira)
	Afro					(Yara)
	Braided					(Mishka)
	Cornrows				(Tiger)
	Curled					(Havana)
	Dreadlocks				(Dreads)
	Eary					(Georgina)
	In a bun				(Adia)
	In a messy bun			(Krayon)
	In a ponytail			(Ponytail)
	In tails				(Kinley)
	Luxurious				(Baroness)
	Messy					(Messy)
	Permed					(Ichigo)
	Shaved sides			(Rebel)
	Up						(Pina)
	Half-Shaved				(Edit)
	Bangs					(Neko)
	Hime					(Nyo)
	Drills					(Bunny)