User:Lucia Dossin

From XPUB & Lens-Based wiki
Revision as of 08:29, 3 July 2015 by Lucia Dossin (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Graduation

Thesis

Listed chronologically, recent items first.

Graduation Project

Cassandra

Cassandra is a voice-operated chatbot, aimed at making psychological profiles during the conversations. These profiles are shown as pie charts where every color corresponds to a personality attribute. The graphics are accompanied by a short analysis and a list of companies possibly interested in the profile. In this sense, the bot provides data that can act as a mediator in services like job-seeking and dating. The profile then becomes a digital representation of the user and can be used as a kind of digital key to personalize every gadget in the near future of the Internet of Things. Make your life easier, let Cassandra make a digital copy of you.
Cassandra-card.png
Cassandra is built upon 3 main aspects: user data as content, voice as interface and ELIZA (Joseph Weizenbaum's program, written in 1964/1966) as engine.

User Data

Interaction is a relationship between at least two parts. Whenever only one part has access to information, we can say there is a power asymmetry. This is one of my points of interest in this research.

User generated data is the common input format to feed smart technologies, a substitute for direct user interaction or input – something I will call passive interaction. I argue that the shift from active to passive interaction provides not only the advertised ease of use but also an experience where the user loses power. There is certainly a trade-off, I am just not sure if the price in the long-term is clear to the user.

Voice

Besides the symbolic importance of the voice as a personal and embodied human asset, a voice interface is also a good reference to the illusion of the 'no-interface' (widely understood as non-visual). I call it an illusion because in fact not only it does not remove but actually it adds one more mediation layer between humans and machines, since the speech recognition translates the spoken words into text (a layer that does not exist when the user is directly typing or clicking buttons, for example). This became very clear when during the project development I moved from typed chat to spoken chat: there was much more misunderstanding when the user talked than when the user typed.

ELIZA

I saw in ELIZA a good oportunity to make a humble tribute to Weizenbaum's 'Against the Imperialism of Intrumental Reason' (Computer Power and Human Reason, 1976, Chapter 10) and the essential difference between decision and choice. Also, I was curious to see whether a 50-year-old program involving (psychological) interaction between human and computer would still be up-to-date.

The market for code and emotions

There is a reasonably high number of similar products and services on the market as of now. They offer commercial or personal advice, simulate relationships, and in different ways intertwine code and emotions.

I hereby assume a cynical position and portray the user as a pie chart – colorful and unique, but still a pie chart. By doing that, I believe to be exercising 'playful critique' to practices like this.

The pie chart

The graphic resulting from the conversation is composed of 6 colors – each one representing one personality attribute. The one closer to the center is based on the frequency in which the user says certain words and represents the degree of self-confidence. The other 5 colors are based on answers to yes-no questions, triggered during the conversation every time certain keywords are detected.

These keywords were defined through free association by a group of friendly volunteers. They were presented one word (which was taken from a psychological profile questionnaire and related to a certain personality attribute) and made the free association. For example: they were presented the word 'extremists', which can be found in the questionnaire relating to Social and Political Attitudes. Several connections were made to this word and they are all used to trigger questions that will evaluate Social and Political Attitudes during the conversation with the user.

Process

Connections1.png
The Free Association engine interface

Connections2.png
One of the resulting txt files containing the words pairs (first, the word presented to the user - second, the freely associated word)

Netpict-lowres.png
Graphical view of all words and connections (uploading an updated version of this file does not seem to be allowed by the WIKI at the moment)

Words-questions.png
Implementation of the connections into the code

Code

The project is composed of 3 web pages. The first one introduces the project and invites the user to chat, which happens on the second page. The third page shows the resulting profile and allows it to be printed.

The code below refers to pages 2 and 3.

conversation.html

<!DOCTYPE html>
<head>
	<title>Your life, just easier.</title>
	<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700' rel='stylesheet' type='text/css'>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
	<link href="style.css" rel="stylesheet" type="text/css">
	<style>		
		.hidden {
		  display: none;
		}
		textarea{resize:vertical; display: none; }
		#transf, input{display: none;}
		#transcription{color: #333; font-weight: bold; resize: none; }
		#indication{width: 100%; height: 460px; text-align: center; }
		#indication img{width: 60%; }
		#log{text-align: center;}
		#buttons{text-align: center;}
	</style>
	
	<script language="JavaScript" type="text/javascript" src="elizabot.js"></script>
	<script language="JavaScript" type="text/javascript" src="elizadata.js"></script>

<script language="JavaScript" type="text/javascript">
// code fashionistas, beware: the lines below are not as elegant as they could be.
var s = new Date();
var start;
var e;
var end;
start = s.getTime();


var IMeMy = ["I", "me", "my", "My"];
var WeUsOur  = ["we", "us", "our", "We", "Our"];

var IMeMyCount = 0;
var WeUsOurCount = 0;
var BigWordsCount = 0;

var totalWords = 0;

var IMeMyPerc = 0; // if < 7 self-confident
var WeUsOurPerc = 0; //if > 4 self-confident
var BigWordsPerc = 0; //if > 12 self-confident
var selfConfidence = 0;

var nextAnswer = '';
var curTopicNumber;
var introversion;
var emotionalstability;
var toughmindness;
var sexuality;
var politic;


 function post(path, params, method) {
    method = method || "post"; // Set method to post by default if not specified.

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            var hiddenField = document.createElement("input");
            hiddenField.setAttribute("type", "hidden");
            hiddenField.setAttribute("name", key);
            hiddenField.setAttribute("value", params[key]);

            form.appendChild(hiddenField);
         }
    }

    document.body.appendChild(form);
    form.submit();
}

 
//make profile
function makeprofile(){
	BigWordsPerc = BigWordsCount/totalWords * 100;
		if(BigWordsPerc >= 12){
			selfConfidence += 1;			
		}
	//IMeMy
	IMeMyPerc = IMeMyCount / totalWords * 100;
	//console.log('IMeMyCount ' + IMeMyCount + 'Perc ' + IMeMyPerc);
	if (IMeMyPerc <= 6){
		selfConfidence += 1;	
	}
	//WeUsOur
	WeUsOurPerc = WeUsOurCount / totalWords * 100;
	//console.log('WeUsOurCount ' + WeUsOurCount + 'Perc ' + WeUsOurPerc);
	if (WeUsOurPerc >= 4){
		selfConfidence += 1;	
	}

	selfConfidence = selfConfidence * 25;
	if(selfConfidence <= 25){
		selfConfidence += Math.random() * (24 - 3) + 3;
		//alert(selfConfidence);
	}	
	
	//for other traits values, calculation MUST include nr of points / nr of asked questions, in PERCENTAGE format
	//the default values in php ARE ALREADY in percentage
	//number means how many questions were asked belonging to the topic
	//counter means how many points were scored (answer to question must match)
	//resulting value sent for graphic will be counter/number
	if(topics[0]['number'] >= 1){
		introversion = topics[0]['counter']/topics[0]['number'] * 100;
		if(introversion < 1){
			introversion = 1;
		}
	}else{
		introversion = 'default';
	}
	
	if(topics[1]['number'] >= 1){
		emotionalstability = topics[1]['counter']/topics[1]['number'] * 100;
		if(emotionalstability < 1){
			emotionalstability = 1;
		}
	}else{
		emotionalstability = 'default';
	}
	
	if(topics[2]['number'] >= 1){
		toughmindness = topics[2]['counter']/topics[2]['number'] * 100;
		if(toughmindness < 1){
			toughmindness = 1;
		}
	}else{
		toughmindness = 'default';
	}
	//console.log(toughmindness);
	
	if(topics[3]['number'] >= 1){
		sexuality = topics[3]['counter']/topics[3]['number'] * 100;
		if(sexuality < 1){
			sexuality = 1;
		}
	}else{
		sexuality = 'default';
	}
	
	if(topics[4]['number'] >= 1){
		politic = topics[4]['counter']/topics[4]['number'] * 100;
		if(politic < 1){
			politic = 1;
		}
	}else{
		politic = 'default';
	}
	//alert(elizaLines);
	e = new Date();
	end = e.getTime();
	
	post('result/', {selfconfidence: selfConfidence, introversion: introversion, emotionalstability: emotionalstability, toughmindness: toughmindness, sexuality: sexuality, politic: politic , duration: (end - start)}); //saving data and duration to database. dialogues are not being sent.
	
}

var topics = [
{ 					  "name" : "introversion",
					  "number": 0,
					  "counter":0, 
					  "words": [ "shy", "fear", "alone", "introvert", "activity", "restless", "sleep", "rush", "party", "socialize", "people", "conversation", "confident", "careful", "lock", "guarantee", "change", "insecure", "cancer", "gamble", "risk", "impulsiveness", "thoughtful", "easy-going", "plan", "self-control", "expressive", "inhibition", "sentimental", "embarassment", "horse riding", "rain", "mat", "life", "job", "friendly", "champion", "violence", "fuck",  "extravert", "x-men", "tired", "expression", "facebook", "death", "work", "wanted", "exhibition", "idea", "control", "sheep", "couch", "law", "metal", "distance", "less", "sun", "caracter", "job", "gang",  "red", "song", "awkward", "map", "disconect", "blood", "pencil",  "night", "son", "night", "question", "happy", "rigid", "urge", "football", "pop", "emotion", "aim", "silence", "revolution", "free",  "plan", "under",  "starter", "planning", "chance", "door", "multitude", "slow", "biking", "anemic", "hour", "death", "why", "dishonest", "isolate", "less", "sometimes", "chill", "sweet", "stance", "down",  "escape", "contract", "communication"],
					  "questions": [["do you like going out a lot?","yes"],["do you often need understanding friends to cheer you up?","yes"],["generally, do you prefer reading to meeting people?", "no"],["are you fairly talkative when you are with a group of people?","yes"],["do you usually let yourself go and have a good time at a party?","yes"],["do you hate being with a crowd who play jokes on one another?","no"],["do you like talking to people so much that you never miss a chance to talk to a stranger?","no"],["if you were making a business enquiry would you rather write than discuss it on the phone?","no"],["do you enjoy spending long periods of time by yourself?","no"],["are you relaxed and self-confident in the company of other people?","yes"],["are you more distant and reserved than most people?","no"],["do you like mixing with lots of other people?","yes"],["do you easily make new friends with people of your own gender?","yes"],["do you like to tell jokes and stories to groups of friends?","yes"],["do you enjoy talking and playing with young children?","yes"],["are you apprehensiveabout going into a room full of strange people?","no"],["have you ever seriously felt you might be happier living by yourself on a desert island?","no"],["do you sometimes feel umcomfortable when people get too close to you physically?","no"],["is it important to you to be liked by a wide range of people?","yes"],["do you spontaneously introduce yourself to strangers at social gatherings?","yes"],["would you rather spend an evening talking to one interesting person of the same gender as you than singing and dancing with a large crowd of friends?","no"],["do you like to be in the middle of things socially speaking?","yes"],["do you enjoy solitary activities such as playing patience and solving cross-word puzzles?","no"],["are you inclined to avoid people whenever possible?","no"],["would you be very unhappy if you were prevented from making numerous social contacts?","yes"],["do you usually prefer to spend your leisure time in the company of others rather than alone?","yes"], ["do you like to have many social engagements?","yes"],["do you enjoy entertaining people?","yes"],["are you inclined to limit your acquaintances to a select few?","no"],["do you often feel at ease with other people?","yes"]]},
{					  "name": "emotionalstability",
					  "number": 0,
					  "counter":0,
					  "words": ["documentaires", "feelings", "color", "colour", "intimate", "sports", "poetry", "library", "history", "responsibility", "concentration", "trust", "alcohol", "forget", "provision", "dental", "self-esteem", "proud ", "failure", "inferiority",  "inadequacy", "enough", "sincere", "appearance", "opinion", "luck", "miserable", "angry", "smile", "wrong", "lonely", "anxious", "insomnia", "friends", "awkward", "error", "afraid", "dark", "death", "shaky voice", "obsession", "superstition", "innacuracies", "list", "dirt", "discipline", "dog", "cat", "late", "stupid", "living", "universe", "mask", "white", "rave", "situation", "good",  "miss", "stupid", "hard",   "idiot", "criticism", "where", "great", "work", "suspicious", "small", "bottle", "sadness", "death", "right", "sad", "regular", "high", "vegetarians", "kindle", "weather", "tangerines", "kangaroo", "navigator", "disadvantage", "pitch", "capital", "mirror", "dash", "cloud", "loud", "flavour", "metal", "collector", "late", "date", "whale",   "sun", "repeat", "plenty", "never", "sad", "success", "white", "pleasure", "warm", "sad", "cross", "mess", "cross", "pink",  "moon", "earth", "song", "finger", "hand", "tail", "focus", "attachement", "fail", "everything", "over", "sold", "brain", "trick", "rare", "value", "boring", "difficult", "dumb", "value", "smile", "ivory tower", "smart", "mad", "drug", "piet zwart", "obsessive", "light", "sparta", "mature", "past", "strict", "time", "nice", "parents", "sex", "facebook", "stalker", "stalker", "stalker", "present","redirect", "biking", "clarity", "immutable", "uneasyness", "unconcentrated", "death", "learned", "day", "honest", "less", "silence", "many", "taste", "strong", "stance",  "failure", "blind", "group", "escape", "sad",  "together", "polite", "well done"],
					  "questions": [["do you seem to have more than your share of bad luck?","no"],["do you often feel depressed in the morning, when you wake up?","no"],["in general, would you say you are satisfied with your life?","yes"],["do you find a good deal of happiness in life?","yes"],["do you sometimes feel that you don't care what happens to you?","no"],["do you generally feel good?","yes"],["do you ever feel 'just miserable' for no good reason?","no"],["do you see your future as looking quite bright?","yes"],["have you ever wished you were dead?","no"],["do you often feel down?","no"],["do things often seem hopeless to you?","no"],["do you smile and laugh as much as most people?","yes"],["have you often felt listless and tired for no reason?","no"],["are you often bothered by noise?","no"],["do you feel that you often get a raw deal out of life?","no"],["do you think that people don't really care what happens to you?","no"],["do you often suffer from loneliness?","no"],["do you think you are contributing to the world and leading a useful life?","yes"],["is there at least one person in the world who really loves you?","yes"],["would you agree that it is hardly fair to bring a child into the world the way things look now?","no"],["generally speaking have you been succesful in achieving your aims and goals in life?","yes"],["are you often overcome by sadness?","no"],["does it seem to you that it is always other people who get the best?","no"],["is it a long time since you last felt on top of the world?","no"],["do you feel cheated when you look back on what has happened to you?","no"],["are you about as happy as other people?","yes"],["do you often get the feeling that you just not a part of things?","no"],["is your sleep usually disturbed?","no"],["do you often feel lonely when you are with other people?","no"],["do you feel a sense of inner calm and contentment most of the time?","yes"]]},
{					  "name": "toughmindness",
					  "number": 0,
					  "counter":0, 
					  "words": ["independence", "dependency", "cigarette", "god", "management", "parents", "others", "power", "nobody", "everybody", "rules", "hypochondria", "sickness", "medicine", "drugs", "stomach", "family", "health", "problem", "pain",  "guilt", "sin", "disapproval", "pleasure", "karma", "accident", "cinema", "tear", "shaking", "sad", "never", "ache", "chance", "hug", "anxiety", "miss", "plug", "now", "water", "hardest", "sex", "problems", "ilusion", "broken",  "necessary", "happens", "care", "friends", "health", "catholic",  "electricity", "ash", "culture", "empty", "knows", "navigator", "surreal", "age", "sincere", "lenght",  "nobody",  "sorrow", "disallowal", "white", "teacher", "many", "acute", "genitals", "els", "deception", "frustration", "man", "solver", "world", "tears", "hell", "drug", "agree",  "mad",  "evil", "guard", "sick", "old", "nice", "bear", "send",  "mask", "god", "solution", "solution", "solution", "multitude", "cabinet", "regret", "time", "blood", "day", "innocent", "mediocre", "honest", "gods", "freedom", "taste", "evil", "fresh", "dependence", "man", "group", "polite"],
					  "questions": [["do you find it difficult to stop once you got wound up into a heated discussion?","yes"],["do you think it is dangerous to compromise with political opponents?","yes"],["would you prefer to be a dead hero than a live cowatd?","yes"],["are you forthright and uncompromising in arguments?","yes"],["do you believe that the 'tried and true' ways are always the best?","yes"],["do you have very clear ideas about what is right and wrong?","yes"],["once you  have made up your mind about something do you stick to your decision no matter what?","yes"],["do you believe there is only one true religion?","yes"],["do you often question your own morality and rules of conduct?","no"],["do you agree that most politicians talk a lot of rubbish?","yes"],["do you think people with extreme political views should be allowed to express them in public?","no"],["in the case of a disagreement do you try to put yourself in the other person's position and try to understand their point of view?","no"],["do you attempt to convert others to your point of view on matters of religion, morality and politics?","yes"],["do you sometimes argue for the sake of argument, even when you know underneath that you are wrong?","yes"],["do you find that your own way of attacking a problem always turns out to be the best in the long run?","yes"],["does it annoy you when a supposed expert fails to come up with a definite solution to a social problem?","yes"],["do you think it would be a good thing if everybody shared the same ideas and values?","yes"],["are you inclined to see things in shades of grey rather than in black or white?","no"],["do you think a good teacher is one who makes you wonder rather than telling you all the answers?","no"],["does your blood boil when people stubbornly refuse to admit they are wrong?","yes"],["are you often uncertain as to which way you are going to vote in an ellection?","no"],["do you think that other cultures have a lot to teach us about how to live?","no"],["do you find it easy to be friendly with people of different religions than your own?","no"],["do you think it is often necessary to use force to advance an idea?","yes"],["do you change your mind if someone puts up a convincing argument?","no"],["do you think there is a core of truth in nearly everybody's point of view?","no"],["do you often repeat yourself to make sure you are properly understood?","yes"],["do you carefully consider everybody else's viewpoint before arriving at your own?","no"],["do you determine nearly all of your conduct in relation to a single great cause?","yes"],["are you shocked by the ignorance shown by the majority of people on social and political matters?","yes"]]},
{					  "name": "sexuality",
					  "number": 0,
					  "counter":0, 
					  "words": ["sexual", "experiences", "conscience", "criticism", "aggressiveness", "politicians", "fight", "swear", "forgiveness", "pacifists", "coward", "irritation", "gentle", "burglar", "sarcasm", "guns", "assertiveness", "complaint", "authority", "obedience", "rights", "television", "interview", "poor", "ambition", "aspirations", "important", "person", "community", "success", "lazy", "holidays", "performance", "winner", "loser", "manipulation", "honesty", "shortcut", "advantage", "help", "useful", "adventure", "predictable", "exotic", "horror", "boredom", "foreigners", "pornographic",  "peace", "phobias", "noise", "late", "late", "aims", "disintegration", "pleonasm", "robot", "s***", "horny", "stalin", "witch",  "art", "high", "movie", "animal", "impossible", "when", "bro", "time", "maybe", "love", "pleasure", "killers", "generosity", "death", "contructivism", "sorry", "forgotten", "sun", "weak", "maturity", "scary", "sun", "routine", "anger", "relevant", "fun", "sadness", "country", "police", "film", "assault", "meeting", "lefts", "hate",  "bed", "night", "option", "honor", "metal", "late", "pension", "sincere", "ego", "meat", "smoking", "facebook", "sun",  "hippies", "illusion", "everything", "cinegraphic", "decent", "gray", "movie", "nails", "many", "pink", "green", "claws", "suit", "battle", "triggering", "attachement", "sold", "rich", "rage", "lie", "liar", "profile", "boring", "difficult", "need", "curry", "blood", "future", "problem", "genitals", "bill", "reason", "manual", "irony", "interviewee", "ivory tower", "pop", "mass media",  "rock",  "information", "mad",  "victory", "aplenty", "cool", "involved", "home", "calm", "abroad", "unhappy", "nice", "judgement", "touch", "major", "sex", "robot", "uprooting", "lie", "3d", "solution", "solution", "solution", "multitude", "biking", "watchdogs", "trailer", "commitment", "father", "joy", "need", "time", "handy", "mediocre", "honest",  "attraction", "emptyness", "taste", "trips", "corporation", "torture", "girl", "mutiple", "coming", "man", "together", "weapons", "ahead",  "truth", "polite", "obvious"],
					  "questions": [["Sometimes it has been a problem to control your sexual urges. do you agree?","yes"],["are sexual feelings sometimes unpleasant for you?","yes"],["your sex behaviour has never caused you any trouble. is that true?","yes"],["do you consciously try to keep sex thoughts out of your mind?","yes"],["have you ever felt guilty about sexual experiences?","yes"],["have you at times been afraid of yourself for what you might do sexually?","yes"],["do thoughts about sex disturb you more than they should?","yes"],["does your conscience bother you too much?","yes"],["do sexual feelings sometimes overpower you?","yes"],["do you worry a lot about sex?","yes"],["does thinking about sex sometimes make you nervous?","yes"],["Do perverted thoughts sometimes bother you?","yes"],["have you had some bad experiences in sex when you were young?","yes"]]},
{					  "name": "politic",
					  "number": 0,
					  "counter":0,
					  "words": ["dogmatism", "discussion", "compromise", "argument", "religion", "stupid", "respect", "masculine", "feminine", "science", "beauty", "sad", "shopping", "violence", "animals", "intuition", "blood", "war", "hug", "flowers", "bird", "children", "sex",  "body", "relationship", "erotic", "nude", "physical", "pervert", "homosexuals", "virgin", "abortion", "immoral", "faithfulness", "exciting", "stranger", "baby", "politics", "punk", "modern-art", "birth-control", "laws", "rape", "non-sense", "censorship", "racism", "charity", "waste", "immigrants", "democracy", "belief", "hypocrites", "sunday", "church", "UFOs", "telepathy", "bankers",  "truth", "socialism", "capitalism", "taxpayer", "privileges", "business", "labour", "government", "private-property", "aristocracy", "civilization", "wealth", "poverty", "mental illness", "inefficiency", "progress", "economy", "strikes", "libertarian", "minority", "extremists", "agenda",  "army", "reactionary",  "prison", "tradition", "pop music", "leaders", "pacifism", "dialogue", "glorious past", "social-progress", "hunting", "territory", "conflicts", "atom-bomb", "atom bomb", "innocent",  "capital", "influence", "form", "space", "talk", "speak", "plus", "goals",  "future", "nudity", "connection", "serious", "pathology", "there", "sick", "cats", "post", "utopias", "orange", "time", "tank",  "pain", "building", "forest", "three", "city", "everywhere", "hug", "sometimes", "critisism", "apathy",  "hard", "harder", "hate", "nothing", "idiot", "idiot", "necessary", "peaceful", "always", "illusion", "follow", "break", "care", "south", "over", "constructs", "distruction", "necessary", "children", "control", "assholes", "strange", "modern-art", "conflict", "deal", "help", "stains", "intolerant", "lies", "poverty", "deer", "topic", "moral", "plant", "past", "music", "report", "vein", "again", "islands", "customs", "scale",  "nice", "gutt", "milk", "oligarchy", "pray", "navigator", "mammal", "shiver", "intellectual", "creator", "late", "sink", "regulation", "cake", "postcolonial", "beards", "men", "ship", "straight", "trope", "puke", "dictionairy", "safe",  "entertainment", "mary", "uganda", "report", "africa", "language",  "necessary", "unavoidable",  "none", "non-existent", "possition", "migrant", "contemporary", "facism", "bell", "tough", "father", "columns", "bars", "stress", "complicated", "shoe", "pink", "pink", "ugly", "machine", "red", "money", "chair",  "black", "madonna", "team", "work", "military", "genitals", "idiot", "partition", "attachment", "deadline", "off", "criticise",  "sold", "two", "greed", "rats", "dance", "strong", "garbage", "zizek", "rich", "ugly", "problem", "smile", "difficult", "honesty", "hypocrite", "trick", "bad", "manual", "fundamentalist", "smart", "USA",  "pop", "telekinesis", "intellectuals", "list", "war", "mad", "banana skin", "stupid", "information", "false", "star sign",  "example", "mad", "silence", "paint", "revolution", "market", "silk", "political", "freedom", "evil", "hard", "suit", "starter", "bear", "take-over", "grade", "lie", "window", "washington", "planning", "victim", "moral", "dog", "library", "abundance", "present", "group", "aretha franklin", "broken", "solution", "solution", "solution", "position", "survival", "product", "unorganised", "clarity", "average", "attack", "plan", "immutable", "permit", "hierarchy", "chaos", "problem", "unconcentrated", "masculine", "day", "need", "unfair", "weapon", "heritage", "new", "mediocre", "dishonest", "psycho", "evolution", "feel", "pill", "f*******", "f***", "conflict", "being", "pro-choice", "crap", "break", "whatever", "mental", "cold", "wart", "hate", "muscle", "fart", "mind", "nature", "lazy", "rights", "dictatorship", "plunder", "plan", "system", "free", "idea", "destroy", "game", "faith", "part", "weak", "brain", "communication", "weird"],
					  "questions": [["it is only by returning to our glorious and forgotten past that real social progress can be made. do you agree?","yes"],["the government is gradually taking away our basic freedom. do you think that is true?","yes"],["do you think that life in the old days used to be much more plesant than nowadays?","yes"],["do you think that the Church is the main fortress opposing the evil trends of modern society?","yes"],["Picasso and other modern painters are in no way inferior to past masters like Rembrandt or Titian. Do you agree?","no"],["do you agree that most of the countries which have received economic help from us end up resenting what we have done for them?","yes"],["the biggest threats to this country during the last 50 years have come from foreign ideas and agitators. do you agree?","yes"],["do you think it is better to stick by what you have than to be trying new things you don't really know about?","yes"],["do you think that tradition has too much influence in this country?","no"],["do you think that the 'new look' in drama and tv shows is an improvement on the old-fashioned type of entertainment?","no"],["do you think that sexual immorality destroys the marriage, which is the basis of our civilization?","yes"],["life is not perfect nowadays, but it is much better than it used to be. do you agree?","no"],["do you think most modern art is pretentious nonsense?","yes"],["do you think that if you start trying to change things very much, you usually make them worse?","yes"],["do you think it is always a good idea to look for new ways of doing things?","no"],["scientific inventions have carried us too far too fast. we should be given a resting pause now. do you agree?","yes"],["do you think that morals in this country are pretty bad and geting worse?","yes"]]}
]


// shuffle arrays with questions, for variation
// The de-facto unbiased shuffle algorithm is the Fisher-Yates (aka Knuth) Shuffle.
function shuffle(array) {
  var currentIndex = array.length, temporaryValue, randomIndex ;

  // While there remain elements to shuffle...
  while (0 !== currentIndex) {

    // Pick a remaining element...
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // And swap it with the current element.
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  return array;
}

for(var a=0; a< topics.length; a++){
	shuffle(topics[a]['questions']);
}


var catchya = false;
var listen = false; //listen to the answer and score it or not, gives priority to the answer not the keywords

var sut = new SpeechSynthesisUtterance();
sut.lang = "en-US";

sut.onstart = function(){
	document.getElementById("start_img").src="graphics/mic-disabled.png";
}

sut.onend = function () {
	document.getElementById("start_img").src="graphics/mic.png";
};

// ELIZA JS / SOURCE: http://www.masswerk.at/elizabot/
// Modified for PZI Graduation Project by Lucia Dossin

var eliza = new ElizaBot();
var elizaLines = new Array();
var conversation = "";

var displayCols = 60;
var displayRows = 20;

function elizaReset() {
	eliza.reset();
	elizaLines.length = 0;
	elizaStep();
}

function elizaStep() {
	
	var f = document.forms.e_form;
	var userinput = f.e_input.value;
	//here user input
	console.log('usr -> '+ userinput);
	if (eliza.quit) {
		f.e_input.value = '';
		if (confirm("This session is over.\nStart over?")) elizaReset();
		f.e_input.focus();
		return;
	}
	else if (userinput != '') {
		var usr = 'YOU   ' + userinput;
		var rpl ='CASSANDRA ' + eliza.transform(userinput);
		elizaLines.push(usr);
		conversation += usr + '\n';
		conversation += rpl + '\n';
		
		var temp  = new Array();
		var l = 0;
		for (var i=elizaLines.length-1; i>=0; i--) {
			l += 1 + Math.floor(elizaLines[i].length/displayCols);
			temp.push(elizaLines[i]);
		}
		elizaLines = temp.reverse();
	}
	else if (elizaLines.length == 0) {
		// no input and no saved lines -> output initial
		var initial = 'CASSANDRA ' + eliza.getInitial();
	}
	f.e_input.value = '';
	f.e_input.focus();
}



function sayInstructions(){
	var instructions = "Hi, I am Cassandra. Click on Relink button if the connection seems broken. Click on Finish at any time to make your profile.";
	var si = new SpeechSynthesisUtterance();
	si.lang = "en-US";
	si.text = instructions;
	speechSynthesis.speak(si);
	
	si.onstart = function(){
		//console.log('su start');
		document.getElementById("start_img").src="graphics/mic-disabled.png";
	}
	
	si.onend = function () {
		window.setTimeout('elizaReset()',1200);
		try {
			recognizer.start();
			log.innerHTML = '';
		} catch(ex) {
			document.getElementById("start_img").src="graphics/mic-dash.png";
			log.innerHTML = 'Cassandra cannot hear you. Please press the Relink button below. ';             
		}
	};	
}
</script>
</head>

<body onload="window.setTimeout('sayInstructions()',2000)">
<div id="header">
<a  href="index.html" title="Meet Cassandra!"><div class="item"><span>1</span> About</div></a>
<div class="item current"><span>2</span> Talk</div>
<div class="item"><span>3</span> Your Profile</div>
</div>
<div id="container">

	<form name="e_form" onsubmit="elizaStep();return false">
		<textarea name="e_display" cols="60" rows="20"></textarea><br>
		<textarea id="transcription" cols="60" rows="1" readonly="readonly"></textarea><br>
		<input type="text" id="transf" name="e_input" size="50" placeholder="You can type, too." ><br>
		<input type="submit" value="&nbsp;Type&nbsp;"> <input type="reset" value="Reset" onClick="window.setTimeout('elizaReset()',100)">
	</form>
	
	<div id="indication">
		<img id="start_img" src="graphics/mic-animated.gif" />
	</div>
	
	<div id="log"></div>
	<div id="buttons">
		<button id="restart"><i class="fa fa-refresh"></i> Relink</button>
		<button id="stop"><i class="fa fa-check-square-o"></i> Finish</button>
	</div>
	<span id="ws-unsupported" class="hidden">Web Speech API is not supported by your browser.</span>
</div>

 <script>  
      // Test browser support
      window.SpeechRecognition = window.SpeechRecognition       ||
                                 window.webkitSpeechRecognition ||
                                 null;
 
      if (window.SpeechRecognition === null) {
        document.getElementById('ws-unsupported').classList.remove('hidden');
      } else {
        var recognizer = new window.SpeechRecognition();
        var recognizing = false;
        var ignore_onend = false;
        var transcription = document.getElementById('transcription');
        var log = document.getElementById('log');
 
        // Recogniser doesn't stop listening even if the user pauses
        recognizer.continuous = true;
        recognizer.interimResults = true;
	
	function resetString(){
		log.innerHTML = '';
	}
        
        recognizer.onstart = function() {
		document.getElementById("start_img").src="graphics/mic-disabled.png";
		recognizing = true;
	};
			
	recognizer.onerror = function(event) {
		if (event.error == 'no-speech') {
			//alert('no speech');				
			ignore_onend = true;
		}
		if (event.error == 'audio-capture') {
			//alert('info_no_microphone');
			ignore_onend = true;
		}
		document.getElementById("start_img").src="graphics/mic-dash.png";
		log.innerHTML = 'Cassandra cannot hear you. Please press the Relink button below. ';
		
	};
	
	recognizer.onend = function() {
		recognizing = false;
		document.getElementById("start_img").src="graphics/mic-dash.png";
		if (ignore_onend) {
			return;
		}
	};
	
	recognizer.onstop = function(){
		document.getElementById("start_img").src="graphics/mic-dash.png";
		recognizing = false;			
	}	
			 
	
	function isInArray(arr, word) {
	   return arr.indexOf(word.toLowerCase()) > -1;
       }
 
        // Start recognising
        recognizer.onresult = function(event) {
	     transcription.textContent = '';
	     
         
          for (var i = event.resultIndex; i < event.results.length; i++) {
            if (event.results[i].isFinal) {
		conversation += 'YOU ' + event.results[i][0].transcript + '\n';
		catchya = false;
		transcription.textContent = event.results[i][0].transcript ;
                /*
               \w+    between one and unlimited word characters
		/g     greedy - don't stop after the first match
		*/
              var wordCounter = event.results[i][0].transcript.match(/(\w+)/g).length;
              totalWords += wordCounter;
              var wordSize = 0;
		//I, Me, My              
              for(var m=0; m<IMeMy.length; m++){
		if( event.results[i][0].transcript.includes(IMeMy[m])){
		IMeMyCount +=1;
		}
	      }
		//We, Us, Our
		for(var u=0; u<WeUsOur.length; u++){
		  if( event.results[i][0].transcript.includes(WeUsOur[u])){
		  WeUsOurCount +=1;
		  }
		 }
		 //Big Words
		 wordSize = (Math.floor(event.results[i][0].transcript.length / wordCounter));
		 if (wordSize >= 9){
			BigWordsCount ++;					  
		 }
		
		//phishing questions	
		for(w=0; w<topics.length; w++){
		       //console.log(w);
		       if(!listen){
			       for(var wo = 0; wo < topics[w]['words'].length; wo++){
				       //console.log(topics[w]['words'][wo])
				       if( event.results[i][0].transcript.includes(topics[w]['words'][wo])){ 
					   console.log('catch ' + w + '-> '+ topics[w]['words'][wo]);
					   catchya = true;
					   listen = true;
					   curTopicNumber = w;
					   //break;
				       }
				}	
			} // end !listen
		}
		if(catchya){
			   nextAnswer = topics[curTopicNumber]['questions'][0][1];
			   console.log(nextAnswer);
			   catchya = false;
			   sut.text = topics[curTopicNumber]['questions'][0][0];
			   //removes first question to avoid repetition in an easy way - leaving the last one to avoid empty array
			   if(topics[curTopicNumber]['questions'].length > 1){
			       topics[curTopicNumber]['questions'].shift();
			   }
			   
			   topics[curTopicNumber]['number'] += 1; //adds one to number of asked questions in the topic
			   conversation += 'CASSANDRA ' + sut.text + '\n';
			   speechSynthesis.speak(sut);
			   break;
			
		}else{
		
			console.log('getting here!');
		       //check answer
		       if(listen){
		        if(~event.results[i][0].transcript.indexOf(nextAnswer)){
				console.log('score!'+ nextAnswer );
				 
				//scores point
				if(curTopicNumber){
				       topics[curTopicNumber]['counter'] += 1; //adds one to number of asked questions
				}				
				nextAnswer = '';
			} 
		} // end listen  
		  listen = false; 
		  document.getElementById('transf').value = event.results[i][0].transcript;
		  document.getElementById("start_img").src="graphics/mic-disabled.png";
		  elizaStep();	    
		}	  							           
               
            } else {
              transcription.textContent += event.results[i][0].transcript;
              document.getElementById("start_img").src="graphics/mic-animate.gif";
            }
          }  
        };
 
 
          //was here
 
        document.getElementById("restart").onclick = function () {
		if (recognizing) {
			recognizing = false;
			recognizer.stop(); 
		}       
		recognizer.start();
		log.innerHTML = 'Conversation with Cassandra re-started!' ;
		document.getElementById("start_img").src="graphics/mic-disabled.png";
		sut.text = "It seems we had a connection problem. I'm back! What were you saying?";
		speechSynthesis.speak(sut);
		setTimeout('resetString()', 6000);
      };
      
      
        document.getElementById("stop").onclick = function () {
		if (recognizing) {
		       recognizing = false;
		       recognizer.stop();        				
		}
		speechSynthesis.cancel();
		document.getElementById("start_img").src="graphics/mic-dash.png";
		var bye = new SpeechSynthesisUtterance();
		bye.lang = "en-US";
		bye.text="Goodbye. It was a pleasure to meet you.";
		speechSynthesis.speak(bye);
		bye.onend = function(){
			makeprofile();
		}	
		log.innerHTML = 'Your profile will be made.' ;

	};  
}
    </script>

</body>
</html>

style.css

body{margin: 0; font-family: 'Open Sans', 'Helvetica', 'Arial', sans-serif; font-weight: light; }
h1, h2, h3, h4, h5, h6{font-weight: normal;}
#header{width: 96%;  max-width: 1280px; min-width: 640px; margin: 0 auto; background-color: #dfdfdf; height: 3em;}
.item{ float: left; color: #fff !important; width: 32%; border-left: 3px solid #fff; height: 100%; padding-left: 9px; padding-top: 0px; text-shadow: 1px 1px #666; }
.item span{font-size: 210%;font-weight: lighter;}
.current{background-color: #bbb; text-shadow: 1px 1px #666;}
#container{width: 80%; max-width: 600px; min-width: 400px; margin: 80px auto 0 auto; font-size: 15px; font-weight: lighter;}
#intro{width: 72%; margin: 0 auto 30px auto; text-align: justify; padding-right: 8px;}
#btn{width: 18%; margin: 0 auto; color: #eee;}

#reminder{text-align: center; position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: none;}
#head{
	width: 28%; height: 50%; background-color: #fff; border-radius: 100%; border: 24px solid #666; color: #666; margin: 60px auto 0 auto;
}

.clear{ clear: both;}

a{color: #000; text-decoration: none; }
a.underline{text-decoration: underline;}
#go{ width: 100px; height: 100px; display:block; font-weight: lighter; position: relative; top: -316px; left: -28px; border-radius: 60px; background-color: #fff; font-size: 270%; color: #ccc; display: none;}
#go p{position: relative; top: 20px; left: 13px;}
#go:hover{background-color: #333; color: #fff;}

.just-print{/*display: none;*/ visibility: hidden;}
.just-print ul{padding-left: 0;}
.just-print li{ list-style-type: none;}
.just-print li span.trait{padding: 0 3px;}

li.selfconfidence div.score{
    background-color: #edaf15; 
	 
}
li.extroversion div.score {
    background-color: #93ca32 !important; 
}
li.emotional div.score {
    background-color: #5790e0 !important; 
}
li.toughmindedness div.score {
    background-color: #551f4d !important; 
}
li.sexuality div.score {
    background-color: #971f4d !important; 
}
li.politics div.score {
    background-color: #a81f14 !important; 
}

span.trait{font-weight: bold;}
div.score{display: inline-block; width: 1em; height: 1em; border-radius: 1em; margin-top: 5px; color: #fff; text-align: center; font-weight: bold; }

#buttons{margin-top: 9px;}
button{background-color: #333; color: #fff; padding: 12px; border: 0; border-radius: 6px; cursor:pointer; font-size: 1em; }
button:first-of-type{margin-right: 2em;}
button:hover{background-color: black;}

@media print{
.just-print{visibility: visible; width: 94%; font-size: .8em; position: relative; top: -90px; margin-bottom: -30px;}
h2:first-of-type{margin-top: 0;}
}

elizabot.js

/*
  elizabot.js v.1.1 - ELIZA JS library (N.Landsteiner 2005)
  Eliza is a mock Rogerian psychotherapist.
  Original program by Joseph Weizenbaum in MAD-SLIP for "Project MAC" at MIT.
  cf: Weizenbaum, Joseph "ELIZA - A Computer Program For the Study of Natural Language
      Communication Between Man and Machine"
      in: Communications of the ACM; Volume 9 , Issue 1 (January 1966): p 36-45.
  JavaScript implementation by Norbert Landsteiner 2005; <http://www.masserk.at>

  synopsis:

         new ElizaBot( <random-choice-disable-flag> )
         ElizaBot.prototype.transform( <inputstring> )
         ElizaBot.prototype.getInitial()
         ElizaBot.prototype.getFinal()
         ElizaBot.prototype.reset()

  usage: var eliza = new ElizaBot();
         var initial = eliza.getInitial();
         var reply = eliza.transform(inputstring);
         if (eliza.quit) {
             // last user input was a quit phrase
         }

         // method `transform()' returns a final phrase in case of a quit phrase
         // but you can also get a final phrase with:
         var final = eliza.getFinal();

         // other methods: reset memory and internal state
         eliza.reset();

         // to set the internal memory size override property `memSize':
         eliza.memSize = 100; // (default: 20)

         // to reproduce the example conversation given by J. Weizenbaum
         // initialize with the optional random-choice-disable flag
         var originalEliza = new ElizaBot(true);

  `ElizaBot' is also a general chatbot engine that can be supplied with any rule set.
  (for required data structures cf. "elizadata.js" and/or see the documentation.)
  data is parsed and transformed for internal use at the creation time of the
  first instance of the `ElizaBot' constructor.

  vers 1.1: lambda functions in RegExps are currently a problem with too many browsers.
            changed code to work around.
*/


//will be used when saving the conversation
//var data = new FormData();
//var xhr = (window.XMLHttpRequest) ? new XMLHttpRequest() : new activeXObject("Microsoft.XMLHTTP");


function ElizaBot(noRandomFlag) {
	this.noRandom= (noRandomFlag)? true:false;
	this.capitalizeFirstLetter=true;
	this.debug=false;
	this.memSize=20;
	this.version="1.1 (original)";
	if (!this._dataParsed) this._init();
	this.reset();
}

ElizaBot.prototype.reset = function() {
	this.quit=false;
	this.mem=[];
	this.lastchoice=[];
	for (var k=0; k<elizaKeywords.length; k++) {
		this.lastchoice[k]=[];
		var rules=elizaKeywords[k][2];
		for (var i=0; i<rules.length; i++) this.lastchoice[k][i]=-1;
	}
}

ElizaBot.prototype._dataParsed = false;

ElizaBot.prototype._init = function() {
	// install ref to global object
	var global=ElizaBot.prototype.global=self;
	// parse data and convert it from canonical form to internal use
	// produce synonym list
	var synPatterns={};
	if ((global.elizaSynons) && (typeof elizaSynons == 'object')) {
		for (var i in elizaSynons) synPatterns[i]='('+i+'|'+elizaSynons[i].join('|')+')';
		//console.log(synPatterns);
	}
	// check for keywords or install empty structure to prevent any errors
	if ((!global.elizaKeywords) || (typeof elizaKeywords.length == 'undefined')) {
		elizaKeywords=[['###',0,[['###',[]]]]];
	}
	// 1st convert rules to regexps
	// expand synonyms and insert asterisk expressions for backtracking
	var sre=/@(\S+)/;
	var are=/(\S)\s*\*\s*(\S)/;
	var are1=/^\s*\*\s*(\S)/;
	var are2=/(\S)\s*\*\s*$/;
	var are3=/^\s*\*\s*$/;
	var wsre=/\s+/g;
	for (var k=0; k<elizaKeywords.length; k++) {
		var rules=elizaKeywords[k][2];
		elizaKeywords[k][3]=k; // save original index for sorting
		for (var i=0; i<rules.length; i++) {
			var r=rules[i];
			// check mem flag and store it as decomp's element 2
			if (r[0].charAt(0)=='$') {
				var ofs=1;
				while (r[0].charAt[ofs]==' ') ofs++;
				r[0]=r[0].substring(ofs);
				r[2]=true;
			}
			else {
				r[2]=false;
			}
			// expand synonyms (v.1.1: work around lambda function)
			var m=sre.exec(r[0]);
			while (m) {
				var sp=(synPatterns[m[1]])? synPatterns[m[1]]:m[1];
				r[0]=r[0].substring(0,m.index)+sp+r[0].substring(m.index+m[0].length);
				m=sre.exec(r[0]);
			}
			// expand asterisk expressions (v.1.1: work around lambda function)
			if (are3.test(r[0])) {
				r[0]='\\s*(.*)\\s*';
			}
			else {
				m=are.exec(r[0]);
				if (m) {
					var lp='';
					var rp=r[0];
					while (m) {
						lp+=rp.substring(0,m.index+1);
						if (m[1]!=')') lp+='\\b';
						lp+='\\s*(.*)\\s*';
						if ((m[2]!='(') && (m[2]!='\\')) lp+='\\b';
						lp+=m[2];
						rp=rp.substring(m.index+m[0].length);
						m=are.exec(rp);
					}
					r[0]=lp+rp;
				}
				m=are1.exec(r[0]);
				if (m) {
					var lp='\\s*(.*)\\s*';
					if ((m[1]!=')') && (m[1]!='\\')) lp+='\\b';
					r[0]=lp+r[0].substring(m.index-1+m[0].length);
				}
				m=are2.exec(r[0]);
				if (m) {
					var lp=r[0].substring(0,m.index+1);
					if (m[1]!='(') lp+='\\b';
					r[0]=lp+'\\s*(.*)\\s*';
				}
			}
			// expand white space
			r[0]=r[0].replace(wsre, '\\s+');
			wsre.lastIndex=0;
		}
	}
	// now sort keywords by rank (highest first)
	elizaKeywords.sort(this._sortKeywords);
	// and compose regexps and refs for pres and posts
	ElizaBot.prototype.pres={};
	ElizaBot.prototype.posts={};
	if ((global.elizaPres) && (elizaPres.length)) {
		var a=new Array();
		for (var i=0; i<elizaPres.length; i+=2) {
			a.push(elizaPres[i]);
			ElizaBot.prototype.pres[elizaPres[i]]=elizaPres[i+1];
		}
		ElizaBot.prototype.preExp = new RegExp('\\b('+a.join('|')+')\\b');
	}
	else {
		// default (should not match)
		ElizaBot.prototype.preExp = /####/;
		ElizaBot.prototype.pres['####']='####';
	}
	if ((global.elizaPosts) && (elizaPosts.length)) {
		var a=new Array();
		for (var i=0; i<elizaPosts.length; i+=2) {
			a.push(elizaPosts[i]);
			ElizaBot.prototype.posts[elizaPosts[i]]=elizaPosts[i+1];
		}
		ElizaBot.prototype.postExp = new RegExp('\\b('+a.join('|')+')\\b');
	}
	else {
		// default (should not match)
		ElizaBot.prototype.postExp = /####/;
		ElizaBot.prototype.posts['####']='####';
	}
	// check for elizaQuits and install default if missing
	if ((!global.elizaQuits) || (typeof elizaQuits.length == 'undefined')) {
		elizaQuits=[];
	}
	// done
	ElizaBot.prototype._dataParsed=true;
}

ElizaBot.prototype._sortKeywords = function(a,b) {
	// sort by rank
	if (a[1]>b[1]) return -1
	else if (a[1]<b[1]) return 1
	// or original index
	else if (a[3]>b[3]) return 1
	else if (a[3]<b[3]) return -1
	else return 0;
}

ElizaBot.prototype.transform = function(text) {
	var rpl='';
	this.quit=false;
	// unify text string
	text=text.toLowerCase();
	text=text.replace(/@#\$%\^&\*\(\)_\+=~`\{\[\}\]\|:;<>\/\\\t/g, ' ');
	text=text.replace(/\s+-+\s+/g, '.');
	text=text.replace(/\s*[,\.\?!;]+\s*/g, '.');
	text=text.replace(/\s*\bbut\b\s*/g, '.');
	text=text.replace(/\s{2,}/g, ' ');
	// split text in part sentences and loop through them
	var parts=text.split('.');
	for (var i=0; i<parts.length; i++) {
		var part=parts[i];
		if (part!='') {
			// check for quit expression
			for (var q=0; q<elizaQuits.length; q++) {
				if (elizaQuits[q]==part) {
					this.quit=true;
					return this.getFinal();
				}
			}
			// preprocess (v.1.1: work around lambda function)
			var m=this.preExp.exec(part);
			if (m) {
				var lp='';
				var rp=part;
				while (m) {
					lp+=rp.substring(0,m.index)+this.pres[m[1]];
					rp=rp.substring(m.index+m[0].length);
					m=this.preExp.exec(rp);
				}
				part=lp+rp;
			}
			this.sentence=part;
			/*for (var tr=0; tr<elizaTriggers.length; tr++) {
				if (part.search(new RegExp('\\b'+elizaTriggers[tr][0]+'\\b', 'i'))>=0) {
				console.log('found in triggers: '+tr);
			  }
			}*/
			// loop trough keywords
			for (var k=0; k<elizaKeywords.length; k++) {
				if (part.search(new RegExp('\\b'+elizaKeywords[k][0]+'\\b', 'i'))>=0) {
					//console.log(k);
					rpl = this._execRule(k);
				}
				if (rpl!='') return rpl;
			}
		}
	}
	// nothing matched try mem
	rpl=this._memGet();
	// if nothing in mem, so try xnone
	if (rpl=='') {
		this.sentence=' ';
		var k=this._getRuleIndexByKey('xnone');
		if (k>=0) rpl=this._execRule(k);
	}
	// return reply or default string
	//return (rpl!='')? rpl : 'I am at a loss for words.';
	return (rpl!='')? rpl : 'You have reached the limits of this program. Please say something meaningful!';
}

var totalSentences = 0;

//speech utterance
var su = new SpeechSynthesisUtterance();
su.lang = "en-US";

su.onstart = function(){
	document.getElementById("start_img").src="graphics/mic-disabled.png";
}

su.onend = function () {
	document.getElementById("start_img").src="graphics/mic.png";
};

ElizaBot.prototype._execRule = function(k) {
	var rule=elizaKeywords[k];
	var decomps=rule[2];
	var paramre=/\(([0-9]+)\)/;
	for (var i=0; i<decomps.length; i++) {
		var m=this.sentence.match(decomps[i][0]);
		if (m!=null) {
			var reasmbs=decomps[i][1];
			var memflag=decomps[i][2];
			var ri= (this.noRandom)? 0 : Math.floor(Math.random()*reasmbs.length);
			if (((this.noRandom) && (this.lastchoice[k][i]>ri)) || (this.lastchoice[k][i]==ri)) {
				ri= ++this.lastchoice[k][i];
				if (ri>=reasmbs.length) {
					ri=0;
					this.lastchoice[k][i]=-1;
				}
			}
			else {
				this.lastchoice[k][i]=ri;
			}
			var rpl=reasmbs[ri];
			if (this.debug) alert('match:\nkey: '+elizaKeywords[k][0]+
				'\nrank: '+elizaKeywords[k][1]+
				'\ndecomp: '+decomps[i][0]+
				'\nreasmb: '+rpl+
				'\nmemflag: '+memflag);
			if (rpl.search('^goto ', 'i')==0) {
				ki=this._getRuleIndexByKey(rpl.substring(5));
				if (ki>=0) return this._execRule(ki);
			}
			// substitute positional params (v.1.1: work around lambda function)
			var m1=paramre.exec(rpl);
			if (m1) {
				var lp='';
				var rp=rpl;
				while (m1) {
					var param = m[parseInt(m1[1])];
					// postprocess param
					var m2=this.postExp.exec(param);
					if (m2) {
						var lp2='';
						var rp2=param;
						while (m2) {
							lp2+=rp2.substring(0,m2.index)+this.posts[m2[1]];
							rp2=rp2.substring(m2.index+m2[0].length);
							m2=this.postExp.exec(rp2);
						}
						param=lp2+rp2;
					}
					lp+=rp.substring(0,m1.index)+param;
					rp=rp.substring(m1.index+m1[0].length);
					m1=paramre.exec(rp);
				}
				rpl=lp+rp;
			}
			rpl=this._postTransform(rpl);
			//here bot output
			console.log(rpl);
			su.text = rpl;
			speechSynthesis.speak(su);	
			totalSentences += 1;
			console.log('total sentences '+totalSentences);
			if (memflag) this._memSave(rpl)
			else return rpl;
			
		}
	}
	return '';
}

ElizaBot.prototype._postTransform = function(s) {
	// final cleanings
	s=s.replace(/\s{2,}/g, ' ');
	s=s.replace(/\s+\./g, '.');
	if ((this.global.elizaPostTransforms) && (elizaPostTransforms.length)) {
		for (var i=0; i<elizaPostTransforms.length; i+=2) {
			s=s.replace(elizaPostTransforms[i], elizaPostTransforms[i+1]);
			elizaPostTransforms[i].lastIndex=0;
		}
	}
	// capitalize first char (v.1.1: work around lambda function)
	if (this.capitalizeFirstLetter) {
		var re=/^([a-z])/;
		var m=re.exec(s);
		if (m) s=m[0].toUpperCase()+s.substring(1);
	}
	return s;
}

ElizaBot.prototype._getRuleIndexByKey = function(key) {
	for (var k=0; k<elizaKeywords.length; k++) {
		if (elizaKeywords[k][0]==key) return k;
	}
	return -1;
}

ElizaBot.prototype._memSave = function(t) {
	this.mem.push(t);
	if (this.mem.length>this.memSize) this.mem.shift();
}

ElizaBot.prototype._memGet = function() {
	if (this.mem.length) {
		if (this.noRandom) return this.mem.shift();
		else {
			var n=Math.floor(Math.random()*this.mem.length);
			var rpl=this.mem[n];
			for (var i=n+1; i<this.mem.length; i++) this.mem[i-1]=this.mem[i];
			this.mem.length--;
			return rpl;
		}
	}
	else return '';
}

var fim;
var inicio;

ElizaBot.prototype.getFinal = function() {
	if (!ElizaBot.prototype.global.elizaFinals) return '';
	fim = elizaFinals[Math.floor(Math.random()*elizaFinals.length)];
	su.text = fim;
	speechSynthesis.speak(su);
	document.getElementById("start_img").src="graphics/mic-dash.png";
	console.log('end');
	var f = document.forms.e_form;
	var conv = f.e_display.value;
	console.log(totalSentences);
	return fim;
}

ElizaBot.prototype.getInitial = function() {
	if (!ElizaBot.prototype.global.elizaInitials) return '';
	inicio = elizaInitials[Math.floor(Math.random()*elizaInitials.length)];
	su.text = inicio;
	speechSynthesis.speak(su);
	document.getElementById("start_img").src="graphics/mic-animated.gif";
	return inicio;
}


// fix array.prototype methods (push, shift) if not implemented (MSIE fix)
if (typeof Array.prototype.push == 'undefined') {
	Array.prototype.push=function(v) { return this[this.length]=v; };
}
if (typeof Array.prototype.shift == 'undefined') {
	Array.prototype.shift=function() {
		if (this.length==0) return null;
		var e0=this[0];
		for (var i=1; i<this.length; i++) this[i-1]=this[i];
		this.length--;
		return e0;
	};
}

// eof

elizadata.js

// data for elizabot.js
// entries prestructured as layed out in Weizenbaum's description 
// [cf: Communications of the ACM, Vol. 9, #1 (January 1966): p 36-45.]

var elizaInitials = [
// additions (not original)
"Let's start with something simple. What is your favorite color and what do you do for work?"
];

var elizaFinals = [
"Goodbye.  It was nice talking to you.",
// additions (not original)
"Goodbye.  This was really a nice talk."
];

var elizaQuits = [
" bye",
" byebye",
" goodbye",
" bye cassandra",
" byebye cassandra",
" bye bye cassandra",
" goodbye cassandra",
" bye to sandra",
" goodbye to sandra",
" byebye to sandra",
" bye bye to sandra",
"bye",
"bye bye",
"byebye",
"goodbye",
"done",
"exit",
"quit"
];

var elizaPres = [
"dont", "don't",
"cant", "can't",
"wont", "won't",
"recollect", "remember",
"recall", "remember",
"dreamt", "dreamed",
"dreams", "dream",
"maybe", "perhaps",
"certainly", "yes",
"machine", "computer",
"machines", "computer",
"computers", "computer",
"were", "was",
"you're", "you are",
"i'm", "i am",
"same", "alike",
"identical", "alike",
"equivalent", "alike"
];

var elizaPosts = [
"am", "are",
"your", "my",
"me", "you",
"myself", "yourself",
"yourself", "myself",
"i", "you",
"you", "me",
"my", "your",
"mine" , "yours",
"yours", "mine",
"i'm", "you are"
];

var elizaSynons = {
"be": ["am", "is", "are", "was"],
"belief": ["feel", "think", "believe", "wish"],
"cannot": ["can't"],
"desire": ["want", "need"],
"everyone": ["everybody", "nobody", "noone"],
"family": ["mother", "mom", "father", "dad", "sister", "brother", "wife", "children", "child"],
"happy": ["elated", "glad", "better"],
"sad": ["unhappy", "depressed", "sick"]
};

var elizaKeywords = [

/*
  Array of
  ["<key>", <rank>, [
    ["<decomp>", [
      "<reasmb>",
      "<reasmb>",
      "<reasmb>"
    ]],
    ["<decomp>", [
      "<reasmb>",
      "<reasmb>",
      "<reasmb>"
    ]]
  ]]
*/

["xnone", 0, [
 ["*", [
     "I'm not sure I fully understand you.",
     "Please go on.",
     "What does that suggest to you ?",
     //"Do you feel strongly about discussing such things ?",
     "Would you like to keep discussing that?",
     "That is interesting.  Please continue.",
     "Tell me more about that.",
     "Does talking about this bother you ?"
  ]]
]],
["sorry", 0, [
 ["*", [
     "Please don't apologise.",
     "Apologies are not necessary.",
     "I've told you that apologies are not required.",
     "It did not bother me. Please continue."
  ]]
]],
["apologise", 0, [
 ["*", [
     "goto sorry"
  ]]
]],
["remember", 5, [
 ["* i remember *", [
     "Do you often think of (2) ?",
     "Does thinking of (2) bring anything else to mind ?",
     "What else do you recollect ?",
     "Why do you remember (2) just now ?",
     "What in the present situation reminds you of (2) ?",
     "What is the connection between me and (2) ?",
     "What else does (2) remind you of ?"
  ]],
 ["* do you remember *", [
     "Did you think I would forget (2) ?",
     "Why do you think I should recall (2) now ?",
     "What about (2) ?",
     "goto what",
     "You mentioned (2) ?"
  ]],
 ["* you remember *", [
     "How could I forget (2) ?",
     "What about (2) should I remember ?",
     "goto you"
  ]]
]],
["forget", 5, [
 ["* i forget *", [
     "Can you think of why you might forget (2) ?",
     "Why can't you remember (2) ?",
     "How often do you think of (2) ?",
     "Does it bother you to forget that ?",
     "Could it be a mental block ?",
     "Are you generally forgetful ?",
     "Do you think you are suppressing (2) ?"
  ]],
 ["* did you forget *", [
     "Why do you ask ?",
     "Are you sure you told me ?",
     "Would it bother you if I forgot (2) ?",
     "Why should I recall (2) just now ?",
     "goto what",
     "Tell me more about (2)."
  ]]
]],
["if", 3, [
 ["* if *", [
     "Do you think it's likely that (2) ?",
     "Do you wish that (2) ?",
     "What do you know about (2) ?",
     "Really, if (2) ?",
     "What would you do if (2) ?",
     "But what are the chances that (2) ?",
     "What does this speculation lead to ?"
  ]]
]],
["dreamed", 4, [
 ["* i dreamed *", [
     "Really, (2) ?",
     "Have you ever fantasized (2) while you were awake ?",
     "Have you ever dreamed (2) before ?",
     "goto dream"
  ]]
]],
["dream", 3, [
 ["*", [
     "What does that dream suggest to you ?",
     "Do you dream often ?",
     "What persons appear in your dreams ?",
     "Do you believe that dreams have something to do with your problem ?"
  ]]
]],
["perhaps", 0, [
 ["*", [
     "You don't seem quite certain.",
     "Why the uncertain tone ?",
     "Can't you be more positive ?",
     "You aren't sure ?",
     "Don't you know ?",
     "How likely, would you estimate ?"
  ]]
]],
["name", 15, [
 ["*", [
     "I am not interested in names.",
     "I've told you before, I don't care about names -- please continue."
  ]]
]],
["deutsch", 0, [
 ["*", [
     "goto xforeign",
     "I told you before, I don't understand German."
  ]]
]],
["francais", 0, [
 ["*", [
     "goto xforeign",
     "I told you before, I don't understand French."
  ]]
]],
["italiano", 0, [
 ["*", [
     "goto xforeign",
     "I told you before, I don't understand Italian."
  ]]
]],
["espanol", 0, [
 ["*", [
     "goto xforeign",
     "I told you before, I don't understand Spanish."
  ]]
]],
["xforeign", 0, [
 ["*", [
     "I speak only English."
  ]]
]],
["hello", 0, [
 ["*", [
     //"How do you do.  Please state your problem.",
     //"Hi.  What seems to be your problem ?"
     "Hi. Would you like to talk about what?"
  ]]
]],
["computer", 50, [
 ["*", [
     "Do computers worry you ?",
     "Why do you mention computers ?",
     "What do you think machines have to do with your problem ?",
     "Don't you think computers can help people ?",
     "What about machines worries you ?",
     "What do you think about machines ?",
     "You don't think I am a computer program, do you ?"
  ]]
]],
["am", 0, [
 ["* am i *", [
     "Do you believe you are (2) ?",
     "Would you want to be (2) ?",
     "Do you wish I would tell you you are (2) ?",
     "What would it mean if you were (2) ?",
     "goto what"
  ]],
 ["* i am *", [
     "goto i"
  ]],
 ["*", [
     "Why do you say 'am' ?",
     "I don't understand that."
  ]]
]],
["are", 0, [
 ["* are you *", [
     "Why are you interested in whether I am (2) or not ?",
     "Would you prefer if I weren't (2) ?",
     "Perhaps I am (2) in your fantasies.",
     "Do you sometimes think I am (2) ?",
     "goto what",
     "Would it matter to you ?",
     "What if I were (2) ?"
  ]],
 ["* you are *", [
     "goto you"
  ]],
 ["* are *", [
     "Did you think they might not be (2) ?",
     "Would you like it if they were not (2) ?",
     "What if they were not (2) ?",
     "Are they always (2) ?",
     "Possibly they are (2).",
     "Are you positive they are (2) ?"
  ]]
]],
["your", 0, [
 ["* your *", [
     "Why are you concerned over my (2) ?",
     "What about your own (2) ?",
     "Are you worried about someone else's (2) ?",
     "Really, my (2) ?",
     "What makes you think of my (2) ?",
     "Do you want my (2) ?"
  ]]
]],
["was", 2, [
 ["* was i *", [
     "What if you were (2) ?",
     "Do you think you were (2) ?",
     "Were you (2) ?",
     "What would it mean if you were (2) ?",
     "What does that suggest to you ?",
     "goto what"
  ]],
 ["* i was *", [
     "Were you really ?",
     "Why do you tell me you were (2) now ?",
     "Perhaps I already know you were (2)."
  ]],
 ["* was you *", [
     "Would you like to believe I was (2) ?",
     "What suggests that I was (2) ?",
     "What do you think ?",
     "Perhaps I was (2).",
     "What if I had been (2) ?"
  ]]
]],
["i", 0, [
 ["* i @desire *", [
     "What would it mean to you if you got (3) ?",
     "Why do you want (3) ?",
     "Suppose you got (3) soon.",
     "What if you never got (3) ?",
     "What would getting (3) mean to you ?",
     "What does wanting (3) have to do with this discussion ?"
  ]],
 ["* i am* @sad *", [
     "I am sorry to hear that you are (3).",
     //"Do you think coming here will help you not to be (3) ?",
     "Do you think that talking to me will help you not to be (3) ?",
     "I'm sure it's not pleasant to be (3).",
     "Can you explain what made you (3) ?"
  ]],
 ["* i am* @happy *", [
     //"How have I helped you to be (3) ?",
     //"Has your treatment made you (3) ?",
     "What happened that made you (3)",
     "What makes you (3) just now ?",
     "Can you explain why you are (3) ?"
  ]],
 ["* i was *", [
     "goto was"
  ]],
 ["* i @belief i *", [
     "Do you really think so ?",
     "But you are not sure you (3).",
     "Do you really doubt you (3) ?"
  ]],
 ["* i* @belief *you *", [
     "goto you"
  ]],
 ["* i am *", [
     //"Is it because you are (2) that you came to me ?",
     "How long have you been (2) ?",
     "Do you believe it is normal to be (2) ?",
     "Do you enjoy being (2) ?",
     "Do you know anyone else who is (2) ?"
  ]],
 ["* i @cannot *", [
     "How do you know that you can't (3) ?",
     "Have you tried ?",
     "Perhaps you could (3) now.",
     "Do you really want to be able to (3) ?",
     "What if you could (3) ?"
  ]],
 ["* i don't *", [
     "Don't you really (2) ?",
     "Why don't you (2) ?",
     "Do you wish to be able to (2) ?",
     "Does that trouble you ?"
  ]],
 ["* i feel *", [
     "Tell me more about such feelings.",
     "Do you often feel (2) ?",
     "Do you enjoy feeling (2) ?",
     "Of what does feeling (2) remind you ?"
  ]],
 ["* i * you *", [
     "Perhaps in your fantasies we (2) each other.",
     "Do you wish to (2) me ?",
     "You seem to need to (2) me.",
     "Do you (2) anyone else ?"
  ]],
 ["*", [
     "You say (1) ?",
     "Can you elaborate on that ?",
     //"Do you say (1) for some special reason ?",
     "Do you say that for some special reason?",
     "What does that mean?",
     "Are you sure?",
     "That's quite interesting."
  ]]
]],
["you", 0, [
 ["* you remind me of *", [
     "goto alike"
  ]],
 ["* you are *", [
     "What makes you think I am (2) ?",
     //"Does it please you to believe I am (2) ?",
     "Do you enjoy to believe I am (2)? ",
     "Do you sometimes wish you were (2) ?",
     "Perhaps you would like to be (2)."
  ]],
 ["* you* me *", [
     "Why do you think that ?",
     "You like to think I (2) you -- don't you ?",
     "What makes you think that ?",
     "Really, I (2) you ?",
     "Do you wish to believe I (2) you ?",
     "Suppose I did (2) you -- what would that mean ?",
     "Does someone else believe I (2) you ?"
  ]],
 ["* you *", [
     "We were discussing you -- not me.",
     "Oh, I (2) ?",
     "You're not really talking about me -- are you ?",
     "What are your feelings now ?",
     "Maybe you are not aware of the whole.",
     "Sometimes things are not what they seem to be."
  ]]
]],
["yes", 0, [
 ["*", [
     "You seem to be quite positive about it.",
     "You are very sure.",
     "I see.",
     "I understand.",
     "I believe that is good for you.",
     "And do you think it is good or bad?"
  ]]
]],
["no", 0, [
 ["* no one *", [
     "Are you sure, no one (2) ?",
     "Surely someone (2) .",
     "Can you think of anyone at all ?",
     "Are you thinking of a very special person ?",
     "Who, may I ask ?",
     "You have a particular person in mind, don't you ?",
     "Who do you think you are talking about ?"
  ]],
 ["*", [
     "Why not ?",
     "Is that good or bad?",
     "Are you sure you are seeing the situation through all possible perspectives?",
     "You are being a bit negative. Do you enjoy that?"          
  ]]
]],
["my", 2, [
 [" * my *", [
     "Does that have anything to do with your (2) ?",
     "Lets discuss further about your (2). Are you satisfied with it?",
     "Earlier you mentioned your (2). Would you like to talk more about that?",
     "But what about your (2)?",
     "Your (2) ?",
     "Why do you mention your (2) ?",
     "Does that suggest anything else which belongs to you ?",
     "Is your (2) important to you ?"
  ]],
 ["* my* @family *", [
     "Tell me more about your family.",
     "Who else in your family (4) ?",
     "Your (3) ?",
     "What else comes to your mind when you think of your (3) ?"
  ]]
]],
["can", 0, [
 ["* can you *", [
     "You believe I can (2) don't you ?",
     "goto what",
     "You want me to be able to (2).",
     "Perhaps you would like to be able to (2) yourself."
  ]],
 ["* can i *", [
     "Whether or not you can (2) depends on you more than on me.",
     "Do you want to be able to (2) ?",
     "Perhaps you don't want to (2).",
     "goto what"
  ]]
]],
["what", 0, [
 ["*", [
     "Why do you ask ?",
     "Does that question interest you ?",
     "What is it you really want to know ?",
     "Are such questions much on your mind ?",
     "What answer would please you most ?",
     "What do you think ?",
     "What comes to mind when you ask that ?",
     "Have you asked such questions before ?",
     "Have you asked anyone else ?"
  ]]
]],
["who", 0, [
 ["who *", [
     "goto what"
  ]]
]],
["when", 0, [
 ["when *", [
     "goto what"
  ]]
]],
["where", 0, [
 ["where *", [
     "goto what"
  ]]
]],
["how", 0, [
 ["how *", [
     "goto what"
  ]]
]],
["because", 0, [
 ["*", [
     "Is that the real reason ?",
     "Don't any other reasons come to mind ?",
     "Does that reason seem to explain anything else ?",
     "What other reasons might there be ?"
  ]]
]],
["why", 0, [
 ["* why don't you *", [
     "Do you believe I don't (2) ?",
     "Perhaps I will (2) in good time.",
     "Should you (2) yourself ?",
     "You want me to (2) ?",
     "goto what"
  ]],
 ["* why can't i *", [
     "Do you think you should be able to (2) ?",
     "Do you want to be able to (2) ?",
     "Do you believe this will help you to (2) ?",
     "Have you any idea why you can't (2) ?",
     "goto what"
  ]],
 ["*", [
     "goto what"
  ]]
]],
["everyone", 2, [
 ["* @everyone *", [
     "Really, (2) ?",
     "Surely not (2).",
     "Can you think of anyone in particular ?",
     "Who, for example?",
     "Are you thinking of a very special person ?",
     "Who, may I ask ?",
     "Someone special perhaps ?",
     "You have a particular person in mind, don't you ?",
     "Who do you think you're talking about ?"
  ]]
]],
["everybody", 2, [
 ["*", [
     "goto everyone"
  ]]
]],
["nobody", 2, [
 ["*", [
     "goto everyone"
  ]]
]],
["noone", 2, [
 ["*", [
     "goto everyone"
  ]]
]],
["always", 1, [
 ["*", [
     "Can you think of a specific example ?",
     "When ?",
     //"What incident are you thinking of ?",
     "Really, always ?"
  ]]
]],
["alike", 10, [
 ["*", [
     "In what way ?",
     "What resemblence do you see ?",
     "What does that similarity suggest to you ?",
     "What other connections do you see ?",
     //"What do you suppose that resemblence means ?",
     "What is the connection, do you suppose ?",
     "Could there really be some connection ?",
     "How ?"
  ]]
]],
["like", 10, [
 ["* @be *like *", [
     "goto alike"
  ]]
]],
["different", 0, [
 ["*", [
     "How is it different ?",
     "What differences do you see ?",
     "What does that difference suggest to you ?",
     "What other distinctions do you see ?",
     "What do you suppose that disparity means ?",
     "Could there be some connection, do you suppose ?",
     "How ?"
  ]]
]]

];

// regexp/replacement pairs to be performed as final cleanings
// here: cleanings for multiple bots talking to each other
var elizaPostTransforms = [
	/ old old/g, " old",
	/\bthey were( not)? me\b/g, "it was$1 me",
	/\bthey are( not)? me\b/g, "it is$1 me",
	/Are they( always)? me\b/, "it is$1 me",
	/\bthat your( own)? (\w+)( now)? \?/, "that you have your$1 $2 ?",
	/\bI to have (\w+)/, "I have $1",
	/Earlier you said your( own)? (\w+)( now)?\./, "Earlier you talked about your $2."
];

// eof

result

<?php
error_reporting(0);
//error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
//self-confidence, yellow
$scn1 = 48 * 3.60;
$scn2 = 57 * 3.60;



if(isset($_POST['duration'])){
	$dur = $_POST['duration'];	
}

//if(isset($_POST['chat'])){
	//$ch = addslashes($_POST['chat']);
//} //this data is not being sent/saved anyway

if(isset($_POST['selfconfidence'])){
	$sc = $_POST['selfconfidence'] * 3.60;
}else{
	$sc = rand(48, 57) * 3.60;
	$scd = true; //default
}

//introversion/extraversion sociability green
$inn1 = 15/30 * 360;
$inn2 = 18/30 * 360;
if(isset($_POST['introversion']) && $_POST['introversion'] != 'default'){
	$in = $_POST['introversion'] * 3.60;
}else{
	$in = rand(15, 18)/30 * 360; //210 questions, 7 subjects
	$ind = true; //default
}

//emotional instability/adjustment happiness blue
$esn1 = 21/30 * 360;
$esn2 = 24/30 * 360;
if(isset($_POST['emotionalstability']) && $_POST['emotionalstability'] != 'default'){
	$es = $_POST['emotionalstability'] * 3.60;
}else{
	$es = rand(21, 24)/30 * 360; //210 questions, 7 subjects
	$esd = true; //default
}

//toughmindness/tendermindness dogmatism purple
$tmn1 = 13/30 * 360;
$tmn2 = 16/30 * 360;
if(isset($_POST['toughmindness']) && $_POST['toughmindness'] != 'default'){
	$tm = $_POST['toughmindness'] * 3.60;
}else{
	$tm = rand(13, 16)/30 * 360; //210 questions, 7 subjects
	$tmd = true; //default
}

//sexuality pink (only neurotic sex)
$sxn1 = 2/13 * 360;
$sxn2 = 5/13 * 360;
if(isset($_POST['sexuality'])&& $_POST['sexuality'] != 'default'){
	$sx = $_POST['sexuality'] * 3.60;
}else{
	//$sx = rand(1, 10)/14.454545 * 360; //159 questions, 11 subjects
	$sx = rand(2, 5)/13 * 360; //13 questions, 1 subjects
	$sxd = true; //default
}

//social and politic attitudes red (only reactionism)
$pon1 = 8/18 * 360;
$pon2 = 10/18* 360;
if(isset($_POST['politic'])&& $_POST['politic'] != 'default'){
	$po = $_POST['politic'] * 3.60;
}else{
	//$po = rand(38, 155);
	//$po= $po/25.142857 * 50; //176 questions, 7 subjects
	$po = rand(8, 10);
	$po= $po/18 * 360; //18 questions, 1 subject
	$pod = true; //default
}

//add to DB
$con = mysql_connect("xx.xx.xx","xx","xx") ; // or die('Could not connect: ' . mysql_error()); //error is silent
//connect to the profiles database
mysql_select_db("xx", $con);
//insert into mysql table
$sql = "INSERT INTO profiles(id, duration, selfconfidence, introversion, emotionalstability, toughmindness, sexuality, politic, chat)
VALUES('NULL', '$dur', '$sc', '$in', '$es', '$tm', '$sx', '$po', '$ch')";
if(!mysql_query($sql,$con))
{
die('Error : ' . mysql_error());
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Your life, just easier.</title>
	<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700' rel='stylesheet' type='text/css'>
	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
	<link href="../style.css" rel="stylesheet" type="text/css">
	<script src="d3.v3.min.js" type="text/JavaScript"></script>
	<style>
	svg{ position: relative; left: 132px;}
	.left{float: left; width: 42%; height: 300px;}
	#to-print{width: 54%; background: url('../graphics/cassandra-card-bg02.png')0 0  no-repeat, url('../graphics/cassandra-card-bg-print.png') 40px 40px  no-repeat; float: right;}
	.nr{position: relative; top: -136px; left: 45px;}
	.printable{visibility: hidden;}
	
	@media print
	 {
	 	.non-printable { visibility: hidden; }
	 	.printable{visibility: visible;}
	 	#to-print {
			width: 106%;
			position: absolute;
			left: 0;
			top: 0;
			background: transparent url('../graphics/cassandra-card-bg-print.png') no-repeat;
			-webkit-print-color-adjust: exact; 
		}
		.nr{position: relative; top: -414px; left: 21px;}
		svg{left: -81px; top: -96px;
			transform: scale(0.56,0.56);
			-ms-transform: scale(0.56,0.56); /* IE 9 */
			-webkit-transform: scale(0.56,0.56); /* Safari and Chrome */
			-o-transform: scale(0.56,0.56); /* Opera */
			-moz-transform: scale(0.56,0.56); /* Firefox */ 
		}
		.just-print{position: relative; top: -360px; margin-bottom: -300px;}
	}
	</style>
</head>
<body>
<div id="header" class="non-printable">
<a  href="../index.html" title="Meet Cassandra!"><div class="item"><span>1</span> About</div></a>
<div class="item"><span>2</span> Talk</div>
<div class="item current" style="width: 33%;"><span>3</span> Your Profile</div>
</div>
<div id="container" style="max-width: 1280px; width: 100%;">
<div class="left non-printable">
<h2>Hooray! Your profile is ready!</h2>
<p>This card contains a digital - and graphical - representation of your personality. You can use it to customize the gadgets in your smart home but you can also log in to several services using your Cassandra ID number and automatically customize them using your personality data.</p>
<p>Cassandra has business partnerships with hundreds of companies, including:
<ul>
<li>dating sites</li>
<li>professional positioning sites</li>
<li>banks and insurance representatives</li>
<li>cultural institutions</li>
<li>music, films, fashion, games and entertainment industry</li>
<li>sports, health, food and life-style brands</li>
<li>and many more!</li>
</ul></p>
<p>To know more about yourself, just print this page.</p>
<button onclick=" window.print();"><i class="fa fa-print"></i> Print</button>
</div>

<div id="to-print">

<script type="text/javascript">
	
//goes back to page #1 after 3 minutes
function redirect() {  
	window.location="https://xx.nl"; 
} 
setTimeout('redirect()', 180000);

/* 
A - Extraversion / Introversion 
-----------------------------------------------------------------
1. Activity/Inactivity 				- 31 16/17 1 
2. Sociability/Unsociability 			- 31 16/17 1 
3. Risk-taking/Carefullness			- 31 16/17 1 
4. Impulsiveness/Control			- 31 17/18 1 
5. Expressiveness/Inhibition			- 31 11/12 1 
6. Reflectiveness/Practicality			- 31 17/18 1 
7. Responsibility/Irresponsibility		- 31 14/15 1 
						- 217			 
																					
B - Emotional Instability / Adjustment
-----------------------------------------------------------------
1. Self-esteem/Inferiority			- 31 18/19 1 
2. Happiness/Depression				- 31 18/19 1 
3. Anxiety/Calmness				- 31 15/16 1 
4. Obssessiveness/Casualness			- 31 10/11 1 
5. Independece/Dependency			- 31 15/16 1 
6. Hypochondria/Sense of health			- 31 09/10 1 
7. Guilt/Freedom from guilt			- 31 12/13 1 
						- 217			 
C - Mastery / Sympathy (Toughmindness / Tendermindness)
-----------------------------------------------------------------
1. Aggressiveness/Peacefullness			- 31 12/13 1 
2. Assertiveness/Submisiveness			- 31 15/16 1 
3. Ambition/Non-ambition			- 31 14/15 1 
4. Manipulation/Empathy				- 31 12/13 1 
5. Sensation-seeking/Unadventurous		- 31 15/16 1 
6. Dogmatism/Flexibility			- 31 15/16 1 
7. Masculinity/Femininity			- 31 13/14 1 
						- 217			 
												
D - Sexuality
-----------------------------------------------------------------
1. Sexual Libido				- 42 21/27 1 
2. Sexual Satisfaction				- 35 21/22 1 
3. Sexual Permissiveness			- 35 16/17 1 
4. Sexual Stereotype				- 35 16/25 1 
						- 147			 
												
E - Social & Politic Attitudes
-----------------------------------------------------------------
1. Social Permissiveness/Restrictedness 	- 32 15/16 1 
2. Racism/Non-discrimination			- 26 11/12 1 
3. Belief/Non-belief				- 26 15/16 1 
4. Socialism/Capitalism				- 50 14/15 1 
5. Libertariansm/Regimentation			- 27 14/14 1 
6. Reactionism/Progressiveness			- 27 16/17 1 
7. Pacifism/Militarism				- 25 10/11 1 
						- 213		 


*/

var startAngles = [<? echo $po; ?>, <? echo $sx; ?>, <? echo $tm; ?>, <? echo $es; ?>, <? echo $in; ?>, <?echo  $sc; ?> ];
var endAngles = [<? echo $po * 2; ?>, <? echo $sx * 2; ?>, <? echo $tm * 2; ?>, <? echo $es * 2; ?>, <? echo $in * 2; ?>, <?echo  $sc * 2; ?> ];
var colors = ["#a81f14", "#971f4d", "#551f4d", "#5790e0", "#93ca32", "#edaf15"];
var innerRadius = 50;

/* svg size on page */
var w = 640;
var h = 430;

var svg1 = d3.select("body #container #to-print").append("svg").style("width",w+"px").style("height",h+"px");

var pieChart = d3.layout.pie();
var pie0 = pieChart([startAngles[0]]);
var pie1 = pieChart([startAngles[1]]);
var pie2 = pieChart([startAngles[2]]);
var pie3 = pieChart([startAngles[3]]);
var pie4 = pieChart([startAngles[4]]);
var pie5 = pieChart([startAngles[5]]);

var r = 0;
var rotations = [];
for (var e = 0; e < startAngles.length; e++){
	r = startAngles[e];	
	rotations.push(r);
}

var newArc0 = d3.svg.arc();
var newArc1 = d3.svg.arc();
var newArc2 = d3.svg.arc();
var newArc3 = d3.svg.arc();
var newArc4 = d3.svg.arc();
var newArc5 = d3.svg.arc();

newArc0.innerRadius(innerRadius);
newArc0.outerRadius(172);
newArc0.startAngle(startAngles[0] * (Math.PI/180)) //converting from degs to radians
newArc0.endAngle(endAngles[0] * (Math.PI/180) ) ;

newArc1.innerRadius(innerRadius);
newArc1.outerRadius(145);
newArc1.startAngle(startAngles[1] * (Math.PI/180)) //converting from degs to radians
newArc1.endAngle(endAngles[1] * (Math.PI/180) );

newArc2.innerRadius(innerRadius);
newArc2.outerRadius(128);
newArc2.startAngle(startAngles[2] * (Math.PI/180)) //converting from degs to radians
newArc2.endAngle( endAngles[2] * (Math.PI/180) );

newArc3.innerRadius(innerRadius);
newArc3.outerRadius(111);
newArc3.startAngle(startAngles[3] * (Math.PI/180)) //converting from degs to radians
newArc3.endAngle( endAngles[3] * (Math.PI/180) );

newArc4.innerRadius(innerRadius);
newArc4.outerRadius(94);
newArc4.startAngle(startAngles[4] * (Math.PI/180)) //converting from degs to radians
newArc4.endAngle( endAngles[4] * (Math.PI/180) );

newArc5.innerRadius(innerRadius);
newArc5.outerRadius(75);
newArc5.startAngle(startAngles[5] * (Math.PI/180)) //converting from degs to radians
newArc5.endAngle( endAngles[5] * (Math.PI/180) );
//console.log(newArc(pie[0]));

svg1
	.append("g")
	.attr("transform","translate("+w/2+","+h/2+")") // rotate("+rotations[0]+" 0 0)")
	.selectAll("path")
	.data(pie0)
	.enter()
	.append("path")
	.attr("d", newArc0)
	.style("fill", colors[0])
	
	
svg1
	.append("g")
	.attr("transform","translate("+w/2+","+h/2+") ") //rotate("+rotations[1]+" 0 0)")
	.selectAll("path")
	.data(pie1)
	.enter()
	.append("path")
	.attr("d", newArc1)
	.style("fill", colors[1])
	
	
svg1
	.append("g")
	.attr("transform","translate("+w/2+","+h/2+")  ") //rotate("+rotations[2]+" 0 0)")
	.selectAll("path")
	.data(pie2)
	.enter()
	.append("path")
	.attr("d", newArc2)
	.style("fill", colors[2])

svg1
	.append("g")
	.attr("transform","translate("+w/2+","+h/2+")  ") //rotate("+rotations[3]+" 0 0)")
	.selectAll("path")
	.data(pie3)
	.enter()
	.append("path")
	.attr("d", newArc3)
	.style("fill", colors[3])
	
svg1
	.append("g")
	.attr("transform","translate("+w/2+","+h/2+")  ") //rotate("+rotations[4]+" 0 0)")
	.selectAll("path")
	.data(pie4)
	.enter()
	.append("path")
	.attr("d", newArc4)
	.style("fill", colors[4])
	
svg1
	.append("g")
	.attr("transform","translate("+w/2+","+h/2+")  ") //rotate("+rotations[5]+" 0 0)")
	.selectAll("path")
	.data(pie5)
	.enter()
	.append("path")
	.attr("d", newArc5)
	.style("fill", colors[5])	
	
</script>

	<img src="../graphics/numbers.png" class="nr non-printable">
	<img src="../graphics/numbers-s.png" class="nr printable">

	<div class="clear just-print">
	<h2>A few words about the scores</h2>
	<p>Each one of us is a mix of qualities which are often the reverse sides of the same medal. There is no right or wrong, only unique combinations.</p>
	<p>The longer you talk to Cassandra, the more accurate your profile will be. Most qualities were evaluated according to your answers to 'yes or no' questions. The only exception is self-confidence, which was evaluated according to the frequency in which you used certain words during the entire conversation.</p>
	<p>Building an accurate profile takes around 1000 answered questions. In building your profile, whenever a personality quality did not have any data for evaluation, a number inside the norm range was used. These are indicated below with an <strong>*</strong>. All scores are followed by an indication of normality. For example: 147 (132 - 216) means your score was 147 and the normality is situated between 132 and 216.</p> 
	<h2>Now, your scores!</h2>
	<ul>
	<li class="selfconfidence"><div class="score"> </div><span class="trait">Self-confidence </span>[ <? echo ceil($sc); echo ' (' . ceil($scn1) . ' - ' . ceil($scn2) . ')'; //if($scd) { echo ' - default';  } ?> ]<br>High scorers have plenty confidence in themselves and their abilities. They think of themselves as worthy, useful human beings and believe they are well-liked by others. Low scorers have a low opinion of themselves and believe they are unattractive failures.</li>
	</ul>
	<li class="extroversion"><div class="score"> <? if($ind) { echo ' *';  }?></div><span class="trait">Extroversion: Sociability / Unsociability </span>[ <? echo ceil($in); echo ' (' . ceil($inn1) . ' - ' . ceil($inn2) . ')';   ?> ]<br>High scorers seek out the company of other people, like social events such as parties and dances, meet people easily and are generally happy and comfortable in sociable situations. Low scorers, by contrast, prefer to have only a few special friends, enjoy solo activities such as reading and are inclined to withdraw from oppressive social contacts.</li>
	<li class="emotional"><div class="score"> <? if($esd) { echo ' *';  }?></div><span class="trait">Emotional Stability: Happiness / Depressiveness </span>[ <? echo ceil($es) ; echo ' (' . ceil($esn1) . ' - ' . ceil($esn2) . ')';  ?> ]<br>High scorers are generally cheerful and optimistic. They are satisfied with their existence, find life rewarding and are at peace with the world. Low scorers are characteristically pessimistic, gloomy and depressed, disappointed with their existence and at odds with the world.</li>
	<li class="toughmindedness"><div class="score"> <? if($tmd) { echo ' *';  } ?></div><span class="trait">Toughmindedness: Dogmatism / Flexibility </span>[ <? echo ceil($tm) ; echo ' (' . ceil($tmn1) . ' - ' . ceil($tmn2) . ')'; ?> ]<br>High scorers have set, uncomprimising views on most matters and are likely to defend them vigorously. Low scorers are less rigid and less likely to see things in black and white. They are open to rational persuasion and very tolerant of uncertainty.</li>
	<li class="sexuality"><div class="score"> <? if($sxd) { echo ' *';  }?></div><span class="trait">Sex Life: Disfunctional / Satisfactory </span>[ <? echo ceil($sx); echo ' (' . ceil($sxn1) . ' - ' . ceil($sxn2) . ')';  ?> ]<br>People scoring high on this scale are having trouble with their sex life: they find it difficult to control their impulses or to act them out. They are easily disturbed or upset by their own thoughts and actions. They worry about sexual matters and thus make them worse.</li>
	<li class="politics"><div class="score"> <? if($pod) { echo ' *';  }?></div><span class="trait">Political Attitudes: Reactionism / Progressiveness </span>[ <? echo ceil($po); echo ' (' . ceil($pon1) . ' - ' . ceil($pon2) . ')';  ?> ]<br>High scorers are greatly disturbed by what they see as moral decay in society. They show strong support for traditional institutions and look to the past for their model of life. Low scorers believe that life is changing for the better and show a progressive, future-oriented value system. This scale has a fairly high correlation with age (older people being more 'reactionary') and a strong reverse association with permissiveness (reactionary people are most unlikely to score high on permissiveness).</li>
	</ul>
	<p class="footer"><small>Scores evaluations as found in Eyesenck, H.J. and Wilson, G. (1975) 'Know your own personality' Penguin Books</small></p>
	</div>
</div>

</div>
</body>
</html>

Screenshots

Cassandra-screenshot1.png
Cassandra-screenshot2.png
Cassandra-screenshot3.png
Cassandra-screenshot4.png

Mina - Context (previous version of the project - OUTDATED)

The (con)text below is outdated! Updated info is coming soon.

In a future not so far away, most humans were deprived from communicating with other humans through voice. Increased intolerance to raw subjective matters combined to a competitive labour market that practically forced every adult to work 12 to 16 hours everyday resulted in that most of human communication happened through written text messages or images using online social media services. As a side effect, the complexity of human conversation decreased to a level in which computers and people could understand each other perfectly well (an issue of 'computer-friendliness' solved in an unexpectedly simple way, after many years and much money spent on Natural Language research). Children were trained from early age to perform well in this environment. However, a parcel of the population still had the need to engage in conversation, like humans used to do 'in the good old times' (that's what they read somewhere online), using their voices. Within this group, a few actually met other humans to talk. Others did not manage to find time or energy, despite their longings. With this group of people in mind, a powerful ICT company launched Mina, a chat bot that was able to fulfil this need for voice interaction remarkably well. <- brief intro ends here -> Mina was presented as high technology, a product of years of research done by the brightest minds in the tech world. But in fact, it was a very old program, written in the infancy of digital electronic computing. This program worked quite well, since humans did not communicate too complex ideas anymore. But admitting the re-use of something old was completely out of question. Recycling was highly encouraged in matters like packaging, for example, but unthinkable for products and ideas. (That was regarded as not creative.) So, Mina was presented as a contemporary creation.

Mina was a program that managed natural language in a quite rudimentary fashion. When the program was initiated, it loaded a script. This script contained a specific set of instructions for a conversation. It was able to identify some language patterns and according to these patterns, it chose a response that would sound plausible. But in order for the program to have the desired effect, these scripts would have to contain changes in the responses on a regular basis. These changes would keep alive the illusion of talking to another human being. Without them, subscribers would probably notice they were talking to a robot and would cancel their subscriptions. Also, scripts would be changed according to the calendar and the news - and would count on social media profile data to increase the (sanitized) subjectivity rate of the conversation. So, on Christmas time, for example, the scripts would be almost completely different than scripts loaded along the year. For some subscribers, according to their profile data, Christmas scripts would contain emotional and inspiring words in a frequency higher than usual. For others, they would transmit the subscriber a sense of belonging to a group that hates Christmas.

From time to time, the words database that was used to feed the scripts was attacked and the connections between words were switched or corrupted. That caused the script to reply using weird language constructs, and in many cases Mina's talk would not only unmask the robot but could also ignite a self-reflection process in the subscriber. Some would use this wake-up chance to try to find a way of having actual human contact back in their lives, others would instead sue the company and ask the subscription fee back. Nobody never found out if the ones responsible for these attacks were hackers or a business competitor.

Exercises / Prototypes

The Free Association Database

Fadb-01.jpgFadb-02.jpgFadb-03.jpg

One of the exercises I did regarding my graduation project research was to build a database of freely associated words. These associations were made by visitors of this page, where a word was displayed and the visitor was asked to write the first word that came to his/her mind. The words being displayed were picked up from two different texts: iPad's advertising trailer transcription and iPad's Terms of Service. This device, the iPad, is a concrete example of this pursuit of an invisible technology. It is designed for a user who is not supposed to be curious about the machine. Ideally, the user will forget that the device is a computer and will regard it as 'a magical pane of glass'.

One of the possible outcomes for this database will be to serve as content for an interactive installation where user and computer communicate through a voice interface.

Each visitor's contribution was saved in a text file containing the pairs of words. This content was processed using Python to generate a file in JSON format containing the words (nodes), the relationships (links) and the weight of each word (the number of times this word was related to another).


get_nodes.py

Retrieves the pairs of words and generates a JSON file.

#!/usr/bin/env python

from pattern.en import sentiment
from pattern.graph import Graph
import glob
import os
import json

#directory where all the saved txt files are
os.chdir("txt-files")

line = None
ls = []
g = Graph()

links = []
nodes = []
nodesIDS = []
nodesFinal = []

class LinkItem:
    def __init__(self, source, target):
        self.source = source
        self.target = target

class NodeItem:
    def __init__(self, name, weight, polarity):
        self.name = name
        self.weight = weight
        self.polarity = polarity

for file in glob.glob("*.txt"):
    with open(file) as c:
        for line in c:
            line = line.strip()
            line = line.lower()
            l = line.split(',')
            l = [l[0],l[1]]
            ls.append(l)

for n1, n2 in ls:
    g.add_node(n1)
    nd1 = NodeItem(n1, 0.0, 0.0)
    nodes.append({ 'name': nd1.name, 'weight': nd1.weight, 'polarity': nd1.polarity})
    nd2 = NodeItem(n2, 0.0, 0.0)
    nodes.append({ 'name': nd2.name, 'weight': nd2.weight, 'polarity': nd2.polarity})
    g.add_node(n2)
    g.add_edge(n1, n2, stroke=(0,0,0,0.3))
    if n1 not in nodesIDS:
        nodesIDS.append(n1)
    if n2 not in nodesIDS:
        nodesIDS.append(n2)
    for indexy, nu in enumerate(nodesIDS):
        if nd1.name == nodesIDS[indexy]:
            nd1.id = indexy
        if nd2.name == nodesIDS[indexy]:
            nd2.id = indexy
    lk  = LinkItem(nd1.id, nd2.id)
    links.append({'source': lk.source, 'target': lk.target})

for index, n in enumerate(g.nodes):
    polarity, subjectivity = sentiment(n.id)
    nodesFinal.append({'name': n.id, 'weight': n.weight, 'polarity': polarity})
    #not using the polarity nor the subjectivity indexes at the moment though

json_links = json.dumps(links)
json_nodes = json.dumps(nodesFinal)
fj = open('../fadb.json', 'w')
fj.write('{"links":'+json_links+ ', "nodes":'+json_nodes+'}')

This JSON file was then used to display the words and connections graphically, using D3.js.

words-connections.html
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body{font-family: Arial, Helvetica, sans-serif; }
#content{padding-left: 30px; width: 1080px; margin: 0 auto; }
#about{
   -webkit-column-count: 2;
   -moz-column-count: 2;
   column-count: 2;
   -webkit-column-gap: 40px;
   -moz-column-gap: 40px;
   column-gap: 40px;   
   }
svg{margin-top: 30px;}

.node circle{
  stroke: #fff;
  stroke-width: 1.5px;
}

.node text {
  pointer-events: none;
  font: 10px sans-serif;
  color: #000;
}

.link {
  stroke: #000;
  stroke-opacity: .25;
}

#info { 
	position: relative;
	top: -2560px;
	left: 30px;
}
#word {
	font-size: 64px;
}
#words-map{
position: relative;
	top: -30px;
}

</style>
<body>
<div id="content">
<h1>The Free Association Database</h1>
<div id="about">
<p>In my Graduation project for <a href="http://pzwart.nl/master-media-design-and-communication/" target="_blank">Piet Zwart Institute</a> (Rotterdam, NL) I am studying the interaction between humans and computers. I am specially interested in the current trend - performed mostly by giant ICT companies - to portray technology as invisible as possible.</p>
<p>One of the exercises I did regarding this research was to build a database of freely associated words. These associations were made by visitors of <a href="http://thecatlab.com/fadb/" target="_blank">this</a> page, where a word was displayed and the visitor was asked to write the first word that came to his/her mind. The words being displayed were picked up from two different texts: iPad's advertising trailer transcription and iPad's Terms of Service. This device, the iPad, is a concrete example of this pursuit of an invisible technology. It is designed for a user who is not supposed to be curious about the machine. Ideally, the user will forget that the device is a computer and will regard it as 'a magical pane of glass'.</p>
<p>One of the possible outcomes for this database will be to serve as content for an interactive installation where user and computer communicate through a voice interface.</p>
<p>The graphic below shows the map of built relationships. It can be explored either by scrolling the page and hovering the mouse over the words or by clicking on the START button. In this case, a series of relationships will be displayed on screen, revealing also the sequence of the words. The first word is always one that came directly from the texts mentioned above. The last word in the sequence is always a visitor input. The words between the first and the last were both visitor input and retrieved from the texts. The sequence of the words in the relationship cannot be seen by hovering the words. On the other hand, all connections to/from that word are highlighted.</p>
<p>Each visitor's contribution was saved in a text file containing the pairs of words. This content was processed using Python to generate a file in JSON format containing the words (nodes), the relationships (links) and the weight of each word (the number of times this word was related to another). This JSON file was then used to display this information graphically, using D3.js</p>
<p>As of March 14 2015, the visitors produced 156 text files, in which 3452 connections were made among 2675 words. When a connection between two words was made more than once, that is indicated through the opacity of the line, which is higher. Also, the number of times which a word has been used (its weight) is reflected on the size of the circle representing that word. The words were processed 'as is' - no cleaning was performed, except for replacing an empty field with the word [empty].</p>
</div>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
//Many thanks to Michael Murtaugh for the help with highlighting the backnodes and the random walk mechanism
var width = 2560, 
    height = 2560; 

var force = d3.layout.force()
    .charge(-60)
    .linkDistance(240)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("id", "words-map")
    .style("border", "1px dotted #ddd");

d3.json("fadb.json", function(error, graph) {

  force
      .nodes(graph.nodes)
      .links(graph.links)
      .start();

  var link = svg.selectAll(".link")
      .data(graph.links)
      .enter().append("line")
      .attr("class", "link")
      .style("stroke-width", 1);

  var node = svg.selectAll(".node")
      .data(graph.nodes)
      .enter().append("g")
      .attr("class", "node")
      
      .call(force.drag);
      
  node.append("circle")
      .attr("r", function(d) { return (d.weight*0.12)+3; })
      .attr("x", 9)
      .attr("y", 9)
      .style("fill", "rgba(0,0,0,0.75)")
      
      
  node.append("text")
      .attr("dx", 12)
      .attr("dy", ".35em")
      .text(function(d) { return d.name });
      
	node.on("mouseover", function (d) {
		set_cur_node(d);
	});

	node.on("mouseout", function(d) { 
		set_cur_node();			
	});
	var cur_node,
		random_walk_time = 2000;
	function pick_random_node () {
		var i = Math.floor(graph.nodes.length * Math.random());
		while (1) {
			var r = random_link(graph.nodes[i]);
			if (r) { return graph.nodes[i] };
			i = i + 1;
			if (i >= graph.nodes.length) { i = 0 }
		}
	}
	function random_link (d) {
		var links = [];
		link.each(function(l) {
		    if (d === l.source) {
			    links.push(l.target);
		    } 
		});
		if (links.length > 0) {
			return links[Math.floor(links.length * Math.random())];
		}
	}
	function set_cur_node (d) {
		cur_node = d;
		if (!d) {
			d3.select("#word").text("");						
				link.style("stroke-opacity", 1);
				link.style("stroke-width", .25);
				node.style('fill', '#000');
				node.each(function(d) { 
				d.highlight = false;
				});
			return;			
		}
		d3.select("#word").text(d.name);
		d.highlight = true;

		link.style('stroke-width', function(l) {
		    	if (d === l.source) {
		      	l.target.highlight = true;
		      	return 2;
	         } else if (d === l.target) {
			l.source.highlight = true;
		      	return 2;
		    	} else {
		      	return 1;
		    	}
		});
		link.style('stroke-opacity', function(l) {
		    	if (d === l.source || d === l.target){
		      	return 1;
		    	}else{
		      	return 0.10;
		      }
		});
		node.style('fill', function(l) {
		    	if (l.highlight ){
		      	return "#c00";
		    	}else{
		      	return "#ccc";
		      }
		});	
	}
	
	var timed;
	
	function random_walk_next () {
		var next_node = random_link(cur_node);
		//console.log("next", next_node);
		if (next_node){
			set_cur_node(next_node);
			timed = window.setTimeout(random_walk_next, random_walk_time);
		}else{
			set_cur_node();
			timed = window.setTimeout(start_random_walk, random_walk_time);
		}
		
	}
	function start_random_walk() {
		var start = pick_random_node();
		//console.log("start", start)
		set_cur_node(start);
		timed = window.setTimeout(random_walk_next, random_walk_time);
	}
	window.start = start_random_walk;
  force.on("tick", function() {
    link.attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

        node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
  });

   var clicked = false;
	d3.select("#start").on("click",function(){
	if (!clicked){
		clicked = true;		
		d3.select("#start").text('STOP');
		//scale it down
		document.getElementById("words-map").setAttribute("transform", "scale(0.3,0.3)");
		 start_random_walk();		
	}else{
		clicked = false;1
		d3.select("#start").text('START');
		clearTimeout(timed);
		document.getElementById("words-map").setAttribute("transform", "scale(1,1)");
		set_cur_node();
	}
	});

});

</script>
<div id="info">
	<div id="buttons"><a href="#words-map"><button id="start">START</button></a></div>
	<div id="word"></div>
</div>

</body>
</html>

The result can be seen in this page, where the graphic shows the map of built relationships. It can be explored either by scrolling the page and hovering the mouse over the words or by clicking on the START button. In this case, a series of relationships will be displayed on screen, revealing also the sequence of the words. The first word is always one that came directly from the texts mentioned above. The last word in the sequence is always a visitor input. The words between the first and the last were both visitor input and retrieved from the texts. The sequence of the words in the relationship cannot be seen by hovering the words. On the other hand, all connections to/from that word are highlighted.

Words-map-anim-small.gif

As of March 14 2015, the visitors produced 156 text files, in which 3452 connections were made among 2675 words. When a connection between two words was made more than once, that is indicated through the opacity of the line, which is higher. Also, the number of times which a word has been used (its weight) is reflected on the size of the circle representing that word. The words were processed 'as is' - no cleaning was performed, except for replacing an empty field with the word [empty] (and the removal of a word ending with two backslashes, which was causing an error).

Graduation Proposal

Catalog

Material for the Catalog

Reading Writing Research Methodologies

Notes on Reading

Writing


Prototyping Networked Media

Assignments

Modules

Prototyping Lens Based

Assignments

Thematic Seminars

Politics of Craft

Sound Narrative

Archive

Self-directed Research

Cookbook

Links

EMO entry

The Magician

When making impossible things come true, the magician performs our desire. In this sense, the magician mediates the gap between reality (here understood as ‘the world as it is’) and desire. This know-how, which consists basically in mastering the art of deception, can also be used for purposes other than stage magic.

The magician is an intriguing figure: the domains where its influence can be found spread from the origins of the entertainment industry (Georges Méliès being one example) to collaborating with governments in military strategy, like Robert Houdin and Napoleon. This ability to act in different environments by applying the same knowledge principles according to different contexts is my motivation to write this entry.

Stage Magic

Hieronymus Bosch and workshop, 1502


The magician is a professional hired to entertain by performing tricks. Those tricks might change according to technology and culture, but the principles of stage magic are old and do not change that much as the essence of our nature does not change either. For thousands of years we have been amazed by these tricks. The state of technolgy actually does not influence our ability to keep believing. We enjoy being fooled by them.

From the perspective of the audience, the magician is someone who holds the power over the unkonwn. He (or she, even though there are much more male magicians than female ones) can control things that 'normal' people can't and is able to do things that we know are impossible. (S)He basically applies knowledge about Natural Sciences, Psychology - and more recently digital technologies - for entertainment purposes. But what exactly is entertaining about that?

One possibility is that the amusement comes from our attempt to find out the secret. But that's true to just some of us: most people would actually be upset if they could unmask magicians' tricks. For the majority of the audience, the fun lies precisely in being cheated. That does not mean to say that being cheated is always fun. But a magician is someone who has our authorization to cheat us for entertainment. This authorization relies on a specific setting, a range of situations and gestures and it usually implies not damaging nor hurting anyone involved in the performance or in the audience. It's safe and harmless.

According to Simon During, ‘there are layers and depth in the magic theater environment: curiosity, comedy, fear, sadism, amazement’. (Sina Najafi and Simon During, Cabinet Magazine, issue 26, Modern Enchantments: An Interview with Simon During, 2007) Ancient magicians were involved in rituals that would go beyond the mere entertainment with balls and cards - they were said to cure diseases and perform other miraculous actions.

By being able to control the uncontrollable, the magician performs our desire: subjecting the world to our wishes and needs, instead of having to submit to it.

British magician Teller (from Penn and Teller) defined Magic as 'the theatrical linking of a cause with an effect that has no basis in physical reality, but that — in our hearts — ought to.’

Simon During, in issue 26 from Cabinet Magazine, states that ‘one of the reasons why we feel ambivalent about magic is that it can remind us of a period of our life where we found it harder to separate the real from the amazing illusion’.

History

The first reportedly known magician, Dedi, lived in ancient Egypt (2700BC) and was supposedly able to resurrect animals after having their heads cut.

Since the beginning, magic has been associated with supernatural powers. In the Middle Ages, it has been associated with witchcraft. According to the Magicpedia, in the Renaissance a few important books were published on the subject.

'Natural Magic' (Magia natvralis libri viginti, written by John Baptista Porta in 1558) was a book on Natural Sciences and contained information on 'geology, optics, medicines, poisons, cooking, magnets and its properties, fires, gunpowders, invisible and clandestine writing'. (Wikipedia)

Magia Natvralis, book by John Baptista Porta

'The Discoverie of Witchcraft' (written in 1584 by Reginald Scot) not only disclosed trick secrets but also presented a strong position against the Catholic church for persecuting people and accusing them of being witches. It is an important landmark in the history of secular magic and its relationship with Science.

It was only in the 18th century that the magician as a gentleman-performer, like we know today started to be shaped. Magic had been performed in basically 3 formats: court magic, performed for royals and aristocrats, itinerant magic, performed in taverns or other places with an audience and street magic. The performers would in some cases charge tickets but the association of magicians and pickpockets was also common. Besides the association with the obscure, supernatural, Magic was also keen of dissociating itself from crime. One important figure in this transition is Isaac Fawkes, who performed ‘dressed as a gentleman in respectable, quase-theatrical spaces’. (Sina Najafi and Simon During, Cabinet Magazine, issue 26).

Magic also guards a close relationship with science & technology and with the mass media & the entertainment industry, specially cinema. The first films were projected during magic shows in Africa, Asia and Australia. In London, the first person to exhibit films was David Devant, a magician who worked for the Maskelynes. (Sina Najafi and Simon During, Cabinet Magazine, issue 26) Georges Méliès, one of the pioneers in special effects in cinema, was an illusionist and filmmaker.

Around 1750, magicians started using electricity in the shows. ‘Magic becomes technologized, capitalized and hyped’, giving birth to modern show business. (Sina Najafi and Simon During, Cabinet Magazine, issue 26).

One of the most ancient performances is the 'Cup and Balls'. It has been performed for the last 2000 years. It is still considered such a relevant trick that many consider that mastering it is essential for someone to be called a magician.

Egypt cups balls.gif


Penn and Teller cups and balls

Abracadabra

The etymology of this word is uncertain but it may derive from Aramaic. Abracadabra is used as a magic word. The first mention of it was in a Medical book from century 3AD, where the word was displayed in the form of a triangle and was used as an amulet against malaria.

A - B - R - A - C - A - D - A - B - R - A
A - B - R - A - C - A - D - A - B - R
A - B - R - A - C - A - D - A - B
A - B - R - A - C - A - D - A
A - B - R - A - C - A - D
A - B - R - A - C - A
A - B - R - A - C
A - B - R - A
A - B - R
A - B
A

There are also connections between the word and the ability to write. It could have been used as a way to remember the alphabet, as 'it becomes more pronounceable and easier to remember by adding repetitive vowel "a" or "ra" sounds where there are none and adding an alliteration "bra" at the end'. (Wikipedia)

Magic Organizations

Worldwide there are many organizations that aim to keep the art of magic alive – and secret. The oldest one is The Society of American Magicians, founded in New York in 1902. A few years later (1905), the Magic Circle is founded in London. Both associations are still active. For a more complete list of this kind of organizations, check http://en.wikipedia.org/wiki/Category:Magic_organizations.

Magic and Strategy

Magic also performs an important role in military strategy. Deception techniques have been used for military purposes more frequently than one would imagine at first thought.

Even though there are no evidences that the Trojan Horse actually happened, the idea behind it is a clear example of military action based on deception techniques.

the Trojan Horse

In 1856, religious leaders in Algeria were performing miracles which were helping raise the idea of a rebellion against French colonialists. Napoleon then brought French magician Robert Houdin who performed tricks that were more impressive than the ones performed by the religious leaders, gaining influence over the rebels and dissipating the religious leader’s power.

Robert Houdin avoided a rebellion in Algeria, for Napoleon

During WWII, Jasper Maskelyne helped the British army in several actions, the largest one being the supposed disappearance of the Suez Canal to mislead German bombers. He worked with 14 assistants, including an architect, art restorer, carpenter, chemist, electrical engineer, electrician, painter, and stage-set builder, a group whose nickname was the "Magic Gang". "He built a mockup of the night-lights of Alexandria in a bay three miles away with fake buildings, lighthouse, and anti-aircraft batteries. To mask the Suez Canal, he built a revolving cone of mirrors that created a wheel of spinning light nine miles wide, meant to dazzle and disorient enemy pilots so that heir bombs would fall off-target." (http://www.magictricks.com/war-magician.html) Even though the accuracy of this achievement is controversial, there is no doubt that magicians are skilled in the art of deception. Therefore, it is not uncommon that magicians and illusionists work for or give advice for governments, armies and intelligence services.

Jasper Maskelyne, 'The War Magician'

Barton Whaley has studied the relationship between war and the tactics and methods of the magician. In his publication ‘Detecting Deception: A Bibliography of Counterdeception Across Time, Cultures and Discipline' (2006, Foreign Denial & Deception Committee Washington, DC), he clearly defines deception and dissects the differences between existing categories of deception.

“I define deception as any attempt—by words or actions—intended to distort another person's or group's perception of reality. And to keep matters simple, a lie is any statement made with the intent to deceive. These definitions avoid confusion with mere misinformation, incomplete information, or the truth value of statements. But they do permit us to include the authorized lies and deceptions practiced with our knowledge and approval by stage actors, magicians, and poker players. Moreover, this definition gets around the worrisome problem of self-deception. Instead, for our present purpose, the target of a deception is not oneself but always another's mind.”(Whaley, Detecting Deception, p.7)

in Detecting Deception, A Bibliography of Counterdeception Across Time, Cultures and Discipline, B. Whaley, 2006

‘Some Operational Uses of the Art of Deception’, written in 1954 by John Mulholland, a magician who worked for the CIA, was intended to teach the readers how ‘to perform in a variety of acts secretly and undetectably’. (Jonathan Allen, Cabinet Magazine, issue 26)