diff --git a/CHANGELOG.md b/CHANGELOG.md index 43a10bc..377501e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project are to be documented in this file. +## Version 0.3.3 + + - Added hub https://github.com/github/hub + - Create persistent environments + - `conda create -y -p $LOCAL_ENVS/tabsAreGreat python=2.7 ipykernel 'scipy==0.16.0'` + - Discover persistent environments + - `conda env list` + - Create a new kernel + - `$LOCAL_ENVS/tabsAreGreat/bin/python -m ipykernel install --prefix $JUPYTER_WORK --name tabsAreGreat --display-name "tabs are great"` + - Refresh main page + - Added ML modules + - Tensorflow 1.6 + - Theano + - Keras + - Optimized image size by starting from ubuntu base + ## Version 0.3.1 - Added `PYTHONUSERBASE` variable, which points at `tacc-work/jupyter_packages`, and allows for persistent local pip installs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 51bb981..f1213be 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,13 +56,13 @@ git checkout -b myFeature development Please add any external example or configuration files in a descriptive folder in ``` -images/custom/ +images/sd2e/ ``` and add a new section at the end of the main `Dockerfile` in ``` -images/custom/Dockerfile +images/sd2e/Dockerfile ``` for your code immediately **before** the permissiosn section. diff --git a/Makefile b/Makefile index fc0484a..b6f3237 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ -.ONESHELL: .PHONY: build test docker help stage release clean ifndef VERBOSE .SILENT: build test docker help stage release clean @@ -9,15 +8,16 @@ all: help .PHONY: help help: - echo "\nUsage: make [action] [target]\n" - echo "Actions:" - echo " - build - build docker images locally" - echo " - test - test images locally" - echo " - stage - push images to staging environment" - echo " - release - push images to production environment\n" - echo "Targets:" - echo " - base - Recipe in images/base" - echo " - sd2e - Recipe in images/custom which is where all community software should belong" + + echo "\nUsage: make [action] [target]\n" && \ + echo "Actions:" && \ + echo " - build - build docker images locally" && \ + echo " - test - test images locally" && \ + echo " - stage - push images to staging environment" && \ + echo " - release - push images to production environment\n" && \ + echo "Targets:" && \ + echo " - base - Recipe in images/base" && \ + echo " - sd2e - Recipe in images/sd2e which is where all community software should belong" && \ echo " - singularity - Image for running on TACC HPC\n" # Make sure image targets are not used as make targets @@ -25,82 +25,82 @@ help: @: docker: - docker info > /dev/null 2> /dev/null - if [ ! $$? -eq 0 ]; then - echo "\n[ERROR] Could not communicate with docker daemon. You may need to run with sudo.\n" - exit 1 + docker info 1> /dev/null 2> /dev/null && \ + if [ ! $$? -eq 0 ]; then \ + echo "\n[ERROR] Could not communicate with docker daemon. You may need to run with sudo.\n"; \ + exit 1; \ fi build: docker - TARGET=$(filter-out $@,$(MAKECMDGOALS)) - case $${TARGET} in - base) - build/build_jupyteruser.sh build images/base - ;; - sd2e) - build/build_jupyteruser.sh build images/custom - ;; - singularity) - build/build_jupyteruser.sh build images/singularity - ;; - *) - $(MAKE) help - ;; + TARGET=$(filter-out $@,$(MAKECMDGOALS)) && \ + case $${TARGET} in \ + base) \ + build/build_jupyteruser.sh build images/base; \ + ;; \ + sd2e) \ + build/build_jupyteruser.sh build images/sd2e; \ + ;; \ + singularity) \ + build/build_jupyteruser.sh build images/singularity; \ + ;; \ + *) \ + $(MAKE) help; \ + ;; \ esac test: docker - TARGET=$(filter-out $@,$(MAKECMDGOALS)) - case $$TARGET in - base) - build/build_jupyteruser.sh test images/base - ;; - sd2e) - build/build_jupyteruser.sh test images/custom - ;; - singularity) - build/build_jupyteruser.sh test images/singularity - ;; - *) - $(MAKE) help - ;; + TARGET=$(filter-out $@,$(MAKECMDGOALS)) && \ + case $$TARGET in \ + base) \ + build/build_jupyteruser.sh test images/base; \ + ;; \ + sd2e) \ + build/build_jupyteruser.sh test images/sd2e; \ + ;; \ + singularity) \ + build/build_jupyteruser.sh test images/singularity; \ + ;; \ + *) \ + $(MAKE) help; \ + ;; \ esac stage: docker - TARGET=$(filter-out $@,$(MAKECMDGOALS)) - case $$TARGET in - base) - build/build_jupyteruser.sh stage images/base - ;; - sd2e) - build/build_jupyteruser.sh stage images/custom - ;; - singularity) - build/build_jupyteruser.sh stage images/singularity - ;; - *) - $(MAKE) help - ;; + TARGET=$(filter-out $@,$(MAKECMDGOALS)) && \ + case $$TARGET in \ + base) \ + build/build_jupyteruser.sh stage images/base; \ + ;; \ + sd2e) \ + build/build_jupyteruser.sh stage images/sd2e; \ + ;; \ + singularity) \ + build/build_jupyteruser.sh stage images/singularity; \ + ;; \ + *) \ + $(MAKE) help; \ + ;; \ esac release: docker - TARGET=$(filter-out $@,$(MAKECMDGOALS)) - case $$TARGET in - base) - build/build_jupyteruser.sh release images/base - ;; - sd2e) - build/build_jupyteruser.sh release images/custom - ;; - singularity) - build/build_jupyteruser.sh release images/singularity - ;; - *) - $(MAKE) help - ;; + TARGET=$(filter-out $@,$(MAKECMDGOALS)) && \ + case $$TARGET in \ + base) \ + build/build_jupyteruser.sh release images/base; \ + ;; \ + sd2e) \ + build/build_jupyteruser.sh release images/sd2e; \ + ;; \ + singularity) \ + build/build_jupyteruser.sh release images/singularity; \ + ;; \ + *) \ + $(MAKE) help; \ + ;; \ esac clean: docker - TARGET=$(filter-out $@,$(MAKECMDGOALS)) - build/build_jupyteruser.sh clean images/singularity - build/build_jupyteruser.sh clean images/custom + TARGET=$(filter-out $@,$(MAKECMDGOALS)) && \ + build/build_jupyteruser.sh clean images/singularity && \ + build/build_jupyteruser.sh clean images/sd2e && \ build/build_jupyteruser.sh clean images/base diff --git a/README.md b/README.md index 0884fd0..e57523d 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ * Jupyter Notebook \(v5.2.0\)server * Conda Python 3.4.x and Python 2.7.x environments + * Custom environments and kernels now supported through `Advanced Jupyter.ipynb` notebook * Pre-installed python packages (highlights) * pandas * matplotlib 2.1.2 @@ -16,6 +17,7 @@ * Plotly, igraph, networkx, graphviz for graphs and plots * MIT's [Open Probabilistic Programming Stack](http://probcomp.org/) * [Common Lisp kernel and stack](http://www.sbcl.org/) + * v1.4.6 Now installed as binary * Bioconda and Bioconductor * BioPython * Git diff --git a/TESTING.md b/TESTING.md index b898cc0..32ca413 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,5 +1,5 @@ # Testing out your changes -After you've added software or updated configurations at `images/custom`, you can and should test in a local instance of Jupyter Notebooks. We've made this really easy for you. You can either leverage the extensive Makefile support for building and testing an updated user image, or manually drive the process. +After you've added software or updated configurations at `images/sd2e`, you can and should test in a local instance of Jupyter Notebooks. We've made this really easy for you. You can either leverage the extensive Makefile support for building and testing an updated user image, or manually drive the process. *Before you issue a PR, you must have tested locally* diff --git a/VERSION b/VERSION index 9e11b32..1c09c74 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.1 +0.3.3 diff --git a/build/build_jupyteruser.sh b/build/build_jupyteruser.sh index e73d280..91c86bd 100755 --- a/build/build_jupyteruser.sh +++ b/build/build_jupyteruser.sh @@ -94,7 +94,8 @@ function testImage { EIP=$(dig +short myip.opendns.com @resolver1.opendns.com) ed "Local Address: http://localhost:8888" ed "External Address: http://${EIP}:8888" - ed "docker run --rm -p 8888:8888 ${IMG}:${VERSION} start-notebook.sh" + # Added -u flag to test as non-existent user + ed "docker run -u 1337 --rm -p 8888:8888 ${IMG}:${VERSION} start-notebook.sh" docker run --rm -p 8888:8888 ${IMG}:${VERSION} start-notebook.sh if [ ! $? -eq 0 ]; then ee "Notebook could not launch" @@ -153,7 +154,7 @@ function pushImage { fi } -helpStr="Usage: $0 option target\n\nAutomating the build and deploy process for taccsciapps images\n\nPlease specify an option and target\n\nOptions:\n - build\n - test\n - push\n - all\n\nTargets:\n - images/base\n - images/custom" +helpStr="Usage: $0 option target\n\nAutomating the build and deploy process for taccsciapps images\n\nPlease specify an option and target\n\nOptions:\n - build\n - test\n - push\n - all\n\nTargets:\n - images/base\n - images/sd2e" # Make sure enough arguments were used if [ ! $# -eq 2 ]; then diff --git a/images/base/Dockerfile b/images/base/Dockerfile index a8e81ad..7c34db2 100644 --- a/images/base/Dockerfile +++ b/images/base/Dockerfile @@ -1,82 +1,301 @@ #Image: sd2e/jupyteruser-base -#Version: 0.1.1 +#Version: 0.2.2 -FROM taccsciapps/jupyteruser-base:0.1.2 -LABEL origin="https://bitbucket.org/gzynda/jupyter/src/40adbad7b10b34de715d5a86aec3fcf65e724b70/notebooks/base/jupyter-notebook/Dockerfile?at=CIC-425-image-redesign&fileviewer=file-view-default" - -############################################### +FROM ubuntu:xenial +LABEL maintainer="Greg Zynda " +################################################################### # Environment -############################################### +################################################################### +ENV DEBIAN_FRONTEND=noninteractive USER root - -# Image release +WORKDIR /root +# Image release in /etc ARG image_version=development -ENV NB_GID=G-819382 RUN echo "${image_version}" > /etc/sd2e_jupyteruser-base-release && \ -chmod a+r /etc/sd2e_jupyteruser-base-release && \ -# Make sure Jupyter group == SD2E-Community == 819382 -groupadd --gid 819382 $NB_GID && \ -usermod -a -G $NB_GID jupyter && \ -usermod -g $NB_GID jupyter && \ -# Jupyterhub correctly sets JUPYTERHUB_USER -echo 'PS1="$JUPYTERHUB_USER@\h:\w\$ "' >> /home/jupyter/.bashrc && \ -# allow users to add kernels -chmod 777 /opt/conda/share/jupyter/kernels && \ -# Environment variables -echo "export JPY_USER=\$JUPYTERHUB_USER\n\ + chmod a+r /etc/sd2e_jupyteruser-base-release +# Use IU ubuntu mirror +RUN sed -i "s~archive.ubuntu.com~ftp.ussg.iu.edu/linux~" /etc/apt/sources.list +# Add clean script +RUN echo "#!/bin/bash\n\ +apt-get clean\n\ +[ -x \"\$(command -v conda)\" ] && conda clean -tipsy\n\ +for dir in /tmp/* /var/tmp/* /home/jupyter/{.ccache,.cache/pip,conda-bld,.conda} /root/* /root/\.[^\.]* /var/lib/apt/lists/* /var/log/*; do\n\ + [ -e \$dir ] && rm -rf \$dir || true\n\ +done" > /usr/bin/docker-clean && chmod a+rx /usr/bin/docker-clean && docker-clean +# Create Singularity Mounts +RUN mkdir /scratch /work /home1 /gpfs /corral-repl /corral-tacc /data +# Expose notebook port +EXPOSE 8888 +################################################################### +# Dependencies +################################################################### +USER root +# Install dependencies +# - jq - required for abaco CLI +# - bsdmainutils->column - required for abaco CLI \ +# - Install *-nox (non-GUI) versions of tools when available +RUN apt-get update && \ + apt-get install -yq --no-install-recommends \ + bzip2 unzip ca-certificates build-essential \ + emacs-nox vim-nox git wget openssh-client curl \ + tree less jq rsync bsdmainutils locales && \ + echo "LANG=\"en_US.UTF-8\"\n\ +LANGUAGE=\"en_US.UTF-8\"\n\ +LC_ALL=\"en_US.UTF-8\"" >> /etc/default/locale && \ + echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen && \ + docker-clean +################################################################### +# Create jupyter user +################################################################### +# the default $NB_USER is jovyan, but we want the default user to be jupyter +# - create jupyter early +# - run all user installation commands as jupyter +# - add jupyter user to special uid + +# Jupyter GIDs +ARG TACC_GID=65536 +ARG AGAVE_GID=G-816877 +# Parameterize GID +# 65536 is a dummy value since we now override user UID/GID at launch +# using Docker nsmap. This should means it's only important for GIDs not +# collide and that g+r(x) permissions are set where needed +ENV NB_USER=jupyter \ + NB_GID=${TACC_GID} \ + NB_GROUP=${TACC_GID} \ + SHELL=/bin/bash +RUN groupadd --gid 816877 ${AGAVE_GID} && \ + useradd --uid 458981 --gid ${AGAVE_GID} -m --home /home/jupyter --shell /bin/bash $NB_USER && \ + groupadd --gid ${NB_GID} ${NB_GROUP} && \ + usermod -a -G ${NB_GROUP} jupyter +# While not ideal, this is required since the users that are injected +# into the container do not exist. +ENV HOME=/home/jupyter \ + USER=jupyter \ + LC_ALL=en_US.UTF-8 \ + LANG=en_US.UTF-8 \ + LANGUAGE=en_US.UTF-8 +# Make primary group TACC_GID +RUN usermod -g ${NB_GROUP} jupyter + +################################################################### +# Modify jupyter user environment +################################################################### + +# Add jupyter helper scripts +ARG BURL=https://raw.githubusercontent.com/jupyter/docker-stacks/master/base-notebook +RUN bash -c "cd /usr/local/bin && for target in fix-permissions start{\"\",-notebook,-singleuser}.sh; do wget -q ${BURL}/\$target && chmod a+rx \$target; done" && \ +mkdir /etc/jupyter && cd /etc/jupyter && wget -q ${BURL}/jupyter_notebook_config.py && \ +fix-permissions /etc/jupyter /usr/local/bin + +# Fix git for all users +# profile is only loaded in an interactive login shell +# - https://askubuntu.com/questions/438150/scripts-in-etc-profile-d-being-ignored/438170#438170 +ADD src/setup-git-user.sh /etc/profile.d/setup-git-user.sh +RUN chmod a+rx /etc/profile.d/setup-git-user.sh + +# login as jupyter +USER jupyter +# Change docker CWD to /home/jupyter +WORKDIR /home/jupyter/ + +# Changes to local bashrc - these will require different variables in Singularity +## Jupyterhub correctly sets JUPYTERHUB_USER +RUN echo 'PS1="${JUPYTERHUB_USER:-jupyter}@\h:\w\$ "' >> /home/jupyter/.bashrc +## Environment variables +RUN echo "export JPY_USER=\$JUPYTERHUB_USER\n\ export WORK=/home/jupyter/tacc-work\n\ export SD2_DATA=/home/jupyter/sd2e-community\n\ -export PYTHONUSERBASE=/home/jupyter/tacc-work/jupyter_packages\n" >> /home/jupyter/.bashrc -# Add activation sripts -ADD src/activate-python.sh /opt/conda/etc/conda/activate.d/activate-python.sh -ADD src/activate-python.sh /opt/conda/envs/python2/etc/conda/activate.d/activate-python.sh -RUN find /opt/conda -type d -name activate.d -exec chmod -R a+rx {} \; +export PROJECTS_DATA=/home/jupyter/sd2e-projects\n\ +export PARTNERS_DATA=/home/jupyter/sd2e-partners\n\ +export PYTHONUSERBASE=/home/jupyter/tacc-work/jupyter_packages\n\n\ +[ -e /etc/profile.d/setup-git-user.sh ] && . /etc/profile.d/setup-git-user.sh" >> /home/jupyter/.bashrc # Add readme ADD docs/SD2E_README.md /home/jupyter/SD2E_README.md # Add examples ADD examples examples +# Add R kernel +ADD https://raw.githubusercontent.com/IRkernel/IRkernel/master/example-notebooks/Demo.ipynb examples/R-Demo.ipynb + +################################################################### +# Install python +################################################################### +USER root +# Add conda env variables +ENV MINICONDA_VERSION=4.4.10 \ + CONDA_DIR=/opt/conda +# Conda path needs to go first so system python is not used +ENV PATH=${CONDA_DIR}/bin:$PATH +# Download and install miniconda +RUN mkdir $CONDA_DIR && chmod -R a+rX $CONDA_DIR && \ + wget --quiet https://repo.continuum.io/miniconda/Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh && \ + bash Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh -f -b -p $CONDA_DIR && \ + rm Miniconda3-${MINICONDA_VERSION}-Linux-x86_64.sh && \ + conda config --system --set auto_update_conda false && \ + conda config --system --set show_channel_urls true && \ + conda update -n base conda && \ + conda update --all --quiet --yes && \ + rm -rf ${CONDA_DIR}/pkgs/* && \ + docker-clean +################################################################### +# Create python3 environment +################################################################### + +# Add packages to python3 environment +## installing r-essentials without r-base breaks gcc +RUN conda install --yes --no-update-deps -c defaults -c conda-forge \ + jupyter \ + 'numpy=1.14*' \ + 'scipy=1.0*' \ + 'cython=0.27*' \ + 'pandas=0.22*' \ + matplotlib seaborn \ + 'h5py=2.7*' \ + 'r-essentials' 'r-base' \ + 'scikit-learn=0.19*' \ + 'scikit-image=0.13*' \ + jupyterhub \ + 'biopython' && \ +conda create --yes -n python2 \ + 'python=2.7' \ + 'ipykernel' \ + 'numpy=1.14*' \ + 'scipy=1.0*' \ + 'cython=0.27*' \ + 'pandas=0.22*' \ + 'h5py=2.7*' \ + matplotlib seaborn \ + 'scikit-learn=0.19*' \ + 'scikit-image=0.13*' \ + 'biopython' \ + && docker-clean && rm -rf ${CONDA_DIR}/pkgs/* + +# Create pip2 and pip3 shortcuts +RUN ln -s $CONDA_DIR/envs/python2/bin/pip $CONDA_DIR/bin/pip2 && \ + ln -s $CONDA_DIR/bin/pip $CONDA_DIR/bin/pip3 && \ + chmod a+rX $CONDA_DIR + +# Add activation sripts +ENV PYTHONUSERBASE=/home/jupyter/tacc-work/jupyter_packages +#ADD src/activate-python.sh /opt/conda/etc/conda/activate.d/activate-python.sh +#ADD src/activate-python.sh /opt/conda/envs/python2/etc/conda/activate.d/activate-python.sh +#RUN find ${CONDA_DIR} -type d -name activate.d -exec chmod -R a+rx {} \; + +################################################################### +# Additional kernels +################################################################### +# Install Python 2 kernel spec globally to avoid permission problems when NB_UID +# switching at runtime and to allow the notebook server running out of the root +# environment to find it. Also, activate the python2 environment upon kernel + +# Create python2 kernel +RUN bash -c "source activate python2 && ipython kernel install" +# Create bash kernel +RUN pip install bash_kernel && \ + python -m bash_kernel.install && \ + docker-clean +# Create R kernel +# 'r-base' && \ +#RUN conda install --quiet --yes -n base r-essentials && docker-clean +#RUN conda create --quiet --yes -n R \ +# 'r-essentials' && \ +# docker-clean +# Install bioconductor +RUN bash -c "source activate base && Rscript -e 'source(\"https://bioconductor.org/biocLite.R\"); biocLite();'" ############################################### -# Packages +# Environment activation Kernels ############################################### -# Bioconductor and BioPython -RUN conda install --yes --quiet -c bioconda bioconductor-biocinstaller && \ - conda install --yes --quiet biopython && \ - conda install --yes --quiet -n python2 biopython && \ +# Fixes compilers and local package installations +ADD src/activate_kernel /opt/conda/bin/activate_kernel +RUN chmod 755 /opt/conda/bin/activate_kernel && \ + TMPF=/tmp/tmp.json && \ + MODK=/usr/local/share/jupyter/kernels/python2/kernel.json && \ + jq " .argv = [\"activate_kernel\", \"python2\", \"{connection_file}\"] " ${MODK} | tee $TMPF && \ + mv $TMPF ${MODK} && \ + MODK=/opt/conda/share/jupyter/kernels/python3/kernel.json && \ + jq " .argv = [\"activate_kernel\", \"base\", \"{connection_file}\"] " ${MODK} | tee $TMPF && \ + mv $TMPF ${MODK} + +################################################################### +# Agave tools +################################################################### + +# install SD2E Agave CLI +ADD src/configuration.rc configuration.rc +RUN git clone https://github.com/SD2E/sd2e-cli.git && \ + mv configuration.rc sd2e-cli/ && cd sd2e-cli && \ + git submodule update --init --recursive && \ + make && make install && \ + cd ../ && rm -rf sd2e-cli && \ + mv ${HOME}/sd2e-cloud-cli /opt/cli && \ + chmod -R a+rX /opt/cli && chmod -R a+x /opt/cli/bin && \ + docker-clean +# add cli to PATH +ENV PATH=$PATH:/opt/cli/bin + +# install agavepy +RUN bash -c "source activate base && pip install git+https://github.com/TACC/agavepy.git" && \ + bash -c "source activate python2 && pip install git+https://github.com/TACC/agavepy.git" && \ + docker-clean # Enable sd2nb sharing service -cd /root && \ +RUN cd /root && \ git clone https://github.com/SD2E/sd2nb-app.git && \ ( cd sd2nb-app && make && make install ) && \ rm -rf sd2nb-app && \ -# Enable sd2e-jupyter -cd /root && \ + docker-clean +# Enable sd2e-jupyter +RUN cd /root && \ git clone https://github.com/SD2E/sd2e-jupyter-ascending.git && \ ( cd sd2e-jupyter-ascending && make && make install ) && \ rm -rf sd2e-jupyter-ascending && \ -# Ubuntu Packages -apt-get update && \ - # jq and bsdmainutils->column is required for abaco CLI - apt-get install -y tree less jq rsync bsdmainutils && \ - #apt-get install -y tree less openjdk-8-jre ca-certificates-java && \ - docker-clean -# Replace stock Agave CLI with SD2E-customized tooling -ADD src/configuration.rc configuration.rc -RUN git clone https://github.com/SD2E/sd2e-cli.git && \ - mv configuration.rc sd2e-cli/ && cd sd2e-cli && \ - git submodule update --init --recursive && make && \ - make install && rm -rf /opt/cli && rm -rf $HOME/sd2e-cli && \ - mv /home/jupyter/sd2e-cloud-cli /opt/cli && \ - chmod -R a+rX /opt/cli && chmod -R a+x /opt/cli/bin && \ -# Spark 2.2.1 and pyspark -#cd /usr/local && \ -# curl http://apache.claz.org/spark/spark-2.2.1/spark-2.2.1-bin-hadoop2.7.tgz | tar -xzf - && \ -# mv spark-2.2.1-bin-hadoop2.7 spark && \ -# conda install --yes pyspark && \ -# conda install -n python2 --yes pyspark && \ -docker-clean -#ENV SPARK_HOME=/usr/local/spark + docker-clean +# Add hub +RUN cd /root && \ + curl -skL -O "https://github.com/github/hub/releases/download/v2.3.0-pre10/hub-linux-amd64-2.3.0-pre10.tgz" && \ + tar zxf hub-linux-amd64-2.3.0-pre10.tgz && \ + cd hub-linux-amd64-2.3.0-pre10 && \ + ./install && \ + cd /root && rm -rf hub-linux-amd64-2.3.0-pre10* + +################################################################### +# Add entrypoint +################################################################### +# Add Tini +ARG TINI_VERSION=v0.17.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /usr/local/bin/tini +RUN chmod a+rx /usr/local/bin/tini +ENTRYPOINT ["tini", "--"] +#ENTRYPOINT ["bash"] +CMD ["start-notebook.sh"] + +############################################### +# Persistent local conda environments +############################################### + +# conda create -p $LOCAL_ENVS/tmnt python=2.7 ipykernel +# conda env list +# source activate tmnt +ENV LOCAL_ENVS=/home/jupyter/tacc-work/jupyter_packages/envs +ENV CONDA_ENVS_PATH=$LOCAL_ENVS:$CONDA_ENVS_PATH + +############################################### +# Persistent local jupyter kernels +############################################### + +# $LOCAL_ENVS/tmnt/bin/python -m ipykernel install --prefix $JUPYTER_WORK --name tmnt --display-name "tmnt python" +# *Must use full path* +# refresh main jupyter to load the new kernel option +ENV JUPYTER_PATH=/home/jupyter/tacc-work/jupyter_packages/share/jupyter:$JUPYTER_PATH +ENV JUPYTER_WORK=/home/jupyter/tacc-work/jupyter_packages + +############################################### +# Affiliated projects +############################################### + +ADD src/add-sd2e-groups.sh /tmp/add-sd2e-groups.sh +RUN bash /tmp/add-sd2e-groups.sh && docker-clean ############################################### # Permissions @@ -84,9 +303,18 @@ docker-clean # The notebook is run by the TACC userid, not jupyter, # so permissions need to be open -RUN chown -R jupyter:G-819382 /home/jupyter && \ +RUN chown -R jupyter:${NB_GROUP} /home/jupyter && \ chmod 777 /home/jupyter && \ find /home/jupyter -type f -exec chmod 666 {} \; && \ find /home/jupyter -type d -exec chmod 777 {} \; +################################################################### +# Cache matplotlib for jupyter user +################################################################### USER jupyter +# build matplotlib python2 font cache +RUN MPLBACKEND=Agg $CONDA_DIR/envs/python2/bin/python -c "import matplotlib.pyplot" && \ + docker-clean +# build matplotlib python3 font cache +RUN MPLBACKEND=Agg python -c "import matplotlib.pyplot" && \ + docker-clean diff --git a/images/base/examples/Advanced Jupyter.ipynb b/images/base/examples/Advanced Jupyter.ipynb new file mode 100644 index 0000000..277338b --- /dev/null +++ b/images/base/examples/Advanced Jupyter.ipynb @@ -0,0 +1,376 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Advanced Jupyter\n", + "\n", + "If you have ever felt constrained by our choices of kernels and environments included in the SD2E Jupyter server, this notebook will demonstrate how to:\n", + "\n", + "- Create your own conda environment\n", + "- Create your own Jupyter Kernel\n", + "- Use your new Jupyter Kernel\n", + "- Clean your local environment\n", + "\n", + "We have taken the time to remove most of the hurdles to this process, but please submit an issue to\n", + "\n", + "https://github.com/SD2E/jupyteruser-sd2e/issues\n", + "\n", + "if you run into any walls.\n", + "\n", + "## Creating a new conda envrionment\n", + "\n", + "We are utilizing the [Anaconda python distribution](https://www.anaconda.com/what-is-anaconda/) for SD2E since it \n", + "\n", + "- ships with the Intel MKL\n", + "- manages python and system packages\n", + "- allows and manages encapsulated environments\n", + "\n", + "So we can support as many development environments as possible. If you would like a brand new environment, but do not want it to be incorporated into the base image (what you are running right now), you can create a local environment that conda will manage and persist between server restarts.\n", + "\n", + "First, lets see what `conda` environments are currently available:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# conda environments:\n", + "#\n", + "base * /opt/conda\n", + "python2 /opt/conda/envs/python2\n", + "\n" + ] + } + ], + "source": [ + "conda env list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you have not modified your environment, you should see two environments:\n", + "\n", + "- **base** - (python3) activated with `source activate base`\n", + "- **python2** - activated with `source activate python2`\n", + "\n", + "I am developing a new analysis that is dependant on scipy 0.16.0, which is older than (and conflicts with) the version of scipy in the main python2 environment. Creating a brand new environment will be the easiest path forward for my development, so lets create one called \"tabsAreGreat\" with [`conda create`](https://conda.io/docs/commands/conda-create.html).\n", + "\n", + "To make your life a little easier, we created a `LOCAL_ENVS` variable for you to prefix your environment with, and added it to the path that conda crawls when search for environments." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Solving environment: done\n", + "\n", + "## Package Plan ##\n", + "\n", + " environment location: /home/jupyter/tacc-work/jupyter_packages/envs/tabsAreGreat\n", + "\n", + " added / updated specs: \n", + " - ipykernel\n", + " - python=2.7\n", + " - scipy==0.16.0\n", + "\n", + "\n", + "The following packages will be downloaded:\n", + "\n", + " package | build\n", + " ---------------------------|-----------------\n", + " scipy-0.16.0 | np110py27_1 23.9 MB anaconda\n", + " scandir-1.7 | py27h14c3975_0 27 KB anaconda\n", + " libgfortran-3.0.0 | 1 281 KB anaconda\n", + " wheel-0.31.0 | py27_0 61 KB anaconda\n", + " openblas-0.2.14 | 4 3.6 MB anaconda\n", + " pyzmq-17.0.0 | py27h14c3975_0 440 KB anaconda\n", + " python-2.7.14 | h1571d57_31 11.8 MB anaconda\n", + " tornado-5.0.1 | py27_1 617 KB anaconda\n", + " python-dateutil-2.7.2 | py27_0 254 KB anaconda\n", + " pip-9.0.3 | py27_0 2.4 MB anaconda\n", + " pexpect-4.4.0 | py27_0 70 KB anaconda\n", + " readline-7.0 | ha6073c6_4 1.1 MB anaconda\n", + " ipykernel-4.8.2 | py27_0 143 KB anaconda\n", + " setuptools-39.0.1 | py27_0 582 KB anaconda\n", + " numpy-1.10.2 | py27_0 5.9 MB anaconda\n", + " ipython-5.6.0 | py27_0 1020 KB anaconda\n", + " jupyter_client-5.2.3 | py27_0 122 KB anaconda\n", + " ------------------------------------------------------------\n", + " Total: 52.2 MB\n", + "\n", + "The following NEW packages will be INSTALLED:\n", + "\n", + " backports: 1.0-py27h63c9359_1 anaconda\n", + " backports.shutil_get_terminal_size: 1.0.0-py27h5bc021e_2 anaconda\n", + " backports_abc: 0.5-py27h7b3c97b_0 anaconda\n", + " ca-certificates: 2018.03.07-0 anaconda\n", + " certifi: 2018.1.18-py27_0 anaconda\n", + " decorator: 4.2.1-py27_0 anaconda\n", + " enum34: 1.1.6-py27h99a27e9_1 anaconda\n", + " futures: 3.2.0-py27h7b459c0_0 anaconda\n", + " ipykernel: 4.8.2-py27_0 anaconda\n", + " ipython: 5.6.0-py27_0 anaconda\n", + " ipython_genutils: 0.2.0-py27h89fb69b_0 anaconda\n", + " jupyter_client: 5.2.3-py27_0 anaconda\n", + " jupyter_core: 4.4.0-py27h345911c_0 anaconda\n", + " libedit: 3.1-heed3624_0 anaconda\n", + " libffi: 3.2.1-hd88cf55_4 anaconda\n", + " libgcc-ng: 7.2.0-hdf63c60_3 anaconda\n", + " libgfortran: 3.0.0-1 anaconda\n", + " libsodium: 1.0.16-h1bed415_0 anaconda\n", + " libstdcxx-ng: 7.2.0-hdf63c60_3 anaconda\n", + " ncurses: 6.0-h9df7e31_2 anaconda\n", + " numpy: 1.10.2-py27_0 anaconda\n", + " openblas: 0.2.14-4 anaconda\n", + " openssl: 1.0.2o-h20670df_0 anaconda\n", + " pathlib2: 2.3.0-py27h6e9d198_0 anaconda\n", + " pexpect: 4.4.0-py27_0 anaconda\n", + " pickleshare: 0.7.4-py27h09770e1_0 anaconda\n", + " pip: 9.0.3-py27_0 anaconda\n", + " prompt_toolkit: 1.0.15-py27h1b593e1_0 anaconda\n", + " ptyprocess: 0.5.2-py27h4ccb14c_0 anaconda\n", + " pygments: 2.2.0-py27h4a8b6f5_0 anaconda\n", + " python: 2.7.14-h1571d57_31 anaconda\n", + " python-dateutil: 2.7.2-py27_0 anaconda\n", + " pyzmq: 17.0.0-py27h14c3975_0 anaconda\n", + " readline: 7.0-ha6073c6_4 anaconda\n", + " scandir: 1.7-py27h14c3975_0 anaconda\n", + " scipy: 0.16.0-np110py27_1 anaconda\n", + " setuptools: 39.0.1-py27_0 anaconda\n", + " simplegeneric: 0.8.1-py27_2 anaconda\n", + " singledispatch: 3.4.0.3-py27h9bcb476_0 anaconda\n", + " six: 1.11.0-py27h5f960f1_1 anaconda\n", + " sqlite: 3.22.0-h1bed415_0 anaconda\n", + " tk: 8.6.7-hc745277_3 anaconda\n", + " tornado: 5.0.1-py27_1 anaconda\n", + " traitlets: 4.3.2-py27hd6ce930_0 anaconda\n", + " wcwidth: 0.1.7-py27h9e3e1ab_0 anaconda\n", + " wheel: 0.31.0-py27_0 anaconda\n", + " zeromq: 4.2.3-h439df22_3 anaconda\n", + " zlib: 1.2.11-ha838bed_2 anaconda\n", + "\n", + "\n", + "Downloading and Extracting Packages\n", + "scipy 0.16.0: ########################################################## | 100% \n", + "scandir 1.7: ########################################################### | 100% \n", + "libgfortran 3.0.0: ##################################################### | 100% \n", + "wheel 0.31.0: ########################################################## | 100% \n", + "openblas 0.2.14: ####################################################### | 100% \n", + "pyzmq 17.0.0: ########################################################## | 100% \n", + "python 2.7.14: ######################################################### | 100% \n", + "tornado 5.0.1: ######################################################### | 100% \n", + "python-dateutil 2.7.2: ################################################# | 100% \n", + "pip 9.0.3: ############################################################# | 100% \n", + "pexpect 4.4.0: ######################################################### | 100% \n", + "readline 7.0: ########################################################## | 100% \n", + "ipykernel 4.8.2: ####################################################### | 100% \n", + "setuptools 39.0.1: ##################################################### | 100% \n", + "numpy 1.10.2: ########################################################## | 100% \n", + "ipython 5.6.0: ######################################################### | 100% \n", + "jupyter_client 5.2.3: ################################################## | 100% \n", + "Preparing transaction: done\n", + "Verifying transaction: done\n", + "Executing transaction: done\n", + "#\n", + "# To activate this environment, use:\n", + "# > source activate /home/jupyter/tacc-work/jupyter_packages/envs/tabsAreGreat\n", + "#\n", + "# To deactivate an active environment, use:\n", + "# > source deactivate\n", + "#\n", + "\n" + ] + } + ], + "source": [ + "conda create -y -p $LOCAL_ENVS/tabsAreGreat python=2.7 ipykernel 'scipy==0.16.0'\n", + "\n", + "# -y - respond yes to all questions\n", + "# -p PATH - prefix/name\n", + "# python=2.7 - python2 environment\n", + "# ipykernel - required to make a kernel file later\n", + "# 'scipy==0.16.0' - scipy requirement" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You should now be able to list this new environment" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# conda environments:\n", + "#\n", + "tabsAreGreat /home/jupyter/tacc-work/jupyter_packages/envs/tabsAreGreat\n", + "base * /opt/conda\n", + "python2 /opt/conda/envs/python2\n", + "\n" + ] + } + ], + "source": [ + "conda env list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can now see that this new \"tabsAreGreat\" environment was created in your `tacc-work` directory, so it will persist between reboots, and you will be able to utilize it with\n", + "```\n", + "source activate tabsAreGreat\n", + "```\n", + "until your delete it.\n", + "\n", + "## Creating new Jupyter kernels\n", + "\n", + "While you now have a brand new conda environment, you can only interact with it over the command line.\n", + "\n", + "\"original\n", + "\n", + "You need to first create a new kernel spec to use it in a notebook. Once again, we created a convenience variable called `JUPYTER_WORK` which the Jupyter server automatically polls. To create it, invoke the python in your new environment\n", + "```\n", + "$LOCAL_ENVS/tabsAreGreat\n", + "```\n", + "with the following arguments:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Installed kernelspec tabsAreGreat in /home/jupyter/tacc-work/jupyter_packages/share/jupyter/kernels/tabsaregreat\n" + ] + } + ], + "source": [ + "$LOCAL_ENVS/tabsAreGreat/bin/python -m ipykernel install \\\n", + " --prefix $JUPYTER_WORK \\\n", + " --name tabsAreGreat \\\n", + " --display-name \"tabs are great\"\n", + "\n", + "# -m ipykernel install - install a jupyter kernel\n", + "# --prefix $JUPYTER_WORK - kernel installation path\n", + "# --name tabsAreGreat - name of the kernel (no spaces)\n", + "# --display-name \"tabs are great\" - the name that will display in the drop-down list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can see that once again, this was installed to your `tacc-work` directory, so it will persist until you delete it.\n", + "\n", + "## Use your new kernel\n", + "\n", + "To use it (as in right now) just refresh the main Jupyter tab and click the \"New\" drop-down tab\n", + "\n", + "\"new\n", + "\n", + "and you should see a new option called \"tabs are great\".\n", + "\n", + "## Clean your environment\n", + "\n", + "When you want to de-clutter your development environment and remove both this kernel and environment, you just have to delete two directories:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# Conda environment\n", + "rm -rf $LOCAL_ENVS/tabsAreGreat\n", + "# Jupyter kernel\n", + "rm -rf $JUPYTER_WORK/share/jupyter/kernels/tabsaregreat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "All traces of this environment should now be gone." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# conda environments:\n", + "#\n", + "base * /opt/conda\n", + "python2 /opt/conda/envs/python2\n", + "\n" + ] + } + ], + "source": [ + "conda env list" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Extra functionality\n", + "\n", + "If you think we should handle additional functionality in the SD2E Jupyter environment, please submit a feature request to\n", + "\n", + "https://github.com/SD2E/jupyteruser-sd2e/issues\n", + "\n", + "Thanks and happy hacking!\n", + "\n", + "-- TACC" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Bash", + "language": "bash", + "name": "bash" + }, + "language_info": { + "codemirror_mode": "shell", + "file_extension": ".sh", + "mimetype": "text/x-sh", + "name": "bash" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/images/base/src/activate_kernel b/images/base/src/activate_kernel new file mode 100644 index 0000000..152988a --- /dev/null +++ b/images/base/src/activate_kernel @@ -0,0 +1,17 @@ +#!/bin/bash + +function usage { + echo -e "\n Usage: activate_kernel conda_env conn_file\n" 1>&2; +} +function ee { + # Echos to STDERR + echo -e "[ERROR] $@" 1>&2; + usage + exit 1 +} + +[ ! -n "$1" ] && ee "Please specify a conda environment" +[ ! -n "$2" ] && ee "Please specify a connection file" + +source activate $1 +python -m ipykernel_launcher -f $2 diff --git a/images/base/src/add-sd2e-groups.sh b/images/base/src/add-sd2e-groups.sh new file mode 100644 index 0000000..96a9278 --- /dev/null +++ b/images/base/src/add-sd2e-groups.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +while read -r nb_gid nb_group ; do + echo "Adding ${nb_gid}:${nb_group}" + groupadd --force --gid ${nb_gid} "G-${nb_gid}" +done </dev/null || true + # Get user info and populate git vars + export GIT_COMMITTER_NAME=$(profiles-list -v me | jq -r '"\(.first_name) \(.last_name)"' 2>/dev/null || echo "Jupyter User") + export GIT_COMMITTER_EMAIL=$(profiles-list -v me | jq -r .email 2>/dev/null || echo ${JUPYTERHUB_USER-jupyter}@tacc.cloud) + else + export GIT_COMMITTER_NAME="Jupyter User" + export GIT_COMMITTER_EMAIL="jupyter@tacc.cloud" + fi +fi diff --git a/images/custom/Dockerfile b/images/custom/Dockerfile deleted file mode 100644 index 63e0ce7..0000000 --- a/images/custom/Dockerfile +++ /dev/null @@ -1,126 +0,0 @@ -#Image: sd2e/jupyteruser-sd2e -#Version: 0.3.1 - -FROM sd2e/jupyteruser-base:0.1.1 - -# Image release -USER root -ARG image_version=development -RUN echo "${image_version}" > /etc/sd2e_jupyteruser-sd2e-release && \ - chmod a+r /etc/sd2e_jupyteruser-sd2e-release - -########################################## -# igraph and networkx -########################################## -USER root -LABEL "comment"="Support for plotly igraph and networkx" "issue"="SD2E/jupyteruser-sd2e/issues/3" -RUN conda install --quiet --yes python-igraph plotly networkx && \ - conda install --quiet --yes -n python2 python-igraph plotly networkx && \ - docker-clean - -########################################## -# Probcomp stack -########################################## -USER root - -LABEL "comment"="Support for Open Probabilistic Programming Stack" "issue"="SD2E/jupyteruser-sd2e/issues/2" -# Libraries -RUN apt-get update && \ - apt-get install -y libboost-all-dev libgsl0-dev ccache && \ - apt-get clean && \ -# Install dependencies and remove anaconda toolchain -conda install -n python2 --quiet --yes flask jsonschema patsy requests six && \ - conda install -n python2 -c conda-forge apsw && \ - conda uninstall -n python2 --yes \ - binutils_impl_linux-64 binutils_linux-64 \ - gcc_impl_linux-64 gcc_linux-64 \ - gxx_impl_linux-64 gxx_linux-64 && \ -# Install probcomp software stack -bash -c "export MPLBACKEND=Agg && source activate python2 && pip2 install git+https://github.com/probcomp/Venturecxx@v0.5.1.1 && \ - pip2 install git+https://github.com/probcomp/cgpm.git@v0.1.2 && \ - pip2 install git+https://github.com/probcomp/crosscat.git@v0.1.56.1 && \ - pip2 install git+https://github.com/probcomp/bayeslite.git@v0.3.2 && \ - pip2 install git+https://github.com/probcomp/iventure.git@v0.2.2" && \ -# Clean cache -docker-clean - -RUN mkdir -p /home/jupyter/examples/probcomp && \ - cd /home/jupyter/examples/probcomp && \ - curl http://probcomp-workshop-materials.s3.amazonaws.com/latest.tgz | tar -xzf - - -########################################## -#### Common Lisp Kernel Setup Begin #### -########################################## - -# Get sbcl from the package manage and use it to build -# the sbcl 1.4.0 from source. The version from the package -# manager is not the current version. -RUN mkdir /opt/common-lisp && \ - apt-get update && \ - apt-get install -y sbcl libzmq3-dev && \ - apt-get clean && \ - cd /opt/common-lisp && \ - git clone git://git.code.sf.net/p/sbcl/sbcl && \ - cd sbcl && \ - git checkout tags/sbcl-1.4.3 && \ - sh make.sh && rm -rf .git && \ - cd /opt/common-lisp/sbcl && \ - sh install.sh && \ - apt-get purge -y sbcl # Uninstall the version from apt-get - -COPY common-lisp/ql_setup.lisp /opt/common-lisp/ql_setup.lisp - -# Install the common lisp jupyter kernel -RUN cd /opt/common-lisp/ && \ - git clone https://github.com/fredokun/cl-jupyter.git && \ - cd cl-jupyter && rm -rf .git && \ - python ./install-cl-jupyter.py && \ - cd /opt/common-lisp && \ - curl -O https://beta.quicklisp.org/quicklisp.lisp && \ - sbcl --load ql_setup.lisp && \ - rm quicklisp.lisp ql_setup.lisp - -# SBCL init file -# Loads required packages for common lisp kernel -# everytime sbcl starts -COPY common-lisp/sbclrc /home/jupyter/.sbclrc - -# Move the kernel json file to the correct location -RUN mkdir /opt/conda/share/jupyter/kernels/lisp && \ - mv $HOME/.ipython/kernels/lisp/kernel.json /opt/conda/share/jupyter/kernels/lisp && \ - chmod -R a+rwX /opt/conda/share/jupyter/kernels/lisp && \ - rm -rf ${HOME}/.ipython && docker-clean - -COPY examples/common-lisp /home/jupyter/examples/common-lisp - -########################################## -# pyemd support -########################################## -USER root -LABEL "comment"="support for pyemd" "issue"="SD2E/jupyteruser-sd2e/issues/8" -RUN conda install --quiet --yes pyemd && \ - conda install --quiet --yes -n python2 pyemd && \ - docker-clean - -########################################## -# Support DSGRN code -########################################## -USER root -LABEL "comment"="Support DSGRN code" "issue"="SD2E/jupyteruser-sd2e/issues/9" -RUN apt-get install -y cmake graphviz && \ - conda install --quiet --yes python-graphviz && \ - conda install --quiet --yes -n python2 python-graphviz && \ - docker-clean - -############################################### -# Permissions -############################################### - -# The notebook is run by the TACC userid, not jupyter, -# so permissions need to be open -RUN chown -R jupyter:G-819382 /home/jupyter && \ - chmod 777 /home/jupyter && \ - find /home/jupyter -type f -exec chmod 666 {} \; && \ - find /home/jupyter -type d -exec chmod 777 {} \; - -USER jupyter diff --git a/images/sd2e/Dockerfile b/images/sd2e/Dockerfile new file mode 100644 index 0000000..0d983cd --- /dev/null +++ b/images/sd2e/Dockerfile @@ -0,0 +1,144 @@ +#Image: sd2e/jupyteruser-sd2e +#Version: 0.3.3 + +FROM sd2e/jupyteruser-base:0.2.2 + +# Convenience variable +ARG CONDA_ARGS="--quiet --no-update-deps --yes" + +# Image release +USER root +ARG image_version=development +RUN echo "${image_version}" > /etc/sd2e_jupyteruser-sd2e-release && \ + chmod a+r /etc/sd2e_jupyteruser-sd2e-release + +########################################## +# igraph and networkx +########################################## +USER root +LABEL "comment"="Support for plotly igraph and networkx" "issue"="SD2E/jupyteruser-sd2e/issues/3" +RUN conda install ${CONDA_ARGS} plotly networkx && \ + bash -c "source activate base && pip install python-igraph" && \ + conda install ${CONDA_ARGS} -n python2 plotly networkx && \ + bash -c "source activate python2 && pip install python-igraph" && \ + docker-clean + +########################################## +# Probcomp stack +########################################## +USER root + +LABEL "comment"="Support for Open Probabilistic Programming Stack" "issue"="SD2E/jupyteruser-sd2e/issues/2" + +# Install run dependencies +RUN apt-get update && apt-get install -yq --no-install-recommends libgsl0-dev && \ + conda install -n python2 ${CONDA_ARGS} flask jsonschema patsy requests six && \ + conda install -n python2 ${CONDA_ARGS} -c conda-forge apsw && \ + docker-clean +# Install probcomp software stack +### Make sure to remove build deps +RUN apt-get update && apt-get install -y --no-install-recommends libboost-all-dev ccache +RUN bash -c "export MPLBACKEND=Agg && source activate python2 && \ + pip install git+https://github.com/probcomp/Venturecxx@v0.5.1.1 && \ + pip install git+https://github.com/probcomp/cgpm.git@v0.1.2 && \ + pip install git+https://github.com/probcomp/crosscat.git@v0.1.56.1 && \ + pip install git+https://github.com/probcomp/bayeslite.git@v0.3.2 && \ + pip install git+https://github.com/probcomp/iventure.git@v0.2.3" && \ + rm -rf .ccache && \ + apt-get --purge remove -y libboost-all-dev ccache && \ + apt-get --purge -y autoremove && \ + docker-clean +# Grab latest example notebooks +RUN mkdir -p /home/jupyter/examples/probcomp && \ + cd /home/jupyter/examples/probcomp && \ + curl http://probcomp-workshop-materials.s3.amazonaws.com/latest.tgz | tar -xzf - + +########################################## +#### Common Lisp Kernel Setup Begin #### +########################################## + +ENV CL_PREFIX=/opt/common-lisp +ARG CLV=1.4.6-x86-64-linux +# Install dependency +RUN apt-get update && apt-get install -yq --no-install-recommends libzmq3-dev && \ + docker-clean +# Install SBCL +RUN curl -L prdownloads.sourceforge.net/sbcl/sbcl-${CLV}-binary.tar.bz2 | tar -xjf - && \ + ( cd sbcl-${CLV} && INSTALL_ROOT=${CL_PREFIX} bash install.sh ) && \ + rm -rf sbcl-${CLV} && \ + docker-clean +# Set env variable for sbcl http://www.sbcl.org/getting.html +ENV SBCL_HOME=${CL_PREFIX}/lib/sbcl +ENV PATH=${CL_PREFIX}/bin:${PATH} + +COPY common-lisp/ql_setup.lisp ${CL_PREFIX}/ql_setup.lisp + +# Install the common lisp jupyter kernel +RUN cd ${CL_PREFIX} && \ + git clone https://github.com/fredokun/cl-jupyter.git && \ + ( cd cl-jupyter && rm -rf .git && ${CONDA_DIR}/bin/python ./install-cl-jupyter.py ) && \ + curl -LO https://beta.quicklisp.org/quicklisp.lisp && \ + sbcl --load ql_setup.lisp && \ + rm quicklisp.lisp ql_setup.lisp + +# SBCL init file +# Loads required packages for common lisp kernel +# everytime sbcl starts +COPY common-lisp/sbclrc /home/jupyter/.sbclrc + +# Move the kernel json file to the correct location +RUN cp -r $HOME/.ipython/kernels/lisp ${CONDA_DIR}/share/jupyter/kernels/ && \ + rm -rf $HOME/.ipython && \ + chmod -R a+rX ${CONDA_DIR}/share/jupyter/kernels/lisp && \ + docker-clean + +COPY examples/common-lisp /home/jupyter/examples/common-lisp + +USER jupyter +RUN sbcl --load ${CL_PREFIX}/cl-jupyter/cl-jupyter.lisp + +########################################## +# pyemd support +########################################## +USER root +LABEL "comment"="support for pyemd" "issue"="SD2E/jupyteruser-sd2e/issues/8" +RUN conda install ${CONDA_ARGS} pyemd && \ + conda install ${CONDA_ARGS} -n python2 pyemd && \ + docker-clean + +########################################## +# Support DSGRN code +########################################## +USER root +LABEL "comment"="Support DSGRN code" "issue"="SD2E/jupyteruser-sd2e/issues/9" +RUN apt-get update && apt-get install -yq --no-install-recommends cmake graphviz && \ + conda install ${CONDA_ARGS} python-graphviz && \ + conda install ${CONDA_ARGS} -n python2 python-graphviz && \ + docker-clean + +########################################## +# Support Tensorflow and Keras +########################################## +USER root +LABEL "comment"="Support Tensorflow and Keras" "issue"="SD2E/jupyteruser-sd2e/issues/13" +RUN conda install ${CONDA_ARGS} 'tensorflow=1.6*' keras theano && \ + conda install ${CONDA_ARGS} -n python2 'tensorflow=1.6*' keras theano && \ + docker-clean +RUN cd examples && \ + git clone https://github.com/leriomaggio/deep-learning-keras-tensorflow.git && \ + cd deep-learning-keras-tensorflow && rm -rf .git +# Necessary for theano +ENV MKL_THREADING_LAYER=GNU + +############################################### +# Permissions +############################################### + +# The notebook is run by the TACC userid, not jupyter, +# so permissions need to be open +RUN chown -R jupyter:${NB_GROUP} /home/jupyter && \ + chmod 777 /home/jupyter && \ + find /home/jupyter -type f -exec chmod 666 {} \; && \ + find /home/jupyter -type d -exec chmod 777 {} \; + +USER jupyter diff --git a/images/custom/common-lisp/ql_setup.lisp b/images/sd2e/common-lisp/ql_setup.lisp similarity index 90% rename from images/custom/common-lisp/ql_setup.lisp rename to images/sd2e/common-lisp/ql_setup.lisp index f3db2df..af97014 100644 --- a/images/custom/common-lisp/ql_setup.lisp +++ b/images/sd2e/common-lisp/ql_setup.lisp @@ -9,8 +9,10 @@ (ql:quickload "alexandria") (ql:quickload "trivial-features") (ql:quickload "babel") +(ql:quickload "ironclad") ;; Run the kernel script once to get all of the required packages installed ;; so that that pacakges aren't installed when running starting the notebook. (load "cl-jupyter/cl-jupyter.lisp") +(ql:quickload "cl-jupyter") (quit) diff --git a/images/custom/common-lisp/sbclrc b/images/sd2e/common-lisp/sbclrc similarity index 100% rename from images/custom/common-lisp/sbclrc rename to images/sd2e/common-lisp/sbclrc diff --git a/images/custom/examples/common-lisp/about-cl-jupyter.ipynb b/images/sd2e/examples/common-lisp/about-cl-jupyter.ipynb similarity index 100% rename from images/custom/examples/common-lisp/about-cl-jupyter.ipynb rename to images/sd2e/examples/common-lisp/about-cl-jupyter.ipynb diff --git a/images/custom/examples/common-lisp/profile/Jupiter's_storm.jpg b/images/sd2e/examples/common-lisp/profile/Jupiter's_storm.jpg similarity index 100% rename from images/custom/examples/common-lisp/profile/Jupiter's_storm.jpg rename to images/sd2e/examples/common-lisp/profile/Jupiter's_storm.jpg diff --git a/images/custom/examples/common-lisp/profile/Portrait_of_Jupiter_from_Cassini.png b/images/sd2e/examples/common-lisp/profile/Portrait_of_Jupiter_from_Cassini.png similarity index 100% rename from images/custom/examples/common-lisp/profile/Portrait_of_Jupiter_from_Cassini.png rename to images/sd2e/examples/common-lisp/profile/Portrait_of_Jupiter_from_Cassini.png diff --git a/images/custom/examples/common-lisp/profile/commonlisp.js b/images/sd2e/examples/common-lisp/profile/commonlisp.js similarity index 100% rename from images/custom/examples/common-lisp/profile/commonlisp.js rename to images/sd2e/examples/common-lisp/profile/commonlisp.js diff --git a/images/custom/examples/common-lisp/profile/custom.js b/images/sd2e/examples/common-lisp/profile/custom.js similarity index 100% rename from images/custom/examples/common-lisp/profile/custom.js rename to images/sd2e/examples/common-lisp/profile/custom.js diff --git a/images/custom/examples/common-lisp/profile/fish.svg b/images/sd2e/examples/common-lisp/profile/fish.svg similarity index 100% rename from images/custom/examples/common-lisp/profile/fish.svg rename to images/sd2e/examples/common-lisp/profile/fish.svg diff --git a/images/custom/examples/common-lisp/profile/fishbowl-small.svg b/images/sd2e/examples/common-lisp/profile/fishbowl-small.svg similarity index 100% rename from images/custom/examples/common-lisp/profile/fishbowl-small.svg rename to images/sd2e/examples/common-lisp/profile/fishbowl-small.svg diff --git a/images/custom/examples/common-lisp/profile/fishbowl.svg b/images/sd2e/examples/common-lisp/profile/fishbowl.svg similarity index 100% rename from images/custom/examples/common-lisp/profile/fishbowl.svg rename to images/sd2e/examples/common-lisp/profile/fishbowl.svg diff --git a/images/custom/examples/common-lisp/profile/jupyter-sq-text.svg b/images/sd2e/examples/common-lisp/profile/jupyter-sq-text.svg similarity index 100% rename from images/custom/examples/common-lisp/profile/jupyter-sq-text.svg rename to images/sd2e/examples/common-lisp/profile/jupyter-sq-text.svg diff --git a/images/custom/examples/common-lisp/profile/lambda.svg b/images/sd2e/examples/common-lisp/profile/lambda.svg similarity index 100% rename from images/custom/examples/common-lisp/profile/lambda.svg rename to images/sd2e/examples/common-lisp/profile/lambda.svg diff --git a/images/custom/examples/probcomp/gapminder-exploratory.ipynb b/images/sd2e/examples/probcomp/gapminder-exploratory.ipynb similarity index 100% rename from images/custom/examples/probcomp/gapminder-exploratory.ipynb rename to images/sd2e/examples/probcomp/gapminder-exploratory.ipynb diff --git a/images/custom/examples/probcomp/gapminder-missing-data.ipynb b/images/sd2e/examples/probcomp/gapminder-missing-data.ipynb similarity index 100% rename from images/custom/examples/probcomp/gapminder-missing-data.ipynb rename to images/sd2e/examples/probcomp/gapminder-missing-data.ipynb diff --git a/images/custom/examples/probcomp/introduction.ipynb b/images/sd2e/examples/probcomp/introduction.ipynb similarity index 100% rename from images/custom/examples/probcomp/introduction.ipynb rename to images/sd2e/examples/probcomp/introduction.ipynb diff --git a/images/custom/examples/probcomp/resources/country-year.csv b/images/sd2e/examples/probcomp/resources/country-year.csv similarity index 100% rename from images/custom/examples/probcomp/resources/country-year.csv rename to images/sd2e/examples/probcomp/resources/country-year.csv diff --git a/images/custom/examples/probcomp/resources/frame_missing_2000.csv b/images/sd2e/examples/probcomp/resources/frame_missing_2000.csv similarity index 100% rename from images/custom/examples/probcomp/resources/frame_missing_2000.csv rename to images/sd2e/examples/probcomp/resources/frame_missing_2000.csv diff --git a/images/custom/examples/probcomp/resources/gapminder.csv b/images/sd2e/examples/probcomp/resources/gapminder.csv similarity index 100% rename from images/custom/examples/probcomp/resources/gapminder.csv rename to images/sd2e/examples/probcomp/resources/gapminder.csv diff --git a/images/custom/examples/probcomp/resources/satellites.csv b/images/sd2e/examples/probcomp/resources/satellites.csv similarity index 100% rename from images/custom/examples/probcomp/resources/satellites.csv rename to images/sd2e/examples/probcomp/resources/satellites.csv diff --git a/images/custom/examples/probcomp/satellites-predictive.ipynb b/images/sd2e/examples/probcomp/satellites-predictive.ipynb similarity index 100% rename from images/custom/examples/probcomp/satellites-predictive.ipynb rename to images/sd2e/examples/probcomp/satellites-predictive.ipynb diff --git a/test/dotjupyter/custom/current_theme.txt b/test/dotjupyter/custom/current_theme.txt new file mode 100644 index 0000000..57904b1 --- /dev/null +++ b/test/dotjupyter/custom/current_theme.txt @@ -0,0 +1 @@ +grade3 \ No newline at end of file diff --git a/test/dotjupyter/custom/custom.css b/test/dotjupyter/custom/custom.css new file mode 100644 index 0000000..5eaf862 --- /dev/null +++ b/test/dotjupyter/custom/custom.css @@ -0,0 +1,3187 @@ +div#notebook { + font-family: sans-serif; + font-size: 13pt; + line-height: 170%; + color: #303030; + -webkit-font-smoothing: antialiased !important; +} +body, +div.body { + font-family: sans-serif; + font-size: 13pt; + color: #303030; + background-color: #ffffff; + background: #ffffff; + -webkit-font-smoothing: antialiased !important; +} +body.notebook_app { + padding: 0; + background-color: #ffffff; + background: #ffffff; + padding-right: 0px !important; + overflow-y: hidden; +} +a { + font-family: sans-serif; + color: #303030; + -webkit-font-smoothing: antialiased !important; +} +a:hover, +a:focus { + color: #2f2f2f; + -webkit-font-smoothing: antialiased !important; +} +.list_header, +div#notebook_list_header.row.list_header { + font-size: 14pt; + color: #2f2f2f; + background-color: transparent; + height: 35px; +} +i.fa.fa-folder { + display: inline-block; + font: normal normal normal 14px "FontAwesome"; + font-family: "FontAwesome" !important; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + font-size: 18px; + -moz-osx-font-smoothing: grayscale; +} +#running .panel-group .panel .panel-heading { + font-size: 14pt; + color: #303030; + padding: 8px 8px; + background: #e4e4e4; + background-color: #e4e4e4; +} +#running .panel-group .panel .panel-heading a { + font-size: 14pt; + color: #303030; +} +#running .panel-group .panel .panel-heading a:focus, +#running .panel-group .panel .panel-heading a:hover { + font-size: 14pt; + color: #303030; +} +#running .panel-group .panel .panel-body .list_container .list_item { + background: #f4f4f4; + background-color: #f4f4f4; + padding: 2px; + border-bottom: 2px solid #dedede; +} +#running .panel-group .panel .panel-body .list_container .list_item:hover { + background: #f4f4f4; + background-color: #f4f4f4; +} +#running .panel-group .panel .panel-body { + padding: 2px; +} +button#refresh_running_list { + border: none !important; +} +button#refresh_cluster_list { + border: none !important; +} +div.running_list_info.toolbar_info { + font-size: 15px; + padding: 4px 0 4px 0; + margin-top: 5px; + margin-bottom: 8px; + height: 24px; + line-height: 24px; + text-shadow: none; +} +.list_placeholder { + font-weight: normal; +} +#tree-selector { + padding: 0px; + border-color: transparent; +} +#project_name > ul > li > a > i.fa.fa-home { + color: #ff7823; + font-size: 17pt; + display: inline-block; + position: static; + padding: 0px 0px; + font-weight: normal; + text-align: center; + vertical-align: text-top; +} +.fa-folder:before { + color: #126dce; +} +.fa-arrow-up:before { + font-size: 14px; +} +.fa-arrow-down:before { + font-size: 14px; +} +span#last-modified.btn.btn-xs.btn-default.sort-action:hover .fa, +span#sort-name.btn.btn-xs.btn-default.sort-action:hover .fa { + color: #ef5c00; +} +.folder_icon:before { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + content: "\f07b"; + color: #126dce; +} +.notebook_icon:before { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + content: "\f02d"; + position: relative; + color: #009e07 !important; + top: 0px; +} +.file_icon:before { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + content: "\f15b"; + position: relative; + top: 0px; + color: #6a737d !important; +} +#project_name a { + display: inline-flex; + padding-left: 7px; + margin-left: -2px; + text-align: -webkit-auto; + vertical-align: baseline; + font-size: 18px; +} +div#notebook_toolbar div.dynamic-instructions { + font-family: sans-serif; + font-size: 17px; + color: #828892; +} +span#login_widget > .button, +#logout { + font-family: "Proxima Nova", sans-serif; + color: #303030; + background: transparent; + background-color: transparent; + border: 2px solid #e5e5e5; + font-weight: normal; + box-shadow: none; + text-shadow: none; + border-radius: 3px; + margin-right: 10px; + padding: 2px 7px; +} +span#login_widget > .button:hover, +#logout:hover { + color: #ef5c00; + background-color: transparent; + background: transparent; + border: 2px solid #ef5c00; + background-image: none; + box-shadow: none !important; + border-radius: 3px; +} +span#login_widget > .button:focus, +#logout:focus, +span#login_widget > .button.focus, +#logout.focus, +span#login_widget > .button:active, +#logout:active, +span#login_widget > .button.active, +#logout.active, +.open > .dropdown-togglespan#login_widget > .button, +.open > .dropdown-toggle#logout { + color: #1c1c1c; + background-color: #303030; + background: #303030; + border-color: #303030; + background-image: none; + box-shadow: none !important; + border-radius: 2px; +} +body > #header #header-container { + padding-bottom: 0px; + padding-top: 4px; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} +body > #header { + background: #ffffff; + background-color: #ffffff; + position: relative; + z-index: 100; +} +.list_container { + font-size: 13pt; + color: #303030; + border: none; + text-shadow: none !important; +} +.list_container > div { + border-bottom: 1px solid rgba(180,180,180,.14); + font-size: 13pt; +} +.list_header > div, +.list_item > div { + padding-top: 6px; + padding-bottom: 2px; + padding-left: 0px; +} +.list_header > div .item_link, +.list_item > div .item_link { + margin-left: -1px; + vertical-align: middle; + line-height: 22px; + font-size: 13pt; +} +.item_icon { + color: #126dce; + font-size: 13pt; + vertical-align: middle; +} +.list_item input:not([type="checkbox"]) { + padding-right: 0px; + height: 1.75em; + width: 25%; + margin: 0px 0 0; + margin-top: 0px; +} +.list_header > div .item_link, +.list_item > div .item_link { + margin-left: -1px; + vertical-align: middle; + line-height: 1.5em; + font-size: 12pt; + display: inline-table; + position: static; +} +#button-select-all { + height: 34px; + min-width: 55px; + z-index: 0; + border: none !important; + padding-top: 0px; + padding-bottom: 0px; + margin-bottom: 0px; + margin-top: 0px; + left: -3px; + border-radius: 0px !important; +} +#button-select-all:focus, +#button-select-all:active:focus, +#button-select-all.active:focus, +#button-select-all.focus, +#button-select-all:active.focus, +#button-select-all.active.focus { + background-color: #e5e5e5 !important; + background: #e5e5e5 !important; +} +button#tree-selector-btn { + height: 34px; + font-size: 12.0pt; + border: none; + left: 0px; + border-radius: 0px !important; +} +input#select-all.pull-left.tree-selector { + margin-left: 7px; + margin-right: 2px; + margin-top: 2px; + top: 4px; +} +input[type="radio"], +input[type="checkbox"] { + margin-top: 1px; + line-height: normal; +} +.delete-button { + border: none !important; +} +i.fa.fa-trash { + font-size: 13.5pt; +} +.list_container a { + font-size: 16px; + color: #303030; + border: none; + text-shadow: none !important; + font-weight: normal; + font-style: normal; +} +div.list_container a:hover { + color: #2f2f2f; +} +.list_header > div input, +.list_item > div input { + margin-right: 7px; + margin-left: 12px; + vertical-align: baseline; + line-height: 22px; + position: relative; + top: -1px; +} +div.list_item:hover { + background-color: #fafafa; +} +.breadcrumb > li { + font-size: 12.0pt; + color: #303030; + border: none; + text-shadow: none !important; +} +.breadcrumb > li + li:before { + content: "/\00a0"; + padding: 0px; + color: #303030; + font-size: 18px; +} +#project_name > .breadcrumb { + padding: 0px; + margin-bottom: 0px; + background-color: transparent; + font-weight: normal; + margin-top: -2px; +} +ul#tabs a { + font-family: sans-serif; + font-size: 13.5pt; + font-weight: normal; + font-style: normal; + text-shadow: none !important; +} +.nav-tabs { + font-family: sans-serif; + font-size: 13.5pt; + font-weight: normal; + font-style: normal; + background-color: transparent; + border-color: transparent; + text-shadow: none !important; + border: 2px solid transparent; +} +.nav-tabs > li > a:active, +.nav-tabs > li > a:focus, +.nav-tabs > li > a:hover, +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:focus, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #ef5c00; + background-color: transparent; + border-color: transparent; + border-bottom: 2px solid transparent; +} +.nav > li.disabled > a, +.nav > li.disabled > a:hover { + color: #828892; +} +.nav-tabs > li > a:before { + content: ""; + position: absolute; + width: 100%; + height: 2px; + bottom: -2px; + left: 0; + background-color: #ef5c00; + visibility: hidden; + -webkit-transform: perspective(0)scaleX(0); + transform: perspective(0)scaleX(0); + -webkit-transition: ease 220ms; + transition: ease 220ms; + -webkit-font-smoothing: antialiased !important; +} +.nav-tabs > li > a:hover:before { + visibility: visible; + -webkit-transform: perspective(1)scaleX(1); + transform: perspective(1)scaleX(1); +} +.nav-tabs > li.active > a:before { + content: ""; + position: absolute; + width: 100%; + height: 2px; + bottom: -2px; + left: 0; + background-color: #ef5c00; + visibility: visible; + -webkit-transform: perspective(1)scaleX(1); + transform: perspective(1)scaleX(1); + -webkit-font-smoothing: subpixel-antialiased !important; +} +div#notebook { + font-family: sans-serif; + font-size: 13pt; + padding-top: 4px; +} +.notebook_app { + background-color: #ffffff; +} +#notebook-container { + padding: 13px 2px; + background-color: #ffffff; + min-height: 0px; + box-shadow: none; + width: 980px; + margin-right: auto; + margin-left: auto; +} +div#ipython-main-app.container { + width: 980px; + margin-right: auto; + margin-left: auto; + margin-right: auto; + margin-left: auto; +} +.container { + width: 980px; + margin-right: auto; + margin-left: auto; +} +div#menubar-container { + width: 100%; + width: 980px; +} +div#header-container { + width: 980px; +} +.notebook_app #header, +.edit_app #header { + box-shadow: none !important; + background-color: #ffffff; + border-bottom: 2px solid rgba(180,180,180,.14); +} +#header, +.edit_app #header { + font-family: sans-serif; + font-size: 13pt; + box-shadow: none; + background-color: #ffffff; +} +#header .header-bar, +.edit_app #header .header-bar { + background: #ffffff; + background-color: #ffffff; +} +body > #header .header-bar { + width: 100%; + background: #ffffff; +} +span.checkpoint_status, +span.autosave_status { + font-size: small; + display: none; +} +#menubar, +div#menubar { + background-color: #ffffff; + padding-top: 0px !important; +} +#menubar .navbar, +.navbar-default { + background-color: #ffffff; + margin-bottom: 0px; + margin-top: 0px; +} +.navbar { + border: none; +} +div.navbar-text, +.navbar-text, +.navbar-text.indicator_area, +p.navbar-text.indicator_area { + margin-top: 8px !important; + margin-bottom: 0px; + color: #ff7823; +} +.navbar-default { + font-family: sans-serif; + font-size: 13pt; + background-color: #ffffff; + border-color: #d4d4d4; + line-height: 1.5em; + padding-bottom: 0px; +} +.navbar-default .navbar-nav > li > a { + font-family: sans-serif; + font-size: 13pt; + color: #303030; + display: block; + line-height: 1.5em; + padding-top: 14px; + padding-bottom: 11px; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #2f2f2f; + background-color: rgba(180,180,180,.14); + border-color: #d4d4d4; + line-height: 1.5em; + transition: 200ms ease; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #1c1c1c; + background-color: #dedede; + border-color: #dedede; + line-height: 1.5em; + transition: 200ms ease; +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0px; +} +.navbar-nav { + margin: 0; +} +div.notification_widget.info, +.notification_widget.info, +.notification_widget:active:hover, +.notification_widget.active:hover, +.open > .dropdown-toggle.notification_widget:hover, +.notification_widget:active:focus, +.notification_widget.active:focus, +.open > .dropdown-toggle.notification_widget:focus, +.notification_widget:active.focus, +.notification_widget.active.focus, +.open > .dropdown-toggle.notification_widget.focus, +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn, +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn:hover, +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn:focus { + color: #303030 !important; + background-color: transparent !important; + border-color: transparent !important; + padding-bottom: 0px !important; + margin-bottom: 0px !important; + font-size: 9pt !important; + z-index: 0; +} +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn { + font-size: 9pt !important; + z-index: 0; +} +.notification_widget { + color: #126dce; + z-index: -500; + font-size: 9pt; + background: transparent; + background-color: transparent; + margin-right: 3px; + border: none; +} +.notification_widget, +div.notification_widget { + margin-right: 0px; + margin-left: 0px; + padding-right: 0px; + vertical-align: text-top !important; + margin-top: 6px !important; + background: transparent !important; + background-color: transparent !important; + font-size: 9pt !important; + border: none; +} +.navbar-btn.btn-xs:hover { + border: none !important; + background: transparent !important; + background-color: transparent !important; + color: #303030 !important; +} +div.notification_widget.info, +.notification_widget.info { + display: none !important; +} +.edit_mode .modal_indicator:before { + font-size: 18px; + color: #ff7823; + opacity: 1.0; + padding-bottom: 0px; + vertical-align: -webkit-baseline-middle; + margin-left: 1px; + margin-bottom: 0px; +} +.command_mode .modal_indicator:before { + font-family: sans-serif; + font-size: 18px; + color: #ff7823; + padding-bottom: 0px; + vertical-align: -webkit-baseline-middle; + margin-left: 1px; + margin-bottom: 0px; +} +.item_icon { + color: #126dce; +} +.item_buttons .kernel-name { + font-size: 13pt; + color: #126dce; +} +.running_notebook_icon:before { + color: #009e07 !important; + font: normal normal normal 15px/1 FontAwesome; + font-size: 15px; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + content: "\f10c"; + vertical-align: middle; + position: static; + display: inherit; +} +.item_buttons .running-indicator { + padding-top: 4px; + color: #009e07; + font-family: sans-serif; + text-rendering: auto; + -webkit-font-smoothing: antialiased; +} +#notification_trusted { + font-family: sans-serif; + font-size: 17px !important; + color: #126dce; + border: none; + background: transparent; + background-color: transparent; + margin-bottom: 0px !important; + margin-top: 11px !important; + vertical-align: middle !important; +} +#modal_indicator { + float: right !important; + color: #4c8be2; + background: #ffffff; + background-color: #ffffff; + margin-top: 8px !important; + margin-left: 0px; +} +#kernel_indicator { + float: right !important; + color: #ff7823; + background: #ffffff; + background-color: #ffffff; + border-left: 2px solid #ff7823; + padding-top: 0px; + padding-bottom: 4px; + margin-top: 8px !important; + margin-left: -2px; +} +#kernel_indicator .kernel_indicator_name { + font-size: 17px; + color: #ff7823; + background: #ffffff; + background-color: #ffffff; + padding-left: 5px; + padding-right: 5px; + margin-top: 4px; + vertical-align: -webkit-baseline-middle; + padding-bottom: 0px; +} +.kernel_idle_icon:before { + display: inline-block; + font: normal normal normal 22px/1 FontAwesome; + font-size: 22px; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + cursor: pointer; + margin-left: 0px !important; + opacity: 0.7; + vertical-align: middle; + margin-top: 1px; + content: "\f1db"; +} +.kernel_busy_icon:before { + display: inline-block; + font: normal normal normal 22px/1 FontAwesome; + font-size: 22px; + -webkit-animation: pulsate 2s infinite ease-out; + animation: pulsate 2s infinite ease-out; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + cursor: pointer; + margin-left: 0px !important; + vertical-align: middle; + margin-top: 1px; + content: "\f111"; +} +@-webkit-keyframes pulsate { + 0% { + -webkit-transform: scale(1.0,1.0); + opacity: 0.8; + } + 8% { + -webkit-transform: scale(1.0,1.0); + opacity: 0.8; + } + 50% { + -webkit-transform: scale(0.75,0.75); + opacity: 0.3; + } + 92% { + -webkit-transform: scale(1.0,1.0); + opacity: 0.8; + } + 100% { + -webkit-transform: scale(1.0,1.0); + opacity: 0.8; + } +} +i#kernel_indicator_icon { + vertical-align: sub; +} +div.notification_widget.info, +.notification_widget.info, +.notification_widget:active:hover, +.notification_widget.active:hover, +.open > .dropdown-toggle.notification_widget:hover, +.notification_widget:active:focus, +.notification_widget.active:focus, +.open > .dropdown-toggle.notification_widget:focus, +.notification_widget:active.focus, +.notification_widget.active.focus, +.open > .dropdown-toggle.notification_widget.focus, +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn, +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn:hover, +div#notification_notebook.notification_widget.btn.btn-xs.navbar-btn:focus { + color: #303030; + background-color: #ffffff; + border-color: #ffffff; +} +#notification_area, +div.notification_area { + float: right !important; + position: static; +} +.notification_widget, +div.notification_widget { + margin-right: 0px; + margin-left: 0px; + padding-right: 0px; + vertical-align: text-top !important; + margin-top: 6px !important; + z-index: 1000; +} +#kernel_logo_widget, +#kernel_logo_widget .current_kernel_logo { + display: none; +} +div#ipython_notebook { + display: none; +} +i.fa.fa-icon { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: auto; +} +.fa { + display: inline-block; + font: normal normal normal 10pt/1 "FontAwesome", sans-serif; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.dropdown-menu { + font-family: sans-serif; + font-size: 13pt; + box-shadow: none; + padding: 0px; + text-align: left; + border: 2px solid #dedede; + background-color: #dedede; + background: #dedede; + line-height: 1; +} +.dropdown-menu:hover { + font-family: sans-serif; + font-size: 13pt; + box-shadow: none; + padding: 0px; + text-align: left; + border: 2px solid #dedede; + background-color: #dedede; + box-shadow: none; + line-height: 1; +} +.dropdown-menu > li > a { + font-family: sans-serif; + font-size: 12.0pt; + line-height: 1.1; + display: block; + padding: 10px 20px 9px 10px; + color: #303030; + background-color: #dedede; + background: #dedede; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #2f2f2f; + background-color: #d4d4d4; + background: #d4d4d4; + border-color: #d4d4d4; + transition: 200ms ease; +} +.dropdown-menu .divider { + height: 1px; + margin: 0px 0px; + overflow: hidden; + background-color: rgba(180,180,180,.30); +} +.dropdown-submenu > .dropdown-menu { + top: 0px; + left: 100%; + margin-top: -2px; + margin-left: 0px; + padding-top: 0px; + transition: 200ms ease; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + font-family: sans-serif; + font-size: 12.0pt; + font-weight: normal; + color: #828892; + padding: none; + display: block; + clear: both; + line-height: 1.1; + white-space: nowrap; +} +.dropdown-submenu > a:after { + color: #303030; + margin-right: -16px; + margin-top: 0px; +} +.dropdown-submenu:hover > a:after, +.dropdown-submenu:active > a:after, +.dropdown-submenu:focus > a:after, +.dropdown-submenu:visited > a:after { + color: #ff7823; + margin-right: -16px; +} +div.kse-dropdown > .dropdown-menu, +.kse-dropdown > .dropdown-menu { + min-width: 0; + top: 94%; +} +.btn, +.btn-default { + font-family: sans-serif; + color: #303030; + background: #e5e5e5; + background-color: #e5e5e5; + border: 2px solid #e5e5e5; + font-weight: normal; + box-shadow: none; + text-shadow: none; + border-radius: 3px; + font-size: initial; +} +.btn:hover, +.btn:active:hover, +.btn.active:hover, +.btn-default:hover, +.open > .dropdown-toggle.btn-default:hover, +.open > .dropdown-toggle.btn:hover { + color: #ef5c00; + border: 2px solid #e0e0e0; + background-color: #e0e0e0; + background: #e0e0e0; + background-image: none; + box-shadow: none !important; + border-radius: 3px; +} +.btn:active, +.btn.active, +.btn:active:focus, +.btn.active:focus, +.btn:active.focus, +.btn.active.focus, +.btn-default:focus, +.btn-default.focus, +.btn-default:active, +.btn-default.active, +.btn-default:active:hover, +.btn-default.active:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn:focus, +.open > .dropdown-toggle.btn.focus, +.open > .dropdown-toggle.btn-default:hover, +.open > .dropdown-toggle.btn-default:focus, +.open > .dropdown-toggle.btn-default.hover, +.open > .dropdown-toggle.btn-default.focus { + color: #ef5c00; + border: 2px solid #e0e0e0; + background-color: #e0e0e0 !important; + background: #e0e0e0 !important; + background-image: none; + box-shadow: none !important; + border-radius: 3px; +} +.btn-default:active:hover, +.btn-default.active:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.btn-default:active.focus, +.btn-default.active.focus { + color: #ef5c00 !important; + background-color: #e5e5e5; + border-color: #ffccac !important; + transition: 2000ms ease; +} +.btn:focus, +.btn.focus, +.btn:active:focus, +.btn.active:focus, +.btn:active, +.btn.active, +.btn:active.focus, +.btn.active.focus { + color: #ef5c00 !important; + outline: none !important; + outline-width: 0px !important; + background: #ffccac !important; + background-color: #ffccac !important; + border-color: #ffccac !important; + transition: 200ms ease !important; +} +.item_buttons > .btn, +.item_buttons > .btn-group, +.item_buttons > .input-group { + font-size: 13pt; + background: transparent; + background-color: transparent; + border: 0px solid #e4e4e4; + border-bottom: 2px solid transparent; + margin-left: 5px; + padding-top: 4px !important; +} +.item_buttons > .btn:hover, +.item_buttons > .btn-group:hover, +.item_buttons > .input-group:hover, +.item_buttons > .btn.active, +.item_buttons > .btn-group.active, +.item_buttons > .input-group.active, +.item_buttons > .btn.focus { + margin-left: 5px; + background: #dfdfdf; + padding-top: 4px !important; + background-color: transparent; + border: 0px solid transparent; + border-bottom: 2px solid #ff7823; + border-radius: 0px; + transition: none; +} +.item_buttons { + line-height: 1.5em !important; +} +.item_buttons .btn { + min-width: 11ex; +} +.btn-group > .btn:first-child { + margin-left: 3px; +} +.btn-group > .btn-mini, +.btn-sm, +.btn-group-sm > .btn, +.btn-xs, +.btn-group-xs > .btn, +.alternate_upload .btn-upload, +.btn-group, +.btn-group-vertical { + font-size: inherit; + font-weight: normal; + height: inherit; + line-height: inherit; +} +.btn-xs, +.btn-group-xs > .btn { + font-size: initial !important; + background-image: none; + font-weight: normal; + text-shadow: none; + display: inline-table; + padding: 2px 5px; + line-height: 1.45; +} +.btn-group > .btn:first-child { + margin-left: 3px; +} +div#new-buttons > button, +#new-buttons > button, +div#refresh_notebook_list, +#refresh_notebook_list { + background: transparent; + background-color: transparent; + border: none; +} +div#new-buttons > button:hover, +#new-buttons > button:hover, +div#refresh_notebook_list, +#refresh_notebook_list, +div.alternate_upload .btn-upload, +.alternate_upload .btn-upload, +div.dynamic-buttons > button, +.dynamic-buttons > button, +.dynamic-buttons > button:focus, +.dynamic-buttons > button:active:focus, +.dynamic-buttons > button.active:focus, +.dynamic-buttons > button.focus, +.dynamic-buttons > button:active.focus, +.dynamic-buttons > button.active.focus, +#new-buttons > button:focus, +#new-buttons > button:active:focus, +#new-buttons > button.active:focus, +#new-buttons > button.focus, +#new-buttons > button:active.focus, +#new-buttons > button.active.focus, +.alternate_upload .btn-upload:focus, +.alternate_upload .btn-upload:active:focus, +.alternate_upload .btn-upload.active:focus, +.alternate_upload .btn-upload.focus, +.alternate_upload .btn-upload:active.focus, +.alternate_upload .btn-upload.active.focus { + background: transparent !important; + background-color: transparent !important; + border: none !important; +} +.alternate_upload input.fileinput { + text-align: center; + vertical-align: bottom; + margin-left: -.5ex; + display: inline-table; + border: solid 0px #e5e5e5; + margin-bottom: -1ex; +} +.alternate_upload .btn-upload { + display: inline-table; + background: transparent; + border: none; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -2px; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; + z-index: 2; +} +.dropdown-header { + font-family: sans-serif !important; + font-size: 13pt !important; + color: #ff7823 !important; + border-bottom: none !important; + padding: 0px !important; + margin: 6px 6px 0px !important; +} +span#last-modified.btn.btn-xs.btn-default.sort-action, +span#sort-name.btn.btn-xs.btn-default.sort-action { + font-family: sans-serif; + font-size: 16px; + background-color: transparent; + background: transparent; + border: none; + color: #303030; + padding-bottom: 0px; + margin-bottom: 0px; + vertical-align: sub; +} +span#last-modified.btn.btn-xs.btn-default.sort-action { + margin-left: 19px; +} +button.close { + border: 0px none; + font-family: sans-serif; + font-size: 20pt; + font-weight: normal; +} +.dynamic-buttons { + padding-top: 0px; + display: inline-block; +} +.close { + color: #de143d; + opacity: .5; + text-shadow: none; + font-weight: normal; +} +.close:hover { + color: #de143d; + opacity: 1; + font-weight: normal; +} +div.nbext-enable-btns .btn[disabled], +div.nbext-enable-btns .btn[disabled]:hover, +.btn-default.disabled, +.btn-default[disabled], +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + color: #4a4a4a; + background: #e2e2e2; + background-color: #e2e2e2; + border-color: #e2e2e2; + transition: 200ms ease; +} +.input-group-addon { + padding: 2px 5px; + font-size: 13pt; + font-weight: normal; + height: auto; + color: #303030; + text-align: center; + background-color: transparent; + border: 2px solid transparent !important; + text-transform: capitalize; +} +a.btn.btn-default.input-group-addon:hover { + background: transparent !important; + background-color: transparent !important; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + height: 100%; +} +.btn-group > .btn + .dropdown-toggle:hover { + background: #e0e0e0 !important; +} +.input-group-btn { + position: relative; + font-size: inherit; + white-space: nowrap; + background: #e4e4e4; + background-color: #e4e4e4; + border: none; +} +.input-group-btn:hover { + background: #dfdfdf; + background-color: #dfdfdf; + border: none; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + background: #e4e4e4; + background-color: #e4e4e4; + border: none; + margin-left: 2px; + margin-right: -1px; + font-size: inherit; +} +.input-group-btn:first-child > .btn:hover, +.input-group-btn:first-child > .btn-group:hover { + background: #e0e0e0; + background-color: #e0e0e0; + border: none; + font-size: inherit; + transition: 200ms ease; +} +div.modal .btn-group > .btn:first-child { + background: #e4e4e4; + background-color: #e4e4e4; + border: 1px solid #e1e1e1; + margin-top: 0px !important; + margin-left: 0px; + margin-bottom: 2px; +} +div.modal .btn-group > .btn:first-child:hover { + background: #dfdfdf; + background-color: #dfdfdf; + border: 1px solid #dfdfdf; + transition: 200ms ease; +} +div.modal > button, +div.modal-footer > button { + background: #e4e4e4; + background-color: #e4e4e4; + border-color: #e4e4e4; +} +div.modal > button:hover, +div.modal-footer > button:hover { + background: #dfdfdf; + background-color: #dfdfdf; + border-color: #dfdfdf; + transition: 200ms ease; +} +.modal-content { + font-family: sans-serif; + font-size: 12.0pt; + position: relative; + background: #e4e4e4; + background-color: #e4e4e4; + border: none; + border-radius: 1px; + background-clip: padding-box; + outline: none; +} +.modal-header { + font-family: sans-serif; + font-size: 13pt; + color: #303030; + background: #e4e4e4; + background-color: #e4e4e4; + border-color: #dedede; + padding: 12px; + min-height: 16.4286px; +} +.modal-content h4 { + font-family: sans-serif; + font-size: 16pt; + color: #303030; + padding: 5px; +} +.modal-body { + background-color: #ffffff; + position: relative; + padding: 15px; +} +.modal-footer { + padding: 8px; + text-align: right; + background-color: #ffffff; + border-top: none; +} +.alert-info { + background-color: #fdfdfd; + border-color: #dedede; + color: #303030; +} +.modal-header .close { + margin-top: -5px; + font-size: 25pt; +} +.modal-backdrop, +.modal-backdrop.in { + opacity: 0.85; + background-color: notebook-bg; +} +div.panel, +div.panel-default, +.panel, +.panel-default { + font-family: sans-serif; + font-size: 13pt; + background-color: #f4f4f4; + color: #303030; + margin-bottom: 14px; + border: 0; + box-shadow: none; +} +div.panel > .panel-heading, +div.panel-default > .panel-heading { + font-size: 14pt; + color: #303030; + background: #e4e4e4; + background-color: #e4e4e4; + border: 0; +} +.modal .modal-dialog { + min-width: 950px; + margin: 50px auto; +} +div.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 0px; + padding-right: 5px; +} +div.form-control, +.form-control { + font-family: sans-serif; + font-size: initial; + color: #303030; + background-color: #ffffff; + border: 1px solid #d0d0d0 !important; + margin-left: 2px; + box-shadow: none; + transition: border-color 0.15s ease-in-out 0s, box-shadow 0.15s ease-in-out 0s; +} +.form-control-static { + min-height: inherit; + height: inherit; +} +.form-group.list-group-item { + color: #303030; + background-color: #f4f4f4; + border-color: #dedede; + margin-bottom: 0px; +} +input, +button, +select, +textarea { + background-color: #ffffff; + font-weight: normal; + border: 1px solid #dedede; +} +select.form-control.select-xs { + height: 33px; + font-size: 13pt; +} +.toolbar select, +.toolbar label { + width: auto; + vertical-align: middle; + margin-right: 0px; + margin-bottom: 0px; + display: inline; + font-size: 92%; + margin-left: 10px; + padding: 0px; + background: #e5e5e5 !important; + background-color: #e5e5e5 !important; + border: 2px solid #e5e5e5 !important; +} +.form-control:focus { + border-color: #ff7823; + outline: 2px solid rgba(240,147,43,.50); + -webkit-box-shadow: none; +} +::-webkit-input-placeholder { + color: #828892; +} +::-moz-placeholder { + color: #828892; +} +:-ms-input-placeholder { + color: #828892; +} +:-moz-placeholder { + color: #828892; +} +[dir="ltr"] #find-and-replace .input-group-btn + .form-control { + border: 2px solid #dedede !important; +} +[dir="ltr"] #find-and-replace .input-group-btn + .form-control:focus { + border-color: #ff7823; + outline: 2px solid rgba(240,147,43,.50); + -webkit-box-shadow: none; + box-shadow: none; +} +div.output.output_scroll { + box-shadow: none; +} +::-webkit-scrollbar { + width: 11px; + max-height: 9px; + background-color: #ebebeb; + border-radius: 3px; + border: none; +} +::-webkit-scrollbar-track { + background: #ebebeb; + border: none; + width: 11px; + max-height: 9px; +} +::-webkit-scrollbar-thumb { + border-radius: 2px; + border: none; + background: #909090; + background-clip: content-box; + width: 11px; +} +HTML, +body, +div, +dl, +dt, +dd, +ul, +ol, +li, +h1, +h2, +h3, +h4, +h5, +h6, +pre, +code, +form, +fieldset, +legend, +input, +button, +textarea, +p, +blockquote, +th, +td, +span, +a { + text-rendering: auto; + -webkit-font-smoothing: antialiased; +} +div.input_area { + background-color: #ededed; + background: #ededed; + padding-right: 1.2em; + border: 0px; + border-radius: 0px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +div.cell { + padding: 0px; + background: #ffffff; + background-color: #ffffff; + border: medium solid #ffffff; + border-radius: 0px; + top: 0; +} +div.cell.selected { + background: #ffffff; + background-color: #ffffff; + border: medium solid #ffffff; + padding: 0px; + border-radius: 3px; +} +.edit_mode div.cell.selected { + padding: 0px; + background: #ffffff; + background-color: #ffffff; + border: medium solid #ffffff; + border-radius: 3px; +} +div.cell.edit_mode { + padding: 0px; + background: #ffffff; + background-color: #ffffff; +} +div.CodeMirror-sizer { + margin-left: 0px; + margin-bottom: -21px; + border-right-width: 16px; + min-height: 37px; + padding-right: 0px; + padding-bottom: 0px; + margin-top: 0px; +} +div.cell.selected:before { + background: #ededed; + border: none; + border-radius: 3px; + position: absolute; + display: block; + top: 0px; + left: 0px; + width: 0px; + height: 100%; +} +.edit_mode div.cell.selected:before { + background: #ffffff; + border: none; + border-radius: 3px; + position: absolute; + display: block; + top: 0px; + left: 0px; + width: 0px; + height: 100%; +} +div.cell.code_cell .input { + border-left: 5px solid #ededed !important; + border-radius: 3px; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +div.cell.code_cell.selected .input { + border-left: 5px solid #ff7823 !important; + border-radius: 3px; +} +.edit_mode div.cell.code_cell.selected .input { + border-left: 5px solid #ffd5bb !important; + border-radius: 3px; +} +div.cell.selected:before, +div.cell.selected.jupyter-soft-selected:before { + position: absolute; + display: block; + top: -1px; + left: -1px; + width: 5px; + height: calc(102%); + content: ''; + background: transparent !important; +} +div.cell.jupyter-soft-selected, +div.cell.selected.jupyter-soft-selected { + border-left-color: #ffd5bb !important; + border-left-width: 0px !important; + padding-left: 7px !important; + border-right-color: #ffd5bb !important; + border-right-width: 0px !important; + background: #ffd5bb !important; + border-radius: 6px !important; +} +div.cell.selected.jupyter-soft-selected .input { + border-left: 5px solid #ededed !important; +} +div.cell.selected.jupyter-soft-selected:before, +.edit_mode div.cell.selected:before .input { + background: #ffd5bb !important; + border: 2px solid #ffd5bb !important; + border-radius: 6px !important; + position: absolute !important; + display: block !important; + top: 0px !important; + left: 0px !important; + width: 6px !important; + height: 100% !important; +} +div.cell.selected.jupyter-soft-selected { + border-left-color: #ff7823; + border-color: #ffffff; + padding-left: 7px; + border-radius: 6px; +} +div.cell.code_cell.selected .input { + border-left: none; + border-radius: 3px; +} +div.cell.selected.jupyter-soft-selected .prompt, +div.cell.text_cell.selected.jupyter-soft-selected .prompt { + top: 0; + border-left: #ededed !important; + border-radius: 2px; +} +div.cell.text_cell.selected.jupyter-soft-selected .input_prompt { + border-left: none !important; +} +div.cell.text_cell.selected.jupyter-soft-selected:before { + background: #f2f2f2 !important; + border: 2px solid #f2f2f2 !important; + border-radius: 6px !important; + position: absolute !important; + display: block !important; + top: 0px !important; + left: 0px !important; + width: 6px !important; + height: 100% !important; +} +div.cell.text_cell.jupyter-soft-selected, +div.cell.text_cell.selected.jupyter-soft-selected { + border-left-color: #f2f2f2 !important; + border-left-width: 0px !important; + padding-left: 7px !important; + border-right-color: #f2f2f2 !important; + border-right-width: 0px !important; + background: #f2f2f2 !important; + border-radius: 6px !important; +} +div.prompt, +.prompt { + font-family: monospace, monospace; + font-size: 9pt !important; + font-weight: normal; + color: #828892; + line-height: 170%; + padding: 0px; + padding-top: 4px; + padding-left: 0px; + padding-right: 1px; + text-align: right !important; + min-width: 12.5ex !important; + width: 12.5ex !important; +} +div.prompt.input_prompt { + font-size: 9pt !important; + background-color: #ededed; + border-top: 0px; + border-top-right-radius: 0px; + border-bottom-left-radius: 0px; + border-bottom-right-radius: 0px; + padding-right: 3px; + min-width: 12.5ex; + width: 12.5ex !important; +} +div.cell.code_cell .input_prompt { + border-right: 2px solid rgba(240,147,43,.50); +} +div.cell.selected .prompt { + top: 0; +} +.edit_mode div.cell.selected .prompt { + top: 0; +} +.edit_mode div.cell.selected .prompt { + top: 0; +} +div.output_wrapper { + background-color: #ffffff; + border: 0px; + left: 0px; + margin-bottom: 0em; + margin-top: 0em; + border-top-right-radius: 0px; + border-top-left-radius: 0px; +} +div.output_subarea.output_text.output_stream.output_stdout, +div.output_subarea.output_text { + font-family: monospace, monospace; + font-size: 8.5pt !important; + line-height: 150% !important; + background-color: #ffffff; + color: #303030; + border-top-right-radius: 0px; + border-top-left-radius: 0px; +} +div.output_area pre { + font-family: monospace, monospace; + font-size: 8.5pt !important; + line-height: 151% !important; + color: #303030; + border-top-right-radius: 0px; + border-top-left-radius: 0px; +} +div.output_area { + display: -webkit-box; +} +div.output_html { + font-family: monospace, monospace; + font-size: 8.5pt; + color: #353535; + background-color: #ffffff; + background: #ffffff; +} +div.output_subarea { + overflow-x: auto; + padding: 0.8em !important; + -webkit-box-flex: 1; + -moz-box-flex: 1; + box-flex: 1; + flex: 1; +} +div.btn.btn-default.output_collapsed { + background: #d7d7d7; + background-color: #d7d7d7; + border-color: #d7d7d7; +} +div.btn.btn-default.output_collapsed:hover { + background: #d2d2d2; + background-color: #d2d2d2; + border-color: #d2d2d2; +} +div.prompt.output_prompt { + font-family: monospace, monospace; + font-size: 9.5pt !important; + font-weight: bold !important; + background-color: #ffffff; + color: transparent; + border-bottom-left-radius: 4px; + border-top-right-radius: 0px; + border-top-left-radius: 0px; + border-bottom-right-radius: 0px; + min-width: 12.5ex !important; + width: 12.5ex !important; + border-right: 2px solid transparent; +} +div.out_prompt_overlay.prompt { + font-family: monospace, monospace; + font-size: 9.5pt !important; + font-weight: bold !important; + background-color: #ffffff; + border-bottom-left-radius: 2px; + border-top-right-radius: 0px; + border-top-left-radius: 0px; + border-bottom-right-radius: 0px; + min-width: 12.5ex !important; + width: 12.5ex !important; + border-right: 2px solid transparent; + color: transparent; +} +div.out_prompt_overlay.prompt:hover { + background-color: #f7f7f7; + box-shadow: none !important; + border: none; + border-bottom-left-radius: 2px; + -webkit-border-: 2px; + -moz-border-radius: 2px; + border-top-right-radius: 0px; + border-top-left-radius: 0px; + min-width: 12.5ex !important; + width: 12.5ex !important; + border-right: 2px solid #f7f7f7 !important; +} +div.cell.code_cell .output_prompt { + border-right: 2px solid transparent; + color: transparent; +} +div.cell.selected .output_prompt, +div.cell.selected .out_prompt_overlay.prompt { + border-left: 5px solid #f2f2f2; + border-right: 2px solid #ffffff; + border-radius: 0px !important; +} +.edit_mode div.cell.selected .output_prompt, +.edit_mode div.cell.selected .out_prompt_overlay.prompt { + border-left: 5px solid #f2f2f2; + border-right: 2px solid #ffffff; + border-radius: 0px !important; +} +div.text_cell, +div.text_cell_render pre, +div.text_cell_render { + font-family: sans-serif; + font-size: 13pt; + line-height: 130% !important; + color: #353535; + background: #ffffff; + background-color: #ffffff; + border-radius: 0px; +} +div .text_cell_render { + padding: 0.4em 0.4em 0.4em 0.4em; +} +div.cell.text_cell .CodeMirror-lines { + padding-top: .7em !important; + padding-bottom: .4em !important; + padding-left: .5em !important; + padding-right: .5em !important; + margin-top: .4em; + margin-bottom: .3em; +} +div.cell.text_cell.unrendered div.input_area, +div.cell.text_cell.rendered div.input_area { + background-color: #ffffff; + background: #ffffff; + border: 0px; + border-radius: 2px; +} +div.cell.text_cell .CodeMirror, +div.cell.text_cell .CodeMirror pre { + line-height: 170% !important; +} +div.cell.text_cell.rendered.selected { + font-family: sans-serif; + line-height: 170% !important; + background: #ffffff; + background-color: #ffffff; + border-radius: 0px; +} +div.cell.text_cell.unrendered.selected { + font-family: sans-serif; + line-height: 170% !important; + background: #ffffff; + background-color: #ffffff; + border-radius: 0px; +} +div.cell.text_cell.selected { + font-family: sans-serif; + line-height: 170% !important; + background: #ffffff; + background-color: #ffffff; + border-radius: 0px; +} +.edit_mode div.cell.text_cell.selected { + font-family: sans-serif; + line-height: 170% !important; + background: #ffffff; + background-color: #ffffff; + border-radius: 0px; +} +div.text_cell.unrendered, +div.text_cell.unrendered.selected, +div.edit_mode div.text_cell.unrendered { + font-family: sans-serif; + line-height: 170% !important; + background: #ffffff; + background-color: #ffffff; + border-radius: 0px; +} +div.cell.text_cell.selected:before { + background: #f2f2f2; + border: 2px solid #f2f2f2; + border-top-left-radius: 2px; + border-bottom-left-radius: 2px; + position: absolute; + display: block; + top: 0px; + left: 0px; + width: 5px; + height: 100%; +} +.edit_mode div.cell.text_cell.selected:before { + background: #f2f2f2; + border: 2px solid #f2f2f2; + border-top-left-radius: 2px; + border-bottom-left-radius: 2px; + position: absolute; + display: block; + top: 0px; + left: 0px; + width: 5px; + height: 100%; +} +div.cell.text_cell .prompt { + border-right: 0; +} +div.cell.text_cell.rendered .prompt { + font-family: monospace, monospace; + font-size: 9.5pt; + font-weight: normal; + color: #828892 !important; + text-align: right !important; + min-width: 12.5ex !important; + width: 12.5ex !important; + background-color: #ffffff; + border-right: 2px solid transparent; + border-left: 5px solid #ffffff; +} +div.cell.text_cell.unrendered .prompt { + font-family: monospace, monospace; + font-size: 9.5pt; + font-weight: normal; + color: #828892 !important; + text-align: right !important; + min-width: 12.5ex !important; + width: 12.5ex !important; + border-right: 2px solid transparent; + border-left: 5px solid #ffffff; +} +div.cell.text_cell.rendered .prompt { + border-right: 2px solid transparent; +} +div.cell.text_cell.rendered.selected .prompt { + top: 0; + border-left: 5px solid #f2f2f2; + border-right: 2px solid transparent; +} +div.text_cell.unrendered.selected .prompt { + top: 0; + background: #ffffff; + border-left: 5px solid #f2f2f2; + border-right: 2px solid transparent; +} +div.rendered_html code { + font-family: monospace, monospace; + font-size: 11pt; + padding-top: 3px; + padding-left: 2px; + color: #303030; + background: #efefef; + background-color: #efefef; +} +pre, +code, +kbd, +samp { + white-space: pre-wrap; +} +.well code, +code { + font-family: monospace, monospace; + font-size: 11pt !important; + line-height: 170% !important; + color: #353535; + background: #efefef; + background-color: #efefef; + border-color: #efefef; +} +kbd { + padding: 1px; + font-size: 11pt; + font-weight: 800; + color: #303030; + background-color: transparent !important; + border: 0; + box-shadow: none; +} +pre { + display: block; + padding: 8.5px; + margin: 0 0 9px; + font-size: 12.0pt; + line-height: 1.42857143; + color: #303030; + background-color: #efefef; + border: 1px solid #e7e7e7; + border-radius: 2px; +} +div.rendered_html { + color: #353535; +} +.rendered_html * + ul { + margin-top: .4em; + margin-bottom: .3em; +} +.rendered_html * + p { + margin-top: .5em; + margin-bottom: .5em; +} +div.rendered_html pre { + font-family: monospace, monospace; + font-size: 11pt !important; + line-height: 170% !important; + color: #353535; + background: #efefef; + background-color: #efefef; + max-width: 80%; + border-radius: 0px; + border-left: 3px solid #efefef; + max-width: 80%; + border-radius: 0px; + padding-left: 5px; + margin-left: 6px; +} +div.text_cell_render pre, +div.text_cell_render code { + font-family: monospace, monospace; + font-size: 11pt !important; + line-height: 170% !important; + color: #353535; + background: #ffffff; + background-color: #ffffff; + max-width: 80%; + border-radius: 0px; + border-left: none; +} +div.text_cell_render pre { + border-left: 3px solid rgba(240,147,43,.50) !important; + max-width: 80%; + border-radius: 0px; + padding-left: 5px; + margin-left: 6px; +} +div.text_cell_render h1, +div.rendered_html h1, +div.text_cell_render h2, +div.rendered_html h2, +div.text_cell_render h3, +div.rendered_html h3, +div.text_cell_render h4, +div.rendered_html h4, +div.text_cell_render h5, +div.rendered_html h5 { + font-family: sans-serif; + margin: 0.4em .2em .3em .2em !important; +} +.rendered_html h1:first-child, +.rendered_html h2:first-child, +.rendered_html h3:first-child, +.rendered_html h4:first-child, +.rendered_html h5:first-child, +.rendered_html h6:first-child { + margin-top: 0.2em !important; + margin-bottom: 0.2em !important; +} +.rendered_html h1, +.text_cell_render h1 { + color: #126dce; + font-size: 200%; + text-align: center; + font-style: normal; + font-weight: lighter; +} +.rendered_html h2, +.text_cell_render h2 { + text-align: left; + font-size: 170%; + color: #3f3d46; + font-style: normal; + font-weight: lighter; +} +.rendered_html h3, +.text_cell_render h3 { + font-size: 140%; + color: #3f3d46; + font-style: normal; + font-weight: lighter; +} +.rendered_html h4, +.text_cell_render h4 { + font-size: 110%; + color: #3f3d46; + font-style: normal; + font-weight: lighter; +} +.rendered_html h5, +.text_cell_render h5 { + font-size: 100%; + color: #2f2f2f; + font-style: normal; + font-weight: lighter; +} +hr { + margin-top: 8px; + margin-bottom: 10px; + border: 0; + border-top: 1px solid #126dce; +} +.rendered_html hr { + color: #126dce; + background-color: #126dce; + margin-right: 2em; +} +#complete > select > option:hover { + background: #d4d4d4; + background-color: #d4d4d4; +} +div#_vivaldi-spatnav-focus-indicator._vivaldi-spatnav-focus-indicator { + position: absolute; + z-index: 9999999999; + top: 0px; + left: 0px; + box-shadow: none; + pointer-events: none; + border-radius: 2px; +} +.rendered_html tr, +.rendered_html th, +.rendered_html td { + text-align: left; + vertical-align: middle; + padding: 0.42em 0.47em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} +.rendered_html td { + font-family: sans-serif !important; + font-size: 9.3pt; +} +.rendered_html table { + font-family: sans-serif !important; + margin-left: 8px; + margin-right: auto; + border: none; + border-collapse: collapse; + border-spacing: 0; + color: #353535; + table-layout: fixed; +} +.rendered_html thead { + font-family: sans-serif !important; + font-size: 10.3pt !important; + background: #ebebeb; + color: #353535; + border-bottom: 1px solid #ebebeb; + vertical-align: bottom; +} +.rendered_html tbody tr:nth-child(odd) { + background: #fafafa; +} +.rendered_html tbody tr { + background: #f2f2f2; +} +.rendered_html tbody tr:hover:nth-child(odd) { + background: #f7f7f7; +} +.rendered_html tbody tr:hover { + background: #f0f0f0; +} +.rendered_html * + table { + margin-top: .05em; +} +div.widget-area { + background-color: #ffffff; + background: #ffffff; + color: #303030; +} +div.widget-area a { + font-family: sans-serif; + font-size: 12.0pt; + font-weight: normal; + font-style: normal; + color: #303030; + text-shadow: none !important; +} +div.widget-area a:hover, +div.widget-area a:focus { + font-family: sans-serif; + font-size: 12.0pt; + font-weight: normal; + font-style: normal; + color: #2f2f2f; + background: rgba(180,180,180,.14); + background-color: rgba(180,180,180,.14); + border-color: transparent; + background-image: none; + text-shadow: none !important; +} +div.widget_item.btn-group > button.btn.btn-default.widget-combo-btn, +div.widget_item.btn-group > button.btn.btn-default.widget-combo-btn:hover { + background: #e1e1e1; + background-color: #e1e1e1; + border: 2px solid #e1e1e1 !important; + font-size: inherit; + z-index: 0; +} +div.jupyter-widgets.widget-hprogress.widget-hbox { + display: inline-table !important; + width: 38% !important; + margin-left: 10px; +} +div.jupyter-widgets.widget-hprogress.widget-hbox .widget-label, +div.widget-hbox .widget-label, +.widget-hbox .widget-label, +.widget-inline-hbox .widget-label, +div.widget-label { + text-align: -webkit-auto !important; + margin-left: 15px !important; + max-width: 240px !important; + min-width: 100px !important; + vertical-align: text-top !important; + color: #303030 !important; + font-size: 14px !important; +} +.widget-hprogress .progress { + flex-grow: 1; + height: 20px; + margin-top: auto; + margin-left: 12px; + margin-bottom: auto; + width: 300px; +} +.progress { + overflow: hidden; + height: 22px; + margin-bottom: 10px; + padding-left: 10px; + background-color: #d6d6d6 !important; + border-radius: 2px; + -webkit-box-shadow: none; + box-shadow: none; + z-index: 10; +} +.progress-bar-danger { + background-color: #e5344a !important; +} +.progress-bar-info { + background-color: #2980b9 !important; +} +.progress-bar-warning { + background-color: #f39c12 !important; +} +.progress-bar-success { + background-color: #5cb85c !important; +} +.widget-select select { + margin-left: 12px; +} +.rendered_html :link { + font-family: sans-serif; + font-size: 100%; + color: #ff7823; + text-decoration: underline; +} +.rendered_html :visited, +.rendered_html :visited:active, +.rendered_html :visited:focus { + color: #fa853d; +} +.rendered_html :visited:hover, +.rendered_html :link:hover { + font-family: sans-serif; + font-size: 100%; + color: #f96000; +} +div.cell.text_cell a.anchor-link:link { + font-size: inherit; + text-decoration: none; + padding: 0px 20px; + visibility: none; + color: rgba(0,0,0,.32); +} +div.cell.text_cell a.anchor-link:link:hover { + font-size: inherit; + color: #828892; +} +.navbar-text { + margin-top: 4px; + margin-bottom: 0px; +} +#clusters > a { + color: #ef5c00; + text-decoration: underline; + cursor: auto; +} +#clusters > a:hover { + color: #126dce; + text-decoration: underline; + cursor: auto; +} +#nbextensions-configurator-container > div.row.container-fluid.nbext-selector > h3 { + font-size: 17px; + margin-top: 5px; + margin-bottom: 8px; + height: 24px; + padding: 4px 0 4px 0; +} +div#nbextensions-configurator-container.container, +#nbextensions-configurator-container.container { + width: 100%; + margin-right: auto; + margin-left: auto; +} +div.nbext-selector > nav > .nav > li > a { + font-family: sans-serif; + font-size: 10.5pt; + padding: 2px 5px; +} +div.nbext-selector > nav > .nav > li > a:hover { + background: transparent; +} +div.nbext-selector > nav > .nav > li:hover { + background-color: rgba(180,180,180,.14) !important; + background: rgba(180,180,180,.14) !important; +} +div.nbext-selector > nav > .nav > li.active:hover { + background: transparent !important; + background-color: transparent !important; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:active, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #1c1c1c; + background-color: rgba(180,180,180,.14) !important; + background: rgba(180,180,180,.14) !important; + -webkit-backface-visibility: hidden; + -webkit-font-smoothing: subpixel-antialiased !important; +} +div.nbext-readme > .nbext-readme-contents > .rendered_html { + font-family: sans-serif; + font-size: 11.5pt; + line-height: 145%; + padding: 1em 1em; + color: #353535; + background-color: #ffffff; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} +.nbext-icon, +.nbext-desc, +.nbext-compat-div, +.nbext-enable-btns, +.nbext-params { + margin-bottom: 8px; + font-size: 11.5pt; +} +div.nbext-readme > .nbext-readme-contents { + padding: 0; + overflow-y: hidden; +} +div.nbext-readme > .nbext-readme-contents:not(:empty) { + margin-top: 0.5em; + margin-bottom: 2em; + border: none; + border-top-color: #828892; +} +.nbext-showhide-incompat { + padding-bottom: 0.5em; + color: #4a4a4a; + font-size: 10.5pt; +} +.nbext-filter-menu.dropdown-menu > li > a:hover, +.nbext-filter-menu.dropdown-menu > li > a:focus, +.nbext-filter-menu.dropdown-menu > li > a.ui-state-focus { + color: #2f2f2f !important; + background-color: #d4d4d4 !important; + background: #d4d4d4 !important; + border-color: #d4d4d4 !important; +} +.nbext-filter-input-wrap > .nbext-filter-input-subwrap, +.nbext-filter-input-wrap > .nbext-filter-input-subwrap > input { + border: none; + outline: none; + background-color: transparent; + padding: 0; + vertical-align: middle; + margin-top: -2px; +} +span.rendered_html code { + background-color: transparent; + color: #303030; +} +#nbextensions-configurator-container > div.row.container-fluid.nbext-selector { + padding-left: 0px; + padding-right: 0px; +} +.nbext-filter-menu { + max-height: 50vh; + overflow-y: auto; + outline: none; + border: 2px solid #dedede; +} +.nbext-filter-menu:hover { + border: 2px solid #dedede; +} +.alert-warning { + background-color: #f4f4f4; + border-color: #f4f4f4; + color: #303030; +} +.notification_widget.danger { + color: #ffffff; + background-color: #e5344a; + border-color: #e5344a; + padding-right: 5px; +} +#nbextensions-configurator-container > div.nbext-buttons.tree-buttons.no-padding.pull-right > span > button { + border: none !important; +} +button#refresh_running_list { + border: none !important; +} +mark, +.mark { + background-color: #ffffff; + color: #353535; + padding: .15em; +} +a.text-warning, +a.text-warning:hover { + color: #828892; +} +a.text-warning.bg-warning { + background-color: #ffffff; +} +span.bg-success.text-success { + background-color: transparent; + color: #009e07; +} +span.bg-danger.text-danger { + background-color: #ffffff; + color: #de143d; +} +.has-success .input-group-addon { + color: #009e07; + border-color: transparent; + background: inherit; + background-color: rgba(83,180,115,.10); +} +.has-success .form-control { + border-color: #009e07; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.025); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.025); +} +.has-error .input-group-addon { + color: #de143d; + border-color: transparent; + background: inherit; + background-color: rgba(192,57,67,.10); +} +.has-error .form-control { + border-color: #de143d; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.025); + box-shadow: inset 0 1px 1px rgba(0,0,0,0.025); +} +.kse-input-group-pretty > kbd { + font-family: monospace, monospace; + color: #303030; + font-weight: normal; + background: transparent; +} +.kse-input-group-pretty > kbd { + font-family: monospace, monospace; + color: #303030; + font-weight: normal; + background: transparent; +} +div.nbext-enable-btns .btn[disabled], +div.nbext-enable-btns .btn[disabled]:hover, +.btn-default.disabled, +.btn-default[disabled] { + background: #e2e2e2; + background-color: #e2e2e2; + color: #282828; +} +label#Keyword-Filter { + display: none; +} +.input-group .nbext-list-btn-add, +.input-group-btn:last-child > .btn-group > .btn { + background: #e4e4e4; + background-color: #e4e4e4; + border-color: #e4e4e4; + border: 2px solid #e4e4e4; +} +.input-group .nbext-list-btn-add:hover, +.input-group-btn:last-child > .btn-group > .btn:hover { + background: #dfdfdf; + background-color: #dfdfdf; + border-color: #dfdfdf; + border: 2px solid #dfdfdf; +} +#notebook-container > div.cell.code_cell.rendered.selected > div.widget-area > div.widget-subarea > div > div.widget_item.btn-group > button.btn.btn-default.dropdown-toggle.widget-combo-carrot-btn { + background: #e4e4e4; + background-color: #e4e4e4; + border-color: #e4e4e4; +} +#notebook-container > div.cell.code_cell.rendered.selected > div.widget-area > div.widget-subarea > div > div.widget_item.btn-group > button.btn.btn-default.dropdown-toggle.widget-combo-carrot-btn:hover { + background: #dfdfdf; + background-color: #dfdfdf; + border-color: #dfdfdf; +} +.ui-widget-content { + background: #e5e5e5; + background-color: #e5e5e5; + border: 2px solid #e5e5e5; + color: #303030; +} +div.collapsible_headings_toggle { + color: rgba(180,180,180,.30) !important; +} +div.collapsible_headings_toggle:hover { + color: #ff7823 !important; +} +.collapsible_headings_toggle .h1, +.collapsible_headings_toggle .h2, +.collapsible_headings_toggle .h3, +.collapsible_headings_toggle .h4, +.collapsible_headings_toggle .h5, +.collapsible_headings_toggle .h6 { + margin: 0.3em .4em 0em 0em !important; + line-height: 1.2 !important; +} +div.collapsible_headings_toggle .fa-caret-down:before, +div.collapsible_headings_toggle .fa-caret-right:before { + font-size: xx-large; + transition: transform 1000ms; + transform: none !important; +} +.collapsible_headings_collapsed.collapsible_headings_ellipsis .rendered_html h1:after, +.collapsible_headings_collapsed.collapsible_headings_ellipsis .rendered_html h2:after, +.collapsible_headings_collapsed.collapsible_headings_ellipsis .rendered_html h3:after, +.collapsible_headings_collapsed.collapsible_headings_ellipsis .rendered_html h4:after, +.collapsible_headings_collapsed.collapsible_headings_ellipsis .rendered_html h5:after, +.collapsible_headings_collapsed.collapsible_headings_ellipsis .rendered_html h6:after { + position: absolute; + right: 0; + bottom: 20% !important; + content: "[\002026]"; + color: rgba(180,180,180,.30) !important; + padding: 0.5em 0em 0em 0em !important; +} +.collapsible_headings_ellipsis .rendered_html h1, +.collapsible_headings_ellipsis .rendered_html h2, +.collapsible_headings_ellipsis .rendered_html h3, +.collapsible_headings_ellipsis .rendered_html h4, +.collapsible_headings_ellipsis .rendered_html h5, +.collapsible_headings_ellipsis .rendered_html h6, +.collapsible_headings_toggle .fa { + transition: transform 1000ms !important; + -webkit-transform: inherit !important; + -moz-transform: inherit !important; + -ms-transform: inherit !important; + -o-transform: inherit !important; + transform: inherit !important; + padding-right: 0px !important; +} +input.raw_input { + font-family: monospace, monospace; + font-size: 11pt !important; + color: #303030; + background-color: #efefef; + border-color: #ececec; + background: #ececec; + width: auto; + vertical-align: baseline; + padding: 0em 0.25em; + margin: 0em 0.25em; + -webkit-box-shadow: none; + box-shadow: none; +} +audio, +video { + display: inline; + vertical-align: middle; + align-content: center; + margin-left: 20%; +} +.cmd-palette .modal-body { + padding: 0px; + margin: 0px; +} +.cmd-palette form { + background: #e5e5e5; + background-color: #e5e5e5; +} +.typeahead-field input:last-child, +.typeahead-hint { + background: #e5e5e5; + background-color: #e5e5e5; + z-index: 1; +} +.typeahead-field input { + font-family: sans-serif; + color: #303030; + border: none; + font-size: 28pt; + display: inline-block; + line-height: inherit; + padding: 3px 10px; + height: 70px; +} +.typeahead-select { + background-color: #e5e5e5; +} +body > div.modal.cmd-palette.typeahead-field { + display: table; + border-collapse: separate; + background-color: #f4f4f4; +} +.typeahead-container button { + font-family: sans-serif; + font-size: 28pt; + background-color: #e4e4e4; + border: none; + display: inline-block; + line-height: inherit; + padding: 3px 10px; + height: 70px; +} +.typeahead-search-icon { + min-width: 40px; + min-height: 55px; + display: block; + vertical-align: middle; + text-align: center; +} +.typeahead-container button:focus, +.typeahead-container button:hover { + color: #2f2f2f; + background-color: #dfdfdf; + border-color: #e0e0e0; +} +.typeahead-list > li.typeahead-group.active > a, +.typeahead-list > li.typeahead-group > a, +.typeahead-list > li.typeahead-group > a:focus, +.typeahead-list > li.typeahead-group > a:hover { + display: none; +} +.typeahead-dropdown > li > a, +.typeahead-list > li > a { + color: #303030; + text-decoration: none; +} +.typeahead-dropdown, +.typeahead-list { + font-family: sans-serif; + font-size: 13pt; + color: #303030; + background-color: #ffffff; + border: none; + background-clip: padding-box; + margin-top: 0px; + padding: 3px 2px 3px 0px; + line-height: 1.7; +} +.typeahead-dropdown > li.active > a, +.typeahead-dropdown > li > a:focus, +.typeahead-dropdown > li > a:hover, +.typeahead-list > li.active > a, +.typeahead-list > li > a:focus, +.typeahead-list > li > a:hover { + color: #2f2f2f; + background-color: #f4f4f4; + border-color: #f4f4f4; +} +.command-shortcut:before { + content: "(command)"; + padding-right: 3px; + color: #828892; +} +.edit-shortcut:before { + content: "(edit)"; + padding-right: 3px; + color: #828892; +} +ul.typeahead-list i { + margin-left: 1px; + width: 18px; + margin-right: 10px; +} +ul.typeahead-list { + max-height: 50vh; + overflow: auto; +} +.typeahead-list > li { + position: relative; + border: none; +} +div.input.typeahead-hint, +input.typeahead-hint, +body > div.modal.cmd-palette.in > div > div > div > form > div > div.typeahead-field > span.typeahead-query > input.typeahead-hint { + color: #828892 !important; + background-color: transparent; + padding: 3px 10px; +} +.typeahead-dropdown > li > a, +.typeahead-list > li > a { + display: block; + padding: 5px; + clear: both; + font-weight: 400; + line-height: 1.7; + border: 1px solid #ffffff; + border-bottom-color: rgba(180,180,180,.30); +} +body > div.modal.cmd-palette.in > div { + min-width: 750px; + margin: 150px auto; +} +.typeahead-container strong { + font-weight: bolder; + color: #ff7823; +} +#find-and-replace #replace-preview .match, +#find-and-replace #replace-preview .insert { + color: #ffffff; + background-color: #ff7823; + border-color: #ff7823; + border-style: solid; + border-width: 1px; + border-radius: 0px; +} +#find-and-replace #replace-preview .replace .match { + background-color: #de143d; + border-color: #de143d; + border-radius: 0px; +} +#find-and-replace #replace-preview .replace .insert { + background-color: #009e07; + border-color: #009e07; + border-radius: 0px; +} +.shortcut_key, +span.shortcut_key { + display: inline-block; + width: 16ex; + text-align: right; + font-family: monospace; +} +.jupyter-keybindings { + padding: 1px; + line-height: 24px; + border-bottom: 1px solid rgba(180,180,180,.14); +} +.jupyter-keybindings i { + background: #efefef; + font-size: small; + padding: 5px; + margin-left: 7px; +} +div#short-key-bindings-intro.well, +.well { + background-color: #e4e4e4; + border: 1px solid #e4e4e4; + color: #303030; + border-radius: 2px; + -webkit-box-shadow: none; + box-shadow: none; +} +#texteditor-backdrop { + background: #ffffff; + background-color: #ffffff; +} +#texteditor-backdrop #texteditor-container .CodeMirror-gutter, +#texteditor-backdrop #texteditor-container .CodeMirror-gutters { + background: #e0e1e3; + background-color: #e0e1e3; + color: #828892; +} +.edit_app #menubar .navbar { + margin-bottom: 0px; +} +#texteditor-backdrop #texteditor-container { + padding: 0px; + background-color: #ededed; + box-shadow: none; +} +.terminal-app { + background: #ffffff; +} +.terminal-app .terminal { + font-family: monospace, monospace; + font-size: 11pt; + line-height: 170%; + color: #303030; + background: #ededed; + padding: 0.4em; + border-radius: 2px; + -webkit-box-shadow: none; + box-shadow: none; +} +.terminal .xterm-viewport { + background-color: #ededed; + color: #303030; + overflow-y: auto; +} +.terminal .xterm-color-0 { + color: #ff7823; +} +.terminal .xterm-color-1 { + color: #de143d; +} +.terminal .xterm-color-2 { + color: #713bc5; +} +.terminal .xterm-color-3 { + color: #e22978; +} +.terminal .xterm-color-4 { + color: #ff8132; +} +.terminal .xterm-color-5 { + color: #009e07; +} +.terminal .xterm-color-6 { + color: #e22978; +} +.terminal .xterm-color-7 { + color: #e22978; +} +.terminal .xterm-color-8 { + color: #ef5c00; +} +.terminal .xterm-color-9 { + color: #009e07; +} +.terminal .xterm-color-10 { + color: #e22978; +} +.terminal .xterm-color-14 { + color: #e22978; +} +.terminal .xterm-bg-color-15 { + background-color: #ededed; +} +.terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { + background-color: #ff7823; + color: #ededed; +} +.terminal:not(.focus) .terminal-cursor { + outline: 1px solid #ff7823; + outline-offset: -1px; +} +.celltoolbar { + font-size: 100%; + padding-top: 3px; + border-color: transparent; + border-bottom: thin solid #828892; + background: transparent; +} +.cell-tag, +.tags-input input, +.tags-input button { + color: #303030; + background-color: #ffffff; + background-image: none; + border: 1px solid #303030; + border-radius: 1px; + box-shadow: none; + width: inherit; + font-size: inherit; + height: 22px; + line-height: 22px; +} +#notebook-container > div.cell.code_cell.rendered.selected > div.input > div.inner_cell > div.ctb_hideshow.ctb_show > div > div > button, +#notebook-container > div.input > div.inner_cell > div.ctb_hideshow.ctb_show > div > div > button { + font-size: 10pt; + color: #303030; + background-color: #ffffff; + background-image: none; + border: 1px solid #303030; + border-radius: 1px; + box-shadow: none; + width: inherit; + font-size: inherit; + height: 22px; + line-height: 22px; +} +div#pager #pager-contents { + background: #ffffff !important; + background-color: #ffffff !important; +} +div#pager pre { + color: #303030 !important; + background: #ededed !important; + background-color: #ededed !important; + padding: 0.4em; +} +div#pager .ui-resizable-handle { + top: 0px; + height: 8px; + background: #ff7823 !important; + border-top: 1px solid #ff7823; + border-bottom: 1px solid #ff7823; +} +div.CodeMirror, +div.CodeMirror pre { + font-family: monospace, monospace; + font-size: 11pt; + line-height: 170%; + color: #303030; +} +div.CodeMirror-lines { + padding-bottom: .9em; + padding-left: .5em; + padding-right: 1.5em; + padding-top: .7em; +} +span.ansiblack, +.ansi-black-fg { + color: #e22978; +} +span.ansiblue, +.ansi-blue-fg, +.ansi-blue-intense-fg { + color: #009e07; +} +span.ansigray, +.ansi-gray-fg, +.ansi-gray-intense-fg { + color: #ff8132; +} +span.ansigreen, +.ansi-green-fg { + color: #333333; +} +.ansi-green-intense-fg { + color: #ff8132; +} +span.ansipurple, +.ansi-purple-fg, +.ansi-purple-intense-fg { + color: #653bc5; +} +span.ansicyan, +.ansi-cyan-fg, +.ansi-cyan-intense-fg { + color: #653bc5; +} +span.ansiyellow, +.ansi-yellow-fg, +.ansi-yellow-intense-fg { + color: #ff8132; +} +span.ansired, +.ansi-red-fg, +.ansi-red-intense-fg { + color: #de143d; +} +div.output-stderr { + background-color: #ebb5b7; +} +div.output-stderr pre { + color: #000000; +} +div.js-error { + color: #de143d; +} +.ipython_tooltip { + font-family: monospace, monospace; + font-size: 11pt; + line-height: 170%; + border: 2px solid #dadada; + background: #eeeeee; + background-color: #eeeeee; + border-radius: 2px; + overflow-x: visible; + overflow-y: visible; + box-shadow: none; + position: absolute; + z-index: 1000; +} +.ipython_tooltip .tooltiptext pre { + font-family: monospace, monospace; + font-size: 11pt; + line-height: 170%; + background: #eeeeee; + background-color: #eeeeee; + color: #303030; + overflow-x: visible; + overflow-y: visible; + max-width: 900px; +} +div#tooltip.ipython_tooltip { + overflow-x: wrap; + overflow-y: visible; + max-width: 800px; +} +div.tooltiptext.bigtooltip { + overflow-x: visible; + overflow-y: scroll; + height: 400px; + max-width: 800px; +} +.cm-s-ipython.CodeMirror { + font-family: monospace, monospace; + font-size: 11pt; + background: #ededed; + color: #303030; + border-radius: 2px; + font-style: normal; + font-weight: normal; +} +.cm-s-ipython div.CodeMirror-selected { + background: #e0e1e3; +} +.CodeMirror-gutters { + border: none; + border-right: 1px solid #e0e1e3 !important; + background-color: #e0e1e3 !important; + background: #e0e1e3 !important; + border-radius: 0px; + white-space: nowrap; +} +.cm-s-ipython .CodeMirror-gutters { + background: #e0e1e3; + border: none; + border-radius: 0px; + width: 36px; +} +.cm-s-ipython .CodeMirror-linenumber { + color: #828892; +} +.CodeMirror-sizer { + margin-left: 40px; +} +.CodeMirror-linenumber, +div.CodeMirror-linenumber, +.CodeMirror-gutter.CodeMirror-linenumberdiv.CodeMirror-gutter.CodeMirror-linenumber { + padding-right: 1px; + margin-left: 0px; + margin: 0px; + width: 26px !important; + padding: 0px; + text-align: right; +} +.CodeMirror-linenumber { + color: #828892; +} +.cm-s-ipython .CodeMirror-cursor { + border-left: 2px solid #ff711a !important; +} +.cm-s-ipython span.cm-comment { + color: #8d8d8d; + font-style: italic; +} +.cm-s-ipython span.cm-atom { + color: #055be0; +} +.cm-s-ipython span.cm-number { + color: #ff8132; +} +.cm-s-ipython span.cm-property { + color: #303030; +} +.cm-s-ipython span.cm-attribute { + color: #303030; +} +.cm-s-ipython span.cm-keyword { + color: #713bc5; + font-weight: normal; +} +.cm-s-ipython span.cm-string { + color: #009e07; +} +.cm-s-ipython span.cm-meta { + color: #aa22ff; +} +.cm-s-ipython span.cm-operator { + color: #055be0; +} +.cm-s-ipython span.cm-builtin { + color: #e22978; +} +.cm-s-ipython span.cm-variable { + color: #303030; +} +.cm-s-ipython span.cm-variable-2 { + color: #de143d; +} +.cm-s-ipython span.cm-variable-3 { + color: #aa22ff; +} +.cm-s-ipython span.cm-def { + color: #e22978; + font-weight: normal; +} +.cm-s-ipython span.cm-error { + background: rgba(191,97,106,.40); +} +.cm-s-ipython span.cm-tag { + color: #e22978; +} +.cm-s-ipython span.cm-link { + color: #ef5c00; +} +.cm-s-ipython span.cm-storage { + color: #055be0; +} +.cm-s-ipython span.cm-entity { + color: #e22978; +} +.cm-s-ipython span.cm-quote { + color: #009e07; +} +div.CodeMirror span.CodeMirror-matchingbracket { + color: #1c1c1c; + background-color: rgba(30,112,199,.30); +} +div.CodeMirror span.CodeMirror-nonmatchingbracket { + color: #1c1c1c; + background: rgba(191,97,106,.40) !important; +} +.cm-header-1 { + font-size: 215%; +} +.cm-header-2 { + font-size: 180%; +} +.cm-header-3 { + font-size: 150%; +} +.cm-header-4 { + font-size: 120%; +} +.cm-header-5 { + font-size: 100%; +} +.cm-s-default .cm-hr { + color: #055be0; +} +div.cell.text_cell .cm-s-default .cm-header { + font-family: sans-serif; + font-weight: normal; + color: #126dce; + margin-top: 0.3em !important; + margin-bottom: 0.3em !important; +} +div.cell.text_cell .cm-s-default span.cm-variable-2 { + color: #353535; +} +div.cell.text_cell .cm-s-default span.cm-variable-3 { + color: #aa22ff; +} +.cm-s-default span.cm-comment { + color: #8d8d8d; +} +.cm-s-default .cm-tag { + color: #009fb7; +} +.cm-s-default .cm-builtin { + color: #e22978; +} +.cm-s-default .cm-string { + color: #009e07; +} +.cm-s-default .cm-keyword { + color: #713bc5; +} +.cm-s-default .cm-number { + color: #ff8132; +} +.cm-s-default .cm-error { + color: #055be0; +} +.cm-s-default .cm-link { + color: #ef5c00; +} +.cm-s-default .cm-atom { + color: #ff8132; +} +.cm-s-default .cm-def { + color: #e22978; +} +.CodeMirror-cursor { + border-left: 2px solid #ff711a !important; + border-right: none; + width: 0; +} +.cm-s-default div.CodeMirror-selected { + background: #e0e1e3; +} +.cm-s-default .cm-selected { + background: #e0e1e3; +} +.MathJax_Display, +.MathJax { + border: 0 !important; + font-size: 100% !important; + text-align: center !important; + margin: 0em !important; + line-height: 2.25 !important; +} +.MathJax:focus, +body :focus .MathJax { + display: inline-block !important; +} +.MathJax:focus, +body :focus .MathJax { + display: inline-block !important; +} +.completions { + position: absolute; + z-index: 110; + overflow: hidden; + border: medium solid rgba(240,147,43,.50); + box-shadow: none; + line-height: 1; +} +.completions select { + background: #ededed; + background-color: #ededed; + outline: none; + border: none; + padding: 0px; + margin: 0px; + margin-left: 2px; + overflow: auto; + font-family: monospace, monospace; + font-size: 11pt; + color: #303030; + width: auto; +} +div#maintoolbar { + display: none !important; +} +#header-container { + display: none !important; +} + + + \ No newline at end of file