Skip to content

Why the contents on npm are different from here? #9

@peter0749

Description

@peter0749

A little mess. Sorry for that...
package.json on npm:

{
  "READ ME": "README.md",
  "_args": [
    [
      {
        "raw": "aimlinterpreter",
        "scope": null,
        "escapedName": "aimlinterpreter",
        "name": "aimlinterpreter",
        "rawSpec": "",
        "spec": "latest",
        "type": "tag"
      },
      "/Users/kuang-yujeng/testtesttest"
    ]
  ],
  "_from": "aimlinterpreter@latest",
  "_id": "aimlinterpreter@0.1.7",
  "_inCache": true,
  "_location": "/aimlinterpreter",
  "_npmUser": {
    "name": "b3nra",
    "email": "bennyra92@gmail.com"
  },
  "_npmVersion": "1.4.28",
  "_phantomChildren": {},
  "_requested": {
    "raw": "aimlinterpreter",
    "scope": null,
    "escapedName": "aimlinterpreter",
    "name": "aimlinterpreter",
    "rawSpec": "",
    "spec": "latest",
    "type": "tag"
  },
  "_requiredBy": [
    "#USER",
    "/"
  ],
  "_resolved": "https://registry.npmjs.org/aimlinterpreter/-/aimlinterpreter-0.1.7.tgz",
  "_shasum": "988c1b6b135a8099b3d1144832ad89691d1b7cf6",
  "_shrinkwrap": null,
  "_spec": "aimlinterpreter",
  "_where": "/Users/kuang-yujeng/testtesttest",
  "author": {
    "name": "B3nRa"
  },
  "bugs": {
    "url": "https://github.com/B3nRa/AIML.js/issues"
  },
  "dependencies": {
    "dom-js": "~0.0.9"
  },
  "description": "Module to interpret AIML files in node.js",
  "devDependencies": {},
  "directories": {},
  "dist": {
    "shasum": "988c1b6b135a8099b3d1144832ad89691d1b7cf6",
    "tarball": "https://registry.npmjs.org/aimlinterpreter/-/aimlinterpreter-0.1.7.tgz"
  },
  "gitHead": "1497b828dfa61cfc8555b935ca40f9dad60c0125",
  "homepage": "https://github.com/B3nRa/AIML.js",
  "keywords": [
    "aiml",
    "ai",
    "interpreter",
    "bot"
  ],
  "license": "BSD",
  "main": "AIMLInterpreter.js",
  "maintainers": [
    {
      "name": "b3nra",
      "email": "bennyra92@gmail.com"
    }
  ],
  "name": "aimlinterpreter",
  "optionalDependencies": {},
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/B3nRa/AIML.js.git"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "version": "0.1.7"
}

diff AIMLInterpreter.js(npm) AIMLInterpreter.js(GitHub)

1,477c1,538
< DomJS = require("dom-js").DomJS;
< fs = require('fs');
< 
< var storedVariableValues = {};
< var botAttributes = {};
< 
< var lastWildCardValue = '';
< var wildCardArray = [];
< 
< var domArray = [];
< var domIndex = 0;
< 
< var isAIMLFileLoadingStarted = false;
< var isAIMLFileLoaded = false;
< 
< var previousAnswer = '';
< 
< //botAttributes contain things like name, age, master, gender...
< var AIMLInterpreter = function(botAttributesParam){
<     var self = this;
<     botAttributes = botAttributesParam;
< 
<     this.loadAIMLFilesIntoArray = function(fileArray){
<         isAIMLFileLoadingStarted = true;
<         var fileIndex = 0;
<         var readAIMLFile = function(file){
<             fs.readFile(file, 'utf8', function (err,data) {
<                 if (err) {
<                     return console.log(err);
<                 }
< 
<                 fileIndex++;
< 
<                 new DomJS().parse(data, function(err, dom) {
<                     var topCategories, topics;
<                     if (err) {
<                         //            return cb(err);
<                     }
<                     if (dom.name === !'aiml') {
<                         //            return cb('Unsupported file');
<                     }
<                     domArray[domIndex] = dom;
<                     domIndex++;
<                     if(fileIndex < fileArray.length){
<                         readAIMLFile(fileArray[fileIndex]);
<                     }
<                     else{
<                         console.log('AIML file is loaded!');
<                         isAIMLFileLoaded = true;
<                     }
<                 });
<             });
<         }
<         readAIMLFile(fileArray[fileIndex]);
<     };
< 
<     this.findAnswerInLoadedAIMLFiles = function(clientInput, cb){
<         //check if all AIML files have been loaded. If not, call this method again after a delay
<         if(isAIMLFileLoaded){
<             clientInput = clientInput.toUpperCase();
<             wildCardArray = [];
<             var result = '';
<             for(var i = 0; i < domArray.length; i++){
<                 cleanDom(domArray[i].children);
<                 result = findCorrectCategory(clientInput, domArray[i].children);
<                 if(result){
<                     break;
<                 }
<             }
< 
<             if(result){
<                 result = cleanStringFormatCharacters(result);
<                 previousAnswer = result;
<             }
<             cb(result, wildCardArray, clientInput);
<         }
<         else{
<             var findAnswerInLoadedAIMLFilesWrapper = function(clientInput, cb){
<                 return function(){
<                     self.findAnswerInLoadedAIMLFiles(clientInput, cb);
<                 };
<             };
< 
<             setTimeout(findAnswerInLoadedAIMLFilesWrapper(clientInput, cb), 1000);
<         }
<     };
< };
< 
< // remove string control characters (like line-breaks '\r\n', leading / trailing spaces etc.)
< var cleanStringFormatCharacters = function(str){
<     var cleanedStr = str.replace(/\r\n/gi, '');
<     cleanedStr = cleanedStr.replace(/^\s*/, '');
<     cleanedStr = cleanedStr.replace(/\s*$/,'');
< 
<     return cleanedStr;
< }
< 
< var cleanDom = function(childNodes){
<     for(var i = 0; i < childNodes.length; i++){
<         if(childNodes[i].hasOwnProperty('text') & typeof(childNodes[i].text) === 'string'){
< 
<             // remove all nodes of type 'text' when they just contain '\r\n'. This indicates line break in the AIML file
<             if(childNodes[i].text.match(/^\s*\r\n\s*$/gi)){
<                 childNodes.splice(i, 1);
<             }
<         }
<     }
< 
< 
<     // traverse through whole tree by recursive calls
<     for(var j = 0; j < childNodes.length; j++){
<         if(childNodes[j].hasOwnProperty('children')){
<             cleanDom(childNodes[j].children);
<         }
<     }
< };
< 
< var findCorrectCategory = function(clientInput, domCategories){
<     //indexOfSetTagAmountWithWildCard indicates how many sets with wildcard occur so that those sets store the correct wildcard value
<     var indexOfSetTagAmountWithWildCard = 0;
< 
<     var  travereseThroughDomToFindMatchingPattern= function(categories){
<         for(var i = 0; i < categories.length; i++){
<             if(categories[i].name === 'category'){
<                 //traverse through the dom
<                 //text gets the value of the current pattern node
<                 var text = travereseThroughDomToFindMatchingPattern(categories[i].children);
<                 //check if the input of the user matches the pattern text
<                 var matches = checkIfMessageMatchesPattern(clientInput, text);
<                 if(matches){
<                     //check if a 'that' tag is existing. If yes, check if the text of the that tag matches the previous given answer.
<                     //If it does not match, continue the traversion through the AIML file
<                     var isMatchingThat = checkForThatMatching(categories[i].children);
<                     if(isMatchingThat){
<                         var text = findFinalTextInTemplateNode(categories[i].children);
<                         if(text){
<                             return text;
<                         }
<                         break;
<                     }
<                 }
<             }
<             else if(categories[i].name === 'pattern'){
<                 var text = resolveChildNodesInPatternNode(categories[i].children);
<                 return text;
<             }
<         }
<     }
< 
<     var checkForThatMatching = function(categoryChildNodes){
<         for(var i = 0; i < categoryChildNodes.length; i++){
<             if(categoryChildNodes[i].name === 'that'){
<                 //if the previous answer of the bot does not match the that-tag text, then return undefined!
<                 if(categoryChildNodes[i].children[0].text != previousAnswer){
<                     return false;
<                 }
<                 else{
<                     return true;
<                 }
<             }
<         }
<         //if no that tag was found, everything 'fits'
<         return true;
<     }
< 
<     var resolveChildNodesInPatternNode = function(patternChildNodes){
<         var text = '';
< 
<         for(var i = 0; i < patternChildNodes.length; i++){
<             if(patternChildNodes[i].name === 'bot'){
<                 text = text + botAttributes[patternChildNodes[i].attributes.name];
<             }
<             else if(patternChildNodes[i].name === 'get'){
<                 text = text + storedVariableValues[patternChildNodes[i].attributes.name];
<             }
<             else if(patternChildNodes[i].name === 'set'){
<                 text = text + patternChildNodes[i].children[0].text;
<             }
<             else{
<                 text = text + patternChildNodes[i].text;
<             }
<         }
< 
<         return text;
<     }
< 
<     var findFinalTextInTemplateNode = function(childNodesOfTemplate){
<         var text = '';
< 
<         //traverse through template nodes until final text is found
<         //return it then to very beginning
<         for(var i = 0; i < childNodesOfTemplate.length; i++){
<             if(childNodesOfTemplate[i].name === 'template'){
<                 //traverse as long through the dom until final text was found
<                 //final text -> text after special nodes (bot, get, set,...) were resolved
<                 return findFinalTextInTemplateNode(childNodesOfTemplate[i].children);
<             }
<             else if(childNodesOfTemplate[i].name === 'condition'){
<                 return resolveSpecialNodes(childNodesOfTemplate);
<             }
<             else if(childNodesOfTemplate[i].name === 'random'){
<                 //if random node was found, it's children are 'li' nodes.
<                 //pick one li node by random and continue dom traversion until final text is found
<                 var randomNumber = Math.floor(Math.random() * (childNodesOfTemplate[i].children.length));
<                 return findFinalTextInTemplateNode([childNodesOfTemplate[i].children[randomNumber]]);
<             }
<             else if(childNodesOfTemplate[i].name === 'srai'){
<                 //take pattern text of srai node to get answer of another category
<                 var sraiText = '' + findFinalTextInTemplateNode(childNodesOfTemplate[i].children);
<                 sraiText = sraiText.toUpperCase();
<                 var referredPatternText = sraiText;
<                 //call findCorrectCategory again to find the category that belongs to the srai node
<                 var text = findCorrectCategory(referredPatternText, domCategories);
<                 return text;
<             }
<             else if(childNodesOfTemplate[i].name === 'li'){
<                 return findFinalTextInTemplateNode(childNodesOfTemplate[i].children);
<             }
<             else if(childNodesOfTemplate[i].name === 'pattern'){
<                 //(here it is already checked that this is the right pattern that matches the user input)
<                 //make use of the functions of the special nodes - bot, set, get...
<                 resolveSpecialNodes(childNodesOfTemplate[i].children);
<                 continue;
<             }
<             else if(childNodesOfTemplate[i].name === 'bot'){
<                 text = resolveSpecialNodes(childNodesOfTemplate);
<                 return text;
<             }
<             else if(childNodesOfTemplate[i].name === 'set'){
<                 text = resolveSpecialNodes(childNodesOfTemplate);
<                 return text;
<             }
<             else if(childNodesOfTemplate[i].name === 'get'){
<                 text = resolveSpecialNodes(childNodesOfTemplate);
<                 return text;
<             }
<             else if(childNodesOfTemplate[i].name === 'sr'){
<                 text = resolveSpecialNodes(childNodesOfTemplate);
<                 return text;
<             }
<             else if(childNodesOfTemplate[i].name === 'star'){
<                 text = resolveSpecialNodes(childNodesOfTemplate);
<                 return text;
<             }
<             else if(childNodesOfTemplate[i].name === 'that'){
< 
<             }
<             else{
<                 //this is the text of template node
<                 //after all special functions (bot, get, set,...) were resolved
<                 //return that text
<                 text = resolveSpecialNodes(childNodesOfTemplate);
<                 if((text.match('[\\n|\\t]*[^A-Z|^a-z|^!|^?]*')[0] === '') && (text.indexOf('function ()') === -1)){
<                     return (text);
<                 }
<             }
<         }
<     };
< 
<     var resolveSpecialNodes = function(innerNodes){
<         var text = '';
<         //concatenate string of all node children - normal text, bot tags, get tags, set tags...
<         for(var i = 0; i < innerNodes.length; i++){
< 
<             if(innerNodes[i].name === 'bot'){
<                 //replace bot tags by the belonging bot attribute value
<                 text = text + botAttributes[innerNodes[i].attributes.name];
<             }
<             else if(innerNodes[i].name === 'get'){
<                 //replace get tag by belonging variable value
<                 text = text + storedVariableValues[innerNodes[i].attributes.name];
<             }
<             else if(innerNodes[i].name === 'set'){
<                 //store value of set tag text into variable (variable name = attribute of set tag)
<                 //replace than set tag by the text value
< 
<                 if(innerNodes[i].children[0].text === '*'){
<                     //the first set-Tag with wildCard gets the first wildCardValue, the second set-Tag with wildCard gets the second wildCardValue etc.
<                     storedVariableValues[innerNodes[i].attributes.name] = wildCardArray[indexOfSetTagAmountWithWildCard];
<                     indexOfSetTagAmountWithWildCard++;
<                 }else{
<                     storedVariableValues[innerNodes[i].attributes.name] = innerNodes[i].children[0].text;
<                 }
< //                text = text + innerNodes[i].children[0].text;
<                 text = text + resolveSpecialNodes(innerNodes[i].children);
<             }
<             else if(innerNodes[i].name === 'sr'){
<                 var result;
< 
<                 //for-loop to go through all loaded AIML files
<                 for(var j = 0; j < domArray.length; j++){
<                     result = findCorrectCategory(lastWildCardValue, domArray[j].children);
<                     //if in one of the dom trees a matching pattern was found, exit this inner loop
<                     if(result){
<                         text = text + result;
<                         break;
<                     }
<                 }
<             }
<             else if(innerNodes[i].name === 'star'){
<                 text = text + lastWildCardValue;
<             }
<             else if(innerNodes[i].name === 'condition') {                
<                 // condition tag specification: list condition tag
<                 if(innerNodes[i].attributes.name === undefined){
<                     if(innerNodes[i].children === undefined){
<                         return undefined;
<                     }
<                     var child;
<                     for(var c in innerNodes[i].children){
<                         child = innerNodes[i].children[c];
<                         if(child.name === 'li'){
<                             if(child.attributes.value == undefined 
<                                 || storedVariableValues[child.attributes.name] === child.attributes.value.toUpperCase()){
<                                 return findFinalTextInTemplateNode(child.children);
<                             }
<                         }
<                     }
<                 } 
<                 // condition tag specification: multi condition tag
<                 else if(innerNodes[i].attributes.value !== undefined){         
<                     if (storedVariableValues[innerNodes[i].attributes.name] === innerNodes[i].attributes.value.toUpperCase()) {
<                         text = text + resolveSpecialNodes(innerNodes[i].children);
<                     }
<                 }
<                 // condition tag specification: single name list condition tags
<                 else if(innerNodes[i].children !== undefined){
<                     var child;
<                     for(var c in innerNodes[i].children){
<                         child = innerNodes[i].children[c];
<                         if(child.name === 'li'){
<                             if(child.attributes.value === undefined 
<                                 || storedVariableValues[innerNodes[i].attributes.name] === child.attributes.value.toUpperCase()){
<                                 return findFinalTextInTemplateNode(child.children);
<                             }
<                         }
<                     }
< 
<                     return undefined;
<                 }
<             }
<             else{
<                 //normal text (no special tag)
<                 text = text + innerNodes[i].text;
<             }
<         }
< 
<         text = cleanStringFormatCharacters(text);
<         return text;
<     }
< 
<     return travereseThroughDomToFindMatchingPattern(domCategories);
< }
< 
< var checkIfMessageMatchesPattern = function(userInput, patternText){
<     //convert wildcards in of the pattern node into a regex that matches every char
<     var regexPattern = convertWildcardToRegex(patternText);
< 
<     //add one with the text in function 'convertWildcardToRegex' here a space is added before and after the user input
<     //to prevent false matching
<     if(userInput.charAt(0) != " "){
<         userInput = " " + userInput;
<     }
< 
<     var lastCharacterPosition  = userInput.length - 1;
<     var lastCharacter = userInput.charAt(lastCharacterPosition);
<     if(lastCharacter != " "){
<         userInput = userInput + " ";
<     }
< 
<     //match userInput with the regex pattern
<     //if it matches, matchedString is defined
<     var matchedString = userInput.match(regexPattern);
< 
<     if(matchedString){
<         //the matched pattern must be at least as long as the user input or must contain the regex
<         if(matchedString[0].length >= userInput.length || regexPattern.indexOf('[A-Z|0-9|\\s]*[A-Z|0-9|-]*[A-Z|0-9]*[!|.|?|\\s]*') > -1){
<             //if patternText contained a wild card, get the user input that were put into this wild card
<             //use original patternText (* is not replaced by regex!)
<             var information = getWildCardValue(userInput, patternText);
< 
<             return true;
<         }
<     }
<     else{
<         return false;
<     }
< }
< 
< var convertWildcardToRegex = function(text){
<     var firstCharacter = text.charAt(0);
<     //add a space before and after the pattern text (THIS IS LATER ALSO DONE FOR THE USER INPUT)
<     //prevents false matchings
<     //e.g. (HI as regex also matches HIM or HISTORY, but <space>HI</space> does only match <space>HI</space>)
<     if(firstCharacter != "*"){
<         var text = " " + text;
<     }
<     var lastCharacterPosition = text.length - 1;
<     var lastCharacter = text.charAt(lastCharacterPosition);
< 
<     //replace space before wildcard
<     var modifiedText = text.replace(' *', '*');
<     //replace wildcard (*) by regex
<     modifiedText = modifiedText.replace(/\*/g, '[A-Z|0-9|\\s]*[A-Z|0-9|\*|-]*[A-Z|0-9]*[!|.|?|\\s]*');
< 
<     if(lastCharacter != "*"){
< //        text = text + " ";
<         //pattern should also match when user inputs ends with a space, ?, ! or .
<         modifiedText = modifiedText + '[\\s|?|!|.]*';
<     }
< 
<     return modifiedText;
< }
< 
< var getWildCardValue = function(userInput, patternText){
<     //get all strings of the pattern that are divided by a *
<     //e.g. WHAT IS THE RELATION BETWEEN * AND * -> [WHAT IS THE RELATION BETWEEN , AND ]
<     var replaceArray = patternText.split('*');
<     var wildCardInput = userInput;
< 
<     if(replaceArray.length > 1){
<         //replace the string of the userInput which is fixed by the pattern
<         for(var i = 0; i < replaceArray.length; i++){
<             wildCardInput = wildCardInput.replace(replaceArray[i], '|');
<         }
<         //split the wildCardInput string by | to differentiate multiple * inputs
<         //e.g. userInput = WHAT IS THE RELATION BETWEEN TIM AND STRUPPI?
<         //-> | TIM | STRUPPI
<         //-> [TIM, STRUPPI]
<         wildCardInput = wildCardInput.split('|');
<         //split function can create an array which also includes spaces etc. -> e.g. [TIM, " ", "", STRUPPI, " "]
<         //we just want the information
<         var wildCardArrayIndex = 0;
<         for(var i = 0; i < wildCardInput.length; i++){
<             if(wildCardInput[i] != '' && wildCardInput[i] != ' ' && wildCardInput != undefined){
<                 var wildCard = wildCardInput[i];
<                 var wildCardLastCharIndex = wildCard.length - 1;
<                 var firstCharOfWildCard = wildCard.charAt(0);
<                 var lastCharOfWildCard = wildCard.charAt(wildCardLastCharIndex);
< 
<                 try{
<                     //harmonize the wildcard string
<                     //remove first char if it is a space.
<                     //calculate the last index again since the length of the string changed
<                     if(firstCharOfWildCard === ' '){
<                         wildCard = wildCard.splice(0);
<                         wildCardLastCharIndex = wildCard.length - 1;
<                         lastCharOfWildCard = wildCard.charAt(wildCardLastCharIndex);
<                     }
<                     //if the last char is a space, remove it
<                     //calculate the last index again since the length of the string changed
<                     if(lastCharOfWildCard === ' '){
<                         wildCard = wildCard.substr(0, wildCardLastCharIndex);
<                         wildCardLastCharIndex = wildCard.length - 1;
<                         lastCharOfWildCard = wildCard.charAt(wildCardLastCharIndex);
<                     }
<                     if(lastCharOfWildCard === '?'){
<                         wildCard = wildCard.substr(0, wildCardLastCharIndex);
<                     }
<                 }
<                 catch(e){
< 
<                 }
<                 wildCardArray[wildCardArrayIndex] = wildCard;
<                 wildCardArrayIndex++;
<             }
<         }
<     }
<     if(wildCardArray.length - 1 >= 0){
<         lastWildCardValue = wildCardArray[wildCardArray.length - 1];
<     }
< 
<     return wildCardArray;
< }
< 
< module.exports = AIMLInterpreter;
< 
---
> DomJS = require("dom-js").DomJS;
> fs = require('fs');
> 
> var storedVariableValues = {};
> var botAttributes = {};
> 
> var lastWildCardValue = '';
> var wildCardArray = [];
> 
> var domArray = [];
> var domIndex = 0;
> 
> var isAIMLFileLoadingStarted = false;
> var isAIMLFileLoaded = false;
> 
> var previousAnswer = '';
> var previousThinkTag = false;
> 
> //botAttributes contain things like name, age, master, gender...
> var AIMLInterpreter = function(botAttributesParam){
>     var self = this;
>     botAttributes = botAttributesParam;
> 
>     this.loadAIMLFilesIntoArray = function(fileArray){
>         isAIMLFileLoadingStarted = true;
>         var fileIndex = 0;
>         var readAIMLFile = function(file){
>             fs.readFile(file, 'utf8', function (err,data) {
>                 if (err) {
>                     return console.log(err);
>                 }
> 
>                 fileIndex++;
> 
>                 data = data.replace(/>\r*\n+\s*</gi,'><');
> 
>                 new DomJS().parse(data, function(err, dom) {
>                     var topCategories, topics;
>                     if (err) {
>                         //            return cb(err);
>                     }
>                     if (dom.name === !'aiml') {
>                         //            return cb('Unsupported file');
>                     }
>                     domArray[domIndex] = dom;
>                     domIndex++;
>                     if(fileIndex < fileArray.length){
>                         readAIMLFile(fileArray[fileIndex]);
>                     }
>                     else{
>                         console.log('AIML file is loaded!');
>                         isAIMLFileLoaded = true;
>                     }
>                 });
>             });
>         }
>         readAIMLFile(fileArray[fileIndex]);
>     };
> 
>     this.findAnswerInLoadedAIMLFiles = function(clientInput, cb){
>         //check if all AIML files have been loaded. If not, call this method again after a delay
>         if(isAIMLFileLoaded){
>             wildCardArray = [];
>             lastWildCardValue = '';
>             var result = '';
>             for(var i = 0; i < domArray.length; i++){
>                 cleanDom(domArray[i].children);
>                 result = findCorrectCategory(clientInput, domArray[i].children);
>                 if(result){
>                     break;
>                 }
>             }
> 
>             if(result){
>                 result = cleanStringFormatCharacters(result);
>                 previousAnswer = result;
>             }
>             cb(result, wildCardArray, clientInput);
>         }
>         else{
>             var findAnswerInLoadedAIMLFilesWrapper = function(clientInput, cb){
>                 return function(){
>                     self.findAnswerInLoadedAIMLFiles(clientInput, cb);
>                 };
>             };
> 
>             setTimeout(findAnswerInLoadedAIMLFilesWrapper(clientInput, cb), 1000);
>         }
>     };
>     //restart the DOM in order to load a new AIML File
>     this.restartDom = function(){
>         domArray=[];
>         domIndex=0;
>     };
> };
> 
> 
> 
> 
> // remove string control characters (like line-breaks '\r\n', leading / trailing spaces etc.)
> var cleanStringFormatCharacters = function(str){
>     var cleanedStr = str.replace(/\r\n/gi, '');
>     cleanedStr = cleanedStr.replace(/^\s*/, '');
>     cleanedStr = cleanedStr.replace(/\s*$/,'');
> 
>     return cleanedStr;
> }
> 
> var cleanDom = function(childNodes){
>     for(var i = 0; i < childNodes.length; i++){
>         if(childNodes[i].hasOwnProperty('text') & typeof(childNodes[i].text) === 'string'){
> 
>             // remove all nodes of type 'text' when they just contain '\r\n'. This indicates line break in the AIML file
>             if(childNodes[i].text.match(/^\s*\r\n\s*$/gi)){
>                 childNodes.splice(i, 1);
>             }
>         }
>     }
> 
> 
>     // traverse through whole tree by recursive calls
>     for(var j = 0; j < childNodes.length; j++){
>         if(childNodes[j].hasOwnProperty('children')){
>             cleanDom(childNodes[j].children);
>         }
>     }
> };
> 
> var findCorrectCategory = function(clientInput, domCategories){
>     //indexOfSetTagAmountWithWildCard indicates how many sets with wildcard occur so that those sets store the correct wildcard value
>     var indexOfSetTagAmountWithWildCard = 0;
> 
>     var  travereseThroughDomToFindMatchingPattern= function(categories){
>         for(var i = 0; i < categories.length; i++){
>             if(categories[i].name === 'category'){
>                 //traverse through the dom
>                 //text gets the value of the current pattern node
>                 var text = travereseThroughDomToFindMatchingPattern(categories[i].children);
>                 //check if the input of the user matches the pattern text
>                 var matches = checkIfMessageMatchesPattern(clientInput, text);
>                 if(matches){
>                     //check if a 'that' tag is existing. If yes, check if the text of the that tag matches the previous given answer.
>                     //If it does not match, continue the traversion through the AIML file
>                     var isMatchingThat = checkForThatMatching(categories[i].children);
>                     if(isMatchingThat){
>                         var text = findFinalTextInTemplateNode(categories[i].children);
>                         if(text){
>                             return text;
>                         }
>                         break;
>                     }
>                 }
>             }
>             else if(categories[i].name === 'pattern'){
>                 var text = resolveChildNodesInPatternNode(categories[i].children);
>                 return text;
>             }
>         }
>     }
> 
>     var checkForThatMatching = function(categoryChildNodes){
>         for(var i = 0; i < categoryChildNodes.length; i++){
>             if(categoryChildNodes[i].name === 'that'){
>                 //if the previous answer of the bot does not match the that-tag text, then return undefined!
>                 if(categoryChildNodes[i].children[0].text != previousAnswer){
>                     return false;
>                 }
>                 else{
>                     return true;
>                 }
>             }
>         }
>         //if no that tag was found, everything 'fits'
>         return true;
>     }
> 
>     var resolveChildNodesInPatternNode = function(patternChildNodes){
>         var text = '';
> 
>         for(var i = 0; i < patternChildNodes.length; i++){
>             if(patternChildNodes[i].name === 'bot'){
>                 text = text + botAttributes[patternChildNodes[i].attributes.name];
>             }
>             else if(patternChildNodes[i].name === 'get'){
>                 text = text + storedVariableValues[patternChildNodes[i].attributes.name];
>             }
>             else if(patternChildNodes[i].name === 'set'){
>                 text = text + patternChildNodes[i].children[0].text;
>             }
>             else{
>                 text = text + patternChildNodes[i].text;
>             }
>         }
> 
>         return text;
>     }
> 
>     var findFinalTextInTemplateNode = function(childNodesOfTemplate){
>         var text = '';
> 
>         //traverse through template nodes until final text is found
>         //return it then to very beginning
> 
>         for(var i = 0; i < childNodesOfTemplate.length; i++){
>             if(childNodesOfTemplate[i].name === 'template'){
>                 //traverse as long through the dom until final text was found
>                 //final text -> text after special nodes (bot, get, set,...) were resolved
>                 return findFinalTextInTemplateNode(childNodesOfTemplate[i].children);
>             }
>             else if(childNodesOfTemplate[i].name === 'condition'){
>                 return resolveSpecialNodes(childNodesOfTemplate);
>             }
>             else if(childNodesOfTemplate[i].name === 'random'){
>                 //if random node was found, its children are 'li' nodes.
>                 return resolveSpecialNodes(childNodesOfTemplate);
>             }
>             else if(childNodesOfTemplate[i].name === 'srai'){
>                 //take pattern text of srai node to get answer of another category
>                 var sraiText = '' + findFinalTextInTemplateNode(childNodesOfTemplate[i].children);
>                 sraiText = sraiText.toUpperCase();
>                 var referredPatternText = sraiText;
>                 //call findCorrectCategory again to find the category that belongs to the srai node
>                 var text = findCorrectCategory(referredPatternText, domCategories);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'li'){
>                 return findFinalTextInTemplateNode(childNodesOfTemplate[i].children);
>             }
>             else if(childNodesOfTemplate[i].name === 'br'){
>                 //br elements are used for putting '\n' into the text
>                 return resolveSpecialNodes(childNodesOfTemplate);
>             }
>             else if(childNodesOfTemplate[i].name === 'pattern'){
>                 //(here it is already checked that this is the right pattern that matches the user input)
>                 //make use of the functions of the special nodes - bot, set, get...
>                 resolveSpecialNodes(childNodesOfTemplate[i].children);
>                 continue;
>             }
>             else if(childNodesOfTemplate[i].name === 'think'){
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'bot'){
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'set'){
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'get'){
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'sr'){
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'star'){
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 return text;
>             }
>             else if(childNodesOfTemplate[i].name === 'that'){
> 
>             }
>             else{
>                 //this is the text of template node
>                 //after all special functions (bot, get, set,...) were resolved
>                 //return that text
>                 text = resolveSpecialNodes(childNodesOfTemplate);
>                 if((text.match('[\\n|\\t]*[^A-Z|^a-z|^1-9|^!|^?]*')[0] === '') && (text.indexOf('function ()') === -1)){
>                     return (text);
>                 }
>             }
>         }
>     };
> 
>     var resolveSpecialNodes = function(innerNodes){
>         var text = '';
>         //concatenate string of all node children - normal text, bot tags, get tags, set tags...
>         for(var i = 0; i < innerNodes.length; i++){
> 
>             if(innerNodes[i].name === 'bot'){
>                 //replace bot tags by the belonging bot attribute value
>                 text = text + botAttributes[innerNodes[i].attributes.name];
>             }
>             else if(innerNodes[i].name === 'get'){
>                 //replace get tag by belonging variable value
>                 var getAux = storedVariableValues[innerNodes[i].attributes.name];
>                 if(getAux === undefined){
>                     text = text + '';
>                 }else{
>                     text = text + getAux;
>                 }
>             }
>             else if(innerNodes[i].name === 'set'){
>                 //store value of set tag text into variable (variable name = attribute of set tag)
>                 //replace than set tag by the text value
>                 var aux='';
>                 if(innerNodes[i].children[0].name === 'star'){
>                     aux = resolveSpecialNodes(innerNodes[i].children);
>                     storedVariableValues[innerNodes[i].attributes.name] = aux;
>                     if(!previousThinkTag){
>                         text = text + aux;
>                     }
>                 }
>                 else if(innerNodes[i].children[0].text === '*'){
>                     //the first set-Tag with wildCard gets the first wildCardValue, the second set-Tag with wildCard gets the second wildCardValue etc.
>                     storedVariableValues[innerNodes[i].attributes.name] = wildCardArray[indexOfSetTagAmountWithWildCard];
>                     indexOfSetTagAmountWithWildCard++;
>                 }else{
>                     storedVariableValues[innerNodes[i].attributes.name] = innerNodes[i].children[0].text;
>                 }
> 
>                 //If this set tag is a think tag's child
>                 if(previousThinkTag){
>                     previousThinkTag=false;
>                     text= text + '';
>                 }else{
>                     text = text + resolveSpecialNodes(innerNodes[i].children);
>                 }
>             }
>             else if(innerNodes[i].name === 'br'){
>                 text = text + '\n';
>             }
>             else if(innerNodes[i].name === 'think'){
>                 previousThinkTag=true;
>                 text = text + resolveSpecialNodes(innerNodes[i].children);
>             }
>             else if(innerNodes[i].name === 'sr'){
>                 var result;
> 
>                 //for-loop to go through all loaded AIML files
>                 for(var j = 0; j < domArray.length; j++){
>                     result = findCorrectCategory(lastWildCardValue, domArray[j].children);
>                     //if in one of the dom trees a matching pattern was found, exit this inner loop
>                     if(result){
>                         text = text + result;
>                         break;
>                     }
>                 }
>             }
>             else if(innerNodes[i].name === 'random'){
>                 //Get a random number and find the li tag chosen
>                 var randomNumber = Math.floor(Math.random() * (innerNodes[i].children.length));
>                 text = text + findFinalTextInTemplateNode([innerNodes[i].children[randomNumber]]);
>             ;
>             }
>             else if(innerNodes[i].name === 'star'){
>               if(innerNodes[i].attributes && innerNodes[i].attributes.index && innerNodes[i].attributes.index <= wildCardArray.length){
>                 text = text + wildCardArray[innerNodes[i].attributes.index-1];
>               }
>               else {
>                 text = text + wildCardArray[0];
>               }
>             }
>             else if(innerNodes[i].name === 'srai'){
>                 //take pattern text of srai node to get answer of another category
>                 var sraiText = '' + findFinalTextInTemplateNode(innerNodes[i].children);
>                 sraiText = sraiText.toUpperCase();
>                 var referredPatternText = sraiText;
>                 //call findCorrectCategory again to find the category that belongs to the srai node
>                 text = text + findCorrectCategory(referredPatternText, domCategories);
>             }
>             else if(innerNodes[i].name === 'condition') {
>                 // condition tag specification: list condition tag
>                 if(innerNodes[i].attributes.name === undefined){
>                     if(innerNodes[i].children === undefined){
>                         return undefined;
>                     }
>                     var child;
>                     for(var c in innerNodes[i].children){
>                         child = innerNodes[i].children[c];
>                         if(child.name === 'li'){
>                             if(child.attributes.value == undefined
>                                 || storedVariableValues[child.attributes.name] === child.attributes.value.toUpperCase()){
>                                 return findFinalTextInTemplateNode(child.children);
>                             }
>                         }
>                     }
>                 }
>                 // condition tag specification: multi condition tag
>                 else if(innerNodes[i].attributes.value !== undefined){
>                     if (storedVariableValues[innerNodes[i].attributes.name] === innerNodes[i].attributes.value.toUpperCase()) {
>                         text = text + resolveSpecialNodes(innerNodes[i].children);
>                     }
>                 }
>                 // condition tag specification: single name list condition tags
>                 else if(innerNodes[i].children !== undefined){
>                     var child;
>                     for(var c in innerNodes[i].children){
>                         child = innerNodes[i].children[c];
>                         if(child.name === 'li'){
>                             if(child.attributes.value === undefined
>                                 || storedVariableValues[innerNodes[i].attributes.name] === child.attributes.value.toUpperCase()){
>                                 return resolveSpecialNodes(child.children);
>                             }
>                         }
>                     }
> 
>                     return undefined;
>                 }
>             }
>             else if(innerNodes[i].name === undefined){
>                 //normal text (no special tag)
>                 text = text + innerNodes[i].text;
>             }
>         }
> 
>         text = cleanStringFormatCharacters(text);
>         return text;
>     }
> 
>     return travereseThroughDomToFindMatchingPattern(domCategories);
> }
> 
> var checkIfMessageMatchesPattern = function(userInput, patternText){
>     //convert wildcards in of the pattern node into a regex that matches every char
>     var regexPattern = convertWildcardToRegex(patternText);
> 
>     //add one with the text in function 'convertWildcardToRegex' here a space is added before and after the user input
>     //to prevent false matching
>     if(userInput.charAt(0) != " "){
>         userInput = " " + userInput;
>     }
> 
>     var lastCharacterPosition  = userInput.length - 1;
>     var lastCharacter = userInput.charAt(lastCharacterPosition);
>     if(lastCharacter != " "){
>         userInput = userInput + " ";
>     }
> 
>     //match userInput with the regex pattern
>     //if it matches, matchedString is defined
>     var matchedString = userInput.toUpperCase().match(regexPattern);
> 
>     if(matchedString){
>         //the matched pattern must be at least as long as the user input or must contain the regex
>         if(matchedString[0].length >= userInput.length || regexPattern.indexOf('[A-Z|0-9|\\s]*[A-Z|0-9|-]*[A-Z|0-9]*[!|.|?|\\s]*') > -1){
>             //if patternText contained a wild card, get the user input that were put into this wild card
>             //use original patternText (* is not replaced by regex!)
>             var information = getWildCardValue(userInput, patternText);
> 
>             return true;
>         }
>     }
>     else{
>         return false;
>     }
> }
> 
> var convertWildcardToRegex = function(text){
>     var firstCharacter = text.charAt(0);
>     //add a space before and after the pattern text (THIS IS LATER ALSO DONE FOR THE USER INPUT)
>     //prevents false matchings
>     //e.g. (HI as regex also matches HIM or HISTORY, but <space>HI</space> does only match <space>HI</space>)
>     if(firstCharacter != "*"){
>         var text = " " + text;
>     }
>     var lastCharacterPosition = text.length - 1;
>     var lastCharacter = text.charAt(lastCharacterPosition);
> 
>     //replace space before wildcard
>     var modifiedText = text.replace(' *', '*');
>     //replace wildcard (*) by regex
>     modifiedText = modifiedText.replace(/\*/g, '[A-Z|0-9|\\s]*[A-Z|0-9|\*|-]*[A-Z|0-9]*[!|.|?|\\s]*');
> 
>     if(lastCharacter != "*"){
> //        text = text + " ";
>         //pattern should also match when user inputs ends with a space, ?, ! or .
>         modifiedText = modifiedText + '[\\s|?|!|.]*';
>     }
> 
>     return modifiedText;
> }
> 
> var getWildCardValue = function(userInput, patternText){
>     //get all strings of the pattern that are divided by a *
>     //e.g. WHAT IS THE RELATION BETWEEN * AND * -> [WHAT IS THE RELATION BETWEEN , AND ]
>     var replaceArray = patternText.split('*');
>     var wildCardInput = userInput;
> 
>     if(replaceArray.length > 1){
>         //replace the string of the userInput which is fixed by the pattern
>         for(var i = 0; i < replaceArray.length; i++){
>             wildCardInput = wildCardInput.replace(new RegExp(replaceArray[i], 'i'), '|');
>         }
>         //split the wildCardInput string by | to differentiate multiple * inputs
>         //e.g. userInput = WHAT IS THE RELATION BETWEEN TIM AND STRUPPI?
>         //-> | TIM | STRUPPI
>         //-> [TIM, STRUPPI]
>         wildCardInput = wildCardInput.split('|');
>         //split function can create an array which also includes spaces etc. -> e.g. [TIM, " ", "", STRUPPI, " "]
>         //we just want the information
>         var wildCardArrayIndex = 0;
>         for(var i = 0; i < wildCardInput.length; i++){
>             if(wildCardInput[i] != '' && wildCardInput[i] != ' ' && wildCardInput != undefined){
>                 var wildCard = wildCardInput[i];
>                 var wildCardLastCharIndex = wildCard.length - 1;
>                 var firstCharOfWildCard = wildCard.charAt(0);
>                 var lastCharOfWildCard = wildCard.charAt(wildCardLastCharIndex);
> 
>                 try{
>                     //harmonize the wildcard string
>                     //remove first char if it is a space.
>                     //calculate the last index again since the length of the string changed
>                     if(firstCharOfWildCard === ' '){
>                         wildCard = wildCard.splice(0);
>                         wildCardLastCharIndex = wildCard.length - 1;
>                         lastCharOfWildCard = wildCard.charAt(wildCardLastCharIndex);
>                     }
>                     //if the last char is a space, remove it
>                     //calculate the last index again since the length of the string changed
>                     if(lastCharOfWildCard === ' '){
>                         wildCard = wildCard.substr(0, wildCardLastCharIndex);
>                         wildCardLastCharIndex = wildCard.length - 1;
>                         lastCharOfWildCard = wildCard.charAt(wildCardLastCharIndex);
>                     }
>                     if(lastCharOfWildCard === '?'){
>                         wildCard = wildCard.substr(0, wildCardLastCharIndex);
>                     }
>                 }
>                 catch(e){
> 
>                 }
>                 wildCardArray[wildCardArrayIndex] = wildCard;
>                 wildCardArrayIndex++;
>             }
>         }
>     }
>     if(wildCardArray.length - 1 >= 0){
>         lastWildCardValue = wildCardArray[wildCardArray.length - 1];
>     }
> 
>     return wildCardArray;
> }
> 
> module.exports = AIMLInterpreter;
\ No newline at end of file

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions