Giter Club home page Giter Club logo

rivescript-java's Introduction

RiveScript-Java

Gitter Build Status Maven Central MIT License

Introduction

This is a RiveScript interpreter library written for the Java programming language. RiveScript is a scripting language for chatterbots, making it easy to write trigger/response pairs for building up a bot's intelligence.

About RiveScript

RiveScript is a scripting language for authoring chatbots. It has a very simple syntax and is designed to be easy to read and fast to write.

A simple example of what RiveScript looks like:

+ hello bot
- Hello human.

This matches a user's message of "hello bot" and would reply "Hello human." Or for a slightly more complicated example:

+ my name is *
* <formal> == <bot name> => <set name=<formal>>Wow, we have the same name!
* <get name> != undefined => <set name=<formal>>Did you change your name?
- <set name=<formal>>Nice to meet you, <get name>!

The official website for RiveScript is https://www.rivescript.com/

To test drive RiveScript in your web browser, try the RiveScript Playground.

Documentation

Also check out the RiveScript Community Wiki for common design patterns and tips & tricks for RiveScript.

Installation

Add the rivescript-core dependency to your project:

Maven:

<dependency>
  <groupId>com.rivescript</groupId>
  <artifactId>rivescript-core</artifactId>
  <version>0.10.0</version>
</dependency>

Gradle:

dependencies {
    compile "com.rivescript:rivescript-core:0.10.0"
}

If you want to use RiveScript in a Spring Boot application see the Spring Boot Starter section.

Usage

When used as a library for writing your own chatbot, the synopsis is as follows:

import com.rivescript.Config;
import com.rivescript.RiveScript;

// Create a new bot with the default settings.
RiveScript bot = new RiveScript();

// To enable UTF-8 mode, you'd have initialized the bot like:
RiveScript bot = new RiveScript(Config.utf8());

// Load a directory full of RiveScript documents (.rive files)
bot.loadDirectory("./replies");

// Load an individual file.
bot.LoadFile("./testsuite.rive");

// Sort the replies after loading them!
bot.sortReplies();

// Get a reply.
String reply = bot.reply("user", "Hello bot!");

The rivescript-core distribution also includes an interactive shell for testing your RiveScript bot. Run it with the path to a folder on disk that contains your RiveScript documents. Example:

java com.rivescript.cmd.Shell [options] </path/to/documents>

Configuration

The com.rivescript.RiveScript constructor takes an optional Config instance. Here is a full example with all the supported options. You only need to provide values for configuration options that are different to the defaults.

RiveScript bot = new RiveScript(Config.newBuilder()
        .throwExceptions(false)          // Whether exception throwing is enabled
        .strict(true)                    // Whether strict syntax checking is enabled
        .utf8(false)                     // Whether UTF-8 mode is enabled
        .unicodePunctuation("[.,!?;:]")  // The unicode punctuation pattern
        .forceCase(false)                // Whether forcing triggers to lowercase is enabled
        .concat(ConcatMode.NONE)         // The concat mode
        .depth(50)                       // The recursion depth limit 
        .sessionManager(sessionManager)  // The session manager for user variables
        .errorMessages(errors)           // Map of custom error messages
        .build());

For convenience, you can use shortcuts:

// The default constructor uses a basic configuration.
RiveScript bot = new RiveScript();

// This is similar as:
RiveScript bot = new RiveScript(Config.basic());

// To use the basic configuration with UTF-8 mode enabled use: 
RiveScript bot = new RiveScript(Config.utf8());

UTF-8 Support

UTF-8 support in RiveScript is considered an experimental feature. It is disabled by default.

By default (without UTF-8 mode on), triggers may only contain basic ASCII characters (no foreign characters), and the user's message is stripped of all characters except letters, numbers and spaces. This means that, for example, you can't capture a user's e-mail address in a RiveScript reply, because of the @ and . characters.

When UTF-8 mode is enabled, these restrictions are lifted. Triggers are only limited to not contain certain metacharacters like the backslash, and the user's message is only stripped of backslashes and HTML angled brackets (to protect from obvious XSS if you use RiveScript in a web application). Additionally, common punctuation characters are stripped out, with the default set being [.,!?;:]. This can be overridden by providing a new regexp string to the Config.Builder#unicodePunctuation() method. Example:

// Make a new bot with UTF-8 mode enabled and override the punctuation
characters that get stripped from the user's message.
RiveScript bot = new RiveScript(Config.Builder
        .utf8()
        .unicodePunctuation("[.,!?;:]")
        .build());

The <star> tags in RiveScript will capture the user's "raw" input, so you can write replies to get the user's e-mail address or store foreign characters in their name.

Spring Boot Starter

Add the rivescript-spring-boot-starter dependency to your project:

Maven:

<dependency>
  <groupId>com.rivescript</groupId>
  <artifactId>rivescript-spring-boot-starter</artifactId>
  <version>0.10.0</version>
</dependency>

Gradle:

dependencies {
    compile "com.rivescript:rivescript-spring-boot-starter:0.10.0"
}

The starter will automatically add the rivescript-core dependency to your project and trigger the auto configuration to create the RiveScript bot instance.

Although the auto configuration will use sensible defaults to create the bot instance, the following properties can be specified inside your application.properties/application.yml file (or as command line switches) to customize the auto configuration behaviour:

rivescript:
  enabled: true # Enable RiveScript for the application.
  source-path: classpath:/rivescript/ # The comma-separated list of RiveScript source files and/or directories.
  file-extensions: .rive, .rs # The comma-separated list of RiveScript file extensions to load.
  throw-exceptions: false # Enable throw exceptions.
  strict: true # Enable strict syntax checking.
  utf8: false # Enable UTF-8 mode.
  unicode-punctuation: [.,!?;:] # The unicode punctuation pattern (only used when UTF-8 mode is enabled).
  force-case: false # Enable forcing triggers to lowercase.
  concat: none # The concat mode (none|newline|space).
  depth: 50 # The recursion depth limit.
  error-messages: # The custom error message overrides. For instance `rivescript.error-messages.deepRecursion=Custom Deep Recursion Detected Message`
  object-handlers: # The comma-separated list of object handler names to register (currently supported: `groovy`, `javascript`, `ruby`).

To automatically register custom Java subroutines and/or non-default supported object handlers in the created RiveScript bot instance, define appropriate beans in your application context like:

@Bean
public Map<String, Subroutine> subroutines() {
    // The key is the name of the Java object macro to register.
    Map<String, Subroutine> subroutines = new HashMap<>();
    subroutines.put("subroutine1", new Subroutine1());
    subroutines.put("subroutine2", new Subroutine2());
    return subroutines;
}

@Bean
public Map<String, ObjectHandler> objectHandlers() {
    // The key is the name of the programming language to register.
    Map<String, ObjectHandler> objectHandlers = new HashMap<>();
    objectHandlers.put("handler1", new ObjectHandler1());
    objectHandlers.put("handler2", new ObjectHandler2());
    return objectHandlers;
}

Building

To compile, test, build all jars and docs run:

./gradlew build

To install all jars into your local Maven cache run:

./gradlew install

Samples

The /samples folder contains various samples of Java RiveScript bot implementations.

  • rsbot - The RSBot.java is a simple implementation using the com.rivescript.cmd.Shell.

    These commands may be used at your input prompt in RSBot:

    /quit        - Quit the program
    /dump topics - Dump the internal topic/trigger/reply struct (debugging)
    /dump sorted - Dump the internal trigger sort buffers (debugging)
    /last        - Print the last trigger you matched.
    

    To execute RSBot to begin chatting with the demo Eliza-based run:

    ./gradlew :rivescript-samples-rsbot:runBot --console plain
    
  • spring-boot-starter-rsbot - This example uses the RiveScript Spring Boot Starter to auto-configure the RiveScript bot instance.

    To begin chatting with the demo bot run:

    ./gradlew :rivescript-samples-spring-boot-starter-rsbot:bootRun --console plain
    

Authors

License

The MIT License (MIT)

Copyright (c) 2016 the original author or authors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

rivescript-java's People

Contributors

diogoneves avatar kirsle avatar marceloverdijk avatar marciopd avatar pmioulet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rivescript-java's Issues

response time get slower

Hi People!
I am working on a small brain (like 200 triggers) and RS response time goes slower and slower each time it responses, talking about 20 or 30 questions.
Simple triggers obviusly response in seconds, but allways takes a little more ms than the last one.
Complex triggers takes 2 o 3 seconds more than the last question.
Is this an RS issue or a begginer issue?
Thanks in advance..
rv

Adding python as a scripting language

I was able to add python as a scripting language using jython and a simple handler.

However I needed to modify this commit in order avoid losing indentation in Object handler.

Adding python requires jython as a dependency, not sure if you want to also add this library to the core as a dep, but my first fix gives the possibility of adding it manually if desired.

Weighted trigger fails

RSTS triggers.yml#weighted_triggers failed:

java.lang.AssertionError: Did not get expected reply for input: nothing
Expected: is "Weighted nothing"
     but: was "Unweighted nothing"

that operator make wrong output

from this rivescript

+ hello
- ok

% ok
+ hello
- not ok

*
- catch

first time i say hello it should reply ok. second time shoud say not ok. otherwise should say catch but the result is
here is image

sorry for my bad english.

Nested calls not working, result not interpreted

val script = """
            + simple1
            - <call>test "<bot VAR1>"</call>

            + complex
            - {@ something <call>test "<bot VAR1>"</call>}

            + interpret
            - {@ build <call>test interpret</call>}

            + setvar *
            - <bot VAR1=<star>>Var updated

            + getvar
            - Var1 is '<bot VAR1>'

            + something *
            - SomethingRef=<star>

            + build *
            - <bot VAR1=<star>>

            > object test javascript
            return "Test:" + args[0]
            < object

            > object interpret javascript
            return "<bot VAR1=interpret>"
            < object
            """.trimIndent()

        val user = "user"
        val re = RiveScript(Config.newBuilder()
                .strict(true)
                .utf8(true)
                .build()).apply {
            stream(script)
            sortReplies()
            setSubroutine("test", { re, args -> "Test:" + args[0] })
            setSubroutine("interpret", { re, args -> "<bot VAR1=interpret>" })
        }

        assertEquals("Var updated", re.reply(user, "setvar 123"))
        assertEquals("Var1 is '123'", re.reply(user, "getvar"))
        assertEquals("Test:123", re.reply(user, "simple1"))
        assertEquals("SomethingRef=Test:123", re.reply(user, "complex"))//failing, is '{__call__test "123"</call>}'
        assertEquals("", re.reply(user, "interpret"))//failing, is 'test interpret</call>}'
        assertEquals("Var1 is 'Test:interpret'", re.reply(user, "getvar"))//failing

javascript result (from https://www.rivescript.com/try)

User: setvar 123
Bot: Var updated
User: getvar
Bot: Var1 is '123'
User: simple1
Bot: Test:123
User: complex
Bot: SomethingRef=Test:123
User: interpret
Bot:
User: getvar
Bot: Var1 is 'Test:interpret'

Array in reply is not replaced

RSTS replies.yml#reply_arrays failed:

java.lang.AssertionError: Did not get expected reply for input: test random array
Expected: one of {"Testing alpha array.", "Testing beta array.", "Testing gamma array."}
     but: was "Testing (@greek) array."

Unicode input return incorrect reply

RSTS unicode.yml#unicode failed:

java.lang.AssertionError: Did not get expected reply for input: äh
Expected: is "What's the matter?"
     but: was "ERR: No Reply Found"

RiveScript#reply is not thread-safe

Look like RiveScript#reply is not thread-safe, RiveScript#currentUser is not ThreadLocal, project has no any synchronized blocks and concurrent classes

Redirections with Macro broken on 0.8.0

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.rivescript.RiveScript;
import com.rivescript.macro.Subroutine;

public class Test {

  public static class B implements Subroutine {
    @Override
    public String call(RiveScript rs, String[] args) {
      System.out.println("B");
      return "none";
    }
  }

  public static void main(String[] args) throws IOException {
    File f = new File("/tmp/test.rs");
    FileWriter w = new FileWriter(f);
    w.write("+ *\n");
    w.write("- end\n");
    w.write("+ hi\n");
    w.write("* <get v> != undefined => A\n");
    w.write("@ <call>b</call>\n");
   // w.write("- <call>b</call>\n"); // works as expected
    w.close();

    RiveScript rs = new RiveScript();
    rs.loadFile(f);
    rs.sortReplies();
    rs.setSubroutine("b", new B());
    rs.setUservar("test", "v", "V");
    System.out.println(rs.reply("test", "Hi"));
  }

}

I got output:

B
end

But condition is true. RiveScript ignore condition if redirection contain macro.

RiveScript version 0.8.0, works as expected on 0.7.2

Using object macro within topic

I am trying to use the object macro within topic and it is failing. However the code snippet before topic is running
Would you please tell me where the error lies

Below is the code snippet of it

+ load the * data set 
* <call>loadDataset <star></call> == pass => Dataset is now \s
^ loaded. You can access the table in the main view. {topic=load}

> topic load

  //This will match if the word "load" exists ANYWHERE in the user query
  + [*] load [*] 
  * <call>loadDataset <star></call> == pass => Dataset is now \s
  ^ loaded. You can access the table in the main view. {topic = random}

< topic
- Data set not found 

Deparse method

I was reading about this issue 61 in the JS version of rivescript and I was wondering if there is any plan to also port this deparse method to the java version of rivescript.

This method would allow me to then dump the data in a mongo database to expose it's content through an api instead of dealing with text files.

Thanks!

Unable to use macros successfully

Hi again, and sorry for making this my personal forum but I don't know a better place to go than this.
I have tried copying the perl macro from the website:

> object hash perl
  my ($rs, $args) = @_;
  my $method = shift @{$args};
  my $string = join " ", @{$args};

  # Here, $method is a hashing method (MD5 or SHA1), and $string
  # is the text to hash.

  if ($method eq "MD5") {
    require Digest::MD5;
    return Digest::MD5::md5_hex($string);
  }
  elsif ($method eq "SHA1") {
    require Digest::SHA1;
    return Digest::SHA1::sha1_hex($string);
  }
< object

// You call an object using the <call> tag.
+ what is the md5 hash of *
- The hash of "<star>" is: <call>hash MD5 <star></call>

+ what is the sha1 hash of *
- The hash of "<star>" is: <call>hash SHA1 <star></call>

but it doesn't work. I have also tried javascript macros which have worked on the online compiler but they don't work here. I even used these imports:
import com.rivescript.;
import com.rivescript.lang.
;
import com.rivescript.macro.*;
Am I missing something? Whenever I call the object macros I get error:object not found in place of my object in the output.

lowercase not work for variable

    RiveScript rs = new RiveScript();
    rs.stream(new String[] { //
        "! version = 2.0", //
        "+ a", //
        "- {lowercase}A{/lowercase}", //
        "+ b", //
        "- {lowercase}<get v>{/lowercase}"});
    rs.sortReplies();
    rs.setUservar("test", "v", "B");
    System.out.println(rs.reply("test", "a"));
    System.out.println(rs.reply("test", "b"));

output is:

a
B

It reproduced on 0.8.* and 0.9.* versions

Wildcards in optionals are matched (which should not be)

+ my favorite [_] is *
- Why is it <star1>?

+ i have [#] questions about *
- Well I don't have any answers about <star1>.

Input: my favorite color is red
Expected: Why is it red?
Actual: Why is it color?

Input: i have 2 questions about bots
Expected :Well I don't have any answers about bots.
Actual: Well I don't have any answers about 2.

Potential parse bug

Here the code is missing a loop on all the entries of the list within the value of the map or maybe this?

if(entry.getValue().contains(UNDEF_TAG)) {
  this.array.remove(entry.getKey());
} else {
  this.array.put(entry.getKey(), entry.getValue());
}

Unicode chars not in reply

RSTS unicode.yml#wildcards failed:

java.lang.AssertionError: Did not get expected reply for input: My name is Bảo
Expected: is "Nice to meet you, bảo."
     but: was "Nice to meet you, bo."

/start command

Hello.
i am using rivescript-java with telegram and i have a problem to "detect" the bot command /start

I has tried without success:

+ /start
- Welcome

and

+ \/start
- Welcome

Can you help me?

Error when using library on Android

java.nio.file Assertions are going to break a lot of Android projects

Error:(28, 12) error: cannot access Path class file for java.nio.file.Path not found

Is there a way to use it in Java-based Android Native?

NPE optional array

RS file:

! version = 2.0

+ [(a|b) ](c|d)
- <star2>

input c

java.lang.NullPointerException
    at com.rivescript.Util.Sv2s(Util.java:52) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
    at com.rivescript.RiveScript.processTags(RiveScript.java:1690) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
    at com.rivescript.RiveScript.reply(RiveScript.java:1511) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]
    at com.rivescript.RiveScript.reply(RiveScript.java:1062) ~[rivescript-core-0.7.0-SNAPSHOT.jar:?]

Continuation does not contain expected new line (\n)

RSTS replies.yml#continuations failed:

java.lang.AssertionError: Did not get expected reply for input: Tell me a poem.
Expected: is "There once was a man named Tim, who never quite learned how to swim. He fell off a dock, and sank like a rock, and that was the end of him.\n"
     but: was "There once was a man named Tim, who never quite learned how to swim. He fell off a dock, and sank like a rock, and that was the end of him."

<star> don't work after condition

RS file:

! version = 2.0

+ hi1 *
- !<star>!

+ hi2 *
* <get some> != undefined => not possible
- !<star>!

Dialog:

you: hi1 test
bot: !test!
you: hi2 test
bot: !!

last reply should be !test!

JavaScript engine not found in AppEngine local devserver

The Jsr223ScriptingHandler currently tries to get the scripting engine by doing:

``
ScriptEngine engine = new ScriptEngineManager().getEngineByName(engineName);


This works in most cases except in Google AppEngine local devserver.
However, supplying an explicit `null` classloader to the `ScriptEngineManager` does give the engine:

ScriptEngine engine = new ScriptEngineManager(null).getEngineByName(engineName);


So it would be good to add a fallback mechanism.

Note: Interestingly it only fails in the AppEngine local devserver. On the Google hosted environment it works without the fallback.

Topic includes/inheritance bug in RPG demo code

From Jonathan Brouwers on Slack:

Hey, I am looking into the java implementation of rivescript at https://github.com/aichaos/rivescript-java. In the examples there is an rpg demo. In the demo you get to a point where you have to type "press button" to advance. However, the topic includes a global topic with an asterisk(*) trigger which overrides the source topic, which means the "press button" trigger does not get matched. When i paste the same rivescript file into the online editor (https://www.rivescript.com/try), the "press button" trigger does get matched. When looking at the spec for rivescript, i find that when including it first matches the one with most words and then with the most characters, which would mean a wildstar should be matched last. Seems this is a bug in the java implementation? Or did i miss something?

There's likely a bug in the topic inheritance/includes that needs to be fixed.

Issue with rpg.rive or interpreter?

I can't seem to continue past puzzle1. It takes me back to the crash site. The script seems to make sense so unclear if it's a nuance I'm not seeing in the example or a bug in the interpreter or what. I'm running rivescript-core 0.10.0 and passing data with .reply

Command order:

north
up
north
push button
take spacesuit
open door
north
west

Multiple/Alternative Triggers

I would like to give multiple triggers for a single response, also i would like to access the '*' within them.
For example:

+ my name *
+ people call me *
+ * is what you should call me
- Ok, I will call you <star>.

What would be the correct way of doing this ?

Embedded tag in reply not working

RSTS replies.yml#embedded_tags failed:

java.lang.AssertionError: Did not get expected reply for input: My name is Bob.
Expected: is "I thought your name was Alice?"
     but: was ">I thought your name was <get name?"

Trouble loading files

Hey guys, thanks so much for making this framework available. I love Rivescript in terms of what it offers, but I am unable to use some rivescript files I have created in my java project and it is KILLING me. I am sure I am doing something wrong here myself, but anyway here is my problem:
I am getting file not found and directory not found exceptions whenever I try to load my rive files or directories. I have tried passing both the absolute and the relative path(I kept it relative to the java file) but to no avail. Even when the absolute path is correct, it says it isnt found. I tried changing the code up here and there but to no avail.
Here is the relevant stack:
Caused by: com.rivescript.RiveScriptException: Directory 'replies' not found
When my code contained this:
bot.loadDirectory("replies");
I tried making it "./replies" and I tried adding my files directly as well. But to no avail.
Can someone please help me? I feel so close yet so far and didn't know where else to go. Much thanks.

Macro split one argument to multiple arguments by space

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.rivescript.RiveScript;
import com.rivescript.macro.Subroutine;

public class RsTest {

  public static class F implements Subroutine {
    @Override
    public String call(RiveScript rs, String[] args) {
      for (String arg : args)
        System.out.println(arg);
      return "";
    }
  }

  public static void main(String[] args) throws IOException {
    File f = new File("/tmp/test.rs");
    FileWriter w = new FileWriter(f);
    w.write("! version = 2.0\n\n");
    w.write("+ *\n");
    w.write("- <call>f <get v></call>\n");
    w.close();

    RiveScript rs = new RiveScript();
    rs.loadFile(f.getAbsolutePath());
    rs.sortReplies();
    rs.setSubroutine("f", new F());
    rs.setUservar("test", "v", "a b");
    System.out.println(rs.reply("test", "Hi"));
  }

}

I got output:

a
b

I expect that macro get one argument a b.

Also if method call return null when NullPointerException thrown. To get undefined result call function should return empty string. Is it OK?

It reproduced on 0.7 and 0.8

Support listing of all topics

Could we expose getter for parsed topics?

private Map<String, Topic> topics;                  // main topic structure

or something in simillar fashion? As we have for subroutines etc.

Build problem

$ ./gradlew build
:rivescript-core:compileJava UP-TO-DATE
:rivescript-core:processResources UP-TO-DATE
:rivescript-core:classes UP-TO-DATE
:rivescript-core:jar UP-TO-DATE
:api
:docs
:docsZip
:rivescript-core:javadoc UP-TO-DATE
:rivescript-core:javadocJar UP-TO-DATE
:rivescript-core:sourcesJar UP-TO-DATE
:distZip
:assemble
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:compileTestJava UP-TO-DATE
:processTestResources UP-TO-DATE
:testClasses UP-TO-DATE
:test UP-TO-DATE
:check UP-TO-DATE
:build
:rivescript-core:signArchives
FAILURE: Build failed with an exception.

* What went wrong:
java.lang.NullPointerException (no error message)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.


BUILD FAILED

Total time: 4.414 secs

gradle_stacktrace.txt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.