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