Skip to content
Snippets Groups Projects
Commit d18ea068 authored by silvergl's avatar silvergl
Browse files

Jupyter Kernel with BaseKernel

parent 4fe67896
No related branches found
No related tags found
No related merge requests found
Showing
with 216 additions and 94 deletions
.gradle
build/
!gradle-wrapper.jar
out/
.idea/
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/test" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="gradle_scope" value="test"/>
<attribute name="gradle_used_by_scope" value="test"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="C:/Users/Lenovo/.gradle/caches/modules-2/files-2.1/io.github.spencerpark/jupyter-jvm-basekernel/2.3.0/abac807e2c2336fe0c68fe5926611445618f65d9/jupyter-jvm-basekernel-2.3.0.jar" sourcepath="C:/Users/Lenovo/.gradle/caches/modules-2/files-2.1/io.github.spencerpark/jupyter-jvm-basekernel/2.3.0/dfcfaa674a99e848672fe6bd6ec9271dc456ef95/jupyter-jvm-basekernel-2.3.0-sources.jar">
<attributes>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin/default"/>
</classpath>
# Ignore Gradle project-specific cache directory
.gradle
# Ignore Gradle build output directory
build
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Dummykernel</name>
<comment>Project Dummykernel created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
connection.project.dir=
eclipse.preferences.version=1
{"name":"Dummykernel","classpathEntries":[{"kind":"binary","path":"C:\\Program Files\\Java\\jre1.8.0_221\\lib\\resources.jar","javadocContainerUrl":"https://docs.oracle.com/javase/1/docs/api/","isSystem":true,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Program Files\\Java\\jre1.8.0_221\\lib\\rt.jar","javadocContainerUrl":"https://docs.oracle.com/javase/1/docs/api/","isSystem":true,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Program Files\\Java\\jre1.8.0_221\\lib\\jsse.jar","javadocContainerUrl":"https://docs.oracle.com/javase/1/docs/api/","isSystem":true,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Program Files\\Java\\jre1.8.0_221\\lib\\jce.jar","javadocContainerUrl":"https://docs.oracle.com/javase/1/docs/api/","isSystem":true,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Program Files\\Java\\jre1.8.0_221\\lib\\charsets.jar","javadocContainerUrl":"https://docs.oracle.com/javase/1/docs/api/","isSystem":true,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Program Files\\Java\\jre1.8.0_221\\lib\\jfr.jar","javadocContainerUrl":"https://docs.oracle.com/javase/1/docs/api/","isSystem":true,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\io.github.spencerpark\\jupyter-jvm-basekernel\\2.3.0\\abac807e2c2336fe0c68fe5926611445618f65d9\\jupyter-jvm-basekernel-2.3.0.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.guava\\guava\\28.0-jre\\54fed371b4b8a8cce1e94a9abd9620982d3aa54b\\guava-28.0-jre.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\org.zeromq\\jeromq\\0.5.1\\7ef8199a62e6bc91b549fcb49f85ccdf6ffc5078\\jeromq-0.5.1.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.code.gson\\gson\\2.8.5\\f645ed69d595b24d4cf8b3fbb64cc505bede8829\\gson-2.8.5.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.guava\\failureaccess\\1.0.1\\1dcf1de382a0bf95a3d8b0849546c88bac1292c9\\failureaccess-1.0.1.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.guava\\listenablefuture\\9999.0-empty-to-avoid-conflict-with-guava\\b421526c5f297295adef1c886e5246c39d4ac629\\listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.code.findbugs\\jsr305\\3.0.2\\25ea2e8b0c338a877313bd4672d3fe056ea78f0d\\jsr305-3.0.2.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\org.checkerframework\\checker-qual\\2.8.1\\eb2e8ab75598548cc8acf9a1ca227e480e01881e\\checker-qual-2.8.1.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.errorprone\\error_prone_annotations\\2.3.2\\d1a0c5032570e0f64be6b4d9c90cdeb103129029\\error_prone_annotations-2.3.2.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\com.google.j2objc\\j2objc-annotations\\1.3\\ba035118bc8bac37d7eff77700720999acd9986d\\j2objc-annotations-1.3.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\org.codehaus.mojo\\animal-sniffer-annotations\\1.17\\f97ce6decaea32b36101e37979f8b647f00681fb\\animal-sniffer-annotations-1.17.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\eu.neilalexander\\jnacl\\1.0.0\\82e9034fb81a33cb9d7e0c4cd241a2ba84802ae2\\jnacl-1.0.0.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\junit\\junit\\4.12\\2973d150c0dc1fefe998f834810d68f278ea58ec\\junit-4.12.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"binary","path":"C:\\Users\\Lenovo\\.gradle\\caches\\modules-2\\files-2.1\\org.hamcrest\\hamcrest-core\\1.3\\42a25dc3219429f0e5d060061f71acb49bf010a0\\hamcrest-core-1.3.jar","isSystem":false,"isOwn":false,"isTest":false,"isJavaContent":false},{"kind":"source","path":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\src\\main\\java","outputFolder":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\bin\\main","isSystem":false,"isOwn":true,"isTest":false,"isJavaContent":true},{"kind":"source","path":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\src\\main\\resources","outputFolder":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\bin\\main","isSystem":false,"isOwn":true,"isTest":false,"isJavaContent":true},{"kind":"source","path":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\src\\test\\java","outputFolder":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\bin\\test","isSystem":false,"isOwn":true,"isTest":true,"isJavaContent":true},{"kind":"source","path":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\src\\test\\resources","outputFolder":"C:\\Users\\Lenovo\\oceandsl\\Dummykernel\\bin\\test","isSystem":false,"isOwn":true,"isTest":true,"isJavaContent":true}]}
\ No newline at end of file
File added
File added
File added
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java Library project to get you started.
* For more details take a look at the Java Libraries chapter in the Gradle
* User Manual available at https://docs.gradle.org/5.6.1/userguide/java_library_plugin.html
*/
apply plugin: 'application'
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
mainClassName='Dummykernel.DummyMain'
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' }
// If using a release version (no SNAPSHOT suffix)
mavenCentral()
}
dependencies {
compile group: 'io.github.spencerpark', name: 'jupyter-jvm-basekernel', version: '2.3.0'
// This dependency is exported to consumers, that is to say found on their compile classpath.
// api 'org.apache.commons:commons-math3:3.6.1'
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:28.0-jre'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
File added
distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
......@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
......@@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
......
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
......@@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
......
/*
* This file was generated by the Gradle 'init' task.
*
* The settings file is used to specify which projects to include in your build.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user manual at https://docs.gradle.org/5.6.1/userguide/multi_project_builds.html
*/
rootProject.name = 'Dummykernel'
package io.github.spencerpark.jupyter;
package Dummykernel;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import io.github.spencerpark.jupyter.kernel.BaseKernel;
import io.github.spencerpark.jupyter.kernel.LanguageInfo;
......@@ -9,69 +15,51 @@ import io.github.spencerpark.jupyter.kernel.util.SimpleAutoCompleter;
import io.github.spencerpark.jupyter.kernel.util.StringSearch;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class NashornKernel extends BaseKernel {
public class DummyKernel extends BaseKernel {
private static final NashornScriptEngineFactory NASHORN_ENGINE_FACTORY = new NashornScriptEngineFactory();
private static final SimpleAutoCompleter autoCompleter = SimpleAutoCompleter.builder()
.preferLong()
private static final SimpleAutoCompleter autoCompleter = SimpleAutoCompleter.builder().preferLong()
// Keywords from a great poem at https://stackoverflow.com/a/12114140
.withKeywords("let", "this", "long", "package", "float")
.withKeywords("goto", "private", "class", "if", "short")
.withKeywords("while", "protected", "with", "debugger", "case")
.withKeywords("continue", "volatile", "interface")
.withKeywords("instanceof", "super", "synchronized", "throw")
.withKeywords("extends", "final", "export", "throws")
.withKeywords("try", "import", "double", "enum")
.withKeywords("extends", "final", "export", "throws").withKeywords("try", "import", "double", "enum")
.withKeywords("false", "boolean", "abstract", "function")
.withKeywords("implements", "typeof", "transient", "break")
.withKeywords("void", "static", "default", "do")
.withKeywords("switch", "int", "native", "new")
.withKeywords("else", "delete", "null", "public", "var")
.withKeywords("in", "return", "for", "const", "true", "char")
.withKeywords("finally", "catch", "byte")
.withKeywords("implements", "typeof", "transient", "break").withKeywords("void", "static", "default", "do")
.withKeywords("switch", "int", "native", "new").withKeywords("else", "delete", "null", "public", "var")
.withKeywords("in", "return", "for", "const", "true", "char").withKeywords("finally", "catch", "byte")
.build();
private static final CharPredicate idChar = CharPredicate.builder()
.inRange('a', 'z')
.inRange('A', 'Z')
.match('_')
private static final CharPredicate idChar = CharPredicate.builder().inRange('a', 'z').inRange('A', 'Z').match('_')
.build();
private final ScriptEngine engine;
private final LanguageInfo languageInfo;
public NashornKernel() {
public DummyKernel() {
this("-scripting");
}
public NashornKernel(String... args) {
this(NASHORN_ENGINE_FACTORY.getScriptEngine(args));
public DummyKernel(final String... args) {
this(DummyKernel.NASHORN_ENGINE_FACTORY.getScriptEngine(args));
}
public NashornKernel(ScriptEngine engine) {
public DummyKernel(final ScriptEngine engine) {
this.engine = engine;
this.languageInfo = new LanguageInfo.Builder(engine.getFactory().getLanguageName())
.version(engine.getFactory().getLanguageVersion())
.mimetype("text/javascript")
.fileExtension(".js")
.pygments("javascript")
.codemirror("javascript")
.build();
this.languageInfo = new LanguageInfo.Builder("XText").version(engine.getFactory().getLanguageVersion())
.mimetype("text/mydsl2").fileExtension(".mydsl2").pygments("hsail").codemirror("java").build();
}
@Override
public LanguageInfo getLanguageInfo() {
return languageInfo;
return this.languageInfo;
}
@Override
public DisplayData eval(String expr) throws Exception {
ScriptContext ctx = engine.getContext();
public DisplayData eval(final String expr) throws Exception {
ScriptContext ctx = this.engine.getContext();
// Redirect the streams
ctx.setWriter(new OutputStreamWriter(System.out));
......@@ -79,18 +67,18 @@ public class NashornKernel extends BaseKernel {
ctx.setReader(new InputStreamReader(System.in));
// Evaluate the code
Object res = engine.eval(expr, ctx);
// Object res = this.engine.eval(expr, ctx);
// If the evaluation returns a non-null value (the code is an expression like
// 'a + b') then the return value should be this result as text. Otherwise
// return null for nothing to be emitted for 'Out[n]'. Side effects may have
// still printed something
return res != null ? new DisplayData(res.toString()) : null;
return new DisplayData("42!");
}
@Override
public DisplayData inspect(String code, int at, boolean extraDetail) throws Exception {
StringSearch.Range match = StringSearch.findLongestMatchingAt(code, at, idChar);
public DisplayData inspect(final String code, final int at, final boolean extraDetail) throws Exception {
StringSearch.Range match = StringSearch.findLongestMatchingAt(code, at, DummyKernel.idChar);
String id = "";
Object val = null;
if (match != null) {
......@@ -102,11 +90,12 @@ public class NashornKernel extends BaseKernel {
}
@Override
public ReplacementOptions complete(String code, int at) throws Exception {
StringSearch.Range match = StringSearch.findLongestMatchingAt(code, at, idChar);
if (match == null)
public ReplacementOptions complete(final String code, final int at) throws Exception {
StringSearch.Range match = StringSearch.findLongestMatchingAt(code, at, DummyKernel.idChar);
if (match == null) {
return null;
}
String prefix = match.extractSubString(code);
return new ReplacementOptions(autoCompleter.autocomplete(prefix), match.getLow(), match.getHigh());
return new ReplacementOptions(DummyKernel.autoCompleter.autocomplete(prefix), match.getLow(), match.getHigh());
}
}
package io.github.spencerpark.jupyter;
import io.github.spencerpark.jupyter.channels.JupyterConnection;
import io.github.spencerpark.jupyter.channels.JupyterSocket;
import io.github.spencerpark.jupyter.kernel.KernelConnectionProperties;
package Dummykernel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.logging.Level;
public class INashornJS {
public static void main(String[] args) throws Exception {
if (args.length < 1)
import io.github.spencerpark.jupyter.channels.JupyterConnection;
import io.github.spencerpark.jupyter.channels.JupyterSocket;
import io.github.spencerpark.jupyter.kernel.KernelConnectionProperties;
public class DummyMain {
public static void main(final String[] args) throws Exception {
if (args.length < 1) {
throw new IllegalArgumentException("Missing connection file argument");
}
Path connectionFile = Paths.get(args[0]);
if (!Files.isRegularFile(connectionFile))
if (!Files.isRegularFile(connectionFile)) {
throw new IllegalArgumentException("Connection file '" + connectionFile + "' isn't a file.");
}
String contents = new String(Files.readAllBytes(connectionFile));
......@@ -28,12 +29,13 @@ public class INashornJS {
JupyterConnection connection = new JupyterConnection(connProps);
String envEngineArgs = System.getenv("JS_ENGINE_ARGS");
if (envEngineArgs == null)
if (envEngineArgs == null) {
envEngineArgs = "-scripting";
}
String[] engineArgs = envEngineArgs.split(" ");
NashornKernel kernel = new NashornKernel(engineArgs);
DummyKernel kernel = new DummyKernel(engineArgs);
kernel.becomeHandlerForConnection(connection);
connection.connect();
......
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package Dummykernel;
public class DummyMainTest {
/*
* @Test public void testSomeLibraryMethod() { DummyMain classUnderTest = new DummyMain();
* assertTrue("someLibraryMethod should return 'true'", classUnderTest.someLibraryMethod()); }
*/
}
Copyright (c) 2017 Spencer Park
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.
\ No newline at end of file
# Jupyter-Base-Kernel
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment