├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── bitstation ├── .dockerignore ├── 01.cauldron │ ├── mirrorlist │ ├── mkimage-buildah-minimal.sh │ ├── mkimage-buildah.sh │ └── proxy.sh ├── 02.setup │ ├── 00-install-pkgs.sh │ ├── 00_mpm.conf │ ├── 01-install-dlang.sh │ ├── 01-install-npm.sh │ ├── 01-install-python.sh │ ├── 01-install-r-pkgs.sh │ ├── 01-install-ruby.sh │ ├── 02-docker-setup.sh │ ├── 02-set-password.sh │ ├── 03-install-jupyter.sh │ ├── 04-remove-build-deps.sh │ ├── 05-log-items.sh │ ├── mkimage-buildah.sh │ ├── openssl.cnf │ ├── proxy.sh │ └── system.conf ├── LGPL.md ├── README.md ├── RELEASE.md ├── config │ ├── bitstation │ │ └── docker-compose.yml │ └── demo │ │ └── docker-compose.yml ├── docker-compose.yml ├── package.json ├── test │ └── test-bitstation.py ├── util │ ├── backup.sh │ ├── clone-volume.sh │ ├── containers-shell.sh │ ├── containers.sh │ ├── push-image.sh │ ├── restore.sh │ ├── rm-stopped-containers.sh │ └── rm-untagged-images.sh └── web │ ├── cgi-bin │ ├── README.md │ └── bittrader │ │ ├── bitcoinaverager.py │ │ ├── conf.sh │ │ ├── environment.sh │ │ ├── login.py │ │ ├── manifest.py │ │ ├── model.py │ │ ├── pageset.py │ │ ├── refresh.sh │ │ ├── timezone.sh │ │ └── wiki.sh │ ├── config │ ├── default-init │ │ ├── etc │ │ │ ├── ajenti │ │ │ │ └── config.json │ │ │ ├── httpd │ │ │ │ └── conf │ │ │ │ │ └── sites.d │ │ │ │ │ └── 00_bitquant.conf │ │ │ ├── mongod.conf │ │ │ ├── shiny-server │ │ │ │ └── shiny-server.conf │ │ │ └── sudoers.d │ │ │ │ └── 00_bitquant_sudo │ │ └── usr │ │ │ └── lib │ │ │ └── systemd │ │ │ └── system │ │ │ ├── bitquant.service │ │ │ └── shiny-server.service │ ├── httpd-lock │ │ └── etc │ │ │ └── httpd │ │ │ └── conf │ │ │ └── webapps.d │ │ │ └── 00_bitquant_auth.conf │ ├── httpd-unlock │ │ └── etc │ │ │ └── httpd │ │ │ └── conf │ │ │ └── webapps.d │ │ │ └── 00_bitquant_auth.conf │ ├── user │ │ ├── wiki-init │ │ ├── wiki-lock │ │ └── wiki-unlock │ ├── vimage │ │ ├── etc │ │ │ ├── cloud │ │ │ │ └── cloud.cfg │ │ │ ├── sysconfig │ │ │ │ └── oem │ │ │ └── systemd │ │ │ │ └── system │ │ │ │ └── getty@tty1.service.d │ │ │ │ └── autologin.conf │ │ └── usr │ │ │ └── lib │ │ │ └── systemd │ │ │ └── system │ │ │ └── cloud-init.service │ ├── webmin-init │ │ └── etc │ │ │ └── webmin │ │ │ ├── config │ │ │ └── miniserv.conf │ ├── wiki-init │ │ └── var │ │ │ └── lib │ │ │ └── dokuwiki │ │ │ └── pages │ │ │ ├── about.txt │ │ │ ├── pyconhk2015.txt │ │ │ └── start.txt │ ├── wiki-lock │ │ └── etc │ │ │ └── dokuwiki │ │ │ ├── acl.auth.php │ │ │ ├── local.php │ │ │ └── users.auth.php │ └── wiki-unlock │ │ └── etc │ │ └── dokuwiki │ │ └── local.php │ ├── css │ ├── gh-fork-ribbon.css │ ├── gh-fork-ribbon.ie.css │ ├── metro-bootstrap.css │ ├── metro-dokuwiki.css │ └── style.css │ ├── data │ └── README.txt │ ├── fonts │ ├── metroSysIcons.ttf │ └── metroSysIcons.woff │ ├── index.html │ ├── js │ ├── logout.js │ └── metro │ │ └── metro.min.js │ └── scripts │ ├── ethercalc-data │ └── test.clc │ ├── install-ethercalc.py │ ├── startup-all.sh │ └── startup-user.sh ├── buildbot └── master │ └── master.cfg ├── hardware-hacking ├── dmidecode.txt └── dual-screen.md ├── ldap ├── docker-compose.yml ├── install.sh ├── package.json ├── proxy.sh └── startup.sh ├── nextcloud ├── 00_mpm.conf ├── backup.sh ├── config.php ├── docker-compose.yml ├── install.sh ├── package.json ├── proxy.sh ├── startup-nextcloud.sh ├── system.conf └── wait-for-it.sh ├── online-campus ├── moo │ ├── Dockerfile │ ├── docker-compose.yml │ ├── install-user.sh │ ├── install.sh │ ├── proxy.sh │ └── startup.sh └── moodle │ ├── backup-moodle.sh │ └── docker-compose.yml ├── overleaf └── docker-compose.yml ├── papers ├── article_template.tex ├── financial-products.txt ├── hk-hybrid.txt ├── hkdx.txt ├── its-obor.pdf ├── its-obor.pptx ├── joequant-qr.png ├── macro.bib ├── macro.pdf ├── macro.tex ├── master.txt ├── money-lender │ ├── privacy.txt │ └── references.txt ├── neutrino.tex ├── nyletter.odt ├── nyletter.pdf ├── nyletter.txt └── paper1.tex ├── smart-contracts-2 ├── contract.js ├── disclaimer.txt ├── display.html ├── notice.txt └── viewer.js └── smart-contracts ├── Calculator.js ├── NOTES.md ├── README.md ├── Viewer.js ├── YEARFRAC.js ├── add-js-dependencies.sh ├── calc-contract.js ├── calc-credit.js ├── contract_viewer.html ├── jquery.appendGrid-1.6.2.min.css ├── jquery.appendGrid-1.6.2.min.js ├── jquery.collapse.js ├── make-pkg.sh ├── misc ├── execution-sheet.txt └── warranty.txt ├── models ├── convertible-note-old │ ├── Notes.js │ ├── Parties.js │ └── TermSheet.js ├── convertible-note │ ├── Notes.js │ ├── Parties.js │ ├── TermSheet.js │ └── note.docx ├── credit-line │ ├── Notes.js │ └── TermSheet.js ├── equity-finance │ ├── convertible-note.txt │ └── safe.txt ├── hire-purchase │ ├── Notes.js │ └── TermSheet.js ├── hk-company-secured │ ├── Notes.js │ ├── Parties.js │ └── TermSheet.js ├── hk-money-lender-2 │ ├── Notes.js │ ├── Parties.js │ └── TermSheet.js ├── hk-money-lender │ ├── Notes.js │ ├── Parties.js │ └── TermSheet.js ├── loan │ ├── Notes.js │ └── TermSheet.js ├── profit-share │ ├── Notes.js │ └── TermSheet.js ├── simple-amortized │ ├── Notes.js │ ├── Parties.js │ └── TermSheet.js └── subclass │ ├── Notes.js │ └── TermSheet.js └── node_modules └── moment ├── LICENSE ├── README.md ├── ender.js ├── min └── moment.min.js ├── package.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.log 3 | \#*# 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/.gitmodules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Bitquant Research Laboratories (Asia) Limited 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Bitquant 2 | ================= 3 | 4 | Scripts and installation routines for Bitquant Research Laboratories 5 | (Asia) Ltd. 6 | 7 | If any of this is useful please make a contribution to https://www.patreon.com/user?u=3971025 8 | 9 | 10 | Smart Contract 11 | ============== 12 | 13 | Smart contract is available at 14 | 15 | http://github.com/joequant/bitquant/tree/master/smart-contracts 16 | 17 | Bitstation trading/analytics platform 18 | ===================================== 19 | 20 | Bitstation is a web-based trading/analytics system built on top of 21 | docker. Documentation is located in the bitstation directory. 22 | 23 | The system is in the directory bitstation. Running the system with 24 | the included scripts will run that image on port 80 25 | 26 | 27 | -------------------------------------------------------------------------------- /bitstation/.dockerignore: -------------------------------------------------------------------------------- 1 | /tmp/* 2 | /var/log/* 3 | -------------------------------------------------------------------------------- /bitstation/01.cauldron/proxy.sh: -------------------------------------------------------------------------------- 1 | #: ' 2 | 3 | if timeout 1 bash -c 'cat < /dev/null > /dev/tcp/172.17.0.1/3128' ; then 4 | echo "running proxy" 5 | export http_proxy=http://172.17.0.1:3128/ 6 | export https_proxy=http://172.17.0.1:3128/ 7 | export ftp_proxy=http://172.17.0.1:3128/ 8 | export HTTP_PROXY=http://172.17.0.1:3128/ 9 | #cache with devpi-server 10 | export PIP_INDEX_URL=http://127.0.0.1:3141/root/pypi/+simple/ 11 | #cache with git-cache-http-server 12 | export GIT_PROXY=http://127.0.0.1:8080/ 13 | #cache with verdacchio 14 | export NPM_CONFIG_REGISTRY=http://127.0.0.1:4873/ 15 | export YARN_REGISTRY=http://127.0.0.1:4873/ 16 | #' 17 | fi 18 | -------------------------------------------------------------------------------- /bitstation/02.setup/00_mpm.conf: -------------------------------------------------------------------------------- 1 | # Select the MPM module which should be used by uncommenting exactly 2 | # one of the following LoadModule lines: 3 | 4 | # prefork MPM: Implements a non-threaded, pre-forking web server 5 | # See: http://httpd.apache.org/docs/2.4/mod/prefork.html 6 | #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so 7 | 8 | # worker MPM: Multi-Processing Module implementing a hybrid 9 | # multi-threaded multi-process web server 10 | # See: http://httpd.apache.org/docs/2.4/mod/worker.html 11 | # 12 | #LoadModule mpm_worker_module modules/mod_mpm_worker.so 13 | 14 | # event MPM: A variant of the worker MPM with the goal of consuming 15 | # threads only for connections with active processing 16 | # See: http://httpd.apache.org/docs/2.4/mod/event.html 17 | # 18 | LoadModule mpm_event_module modules/mod_mpm_event.so 19 | 20 | -------------------------------------------------------------------------------- /bitstation/02.setup/01-install-dlang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -v 4 | set -o errexit 5 | 6 | if [ -f $rootfsDir/tmp/proxy.sh ] ; then 7 | source $rootfsDir/tmp/proxy.sh 8 | fi 9 | pushd $rootfsDir/tmp 10 | git clone https://github.com/symmetryinvestments/jupyter-wire.git 11 | git clone https://github.com/joequant/dlang-kernel.git 12 | pushd dlang-kernel 13 | dub build 14 | mv dlang_kernel $rootfsDir/usr/bin 15 | mkdir -p $rootfsDir/usr/share/jupyter/kernels/dlang_kernel 16 | cp kernel.json $rootfsDir/usr/share/jupyter/kernels/dlang_kernel 17 | popd 18 | popd 19 | -------------------------------------------------------------------------------- /bitstation/02.setup/01-install-npm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -v 4 | set +o errexit 5 | 6 | source $rootfsDir/tmp/proxy.sh 7 | npm install -g node-gyp coffeescript typescript 8 | 9 | # livescript 10 | node-gyp -g install 11 | # put yelp_uri in back to override downloaded version 12 | npm install -g --unsafe-perm=true ijavascript --zmq-external 13 | 14 | # use git because of 15 | # https://github.com/nearbydelta/itypescript/issues/20 16 | npm install -g --unsafe-perm=true git+http://github.com/joequant/itypescript.git --zmq-external 17 | npm install -g --unsafe-perm=true jp-coffeescript --zmq-external 18 | npm install -g --unsafe-perm=true git+http://github.com/joequant/jp-livescript.git --zmq-external 19 | npm install -g --unsafe-perm=true jp-babel --zmq-external 20 | npm install -g --unsafe-perm=true configurable-http-proxy solc modclean 21 | 22 | #jp-livescript 23 | 24 | # jupyter --version is breaking installs 25 | # https://github.com/n-riesco/ijavascript/issues/200 26 | # fixed for all but livescript 27 | # 28 | npm i -g --unsafe-perm=true ethercalc 29 | pump --shutdown 30 | -------------------------------------------------------------------------------- /bitstation/02.setup/01-install-r-pkgs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Setup and configure website to use giving configuration 3 | 4 | set -v 5 | echo "Running r installation" 6 | 7 | export PATH=/usr/lib64/R/bin:/usr/lib/R/bin:$PATH 8 | source $rootfsDir/tmp/proxy.sh 9 | 10 | echo "Generating new modules" 11 | R -e "install.packages(c('stringi', 'magrittr', 'devtools', 'crayon', 'pbdZMQ', 'reticulate', 'shiny', 'Quandl','knitr', 'rzmq', 'rmarkdown', 'IRkernel', 'formatR', 'styler'), repos='http://cran.r-project.org/', dependencies=TRUE)" 12 | #/usr/bin/R -e 'options(repos=c(CRAN = "http://cran.r-project.org/")); library(devtools) ; devtools::install_github("rstudio/rmarkdown")' 13 | #/usr/bin/R -e 'options(repos=c(CRAN = "http://cran.r-project.org/")); library(devtools) ; install_github("IRkernel/repr"); devtools::install_github("IRKernel/IRdisplay"); devtools::install_github("IRKernel/IRkernel")' 14 | 15 | pump --shutdown 16 | -------------------------------------------------------------------------------- /bitstation/02.setup/01-install-ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # TODO - fixes 3 | set -v 4 | source $rootfsDir/tmp/proxy.sh 5 | export CPPFLAGS="-Wno-error=deprecated-declarations" 6 | export JUPYTER_DATA_DIR=/usr/share/jupyter 7 | 8 | gem install --no-document ffi -n /usr/bin -i /usr/share/gems -- --with-ldflags="-pthread -ldl" 9 | gem install --no-document ffi-rzmq -n /usr/bin -i /usr/share/gems 10 | 11 | #disable Werror 12 | gem install --no-document iruby -n /usr/bin -i /usr/share/gems --pre 13 | gem install --no-document pry awesome_print gnuplot rubyvis nyaplot pry-doc -n /usr/bin -i /usr/share/gems 14 | pump --shutdown 15 | -------------------------------------------------------------------------------- /bitstation/02.setup/02-docker-setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -v 3 | echo "ZONE=UTC" > /etc/sysconfig/clock 4 | export TZ="UTC" 5 | # copy examples into /etc/skel 6 | pushd /etc/skel > /dev/null 7 | git clone --single-branch --depth 1 https://github.com/joequant/example-notebooks.git 8 | popd > /dev/null 9 | 10 | source /tmp/02-set-password.sh 11 | pushd ~user > /dev/null 12 | mkdir git 13 | pushd git > /dev/null 14 | git clone --single-branch --depth 1 https://github.com/joequant/bitquant.git 15 | popd > /dev/null 16 | chown -R user:user . 17 | popd > /dev/null 18 | 19 | WEB_DIR=/home/user/git/bitquant/bitstation/web 20 | ME=user 21 | GROUP=user 22 | 23 | pushd $WEB_DIR > /dev/null 24 | 25 | pushd /var/www/html > /dev/null 26 | rm -f * 27 | for i in index.html css data fonts js ; do 28 | ln -s -f ../../..$WEB_DIR/$i $i 29 | done 30 | popd > /dev/null 31 | 32 | # Do a special copy so that suexec works 33 | pushd /var/www/cgi-bin > /dev/null 34 | rm -rf /var/www/cgi-bin/* 35 | for i in $WEB_DIR/cgi-bin/*; do 36 | cp -r ../../..$WEB_DIR/cgi-bin/$(basename $i) $(basename $i) 37 | chown -R $ME:$GROUP $(basename $i) 38 | done 39 | popd > /dev/null 40 | 41 | pushd /etc/httpd/conf/webapps.d > /dev/null 42 | if [ -f 00_default_vhosts.conf ] ; then 43 | mv -f 00_default_vhosts.conf 00_default_vhosts.conf.bak 44 | fi 45 | popd > /dev/null 46 | 47 | # Create root copy of scripts 48 | mkdir -p /usr/share/bitquant 49 | cp $WEB_DIR/cgi-bin/bittrader/environment.sh /usr/share/bitquant 50 | cp $WEB_DIR/cgi-bin/bittrader/conf.sh /usr/share/bitquant 51 | cp $WEB_DIR/cgi-bin/bittrader/timezone.sh /usr/share/bitquant 52 | chown $ME:$GROUP /usr/share/bitquant/environment.sh 53 | chmod o-w /usr/share/bitquant/*.sh 54 | popd > /dev/null 55 | 56 | echo "Doing initial installation" 57 | pushd /var/lib 58 | git clone --depth 1 https://github.com/joequant/etherpad-lite.git 59 | popd 60 | echo "Installing npm packages" 61 | if [ -d /var/lib/etherpad-lite ] ; then 62 | pushd /var/lib/etherpad-lite 63 | make 64 | if [ -d src/node_modules ] ; then 65 | pushd src/node_modules 66 | modclean -r 67 | popd 68 | fi 69 | popd 70 | fi 71 | chown -R $ME:$GROUP /var/lib/etherpad-lite 72 | 73 | #set httpd 74 | /usr/share/bitquant/conf.sh /httpd-lock 75 | 76 | #set wiki conf 77 | echo "Set up wiki" 78 | /usr/share/bitquant/conf.sh /wiki-lock 79 | /usr/share/bitquant/conf.sh /wiki-init 80 | 81 | # Refresh configurations 82 | /usr/share/bitquant/conf.sh /default-init 83 | 84 | # sed -i '/ipv6/d' /etc/mongod.conf 85 | # sed -i '/ipv6/d' /etc/mongos.conf 86 | chmod a+rwx /srv 87 | -------------------------------------------------------------------------------- /bitstation/02.setup/02-set-password.sh: -------------------------------------------------------------------------------- 1 | # adjust this to set the password 2 | 3 | echo 'cubswin:)' | passwd user --stdin 4 | echo 'cubswin:)' | passwd root --stdin 5 | -------------------------------------------------------------------------------- /bitstation/02.setup/03-install-jupyter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # sudo portion of r package installations 3 | set -v 4 | set +o errexit 5 | 6 | source $rootfsDir/tmp/proxy.sh 7 | 8 | echo "Running r installation" 9 | if [ `uname -m` = "x86_64" -o `uname -m` = " x86-64" ]; then 10 | LIBDIR="lib64" 11 | else 12 | LIBDIR="lib" 13 | fi 14 | 15 | # Without this the installation will try to put the R library in the 16 | # system directories where it does not have permissions 17 | 18 | R_VERSION=$(R --version | head -1 | cut -d \ -f 3 | awk -F \. {'print $1"."$2'}) 19 | 20 | /usr/bin/R -e 'IRkernel::installspec(prefix="/usr", user=FALSE)' 21 | 22 | if [ -d /home/user/git/shiny-server ] 23 | then echo "Installing shiny server" 24 | pushd /home/user/git/shiny-server 25 | sed -i -e s!bin/node!! -e s!bin/npm!! CMakeLists.txt 26 | sed -i -e s!add_subdirectory\(external/node\)!! CMakeLists.txt 27 | popd 28 | make -C /home/user/git/shiny-server install 29 | ln -s -f ../lib/shiny-server/bin/shiny-server /usr/bin/shiny-server 30 | #Create shiny user. On some systems, you may need to specify the full path to 'useradd' 31 | useradd -r shiny -s /bin/false -M 32 | 33 | # Create log, config, and application directories 34 | mkdir -p /var/log/shiny-server 35 | mkdir -p /var/www/shiny-server 36 | mkdir -p /var/lib/shiny-server 37 | chown shiny /var/log/shiny-server 38 | mkdir -p /etc/shiny-server 39 | cp -r /usr/$LIBDIR/R/library/shiny/examples/* /var/www/shiny-server 40 | fi 41 | 42 | #npm 43 | ijsinstall --install=global 44 | its --install=global 45 | jp-coffee-install --install=global 46 | jp-babel-install --install=global 47 | jp-livescript-install --install=global 48 | 49 | mkdir -p /usr/share/jupyter/kernels 50 | mv /usr/local/share/jupyter/kernels/* /usr/share/jupyter/kernels 51 | # ruby 52 | iruby register --force 53 | pump --shutdown 54 | 55 | #julia 56 | export JUPYTER=/usr/bin/jupyter 57 | julia -e 'empty!(DEPOT_PATH); push!(DEPOT_PATH, "/usr/share/julia"); using Pkg; Pkg.add("IJulia")' 58 | cp -r /root/.local/share/jupyter/kernels/julia-* /usr/share/jupyter/kernels/ 59 | chmod -R +rx /usr/share/julia/ 60 | chmod -R +rx /usr/share/jupyter/kernels/julia-*/ 61 | -------------------------------------------------------------------------------- /bitstation/02.setup/04-remove-build-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # remove build deps 3 | 4 | set -e -v 5 | source $script_dir/proxy.sh 6 | 7 | # don't remove scipy 8 | dnf -y $rootfsArg \ 9 | autoremove \ 10 | cmake \ 11 | libtool \ 12 | automake \ 13 | autoconf \ 14 | swig \ 15 | protobuf-compiler \ 16 | cargo \ 17 | `rpm -qa $rootfsRpmArg | grep devel | grep -v python | grep -v glibc | \ 18 | grep -v xcrypt | \ 19 | grep -v ^gcc | grep -v libstd | grep -v gettext | \ 20 | grep -v acl | grep -v croco | grep -v ffi | grep -v blkid | \ 21 | grep -v glib | grep -v lzma | grep -v zlib | grep -v xml | \ 22 | grep -v mount | grep -v pcre | grep -v uuid | grep -v unistring | \ 23 | grep -v ncurses | grep -v fftw | grep -v gomp` 24 | 25 | dnf -y $rootfsArg \ 26 | autoremove \ 27 | `rpm -qa $rootfsRpmArg | grep openjdk` \ 28 | `rpm -qa $rootfsRpmArg | grep firefox` \ 29 | `rpm -qa $rootfsRpmArg | grep initscripts` \ 30 | `rpm -qa $rootfsRpmArg | grep qtbase5-common` 31 | 32 | # add iproute2 for webmin 33 | dnf -y $rootfsArg \ 34 | --setopt=install_weak_deps=False --nodocs \ 35 | install java-headless iproute2 \ 36 | quantlib-devel pybind11-devel \ 37 | xwidgets-devel root-r \ 38 | phobos-devel \ 39 | python3-jupyroot \ 40 | root \ 41 | root-physics \ 42 | root-geom \ 43 | root-fftw \ 44 | root-hist \ 45 | root-foam \ 46 | root-vecops \ 47 | root-graf \ 48 | root-graf-asimage \ 49 | root-graf-gpad \ 50 | root-graf-gpadv7 \ 51 | root-graf-gviz \ 52 | root-graf-postscript \ 53 | root-graf-primitives \ 54 | root-graf3d \ 55 | root-geom \ 56 | root-gui \ 57 | root-hist \ 58 | root-mathcore \ 59 | root-mathmore \ 60 | root-matrix \ 61 | root-minuit \ 62 | root-multiproc \ 63 | root-graf-postscript \ 64 | root-graf-asimage 65 | 66 | dnf clean all $rootfsArg 67 | # don't erase mesa as those are needed for 68 | # root cairo plotting 69 | rpm --erase --nodeps $rootfsRpmArg \ 70 | `rpm -qa $rootfsRpmArg | grep font | grep x11` \ 71 | `rpm -qa $rootfsRpmArg | grep adwaita` 72 | 73 | #set default python to python3 74 | pushd $rootfsDir/usr/bin 75 | ln -sf python3 python 76 | popd 77 | 78 | pushd $rootfsDir 79 | rm -rf root/.cache 80 | rm -rf root/.npm 81 | rm -rf root/.superset 82 | rm -rf var/lib/mongodb/journal 83 | rm -rf etc/resolveconf sbin/resolvconf etc/rc.d/init.d/resolvconf 84 | rm -rf usr/lib64/python*/test 85 | 86 | find usr/lib*/python* -name tests | xargs rm -rf 87 | find usr/lib*/python* -name examples | xargs rm -rf 88 | find usr/lib*/python* -name testsuite | xargs rm -rf 89 | 90 | pushd usr/lib/node_modules 91 | modclean -r -f 92 | popd 93 | rm -rf root/.gitconfig 94 | rm -rf etc/npmrc 95 | 96 | rm -rf usr/share/doc 97 | rm -rf usr/share/gems/doc 98 | rm -rf home/user/git/shiny-server 99 | rm -rf home/user/git/ethercalc 100 | rm -rf home/user/.npm/ 101 | rm -rf home/user/.node-gyp 102 | rm -rf root/.cache 103 | rm -rf root/.node-gyp 104 | rm -rf usr/local/share 105 | rm -rf usr/lib/.build-id 106 | rm -rf var/cache/* 107 | # need to keep archive for dmd 108 | rm -f lib/*.so lib/*.so.* lib/*.a lib/*.o 109 | # remove 32 bit items 110 | rm -rf lib/gcc/x86_64-mageia-linux-gnu/*/32 111 | 112 | #put in link to allow loading of iruby 113 | pushd usr/lib64 114 | if [ ! -f libzmq.so ] ; then 115 | ln -s libzmq.so.5 libzmq.so 116 | fi 117 | popd 118 | dnf clean all $rootfsArg 119 | 120 | # remove link that moves out of volume to allow running in podman 121 | rm -rf etc/X11 122 | rm -rf etc/alsa 123 | 124 | # needs fonts for root plotting 125 | #rm -rf etc/fonts 126 | 127 | pushd usr/share/locale 128 | rm -rf `ls | grep -v "^ISO" | grep -v "^UTF" | grep -v "^en" | grep -v "^C.UTF"` 129 | popd 130 | chmod -R a+rx var/lib/rpm var/lib/dnf 131 | rm -rf var/cache/* 132 | popd 133 | ldconfig $rootfsLdconfigArg 134 | pump --shutdown 135 | -------------------------------------------------------------------------------- /bitstation/02.setup/05-log-items.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | pushd /usr/share/bitquant 3 | rpm -qa | sort > rpm.log 4 | pip list > pip.log 5 | jupyter serverextension list > jupyter-serverextension.log 6 | jupyter labextension list > jupyter-labextension.log 7 | jupyter nbextension list > jupyter-nbextension.log 8 | jupyter bundlerextension list > jupyter-bundlerextension.log 9 | popd 10 | chmod a+r /usr/share/bitquant/* 11 | -------------------------------------------------------------------------------- /bitstation/02.setup/mkimage-buildah.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e -v 4 | 5 | mkimg="$(basename "$0")" 6 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 7 | container=$(buildah from joequant/cauldron) 8 | 9 | buildah config --label maintainer="Joseph C Wang " $container 10 | buildah config --user root $container 11 | mountpoint=$(buildah mount $container) 12 | 13 | export rootfsDir=$mountpoint 14 | export rootfsArg="--installroot=$mountpoint" 15 | export rootfsRpmArg="--root $mountpoint" 16 | export rootfsLdconfigArg="-r $mountpoint" 17 | export LC_ALL=C 18 | export LANGUAGE=C 19 | export LANG=C 20 | name="joequant/bitstation" 21 | cp $script_dir/*.sh $rootfsDir/tmp 22 | chmod a+x $rootfsDir/tmp/*.sh 23 | systemd-sysusers --root=$rootfsDir $script_dir/system.conf 24 | source $script_dir/00-install-pkgs.sh 25 | cp $script_dir/openssl.cnf $rootfsDir/etc/pki/tls 26 | 27 | pushd $rootfsDir/etc/httpd/conf 28 | rm -f conf.d/security.conf 29 | cp $script_dir/00_mpm.conf modules.d 30 | if [ -e modules.d/00-php-fpm.conf ] ; then 31 | mv modules.d/00-php-fpm.conf modules.d/10-php-fpm.conf 32 | fi 33 | popd 34 | 35 | buildah run $container parallel --halt 2 --tagstring '{}' --linebuffer source '/tmp/{}' ::: 01-install-r-pkgs.sh 01-install-python.sh 01-install-npm.sh 01-install-ruby.sh 01-install-dlang.sh 36 | buildah run $container /bin/bash /tmp/02-docker-setup.sh 37 | buildah run $container /bin/bash /tmp/03-install-jupyter.sh 38 | source $script_dir/04-remove-build-deps.sh 39 | 40 | cat > $rootfsDir/usr/share/bitquant/bitquant.sh < /dev/tcp/'$cache_server'/3128' || export timeout_exit=1 6 | 7 | if [ $timeout_exit == 0 ] ; then 8 | echo "running proxy" 9 | export http_proxy=http://$cache_server:3128/ 10 | export https_proxy=http://$cache_server:3128/ 11 | export ftp_proxy=http://$cache_server:3128/ 12 | export HTTP_PROXY=http://$cache_server:3128/ 13 | #cache with devpi-server 14 | export PIP_INDEX_URL=http://127.0.0.1:3141/root/pypi/+simple/ 15 | #cache with git-cache-http-server 16 | export GIT_PROXY=http://127.0.0.1:8080/ 17 | #cache with verdacchio 18 | export NPM_CONFIG_REGISTRY=http://127.0.0.1:4873/ 19 | export YARN_REGISTRY=http://127.0.0.1:4873/ 20 | #' 21 | fi 22 | 23 | export timeout_exit=0 24 | timeout 1 bash -c 'cat < /dev/null > /dev/tcp/$cache_server/3632' || export timeout_exit=1 25 | : ' 26 | if [ $timeout_exit == 0 ] ; then 27 | echo "running distcc" 28 | export PATH=/usr/lib64/distcc:$PATH 29 | export DISTCC_HOSTS="$cache_server" 30 | fi 31 | ' 32 | if [ $timeout_exit == 0 ] ; then 33 | echo "running distcc (pump mode)" 34 | export PATH=/usr/lib64/distcc:$PATH 35 | export DISTCC_HOSTS='172.17.0.1,cpp,lzo' 36 | eval `pump --startup` 37 | fi 38 | -------------------------------------------------------------------------------- /bitstation/02.setup/system.conf: -------------------------------------------------------------------------------- 1 | # mongodb can write the pid there 2 | # this range should match /etc/login.defs 3 | u mongod 184 "MongoDB Database Server" /var/lib/mongodb 4 | g mongod 184 - 5 | u apache 48 "system user for webserver" /var/www 6 | g apache 48 7 | 8 | 9 | -------------------------------------------------------------------------------- /bitstation/README.md: -------------------------------------------------------------------------------- 1 | Requirements 2 | ------------ 3 | 4 | The docker script requires docker 1.8 to implement cp from containers 5 | 6 | Running an image 7 | ---------------- 8 | 9 | To run 10 | 11 | docker-compose up 12 | 13 | The image for bitstation is stored on docker hub as 14 | joequant/bitstation which will be downloaded automatically by the 15 | script. 16 | 17 | The default user and password are "user" and "cubswin:)" 18 | 19 | The scripts assume that you have set up docker to be runnable by your 20 | user account. You can also set the environment variable SUDO to sudo 21 | if you are running docker via root. 22 | 23 | You can then connect to the system via the localhost port 80 24 | 25 | To build the image locally 26 | -------------------------- 27 | 28 | pnpm run build 29 | 30 | The system uses a podman/buildah toolchain to build an image. 31 | However, right now there is a problem in using podman to run an image 32 | with volumes because podman doesn't handle symlinks that go outside a 33 | volume. 34 | 35 | See: https://github.com/containers/podman/issues/6003 36 | 37 | Proxy server 38 | ------------ 39 | 40 | There is a docker image called joequant/cacher which sets up a 41 | caching server that includes squid and compile caching. To run the 42 | cacher go to the repository joequant/cacher and run docker-compose. 43 | 44 | Cacher sets up a number of proxy and distccd caches that speed up 45 | compiles. 46 | 47 | License 48 | ------- 49 | 50 | Copyright (C) 2016- 51 | Bitquant Research Laboratories (Asia) Limited 52 | 53 | The contents of this directory are released under the terms of the GNU 54 | Lesser General Public License. -------------------------------------------------------------------------------- /bitstation/RELEASE.md: -------------------------------------------------------------------------------- 1 | 202008.1 2 | 3 | * added patches for root to make 3d work 4 | -------------------------------------------------------------------------------- /bitstation/config/bitstation/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | bitstation: 4 | image: "joequant/bitstation:production" 5 | stdin_open: true 6 | tty: true 7 | ports: 8 | - 82:80 9 | - 4443:443 10 | environment: 11 | - INSTANCE_NAME=bitstation 12 | - "PS1=bitstation\\$$ " 13 | devices: 14 | - /dev/fuse:/dev/fuse 15 | cap_add: 16 | - SYS_ADMIN 17 | volumes: 18 | - home:/home 19 | - dokuwiki:/var/lib/dokuwiki 20 | - mongodb:/var/lib/mongodb 21 | - redis:/var/lib/redis 22 | - bitcoin:/var/lib/bitcoin 23 | - log:/var/log 24 | - etc:/etc 25 | - srv:/srv 26 | cauldron: 27 | image: "joequant/cauldron" 28 | entrypoint: ["echo", "Service cauldron disabled"] 29 | nextcloud: 30 | image: "joequant/nextcloud:production" 31 | volumes: 32 | - nextcloud_lib_apps:/var/lib/nextcloud/apps 33 | - nextcloud_lib_data:/var/lib/nextcloud/data 34 | - nextcloud_etc:/etc/nextcloud 35 | restart: always 36 | depends_on: 37 | - db 38 | db: 39 | image: postgres:12-alpine 40 | restart: always 41 | environment: 42 | - POSTGRES_PASSWORD=mypass 43 | volumes: 44 | - db:/var/lib/postgresql/data 45 | restart: always 46 | 47 | volumes: 48 | home: 49 | dokuwiki: 50 | mongodb: 51 | redis: 52 | bitcoin: 53 | log: 54 | etc: 55 | srv: 56 | nextcloud_lib_apps: 57 | nextcloud_lib_data: 58 | nextcloud_etc: 59 | db: 60 | -------------------------------------------------------------------------------- /bitstation/config/demo/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | bitstation: 4 | image: "joequant/bitstation" 5 | stdin_open: true 6 | tty: true 7 | ports: 8 | - 8085:80 9 | - 4455:443 10 | environment: 11 | - INSTANCE_NAME=demo 12 | volumes: 13 | - home:/home 14 | - dokuwiki:/var/lib/dokuwiki 15 | - mongodb:/var/lib/mongodb 16 | - redis:/var/lib/redis 17 | - bitcoin:/var/lib/bitcoin 18 | - log:/var/log 19 | - etc:/etc 20 | - srv:/srv 21 | cauldron: 22 | image: "joequant/cauldron" 23 | entrypoint: ["echo", "Service cauldron disabled"] 24 | nextcloud: 25 | image: "joequant/nextcloud:20" 26 | volumes: 27 | - nextcloud_lib_apps:/var/lib/nextcloud/apps 28 | - nextcloud_lib_data:/var/lib/nextcloud/data 29 | - nextcloud_etc:/etc/nextcloud 30 | restart: always 31 | depends_on: 32 | - db 33 | db: 34 | image: postgres:12-alpine 35 | restart: always 36 | environment: 37 | - POSTGRES_PASSWORD=mypass 38 | volumes: 39 | - db:/var/lib/postgresql/data 40 | restart: always 41 | 42 | volumes: 43 | home: 44 | dokuwiki: 45 | mongodb: 46 | redis: 47 | bitcoin: 48 | log: 49 | etc: 50 | srv: 51 | nextcloud_lib_apps: 52 | nextcloud_lib_data: 53 | nextcloud_etc: 54 | db: 55 | -------------------------------------------------------------------------------- /bitstation/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | bitstation: 4 | image: "joequant/bitstation" 5 | build: 6 | context: 02.setup 7 | dockerfile: Dockerfile 8 | args: 9 | base: "joequant/cauldron" 10 | stdin_open: true 11 | tty: true 12 | ports: 13 | - 80:80 14 | - 443:443 15 | devices: 16 | - /dev/fuse:/dev/fuse 17 | cap_add: 18 | - SYS_ADMIN 19 | volumes: 20 | - home:/home 21 | - dokuwiki:/var/lib/dokuwiki 22 | - mongodb:/var/lib/mongodb 23 | - redis:/var/lib/redis 24 | - bitcoin:/var/lib/bitcoin 25 | - log:/var/log 26 | - etc:/etc 27 | - srv:/srv 28 | cauldron: 29 | image: "joequant/cauldron" 30 | build: 01.cauldron 31 | entrypoint: ["echo", "Service cauldron disabled"] 32 | nextcloud: 33 | image: "joequant/nextcloud" 34 | build: 35 | context: . 36 | dockerfile: Dockerfile 37 | volumes: 38 | - nextcloud_lib_apps:/var/lib/nextcloud/apps 39 | - nextcloud_lib_data:/var/lib/nextcloud/data 40 | - nextcloud_etc:/etc/nextcloud 41 | restart: always 42 | depends_on: 43 | - db 44 | db: 45 | image: postgres:12-alpine 46 | restart: always 47 | environment: 48 | - POSTGRES_PASSWORD:mypass 49 | volumes: 50 | - db:/var/lib/postgresql/data 51 | restart: always 52 | 53 | volumes: 54 | home: 55 | dokuwiki: 56 | mongodb: 57 | redis: 58 | bitcoin: 59 | log: 60 | etc: 61 | srv: 62 | nextcloud_lib_apps: 63 | nextcloud_lib_data: 64 | nextcloud_etc: 65 | db: 66 | -------------------------------------------------------------------------------- /bitstation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bitstation", 3 | "scripts": { 4 | "build": "buildah unshare /bin/bash ./02.setup/mkimage-buildah.sh", 5 | "build-base": "buildah unshare /bin/bash 01.cauldron/mkimage-buildah.sh", 6 | "build-base-minimal": "buildah unshare /bin/bash 01.cauldron/mkimage-buildah-minimal.sh", 7 | "docker-push": "skopeo copy containers-storage:localhost/joequant/bitstation docker-daemon:joequant/bitstation:latest ; ./util/containers.sh restart", 8 | "production-revert": "docker tag joequant/bitstation:production joequant/bitstation:latest ; docker tag joequant/nextcloud:production joequant/nextcloud:latest ; ./util/containers.sh restart", 9 | "production-tag": "docker tag joequant/bitstation:latest joequant/bitstation:production ; docker tag joequant/nextcloud:latest joequant/nextcloud:production ; ./util/containers.sh restart", 10 | "up": "./util/containers.sh up", 11 | "down": "./util/containers.sh down", 12 | "restart": "./util/containers.sh restart", 13 | "proxy-start": "nohup podman-compose -f ../cacher/docker-compose.yml up >> proxy.out &", 14 | "shell": "./util/containers-shell.sh bitstation_bitstation", 15 | "clean-images": "./util/rm-stopped-containers.sh ; ./util/rm-untagged-images.sh", 16 | "shell-base": "docker run -ti joequant/cauldron /bin/bash", 17 | "shell-nextcloud": "./util/containers-shell.sh -u apache bitstation_nextcloud" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /bitstation/test/test-bitstation.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | from selenium import webdriver 4 | from selenium.webdriver.common.keys import Keys 5 | import os 6 | 7 | driver = webdriver.Firefox() 8 | driver.get(os.environ['BITSTATION_URL']) 9 | calc_link = driver.find_element_by_link_text("Calculation Engine") 10 | doc_link = driver.find_element_by_link_text("Document management") 11 | main_window = driver.current_window_handle 12 | calc_link.click() 13 | doc_link.click() 14 | 15 | 16 | -------------------------------------------------------------------------------- /bitstation/util/backup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -f 2 | 3 | DATE=$(date -u +'%Y%m%d.%H%M%S') 4 | CMD=docker 5 | dir=`pwd` 6 | while getopts 'c:d:' OPTION; do 7 | case "$OPTION" in 8 | c) 9 | CMD="$OPTARG" 10 | ;; 11 | d) 12 | dir="$OPTARG" 13 | if [ ! -d $dir ] ; then 14 | echo "cannot find directory $dir" 15 | exit 1 16 | fi 17 | ;; 18 | ?) 19 | echo "script usage: -c cmd image" >&2 20 | exit 1 21 | ;; 22 | esac 23 | done 24 | shift "$(($OPTIND -1))" 25 | ID=${1:-bitstation} 26 | 27 | pushd $dir 28 | VOLUMES=$($CMD volume ls | awk 'FNR >=2 {print $NF}' | grep ^$ID) 29 | 30 | for vol in $VOLUMES; do 31 | echo $vol 32 | $CMD run -v $vol:/volume --rm loomchild/volume-backup backup -c xz - > ${vol}.$DATE.tar.xz 33 | done 34 | popd 35 | -------------------------------------------------------------------------------- /bitstation/util/clone-volume.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #Author: Guido Diepen 4 | 5 | #Convenience script that can help me to easily create a clone of a given 6 | #data volume. The script is mainly useful if you are using named volumes 7 | 8 | export LANG=C LC_ALL=C 9 | CMD=docker 10 | VERBOSE=0 11 | while getopts 'c:v' OPTION; do 12 | case "$OPTION" in 13 | c) 14 | CMD="$OPTARG" 15 | ;; 16 | v) 17 | VERBOSE=1 18 | ;; 19 | ?) 20 | echo "script usage: -u usernae image cmd" >&2 21 | exit 1 22 | ;; 23 | esac 24 | done 25 | shift "$(($OPTIND -1))" 26 | 27 | #First check if the user provided all needed arguments 28 | if [ "$1" = "" ] 29 | then 30 | echo "Please provide a source volume name" 31 | exit 32 | fi 33 | 34 | if [ "$2" = "" ] 35 | then 36 | echo "Please provide a destination volume name" 37 | exit 38 | fi 39 | 40 | #Check if the source volume name does exist 41 | $CMD volume inspect $1 > /dev/null 2>&1 42 | if [ "$?" != "0" ] 43 | then 44 | echo "The source volume \"$1\" does not exist" 45 | exit 46 | fi 47 | 48 | #Now check if the destinatin volume name does not yet exist 49 | $CMD volume inspect $2 > /dev/null 2>&1 50 | 51 | if [ "$?" = "0" ] 52 | then 53 | echo "The destination volume \"$2\" already exists" 54 | exit 55 | fi 56 | 57 | echo "Creating destination volume \"$2\"..." 58 | $CMD volume create --name $2 59 | echo "Copying data from source volume \"$1\" to destination volume \"$2\"..." 60 | $CMD run --rm \ 61 | -i \ 62 | -t \ 63 | -v $1:/from \ 64 | -v $2:/to \ 65 | alpine ash -c "cd /from ; cp -av . /to" 66 | -------------------------------------------------------------------------------- /bitstation/util/containers-shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | export LANG=C LC_ALL=C 3 | CMD=docker 4 | VERBOSE=0 5 | while getopts 'c:u:v' OPTION; do 6 | case "$OPTION" in 7 | c) 8 | CMD="$OPTARG" 9 | ;; 10 | u) 11 | user="$OPTARG" 12 | ;; 13 | v) 14 | VERBOSE=1 15 | ;; 16 | ?) 17 | echo "script usage: -u usernae image cmd" >&2 18 | exit 1 19 | ;; 20 | esac 21 | done 22 | shift "$(($OPTIND -1))" 23 | 24 | args=() 25 | 26 | if [ $# -ge 1 ]; then 27 | IMAGE=$($CMD ps | awk 'FNR >=2 {print $NF}' | grep ^$1 | head -1) 28 | else 29 | IMAGE=$($CMD ps | awk 'FNR==2 {print $NF}') 30 | fi 31 | 32 | if [[ -z $IMAGE ]]; then 33 | echo "image not found" 34 | exit 1 35 | elif [ $VERBOSE -eq 1 ] ; then 36 | echo "Image: "$IMAGE 37 | fi 38 | 39 | if [ -t 1 ] ; then 40 | args+=(-it) 41 | fi 42 | 43 | if [[ ! -z $user ]]; then 44 | args+=(-u) 45 | args+=($user) 46 | fi 47 | 48 | args+=($IMAGE) 49 | 50 | if [ $# -ge 2 ]; then 51 | shift 52 | args+=($@) 53 | else 54 | args+=("/bin/bash") 55 | fi 56 | 57 | 58 | 59 | if [ $VERBOSE -eq 1 ] ; then 60 | echo "running '"$CMD exec ${args[@]}"'" 61 | fi 62 | exec $CMD exec ${args[@]} 63 | -------------------------------------------------------------------------------- /bitstation/util/containers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | CONFIG_DIR=$SCRIPT_DIR/../config 4 | LOG_DIR=$SCRIPT_DIR/../log 5 | DATE=$(date -u +%Y%m%d%H%M%S) 6 | CMD=$1 7 | if [ -z $CMD ] ; then 8 | echo "no command" 9 | exit 1 10 | fi 11 | 12 | cd $CONFIG_DIR 13 | if [ -z $2 ] ; then 14 | images=`echo */` 15 | else 16 | images=$2 17 | fi 18 | 19 | if [ $CMD != "up" ] && [ $CMD != "down" ] && [ $CMD != "restart" ] ; then 20 | echo "unknown command: " $CMD 21 | exit 1 22 | fi 23 | 24 | if [ $CMD == "down" ] || [ $CMD == "restart" ] ; then 25 | for f in $images; do 26 | if [ -d "$f" ]; then 27 | docker-compose -f $f/docker-compose.yml down & 28 | fi 29 | done 30 | for job in `jobs -p` ; do 31 | echo $job 32 | wait $job || let "FAIL+=1" 33 | done 34 | fi 35 | 36 | if [ $CMD == "up" ] || [ $CMD == "restart" ] ; then 37 | for f in $images; do 38 | if [ -d "$f" ]; then 39 | docker-compose -f $f/docker-compose.yml up > $LOG_DIR/`basename $f`.$DATE.log & 40 | fi 41 | done 42 | fi 43 | -------------------------------------------------------------------------------- /bitstation/util/push-image.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -f 2 | # This script moves the latest podman image to docker. This is because 3 | # the docker image is on a disk limited volume. 4 | 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | IMAGES=demo 7 | pushd $SCRIPT_DIR 8 | ./containers.sh down $IMAGES 9 | docker tag joequant/bitstation:production joequant/bitstation:latest 10 | docker tag joequant/nextcloud:production joequant/nextcloud:latest 11 | ./rm-stopped-containers.sh 12 | ./rm-untagged-images.sh 13 | skopeo copy containers-storage:localhost/joequant/bitstation docker-daemon:joequant/bitstation:latest 14 | skopeo copy containers-storage:localhost/joequant/nextcloud docker-daemon:joequant/nextcloud:latest 15 | ./containers.sh up $IMAGES 16 | popd 17 | -------------------------------------------------------------------------------- /bitstation/util/restore.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CMD=docker 3 | 4 | while getopts 'c:' OPTION; do 5 | case "$OPTION" in 6 | c) 7 | CMD="$OPTARG" 8 | ;; 9 | ?) 10 | echo "script usage: -c cmd image" >&2 11 | exit 1 12 | ;; 13 | esac 14 | done 15 | shift "$(($OPTIND -1))" 16 | ID=${1} 17 | 18 | IFS='.' 19 | read -ra ARR <<< $(basename "$ID") 20 | IFS=' ' 21 | 22 | volname="${ARR[0]}" 23 | compression="${ARR[-1]}" 24 | 25 | echo "Moving ${1} into ${volname}" 26 | 27 | cat $1 | $CMD run -i -v $volname:/volume --rm loomchild/volume-backup restore -c $compression - 28 | #cat demo_home.20200503.113330.tar.xz | tar -J -tf - 29 | 30 | -------------------------------------------------------------------------------- /bitstation/util/rm-stopped-containers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CMD=${1:-docker} 3 | $CMD rm $($CMD ps -a -q) 4 | exit 0 5 | -------------------------------------------------------------------------------- /bitstation/util/rm-untagged-images.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | CMD=${1:-docker} 3 | $CMD rmi $($CMD images | grep "^" | awk '{print $3}') 4 | exit 0 5 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/README.md: -------------------------------------------------------------------------------- 1 | The scripts in this directory are copied into /var/www/cgi-bin rather 2 | than symlinked so that the suexec mechanism will work. This means 3 | that changes in these scripts are not automatically refreshed. 4 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/conf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set setuid so that it is run with the user which checked out the 3 | # orginal git 4 | 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | . $SCRIPT_DIR/environment.sh 7 | 8 | if [[ $UID -ne 0 ]]; then 9 | SUDO=sudo 10 | fi 11 | 12 | if [ $# -ge 1 ] ; then 13 | export PATH_INFO=$1 14 | else 15 | echo "Content-type: text/html" 16 | echo "" 17 | fi 18 | 19 | if [ "$PATH_INFO" = "" ] ; then 20 | echo "no path" 21 | exit 0 22 | fi 23 | 24 | export CONFIG=${PATH_INFO#/} 25 | 26 | echo "
"
27 | pushd $WEB_DIR > /dev/null
28 | if [ -e "config/$CONFIG" ] ; then
29 | for i in `find config/$CONFIG/* -type d` ; do $SUDO mkdir -p ${i#config/$CONFIG} ;done
30 | for i in `find config/$CONFIG/* -type f ! -iname "*~" ` 
31 | do TARGET=${i#config/$CONFIG}
32 | echo "copying to $TARGET"
33 | $SUDO cp $i $TARGET
34 | $SUDO sed -i -e "s/%USER%/$ME/g" -e "s/%GROUP%/$GROUP/g" $TARGET
35 | if [ -e "config/user/$CONFIG" ] ; then
36 | OWNER=`cat config/user/$CONFIG | sed -e "s/%USER%/$ME/g" -e "s/%GROUP%/$GROUP/g"`
37 | echo "changing owner of $TARGET to $OWNER"
38 | $SUDO chown  $OWNER $TARGET
39 | fi
40 | 
41 | done
42 | if [ -e "config/exec/$CONFIG" ] ; then
43 | echo "executing config/exec/$CONFIG"
44 | . config/exec/$CONFIG
45 | fi
46 | popd > /dev/null
47 | else
48 | echo "Unknown config $CONFIG"
49 | fi
50 | echo "
" 51 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/environment.sh: -------------------------------------------------------------------------------- 1 | ME=user 2 | GROUP=user 3 | MY_HOME=$(eval echo ~$ME) 4 | # needed for building ethercalc 5 | USERPROFILE=$MY_HOME 6 | export HOME=$MY_HOME 7 | GIT_DIR=$MY_HOME/git/bitquant 8 | WEB_DIR=$MY_HOME/git/bitquant/bitstation/web 9 | LOG_DIR=$WEB_DIR/log 10 | INSTALL_MIFOS=false 11 | INSTALL_OPENGAMMA=false 12 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/login.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import pexpect 3 | import os 4 | import subprocess 5 | import traceback 6 | 7 | os.environ['LC_ALL']="C" 8 | 9 | def auth(username, password): 10 | '''Accepts username and password and tried to use PAM for authentication''' 11 | try: 12 | child = pexpect.spawn('/bin/su -f - %s -c "echo success"'%(username)) 13 | child.expect('Password:') 14 | child.sendline(password) 15 | result=child.expect(['success']) 16 | child.close() 17 | except Exception as err: 18 | child.close() 19 | return False 20 | if result != 0: 21 | return False 22 | else: 23 | return True 24 | 25 | def chpasswd(username, password): 26 | try: 27 | child = pexpect.spawn("sudo passwd %s" % username) 28 | child.expect("password:") 29 | child.sendline(password) 30 | child.expect("password:") 31 | child.sendline(password) 32 | child.expect(['success']) 33 | child.close() 34 | except Exception as err: 35 | return traceback.format_exc() 36 | return "password changed for %s" % (username) 37 | 38 | if __name__ == '__main__': 39 | print(auth(username='user',password='cubswin:)')) 40 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/manifest.py: -------------------------------------------------------------------------------- 1 | #!/bin/python3 2 | import cgi 3 | import cgitb 4 | import subprocess 5 | cgitb.enable() 6 | 7 | def run_subprocess(arg, **kwargs): 8 | try: 9 | print(subprocess.check_output(arg, **kwargs).decode('utf-8')) 10 | except subprocess.CalledProcessError: 11 | pass 12 | 13 | print("Content-type: text/html\n") 14 | print("
")
15 | 
16 | run_subprocess(['pip3', 'list'])
17 | run_subprocess(['npm', 'list', '-g'])
18 | run_subprocess('rpm -qa | sort', shell=True)
19 | print("
") 20 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/pageset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | from wsgiref.handlers import CGIHandler 3 | from flask import Flask, Response, request 4 | import os 5 | import sys 6 | app = Flask(__name__) 7 | script_dir = os.path.dirname(os.path.realpath(__file__)) 8 | template = """ 9 | 10 | 11 | 12 | 13 | 19 | 20 |
21 | The following links will be open in new tabs. Drag this tab out to create a new frame

22 | %s 23 | 24 | """ 25 | 26 | @app.route('/', methods=['GET','POST']) 27 | def index(): 28 | if request.method == "POST": 29 | string = request.form["resource"]; 30 | open_string = "" 31 | page_string = "" 32 | for i in string.split("\n"): 33 | i = i.strip(); 34 | if i == "": 35 | continue 36 | open_string += "window.open('%s');\n" % i 37 | page_string += "%s
" % i; 38 | return template % (open_string, page_string); 39 | else: 40 | return template % ("", ""); 41 | 42 | if __name__ == '__main__' and len(sys.argv) == 1: 43 | from wsgiref.handlers import CGIHandler 44 | CGIHandler().run(app) 45 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/refresh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Content-type: text/plain" 3 | echo "" 4 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | python3 $SCRIPT_DIR/model.py refresh-scripts 6 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/timezone.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ $# -eq 1 ] ; then 3 | TZ=$1 4 | fi 5 | 6 | if [ "$TZ" != "" ] ; then 7 | sudo /bin/timedatectl set-timezone $TZ 8 | echo "New timezone "`/bin/timedatectl | grep Timezone:` 9 | fi 10 | 11 | -------------------------------------------------------------------------------- /bitstation/web/cgi-bin/bittrader/wiki.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # set setuid so that it is run with the user which checked out the 3 | # orginal git 4 | 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | . $SCRIPT_DIR/environment.sh 7 | 8 | if [ $# -ge 1 ] ; then 9 | export PATH_INFO=$1 10 | else 11 | echo "Content-type: text/html" 12 | echo "" 13 | fi 14 | echo "

"
15 | if [ "$PATH_INFO" == "/rmuser" ] ; then 
16 | if [ $# -eq 2 ] ; then
17 | grep -v "$2:" /etc/dokuwiki/users.auth.php > /tmp/users.auth.php
18 | sudo cp /tmp/users.auth.php /etc/dokuwiki/users.auth.php
19 | sudo chown -R apache:apache /etc/dokuwiki/users.auth.php
20 | fi
21 | echo "User removed $2"
22 | elif [ "$PATH_INFO" == "/adduser" ] ; then 
23 | if [ $# -eq 2 ] ; then
24 | echo "$2" | sudo tee -a /etc/dokuwiki/users.auth.php > /dev/null
25 | fi
26 | echo "User added"
27 | else
28 | echo "unknown path $PATH_INFO"
29 | fi
30 | 
31 | echo "
" 32 | -------------------------------------------------------------------------------- /bitstation/web/config/default-init/etc/ajenti/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "users": { 3 | "root": { 4 | "configs": { 5 | "ajenti.plugins.fm.fm.FileManager": "{\"start\": \"/\", \"root\": \"/\"}", 6 | "ajenti.plugins.terminal.main.Terminals": "{\"shell\": \"sh -c $SHELL || bash\"}", 7 | "ajenti.plugins.logs.main.Logs": "{\"root\": \"/var/log\"}", 8 | "ajenti.users.UserManager": "{\"sync-provider\": \"unix\"}", 9 | "ajenti.plugins.dashboard.dash.Dash": "{\"widgets\": [{\"index\": 0, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.sensors.memory.MemoryWidget\"}, {\"index\": 1, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.sensors.memory.SwapWidget\"}, {\"index\": 2, \"config\": null, \"container\": \"1\", \"class\": \"ajenti.plugins.dashboard.welcome.WelcomeWidget\"}, {\"index\": 0, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.sensors.uptime.UptimeWidget\"}, {\"index\": 1, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.power.power.PowerWidget\"}, {\"index\": 2, \"config\": null, \"container\": \"0\", \"class\": \"ajenti.plugins.sensors.cpu.CPUWidget\"}]}", 10 | "ajenti.plugins.notepad.notepad.Notepad": "{\"bookmarks\": [], \"root\": \"/\"}", 11 | "ajenti.plugins.tasks.manager.TaskManager": "{\"task_definitions\": []}" 12 | }, 13 | "password": "sha512|$6$rounds=40000$nIVrqqz638rB8wOo$VbMv8y2lStgcsYxEuu7JfHiEd06eeiSoIbg7Hvivj9K1vPayaCbAiAqtpyOoIkNfIXFmMD0jK6Dd4WFnvywkY1", 14 | "permissions": [] 15 | }, 16 | "joe": { 17 | "configs": {}, 18 | "password": "", 19 | "permissions": [] 20 | } 21 | }, 22 | "language": "", 23 | "bind": { 24 | "host": "0.0.0.0", 25 | "port": 8000 26 | }, 27 | "enable_feedback": true, 28 | "ssl": { 29 | "enable": false, 30 | "certificate_path": "" 31 | }, 32 | "authentication": true, 33 | "installation_id": 69059 34 | } -------------------------------------------------------------------------------- /bitstation/web/config/default-init/etc/mongod.conf: -------------------------------------------------------------------------------- 1 | ## 2 | ## For list of options visit: 3 | ## https://docs.mongodb.org/manual/reference/configuration-options/ 4 | ## 5 | 6 | # systemLog Options - How to do logging 7 | systemLog: 8 | # The default log message verbosity level for components (0-5) 9 | verbosity: 0 10 | 11 | # The destination to which MongoDB sends all log output (file|syslog, if not specifed to STDOUT) 12 | destination: file 13 | 14 | # Log file to send write to instead of stdout - has to be a file, not directory 15 | path: /var/log/mongodb/mongod.log 16 | 17 | # Append to logpath instead of over-writing (false by default) 18 | logAppend: true 19 | 20 | # Set the log rotation behavior (rename|reopen, rename by default) 21 | logRotate: reopen 22 | 23 | 24 | # processManagement Options - How the process runs 25 | processManagement: 26 | # Fork server process (false by default) 27 | fork: true 28 | 29 | # Full path to pidfile (if not set, no pidfile is created) 30 | pidFilePath: /var/run/mongodb/mongod.pid 31 | 32 | 33 | # net Options - Network interfaces settings 34 | net: 35 | # Specify port number (27017 by default) 36 | port: 27017 37 | 38 | # Comma separated list of ip addresses to listen on (all local ips by default) 39 | bindIp: 127.0.0.1,::1 40 | 41 | # Enable IPv6 support (disabled by default) 42 | 43 | unixDomainSocket: 44 | # Enable/disable listening on the UNIX domain socket (true by default) 45 | enabled: true 46 | 47 | # Alternative directory for UNIX domain sockets (defaults to /tmp) 48 | pathPrefix: /var/run/mongodb 49 | 50 | #ssl: 51 | # Set the SSL operation mode (disabled|allowSSL|preferSSL|requireSSL) 52 | #mode: 53 | 54 | # PEM file for ssl 55 | #PEMKeyFile: 56 | 57 | # Certificate Authority file for SSL 58 | #CAFile: 59 | 60 | 61 | # storage Options - How and Where to store data 62 | storage: 63 | # Directory for datafiles (defaults to /data/db/) 64 | dbPath: /var/lib/mongodb 65 | 66 | #journal: 67 | # Enable/Disable journaling (journaling is on by default for 64 bit) 68 | #enabled: true 69 | 70 | # The storage engine for the mongod database (mmapv1|wiredTiger, wiredTiger by default 71 | # - works for 64 bit only) 72 | # Also possible to use unstable engines: devnull|ephemeralForTest 73 | # engine: mmapv1 74 | 75 | #mmapv1: 76 | # Enable or disable the preallocation of data files (true by default) 77 | #preallocDataFiles: 78 | 79 | # Use a smaller default file size (false by default) 80 | #smallFiles: 81 | 82 | #wiredTiger: 83 | #engineConfig: 84 | # The maximum size of the cache that WiredTiger will use for all data 85 | # (max(60% of RAM - 1GB, 1GB) by default) 86 | #cacheSizeGB: 5 87 | 88 | # The type of compression to use to compress WiredTiger journal data 89 | # (none|snappy|zlib, snappy by default) 90 | #journalCompressor: 91 | 92 | #collectionConfig: 93 | # The default type of compression to use to compress collection data 94 | # (none|snappy|zlib, snappy by default) 95 | #blockCompressor: 96 | 97 | 98 | # secutiry Options - Authorization and other security settings 99 | #security: 100 | # Private key for cluster authentication 101 | #keyFile: 102 | 103 | # Run with/without security (enabled|disabled, disabled by default) 104 | #authorization 105 | 106 | 107 | # setParameter Options - Set MongoDB server parameters 108 | # setParameter: 109 | 110 | # opratrionProfiling Options - Profiling settings 111 | #operationProfiling: 112 | 113 | # replication Options - ReplSet settings 114 | #replication: 115 | 116 | # sharding Options - Shard settings 117 | #sharding: 118 | 119 | -------------------------------------------------------------------------------- /bitstation/web/config/default-init/etc/shiny-server/shiny-server.conf: -------------------------------------------------------------------------------- 1 | # Instruct Shiny Server to run applications as the user "shiny" 2 | run_as shiny; 3 | 4 | # Define a server that listens on port 3838 5 | server { 6 | listen 3838; 7 | 8 | # Define a location at the base URL 9 | location /shiny { 10 | 11 | # Host the directory of Shiny Apps stored in this directory 12 | site_dir /var/www/shiny-server; 13 | 14 | # Log all Shiny output to files in this directory 15 | log_dir /var/log/shiny-server; 16 | 17 | # When a user visits the base URL rather than a particular application, 18 | # an index of the applications available in this directory will be shown. 19 | directory_index on; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bitstation/web/config/default-init/etc/sudoers.d/00_bitquant_sudo: -------------------------------------------------------------------------------- 1 | ## Sudoers allows particular users to run various commands as 2 | ## the root user, without needing the root password. 3 | ## 4 | ## Examples are provided at the bottom of the file for collections 5 | ## of related commands, which can then be delegated out to particular 6 | ## users or groups. 7 | ## 8 | ## This file must be edited with the 'visudo' command. 9 | 10 | ## Host Aliases 11 | ## Groups of machines. You may prefer to use hostnames (perhaps using 12 | ## wildcards for entire domains) or IP addresses instead. 13 | # Host_Alias FILESERVERS = fs1, fs2 14 | # Host_Alias MAILSERVERS = smtp, smtp2 15 | 16 | ## User Aliases 17 | ## These aren't often necessary, as you can use regular groups 18 | ## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname 19 | ## rather than USERALIAS 20 | # User_Alias ADMINS = jsmith, mikem 21 | 22 | 23 | ## Command Aliases 24 | ## These are groups of related commands... 25 | 26 | ## Networking 27 | # Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, 28 | # /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, 29 | # /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool 30 | 31 | ## Bitquant install 32 | Cmnd_Alias BITQUANT = /usr/share/bitquant/conf.sh,/usr/share/bitquant/install-python-sudo.sh, /usr/share/bitquant/install-r-pkgs-sudo.sh, /usr/share/bitquant/install-build-deps.sh, /usr/share/bitquant/mkogdirs-sudo.sh, /usr/share/bitquant/install-mifos-sudo.sh, /usr/share/bitquant/install-npm-sudo.sh 33 | 34 | 35 | ## Installation and management of software 36 | #Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum, /usr/sbin/urpmi, /usr/sbin/urpme, /bin/pip 37 | 38 | ## Services 39 | Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /bin/systemctl 40 | 41 | ## Updating the locate database 42 | # Cmnd_Alias LOCATE = /usr/bin/updatedb 43 | 44 | ## Storage 45 | # Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount 46 | 47 | ## Delegating permissions 48 | #Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp 49 | 50 | ## Processes 51 | Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall 52 | 53 | ## Drivers 54 | # Cmnd_Alias DRIVERS = /sbin/modprobe 55 | 56 | Cmnd_Alias USER = /bin/passwd 57 | 58 | Cmnd_Alias TIME = /bin/timedatectl 59 | 60 | # Defaults specification 61 | 62 | # 63 | # Disable "ssh hostname sudo ", because it will show the password in clear. 64 | # You have to run "ssh -t hostname sudo ". 65 | # 66 | Defaults requiretty 67 | 68 | Defaults env_reset 69 | Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS" 70 | Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" 71 | Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" 72 | Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" 73 | Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY" 74 | 75 | Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin 76 | 77 | ## Next comes the main part: which users can run what software on 78 | ## which machines (the sudoers file can be shared between multiple 79 | ## systems). 80 | ## Syntax: 81 | ## 82 | ## user MACHINE=COMMANDS 83 | ## 84 | ## The COMMANDS section may have other options added to it. 85 | ## 86 | Cmnd_Alias JUPYTER_CMD=/bin/sudospawner 87 | Cmnd_Alias JPHUB_CMD=/bin/jupyterhub 88 | Defaults!BITQUANT !requiretty 89 | Defaults!USER !requiretty 90 | Defaults!SERVICES !requiretty 91 | Defaults!TIME !requiretty 92 | Defaults!PROCESSES !requiretty 93 | user ALL= ALL, NOPASSWD:BITQUANT, NOPASSWD: SERVICES, NOPASSWD: USER, NOPASSWD: TIME, NOPASSWD: PROCESSES, NOPASSWD: JUPYTER_CMD, NOPASSWD: JPHUB_CMD 94 | 95 | 96 | # the command(s) the Hub can run on behalf of the above users without needing a password 97 | # the exact path may differ, depending on how sudospawner was installed 98 | Defaults!/bin/passwd !requiretty 99 | apache ALL=(ALL) NOPASSWD:/bin/passwd 100 | 101 | # actually give the Hub user permission to run the above command on behalf 102 | # of the above users without prompting for a password 103 | Defaults!JPHUB_CMD !requiretty 104 | Defaults!JUPYTER_CMD !requiretty 105 | rhea ALL=(ALL) ALL, NOPASSWD:JPHUB_CMD, NOPASSWD:JUPYTER_CMD 106 | -------------------------------------------------------------------------------- /bitstation/web/config/default-init/usr/lib/systemd/system/bitquant.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Bitquant servers 3 | After=httpd.service shiny-server.service 4 | Wants=httpd.service shiny-server.service 5 | 6 | [Service] 7 | Type=forking 8 | WorkingDirectory=/home/%USER%/git/bitquant/web/scripts 9 | User=%USER% 10 | Group=%GROUP% 11 | ExecStop=/home/%USER%/git/bitquant/web/scripts/shutdown.sh 12 | ExecStart=/home/%USER%/git/bitquant/web/scripts/startup.sh 13 | 14 | 15 | [Install] 16 | WantedBy=multi-user.target 17 | -------------------------------------------------------------------------------- /bitstation/web/config/default-init/usr/lib/systemd/system/shiny-server.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=shiny-server deploys R shiny applications 3 | 4 | [Service] 5 | Type=simple 6 | User=shiny 7 | ExecStart=/usr/bin/shiny-server 8 | 9 | [Install] 10 | WantedBy=multi-user.target 11 | -------------------------------------------------------------------------------- /bitstation/web/config/httpd-lock/etc/httpd/conf/webapps.d/00_bitquant_auth.conf: -------------------------------------------------------------------------------- 1 | 2 | AuthType Basic 3 | AuthName ${AUTH_NAME} 4 | AuthBasicProvider external 5 | AuthExternal pwauth 6 | require valid-user 7 | 8 | 9 | RewriteEngine on 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] 11 | 12 | -------------------------------------------------------------------------------- /bitstation/web/config/httpd-unlock/etc/httpd/conf/webapps.d/00_bitquant_auth.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/bitstation/web/config/httpd-unlock/etc/httpd/conf/webapps.d/00_bitquant_auth.conf -------------------------------------------------------------------------------- /bitstation/web/config/user/wiki-init: -------------------------------------------------------------------------------- 1 | apache:apache 2 | -------------------------------------------------------------------------------- /bitstation/web/config/user/wiki-lock: -------------------------------------------------------------------------------- 1 | apache:apache 2 | -------------------------------------------------------------------------------- /bitstation/web/config/user/wiki-unlock: -------------------------------------------------------------------------------- 1 | apache:apache 2 | -------------------------------------------------------------------------------- /bitstation/web/config/vimage/etc/cloud/cloud.cfg: -------------------------------------------------------------------------------- 1 | users: 2 | - default 3 | 4 | disable_root: 1 5 | ssh_pwauth: 0 6 | 7 | locale_configfile: /etc/sysconfig/i18n 8 | mount_default_fields: [~, ~, 'auto', 'defaults,nofail', '0', '2'] 9 | resize_rootfs_tmp: /dev 10 | ssh_deletekeys: 0 11 | ssh_genkeytypes: ~ 12 | syslog_fix_perms: ~ 13 | 14 | cloud_init_modules: 15 | - migrator 16 | - bootcmd 17 | - write-files 18 | - growpart 19 | - resizefs 20 | - set_hostname 21 | - update_hostname 22 | - update_etc_hosts 23 | - rsyslog 24 | - users-groups 25 | - ssh 26 | 27 | cloud_config_modules: 28 | - mounts 29 | - locale 30 | - set-passwords 31 | - timezone 32 | - puppet 33 | - chef 34 | - salt-minion 35 | - mcollective 36 | - disable-ec2-metadata 37 | - runcmd 38 | 39 | cloud_final_modules: 40 | - rightscale_userdata 41 | - scripts-per-once 42 | - scripts-per-boot 43 | - scripts-per-instance 44 | - scripts-user 45 | - ssh-authkey-fingerprints 46 | - keys-to-console 47 | - phone-home 48 | - final-message 49 | 50 | system_info: 51 | default_user: 52 | name: user 53 | lock_passwd: false 54 | gecos: Cloud User 55 | groups: [wheel, adm, systemd-journal] 56 | sudo: ["ALL=(ALL) NOPASSWD:ALL"] 57 | shell: /bin/bash 58 | distro: mageia 59 | paths: 60 | cloud_dir: /var/lib/cloud 61 | templates_dir: /etc/cloud/templates 62 | ssh_svcname: sshd 63 | 64 | # vim:syntax=yaml 65 | -------------------------------------------------------------------------------- /bitstation/web/config/vimage/etc/sysconfig/oem: -------------------------------------------------------------------------------- 1 | R='Bitstation development' 2 | R=$R$'\npowered by ' 3 | R=$R$(cat /etc/release) 4 | -------------------------------------------------------------------------------- /bitstation/web/config/vimage/etc/systemd/system/getty@tty1.service.d/autologin.conf: -------------------------------------------------------------------------------- 1 | [Service] 2 | ExecStart= 3 | ExecStart=-/usr/sbin/agetty --autologin user --noclear %I 38400 linux 4 | -------------------------------------------------------------------------------- /bitstation/web/config/vimage/usr/lib/systemd/system/cloud-init.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Initial cloud-init job (metadata service crawler) 3 | After=local-fs.target network.target cloud-init-local.service 4 | Requires=network.target 5 | Wants=local-fs.target cloud-init-local.service 6 | 7 | [Service] 8 | Type=oneshot 9 | ExecStart=/usr/bin/cloud-init init 10 | RemainAfterExit=yes 11 | TimeoutSec=0 12 | 13 | # Output needs to appear in instance console output 14 | #StandardOutput=tty 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | -------------------------------------------------------------------------------- /bitstation/web/config/webmin-init/etc/webmin/config: -------------------------------------------------------------------------------- 1 | ld_env=LD_LIBRARY_PATH 2 | tempdelete_days=7 3 | find_pid_command=ps auwwwx | grep NAME | grep -v grep | awk '{ print $2 }' 4 | passwd_uindex=0 5 | passwd_cindex=2 6 | passwd_pindex=1 7 | passwd_mindex=4 8 | by_view=0 9 | charset=UTF-8 10 | path=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin 11 | passwd_file=/etc/shadow 12 | os_type=mageia-linux 13 | os_version=8 14 | real_os_type=Mageia Linux 15 | real_os_version=8 16 | lang=en.UTF-8 17 | log=1 18 | referers=localhost 19 | md5pass=1 20 | theme=blue-theme 21 | theme=gray-theme 22 | product=webmin 23 | webprefix=/webmin 24 | webprefixnoredir=1 25 | -------------------------------------------------------------------------------- /bitstation/web/config/webmin-init/etc/webmin/miniserv.conf: -------------------------------------------------------------------------------- 1 | port=10000 2 | root=/usr/share/webmin 3 | mimetypes=/usr/share/webmin/mime.types 4 | addtype_cgi=internal/cgi 5 | realm=Webmin Server 6 | logfile=/var/run/webmin/miniserv.log 7 | errorlog=/var/run/webmin/miniserv.error 8 | pidfile=/var/run/webmin/miniserv.pid 9 | logtime=168 10 | ppath= 11 | ssl= 12 | no_ssl2=1 13 | no_ssl3=1 14 | no_tls1=1 15 | no_tls1_1=1 16 | ssl_honorcipherorder=1 17 | no_sslcompression=1 18 | env_WEBMIN_CONFIG=/etc/webmin 19 | env_WEBMIN_VAR=/var/run/webmin 20 | atboot= 21 | logout=/etc/webmin/logout-flag 22 | listen=10000 23 | denyfile=\.pl$ 24 | log=1 25 | blockhost_failures=5 26 | blockhost_time=60 27 | syslog=1 28 | ipv6=1 29 | session=1 30 | premodules=WebminCore 31 | server=MiniServ/1.831 32 | userfile=/etc/webmin/miniserv.users 33 | keyfile=/etc/pki/tls/private/miniserv.pem 34 | localauth=/usr/sbin/lsof 35 | passwd_file=/etc/shadow 36 | passwd_uindex=0 37 | passwd_pindex=1 38 | passwd_cindex=2 39 | passwd_mindex=4 40 | passwd_mode=0 41 | preroot=gray-theme 42 | preroot=gray-theme 43 | passdelay=1 44 | login_script=/etc/webmin/login.pl 45 | failed_script=/etc/webmin/failed.pl 46 | logout_script=/etc/webmin/logout.pl 47 | cipher_list_def=1 48 | cookiepath=/webmin 49 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-init/var/lib/dokuwiki/pages/about.txt: -------------------------------------------------------------------------------- 1 | The Bittrader analytics system is an alert and analytics system designed for individual traders and small proprietary shops. It consists of a web based system which can be uploaded to a cloud server, and is powered by the [[http://www.opengamma.com/|OpenGamma]] risks analytics engine, and [[http://www.r-project.org|R]] statistical project. Bitquant is developing this software to support its proprietary trading of bitcoin and bitcoin derivatives. 2 | 3 | The system completely open source and is distributed as a disk image on sourceforge which can be run via VirtualBox or uploaded to a cloud server. The source code is BSD-licensed and completely available at Github. 4 | 5 | To check out our progress see the [[http://bitquant.wordpress.com|Bitquant blog]] 6 | 7 | Our target date for alpha for an MVP (minimally viable product) is August 2014. 8 | 9 | What is unique about bittrader? 10 | 11 | * 100% open source / BSD licensed / all development on github 12 | * thin javascript client 13 | * distributed as a virtual disk image. Upload the image to a cloud or run as a virtual machine with VirtualBox. 14 | 15 | Bittrader pulls together several different technologies into one system 16 | 17 | * jqueryui (and friends) - display 18 | * mageia - infrastructure 19 | * ipython/irkernel - data exploration/reports 20 | * quantlib - algo trading 21 | 22 | see slides from [[pyconhk2015]] 23 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-init/var/lib/dokuwiki/pages/pyconhk2015.txt: -------------------------------------------------------------------------------- 1 | ~~SLIDESHOW~~ 2 | ====== PyCon Hong Kong 2015 ====== 3 | * How to start your own investment banq with python (see wikipedia entry on banq) 4 | * Joseph Wang 5 | * web: http://www.bitquant.com.hk/ 6 | * github: joequant/bitquant 7 | * docker: joequant/bitstation 8 | ===== This talk ===== 9 | * Mostly finance 10 | * There are bits of deep coding 11 | ===== About me ===== 12 | * Started out a physicist of supernova turned into a physicist of money 13 | * Software developer / Quant at big bank 14 | * Not a trader until recently 15 | ===== About Bitquant ===== 16 | * Financial research laboratory and investment banq 17 | * Worldwide scavanger hunt 18 | * World's first smart contract - HK contract written with javascript 19 | * Provide investment banking services to SME's 20 | * http://www.air-button.com/ - Button for android 21 | * Regulatory stuff - HKMA / Hong Kong Police 22 | * Two employees - Never more than five employees 23 | ===== Open Source ===== 24 | * Everything is BSD licensed 25 | * Feel free to make money off it 26 | * Github - joequant/bitquant 27 | * Open about strategies (HK/Mainland China reasons) 28 | ===== Financials ===== 29 | * AUM - HKD 3 million - USD 400k 30 | * Current return - HKD 20k/month - USD 2.5k / month 31 | * Target return - HKD 50k/month - USD 6k /month 32 | * World's first real smart contract - HK contract in javascript 33 | * No glass ceiling 34 | * Tax free !!!! 35 | * Half angel investment / Half trading 36 | * Cha-Chan-Teng / Taco Truck versus McDonald's 37 | ===== What is money? ===== 38 | * Money is information 39 | * Banking is about transferring information 40 | * Data can be stored 41 | * Money can be scripted 42 | ===== Python in Investment Banking ===== 43 | * Python is used to run IB's 44 | * Everything trading, risk management 45 | * JPMorgan - Athena / BAML - Quartz 46 | * Large parts of the python infrastructure was funded by banks 47 | * Washington Square Technologies 48 | ===== Why you haven't heard of this ===== 49 | * No reason to talk 50 | * Regulators 51 | * Patent trolls 52 | ===== Software lifecycle ===== 53 | * Driven by bonus system 54 | * Weird politics 55 | * Cutting edge to legacy system 56 | * Wild mix of technology 57 | * Best and the worst software development 58 | ===== Crisis in banking ===== 59 | * The money is gone and so is the fun 60 | * Not able to make the next jump to mobile 61 | * Competition from boutiques (like me) 62 | * Bottleneck to major changes 63 | * Not money 64 | * Software is the only thing 65 | ===== Trading strategies ===== 66 | * Bitcoin futures 67 | * Hong Kong options - see http://www.practicaloption.com.hk/ 68 | * Will love to talk about what I do 69 | * Trading is 90% psychology 70 | * Go to a casino - see what people do -and don't do that 71 | ===== Bitcoin futures ===== 72 | * Linear - Leveraged trades 73 | * Video game 74 | * Bitcoin is perfect for learning to trade 75 | * Spreadsheet 76 | ===== HK Options ===== 77 | * Non-linear 78 | * Short puts and short covered calls 79 | * Slot machine 80 | * Picking up pennies in front of a bulldozer 81 | * Risk management!!!! 82 | ===== Analytics platform ===== 83 | * Risk management and position visualization 84 | * Anti-casino human factors 85 | * Docker image 86 | * Mageia linux 87 | * Dokuwiki - note taking 88 | * Jupyter - Analytics - python3 / R / ijavascript 89 | * Ethercalc - Spreadsheet (!!!) 90 | ===== Trading scripting platform ===== 91 | * I need to sleep and have a life 92 | * Algobroker - pypi 93 | * Small scripts linked with pyzmq 94 | * Web interface with gevent 95 | * Mobile integrated!!!! 96 | * Biggest headache - HK Stock Exchange API rules 97 | ===== Current project ===== 98 | * Integrating ethercalc with python 99 | * Want to move out of LibreOffice (not web enabled) 100 | * ethercalc has an API - feed data with python 101 | * Finish up trading bot 102 | * Steal my software please!!!! 103 | ===== Lessons learned ===== 104 | * Unlearning corporate thinking 105 | * Enterprise software stinks 106 | * Trying to write software was a mistake 107 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-init/var/lib/dokuwiki/pages/start.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | About 11 | Trade Diary 13 | Scratchpad 15 | Links 17 |

18 | Calculation engine 20 | Document management 22 |

23 | Spreadsheet 24 | Pads

25 | Setup page 26 | Change password 27 | Logout 28 |
29 | 30 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-lock/etc/dokuwiki/acl.auth.php: -------------------------------------------------------------------------------- 1 | acl.auth.php 2 | # 3 | # Don't modify the lines above 4 | # 5 | # Access Control Lists 6 | # 7 | # Editing this file by hand shouldn't be necessary. Use the ACL 8 | # Manager interface instead. 9 | # 10 | # If your auth backend allows special char like spaces in groups 11 | # or user names you need to urlencode them (only chars <128, leave 12 | # UTF-8 multibyte chars as is) 13 | # 14 | # none 0 15 | # read 1 16 | # edit 2 17 | # create 4 18 | # upload 8 19 | # delete 16 20 | 21 | * @ALL 31 22 | * @users 31 23 | 24 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-lock/etc/dokuwiki/local.php: -------------------------------------------------------------------------------- 1 | 14 | 15 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-lock/etc/dokuwiki/users.auth.php: -------------------------------------------------------------------------------- 1 | # users.auth.php 2 | # 3 | # Don't modify the lines above 4 | # 5 | # Userfile 6 | # 7 | # Format: 8 | # 9 | # login:passwordhash:Real Name:email:groups,comma,seperated 10 | 11 | 12 | -------------------------------------------------------------------------------- /bitstation/web/config/wiki-unlock/etc/dokuwiki/local.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | -------------------------------------------------------------------------------- /bitstation/web/css/gh-fork-ribbon.css: -------------------------------------------------------------------------------- 1 | /* Left will inherit from right (so we don't need to duplicate code) */ 2 | .github-fork-ribbon { 3 | /* The right and left classes determine the side we attach our banner to */ 4 | position: absolute; 5 | 6 | /* Add a bit of padding to give some substance outside the "stitching" */ 7 | padding: 2px 0; 8 | 9 | /* Set the base colour */ 10 | background-color: #a00; 11 | 12 | /* Set a gradient: transparent black at the top to almost-transparent black at the bottom */ 13 | background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(0, 0, 0, 0.15))); 14 | background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 15 | background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 16 | background-image: -ms-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 17 | background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 18 | background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.15)); 19 | 20 | /* Add a drop shadow */ 21 | -webkit-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5); 22 | -moz-box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5); 23 | box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.5); 24 | 25 | z-index: 9999; 26 | pointer-events: auto; 27 | } 28 | 29 | .github-fork-ribbon a, 30 | .github-fork-ribbon a:hover { 31 | /* Set the font */ 32 | font: 700 13px "Helvetica Neue", Helvetica, Arial, sans-serif; 33 | color: #fff; 34 | 35 | /* Set the text properties */ 36 | text-decoration: none; 37 | text-shadow: 0 -1px rgba(0, 0, 0, 0.5); 38 | text-align: center; 39 | 40 | /* Set the geometry. If you fiddle with these you'll also need 41 | to tweak the top and right values in .github-fork-ribbon. */ 42 | width: 200px; 43 | line-height: 20px; 44 | 45 | /* Set the layout properties */ 46 | display: inline-block; 47 | padding: 2px 0; 48 | 49 | /* Add "stitching" effect */ 50 | border-width: 1px 0; 51 | border-style: dotted; 52 | border-color: #fff; 53 | border-color: rgba(255, 255, 255, 0.7); 54 | } 55 | 56 | .github-fork-ribbon-wrapper { 57 | width: 150px; 58 | height: 150px; 59 | position: absolute; 60 | overflow: hidden; 61 | top: 0; 62 | z-index: 9999; 63 | pointer-events: none; 64 | } 65 | 66 | .github-fork-ribbon-wrapper.fixed { 67 | position: fixed; 68 | } 69 | 70 | .github-fork-ribbon-wrapper.left { 71 | left: 0; 72 | } 73 | 74 | .github-fork-ribbon-wrapper.right { 75 | right: 0; 76 | } 77 | 78 | .github-fork-ribbon-wrapper.left-bottom { 79 | position: fixed; 80 | top: inherit; 81 | bottom: 0; 82 | left: 0; 83 | } 84 | 85 | .github-fork-ribbon-wrapper.right-bottom { 86 | position: fixed; 87 | top: inherit; 88 | bottom: 0; 89 | right: 0; 90 | } 91 | 92 | .github-fork-ribbon-wrapper.right .github-fork-ribbon { 93 | top: 42px; 94 | right: -43px; 95 | 96 | -webkit-transform: rotate(45deg); 97 | -moz-transform: rotate(45deg); 98 | -ms-transform: rotate(45deg); 99 | -o-transform: rotate(45deg); 100 | transform: rotate(45deg); 101 | } 102 | 103 | .github-fork-ribbon-wrapper.left .github-fork-ribbon { 104 | top: 42px; 105 | left: -43px; 106 | 107 | -webkit-transform: rotate(-45deg); 108 | -moz-transform: rotate(-45deg); 109 | -ms-transform: rotate(-45deg); 110 | -o-transform: rotate(-45deg); 111 | transform: rotate(-45deg); 112 | } 113 | 114 | 115 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { 116 | top: 80px; 117 | left: -43px; 118 | 119 | -webkit-transform: rotate(45deg); 120 | -moz-transform: rotate(45deg); 121 | -ms-transform: rotate(45deg); 122 | -o-transform: rotate(45deg); 123 | transform: rotate(45deg); 124 | } 125 | 126 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { 127 | top: 80px; 128 | right: -43px; 129 | 130 | -webkit-transform: rotate(-45deg); 131 | -moz-transform: rotate(-45deg); 132 | -ms-transform: rotate(-45deg); 133 | -o-transform: rotate(-45deg); 134 | transform: rotate(-45deg); 135 | } 136 | -------------------------------------------------------------------------------- /bitstation/web/css/gh-fork-ribbon.ie.css: -------------------------------------------------------------------------------- 1 | /* IE voodoo courtesy of http://stackoverflow.com/a/4617511/263871 and 2 | * http://www.useragentman.com/IETransformsTranslator */ 3 | 4 | .github-fork-ribbon { 5 | filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#000000', EndColorStr='#000000'); 6 | } 7 | 8 | .github-fork-ribbon-wrapper.right .github-fork-ribbon { 9 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ 10 | top: -22px; 11 | right: -62px; 12 | 13 | /* IE8+ */ 14 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; 15 | /* IE6 and 7 */ 16 | filter: progid:DXImageTransform.Microsoft.Matrix( 17 | M11=0.7071067811865474, 18 | M12=-0.7071067811865477, 19 | M21=0.7071067811865477, 20 | M22=0.7071067811865474, 21 | SizingMethod='auto expand' 22 | ); 23 | } 24 | 25 | .github-fork-ribbon-wrapper.left .github-fork-ribbon { 26 | top: -22px; 27 | left: -22px; 28 | 29 | /* IE8+ */ 30 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; 31 | /* IE6 and 7 */ 32 | filter: progid:DXImageTransform.Microsoft.Matrix( 33 | M11=0.7071067811865483, 34 | M12=0.7071067811865467, 35 | M21=-0.7071067811865467, 36 | M22=0.7071067811865483, 37 | SizingMethod='auto expand' 38 | ); 39 | } 40 | 41 | .github-fork-ribbon-wrapper.left-bottom .github-fork-ribbon { 42 | /* IE positioning hack (couldn't find a transform-origin alternative for IE) */ 43 | top: 12px; 44 | left: -22px; 45 | 46 | 47 | /* IE8+ */ 48 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865474, M12=-0.7071067811865477, M21=0.7071067811865477, M22=0.7071067811865474, SizingMethod='auto expand')"; 49 | /* IE6 and 7 */ 50 | /* filter: progid:DXImageTransform.Microsoft.Matrix( 51 | M11=0.7071067811865474, 52 | M12=-0.7071067811865477, 53 | M21=0.7071067811865477, 54 | M22=0.7071067811865474, 55 | SizingMethod='auto expand' 56 | ); 57 | */} 58 | 59 | .github-fork-ribbon-wrapper.right-bottom .github-fork-ribbon { 60 | top: 12px; 61 | right: -62px; 62 | 63 | /* IE8+ */ 64 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.7071067811865483, M12=0.7071067811865467, M21=-0.7071067811865467, M22=0.7071067811865483, SizingMethod='auto expand')"; 65 | /* IE6 and 7 */ 66 | filter: progid:DXImageTransform.Microsoft.Matrix( 67 | M11=0.7071067811865483, 68 | M12=0.7071067811865467, 69 | M21=-0.7071067811865467, 70 | M22=0.7071067811865483, 71 | SizingMethod='auto expand' 72 | ); 73 | } 74 | -------------------------------------------------------------------------------- /bitstation/web/css/metro-dokuwiki.css: -------------------------------------------------------------------------------- 1 | .metro .button, 2 | .metro .button:hover, 3 | .metro .button:active, 4 | .metro .button:focus { 5 | background-image: none; 6 | text-decoration: none; 7 | } 8 | -------------------------------------------------------------------------------- /bitstation/web/data/README.txt: -------------------------------------------------------------------------------- 1 | data files 2 | -------------------------------------------------------------------------------- /bitstation/web/fonts/metroSysIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/bitstation/web/fonts/metroSysIcons.ttf -------------------------------------------------------------------------------- /bitstation/web/fonts/metroSysIcons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/bitstation/web/fonts/metroSysIcons.woff -------------------------------------------------------------------------------- /bitstation/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Bitstation 4 | 5 | 6 | 7 | 8 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /bitstation/web/js/logout.js: -------------------------------------------------------------------------------- 1 | function logout() { 2 | var out = window.location.href.replace(/:\/\//, '://log:out@'); 3 | jQuery.get(out).always(function() { 4 | jQuery.get('/jupyterhub/hub/logout').always(function () {}); 5 | jQuery.get('/nextcloud/index.php/logout').always(function () {}); 6 | jQuery.get('/dokuwiki/doku.php?do=logout').always(function() { 7 | window.location.assign('/'); reload(true); 8 | }); 9 | }); 10 | return false; 11 | } 12 | -------------------------------------------------------------------------------- /bitstation/web/scripts/ethercalc-data/test.clc: -------------------------------------------------------------------------------- 1 | socialcalc:version:1.0 2 | MIME-Version: 1.0 3 | Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave 4 | --SocialCalcSpreadsheetControlSave 5 | Content-type: text/plain; charset=UTF-8 6 | 7 | # SocialCalc Spreadsheet Control Save 8 | version:1.0 9 | part:sheet 10 | part:edit 11 | part:audit 12 | --SocialCalcSpreadsheetControlSave 13 | Content-type: text/plain; charset=UTF-8 14 | 15 | version:1.5 16 | sheet:c:1:r:1:tvf:1 17 | valueformat:1:text-wiki 18 | --SocialCalcSpreadsheetControlSave 19 | Content-type: text/plain; charset=UTF-8 20 | 21 | version:1.0 22 | rowpane:0:1:1 23 | colpane:0:1:1 24 | ecell:A1 25 | --SocialCalcSpreadsheetControlSave 26 | Content-type: text/plain; charset=UTF-8 27 | 28 | --SocialCalcSpreadsheetControlSave-- 29 | 30 | -------------------------------------------------------------------------------- /bitstation/web/scripts/install-ethercalc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import ethercalc 4 | import os 5 | import sys 6 | import requests 7 | import os.path 8 | 9 | cwd = os.path.dirname(os.path.realpath(sys.argv[0])) 10 | ethercalc_dir = os.path.join(cwd, "ethercalc-data") 11 | ec = ethercalc.EtherCalc("http://localhost/calc/") 12 | lockfile = os.path.join("/var", "log", "bitquant", "ethercalc-init.txt") 13 | if os.path.isfile(lockfile): 14 | print("ethercalc already init. exiting") 15 | exit(0) 16 | 17 | for i in os.listdir(ethercalc_dir): 18 | if i.endswith(".clc"): 19 | item = i.rsplit(".", maxsplit=1)[0] 20 | try: 21 | a = ec.export(i) 22 | except requests.exceptions.HTTPError: 23 | txt = open(os.path.join(ethercalc_dir, i)) 24 | data = txt.read() 25 | # print (data) 26 | print (ec.update(item, data)) 27 | 28 | f = open(lockfile, "w") 29 | f.write("This file shows that ethercalc has been init.") 30 | f.close() 31 | -------------------------------------------------------------------------------- /bitstation/web/scripts/startup-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | WEB_DIR=$SCRIPT_DIR/.. 4 | GIT_DIR=$WEB_DIR/../.. 5 | LOG_DIR=/var/log/bitquant 6 | cd $SCRIPT_DIR 7 | 8 | mkdir -p $LOG_DIR 9 | chmod a+w $LOG_DIR 10 | chmod a+rx /home/user 11 | 12 | if [ -e /usr/share/bitquant/bitquant.sh ] ; then 13 | source /usr/share/bitquant/bitquant.sh 14 | echo "Bitstation - build $build_date $commit_id" 15 | fi 16 | echo "Create tmpfiles" 17 | systemd-tmpfiles --create 18 | echo "Start redis" 19 | sudo -u redis /usr/bin/redis-server /etc/redis.conf & 20 | echo "Start mongo" 21 | chown -R mongod:mongod /var/lib/mongodb 22 | sudo -u mongod /usr/bin/mongod --quiet -f /etc/mongod.conf & 23 | echo "Starting httpd" 24 | if [ -z "${AUTH_NAME}" ] ; then 25 | if [ ! -z "${INSTANCE_NAME}" ] ; then 26 | export AUTH_NAME=${INSTANCE_NAME} 27 | else 28 | export AUTH_NAME="PAM Authentication" 29 | fi 30 | fi 31 | 32 | if [ ! -z "${INSTANCE_NAME}" ] ; then 33 | export PS1="${INSTANCE_NAME}\\$ " 34 | fi 35 | 36 | if [ ! -d /var/lib/dokuwiki/log ] ; then 37 | mkdir -p /var/lib/dokuwiki/log 38 | chown apache:apache /var/lib/dokuwiki/log 39 | fi 40 | 41 | /usr/sbin/httpd -DFOREGROUND & 42 | if [ -f /etc/webmin/start ] ; then 43 | echo "Start webmin" 44 | /etc/webmin/start 45 | elif [ -f /usr/share/webmin/postinstall.sh ] ; then 46 | echo "Installing webmin" 47 | /usr/share/webmin/postinstall.sh 48 | sed -i -e 's!ssl=1!ssl=0!' /etc/webmin/miniserv.conf 49 | cat < /etc/webmin/miniserv.users 50 | user:x:0 51 | EOF 52 | cat <> /etc/webmin/config 53 | webprefix=/webmin 54 | webprefixnoredir=1 55 | EOF 56 | grep ^root: /etc/webmin/webmin.acl | sed -e s/root:/user:/ >> /etc/webmin/webmin.acl 57 | if [ -f /etc/webmin/useradmin/config ] ; then 58 | sed -i -e 's!base_uid=500!base_uid=1000!' /etc/webmin/useradmin/config 59 | sed -i -e 's!base_gid=500!base_gid=1000!' /etc/webmin/useradmin/config 60 | fi 61 | if [ -f /etc/webmin/start ] ; then 62 | echo "Start webmin" 63 | /etc/webmin/start 64 | fi 65 | fi 66 | 67 | if [ ! -f /etc/dmd.conf ] ; then 68 | cat < /etc/dmd.conf 69 | ; 70 | ; dmd.conf file for dmd 71 | ; 72 | ; dmd will look for dmd.conf in the following sequence of directories: 73 | ; - current working directory 74 | ; - directory specified by the HOME environment variable 75 | ; - directory dmd resides in 76 | ; - /etc directory 77 | ; 78 | ; Names enclosed by %% are searched for in the existing environment and inserted 79 | ; 80 | ; The special name %@P% is replaced with the path to this file 81 | ; 82 | 83 | [Environment32] 84 | DFLAGS=-I/usr/include/dlang/dmd -L-L/usr/lib -L--export-dynamic -fPIC -defaultlib=phobos2 -debuglib=phobos2 85 | 86 | [Environment64] 87 | DFLAGS=-I/usr/include/dlang/dmd -L-L/usr/lib64 -L--export-dynamic -fPIC -defaultlib=phobos2 -debuglib=phobos2 88 | EOF 89 | fi 90 | 91 | if [ ! -f /etc/jupyterhub ] ; then 92 | echo "Create jupyterhub" 93 | mkdir -p /etc/jupyterhub 94 | chown -R rhea:rhea /etc/jupyterhub 95 | fi 96 | 97 | if [ ! -f /etc/jupyter/jupyter_server_config.d ] ; then 98 | mkdir -p /etc/jupyter/jupyter_server_config.d 99 | echo < /etc/jupyter/jupyter_server_config.d/jupyterlab.json 100 | { 101 | "ServerApp": { 102 | "jpserver_extensions": { 103 | "jupyterlab": true 104 | } 105 | } 106 | } 107 | EOF 108 | mkdir -p /etc/jupyter 109 | echo < /etc/jupyter/jupyter_server_config.py 110 | # Extra static path for JupyROOT - start - do not remove this line 111 | c.ServerApp.extra_static_paths.append('/usr/share/root/notebook') 112 | # Extra static path for JupyROOT - end - do not remove this line 113 | EOF 114 | fi 115 | 116 | if [ -x /usr/bin/jupyterhub ] ; then 117 | echo "Start jupyterhub" 118 | pushd /etc/jupyterhub 119 | rm -f jupyterhub-proxy.pid 120 | sudo -u rhea /usr/bin/jupyterhub --JupyterHub.spawner_class=sudospawner.SudoSpawner --JupyterHub.authenticator_class='jhub_remote_user_authenticator.remote_user_auth.RemoteUserAuthenticator' --base-url='/jupyterhub' --Spawner.default_url='/lab' --debug >> $LOG_DIR/jupyterhub.log 2>&1 & 121 | popd 122 | fi 123 | 124 | if [ -x /usr/sbin/php-fpm ] ; then 125 | echo "Restarting php-fpm" 126 | sudo -u apache /usr/sbin/php-fpm --nodaemonize --fpm-config /etc/php-fpm.conf >> $LOG_DIR/php-fpm.log 2>&1 & 127 | fi 128 | 129 | echo "Pulling git" 130 | pushd $WEB_DIR/.. 131 | sudo -u user git config --global pull.rebase true 132 | sudo -u user git pull 133 | popd 134 | sudo -u user ./startup-user.sh 135 | while :; do sleep 20000; done 136 | -------------------------------------------------------------------------------- /bitstation/web/scripts/startup-user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | WEB_DIR=$SCRIPT_DIR/.. 4 | GIT_DIR=$WEB_DIR/../../.. 5 | LOG_DIR=$WEB_DIR/log 6 | cd $SCRIPT_DIR 7 | 8 | if [ -w /var/log/bitquant ] ; then 9 | LOG_DIR=/var/log/bitquant 10 | fi 11 | 12 | java_arch="i386" 13 | if [ "`uname -m`" == "x86_64" ] ; then 14 | java_arch="amd64" 15 | fi 16 | 17 | if [ -d $GIT_DIR/OG-Platform ] && [ -f /usr/bin/mvn ] ; then 18 | echo "Restarting opengamma" 19 | pushd $GIT_DIR/OG-Platform/examples/examples-simulated/ > /dev/null 20 | mvn opengamma:server-start -Dconfig=bitquant >> $LOG_DIR/og.log & 21 | popd > /dev/null 22 | fi 23 | 24 | if [ -f /usr/bin/ethercalc ] ; then 25 | echo "Restarting ethercalc" 26 | /usr/bin/ethercalc --basepath /calc/ --port 8100 >> $LOG_DIR/ethercalc.log 2>&1 & 27 | $SCRIPT_DIR/install-ethercalc.py 28 | fi 29 | 30 | if [ -e /usr/bin/configurable-http-proxy ] ; then 31 | echo "Restarting configurable-http-proxy" 32 | configurable-http-proxy --port 9010 --api-port 9011 --no-include-prefix >> $LOG_DIR/configurable-http-proxy 2 >&1 & 33 | fi 34 | 35 | if [ -d /var/lib/etherpad-lite ] ; then 36 | echo "Restarting etherpad" 37 | pushd /var/lib/etherpad-lite > /dev/null 38 | bin/run.sh >> $LOG_DIR/etherpad.log 2>&1 & 39 | popd > /dev/null 40 | fi 41 | 42 | if [ -f /usr/bin/rserver ] ; then 43 | echo "Restarting rserver" 44 | /usr/bin/rserver >> $LOG_DIR/rserver.log 2>&1 & 45 | fi 46 | 47 | -------------------------------------------------------------------------------- /hardware-hacking/dual-screen.md: -------------------------------------------------------------------------------- 1 | Alder Lake laptop - Laptop is *FAST* because of the 32GB ram although 2 | seems somewhat underpowered CPU. 3 | 4 | Able to install Linux - Wifi works. Audio seems to have issues but 5 | reports of kernel fixes 6 | 7 | Can't seem to charge with USB-C port. 8 | 9 | Big issue is screens. The work although they seem to be inverted. 10 | Setting up xandr and adding a monitor configuration works, for X 11 | applications. Causes headaches for GDM which doesn't use X 12 | configurations. Adding video config to grub causes screen to be 13 | correctly oriented but causes mouse to go upside down. 14 | 15 | xandr causes everything to work. Screens do not turn off 16 | automatically when lid is closed, but xrandr fixes that. 17 | 18 | Touch screen seems to have orientation issues. Screen seems to 19 | respond but need to fix orientation. -------------------------------------------------------------------------------- /ldap/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | ldap: 4 | image: "joequant/ldap" 5 | ports: 6 | - 3389:389 7 | - 9091:9090 8 | volumes: 9 | - spool:/var/spool 10 | - log:/var/log 11 | 12 | volumes: 13 | spool: 14 | log: 15 | -------------------------------------------------------------------------------- /ldap/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -v 3 | 4 | scriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | container=$(buildah from joequant/cauldron-minimal) 6 | buildah config --label maintainer="Joseph C Wang " $container 7 | buildah config --user root $container 8 | mountpoint=$(buildah mount $container) 9 | rootfsDir=$mountpoint 10 | name=joequant/ldap 11 | releasever=cauldron 12 | LANG=C 13 | LANGUAGE=C 14 | LC_ALL=C 15 | 16 | if [ -z $buildarch ]; then 17 | # Attempt to identify target arch 18 | buildarch="$(rpm --eval '%{_target_cpu}')" 19 | fi 20 | 21 | . $scriptDir/proxy.sh 22 | 23 | reposetup="--disablerepo=* --enablerepo=mageia-$buildarch --enablerepo=updates-$buildarch" 24 | 25 | cp $scriptDir/startup.sh $rootfsDir/sbin/startup.sh 26 | chmod a+rwx $rootfsDir/sbin/startup.sh 27 | ( 28 | dnf --installroot="$rootfsDir" \ 29 | --forcearch="$buildarch" \ 30 | --setopt=install_weak_deps=False --best -v -y \ 31 | --nodocs --allowerasing \ 32 | --releasever="$releasever" \ 33 | --nogpgcheck \ 34 | --refresh \ 35 | install \ 36 | 389-ds-base \ 37 | 389-console \ 38 | cockpit-389-ds \ 39 | cockpit-ws \ 40 | cockpit-dashboard \ 41 | cockpit \ 42 | procps-ng 43 | ) 44 | 45 | rpm --erase --nodeps --root $rootfsDir systemd \ 46 | `rpm -qa --root $rootfsDir | grep vulkan` \ 47 | `rpm -qa --root $rootfsDir | grep drm` \ 48 | `rpm -qa --root $rootfsDir | grep dri` \ 49 | `rpm -qa --root $rootfsDir | grep wayland` \ 50 | `rpm -qa --root $rootfsDir | grep adwaita` 51 | 52 | rpm --rebuilddb --root $rootfsDir 53 | pushd $rootfsDir 54 | rm -rf var/cache/* 55 | rm -f lib/*.so lib/*.so.* lib64/*.a lib/*.a lib/*.o 56 | rm -rf usr/lib/.build-id usr/lib64/mesa 57 | rm -rf usr/local usr/games 58 | rm -rf usr/lib/gcc/*/*/32 59 | #modclean seems to interfere with verdaccio 60 | #https://github.com/verdaccio/verdaccio/issues/1883 61 | popd 62 | 63 | buildah config --cmd "/sbin/startup.sh" $container 64 | buildah commit --format docker --rm $container $name 65 | buildah push $name:latest docker-daemon:$name:latest 66 | pump --shutdown 67 | -------------------------------------------------------------------------------- /ldap/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cacher", 3 | "scripts": { 4 | "build": "buildah unshare ./install.sh", 5 | "shell": "podman exec -ti ldap_ldap_1 /bin/bash", 6 | "up": "nohup podman-compose up >> ldap.log &", 7 | "down": "podman-compose down", 8 | "restart": "podman-compose down ; nohup podman-compose up >> ldap.log &" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ldap/proxy.sh: -------------------------------------------------------------------------------- 1 | # this is the location of the main server from a docker image 2 | export cache_server=172.17.0.1 3 | 4 | export timeout_exit=0 5 | timeout 1 bash -c 'cat < /dev/null > /dev/tcp/'$cache_server'/3128' || export timeout_exit=1 6 | 7 | if [ $timeout_exit == 0 ] ; then 8 | echo "running proxy" 9 | export http_proxy=http://$cache_server:3128/ 10 | export https_proxy=http://$cache_server:3128/ 11 | export ftp_proxy=http://$cache_server:3128/ 12 | export HTTP_PROXY=http://$cache_server:3128/ 13 | #cache with devpi-server 14 | export PIP_INDEX_URL=http://127.0.0.1:3141/root/pypi/+simple/ 15 | #cache with git-cache-http-server 16 | export GIT_PROXY=http://127.0.0.1:8080/ 17 | #cache with verdacchio 18 | export NPM_CONFIG_REGISTRY=http://127.0.0.1:4873/ 19 | export YARN_REGISTRY=http://127.0.0.1:4873/ 20 | #' 21 | fi 22 | 23 | export timeout_exit=0 24 | timeout 1 bash -c 'cat < /dev/null > /dev/tcp/$cache_server/3632' || export timeout_exit=1 25 | : ' 26 | if [ $timeout_exit == 0 ] ; then 27 | echo "running distcc" 28 | export PATH=/usr/lib64/distcc:$PATH 29 | export DISTCC_HOSTS="$cache_server" 30 | fi 31 | ' 32 | if [ $timeout_exit == 0 ] ; then 33 | echo "running distcc (pump mode)" 34 | export PATH=/usr/lib64/distcc:$PATH 35 | export DISTCC_HOSTS='172.17.0.1,cpp,lzo' 36 | eval `pump --startup` 37 | fi 38 | -------------------------------------------------------------------------------- /ldap/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "starting" 3 | /usr/libexec/cockpit-ws --proxy-tls-redirect --no-tls --port 0 & 4 | while :; do sleep 200000; done 5 | -------------------------------------------------------------------------------- /nextcloud/00_mpm.conf: -------------------------------------------------------------------------------- 1 | # Select the MPM module which should be used by uncommenting exactly 2 | # one of the following LoadModule lines: 3 | 4 | # prefork MPM: Implements a non-threaded, pre-forking web server 5 | # See: http://httpd.apache.org/docs/2.4/mod/prefork.html 6 | #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so 7 | 8 | # worker MPM: Multi-Processing Module implementing a hybrid 9 | # multi-threaded multi-process web server 10 | # See: http://httpd.apache.org/docs/2.4/mod/worker.html 11 | # 12 | #LoadModule mpm_worker_module modules/mod_mpm_worker.so 13 | 14 | # event MPM: A variant of the worker MPM with the goal of consuming 15 | # threads only for connections with active processing 16 | # See: http://httpd.apache.org/docs/2.4/mod/event.html 17 | # 18 | LoadModule mpm_event_module modules/mod_mpm_event.so 19 | 20 | -------------------------------------------------------------------------------- /nextcloud/backup.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash -f 2 | DATE=$(date -u +'%Y%m%d.%H%M%S') 3 | ID=nextcloud 4 | 5 | docker run -v ${ID}_lib:/volume --rm loomchild/volume-backup backup -c xz - > ${ID}_lib.$DATE.tar.xz 6 | docker run -v ${ID}_db:/volume --rm loomchild/volume-backup backup -c xz - > ${ID}_db.$DATE.tar.xz 7 | docker run -v ${ID}_etc:/volume --rm loomchild/volume-backup backup -c xz - > ${ID}_etc.$DATE.tar.xz 8 | -------------------------------------------------------------------------------- /nextcloud/config.php: -------------------------------------------------------------------------------- 1 | "file", 4 | "logfile" => "/var/log/httpd/nextcloud.log", 5 | "datadirectory" => "/var/lib/nextcloud/data", 6 | "updatechecker" => false, 7 | "check_for_working_htaccess" => false, 8 | "asset-pipeline.enabled" => false, 9 | "assetdirectory" => '/var/lib/nextcloud', 10 | "preview_libreoffice_path" => '/usr/bin/libreoffice', 11 | 'memcache.local' => '\OC\Memcache\APCu', 12 | "apps_paths" => array( 13 | 0 => 14 | array ( 15 | 'path'=> '/usr/share/nextcloud/apps', 16 | 'url' => '/apps', 17 | 'writable' => false, 18 | ), 19 | 1 => 20 | array ( 21 | 'path' => '/var/lib/nextcloud/apps', 22 | 'url' => '/apps-appstore', 23 | 'writable' => true, 24 | ), 25 | ), 26 | 'trusted_proxies'=>['172.16.0.0/12', '10.0.0.0/8', '192.168.0.0/16'], 27 | 'filelocking.enabled' => true, 28 | 'memcache.locking' => '\OC\Memcache\Redis', 29 | 'redis' => array( 30 | 'host' => 'localhost', 31 | 'port' => 6379, 32 | 'timeout' => 0.0, 33 | ), 34 | 'user_backends' => array( 35 | array( 36 | 'class' => 'OC_User_BasicAuth', 37 | 'arguments' => array('http://bitstation/dokuwiki/'), 38 | ), 39 | ), 40 | ); 41 | -------------------------------------------------------------------------------- /nextcloud/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | nextcloud: 4 | image: "joequant/nextcloud" 5 | ports: 6 | - 8081:80 7 | - 4433:443 8 | volumes: 9 | - lib_apps:/var/lib/nextcloud/data 10 | - lib_data:/var/lib/nextcloud/apps 11 | - etc:/etc/nextcloud 12 | restart: always 13 | depends_on: 14 | - db 15 | db: 16 | image: postgres:12-alpine 17 | restart: always 18 | environment: 19 | - POSTGRES_PASSWORD=mypass 20 | volumes: 21 | - db:/var/lib/postgresql/data 22 | restart: always 23 | 24 | volumes: 25 | lib_apps: 26 | lib_data: 27 | db: 28 | etc: 29 | -------------------------------------------------------------------------------- /nextcloud/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -v 3 | 4 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | container=$(buildah from joequant/cauldron) 6 | buildah config --label maintainer="Joseph C Wang " $container 7 | mountpoint=$(buildah mount $container) 8 | rootfsDir=$mountpoint 9 | name=joequant/nextcloud 10 | releasever=cauldron 11 | LANG=C 12 | LANGUAGE=C 13 | LC_ALL=C 14 | 15 | if [ -z $buildarch ]; then 16 | # Attempt to identify target arch 17 | buildarch="$(rpm --eval '%{_target_cpu}')" 18 | fi 19 | 20 | . $script_dir/proxy.sh 21 | 22 | systemd-sysusers --root=$rootfsDir $script_dir/system.conf 23 | #source $script_dir/proxy.sh 24 | ( 25 | dnf --installroot="$rootfsDir" \ 26 | --forcearch="$buildarch" \ 27 | --setopt=install_weak_deps=False --best -v -y \ 28 | --nodocs --allowerasing \ 29 | --releasever="$releasever" \ 30 | --nogpgcheck \ 31 | --refresh \ 32 | install \ 33 | nextcloud-sqlite \ 34 | nextcloud-postgresql \ 35 | apache \ 36 | apache-mod_proxy \ 37 | php-fpm \ 38 | php-cli \ 39 | php-intl \ 40 | php-pcntl \ 41 | php-redis \ 42 | php-apcu \ 43 | php-posix\ 44 | sudo \ 45 | tar gzip \ 46 | redis \ 47 | cronie \ 48 | locales-en \ 49 | curl \ 50 | timezone \ 51 | psmisc \ 52 | php-fpm-apache \ 53 | nodejs \ 54 | git 55 | ) 56 | 57 | rpm --erase --nodeps systemd --root $rootfsDir 58 | cat < $rootfsDir/etc/sudo.conf 59 | Set disable_coredump false 60 | EOF 61 | 62 | # prevent link from accessing outside 63 | pushd $rootfsDir/etc/nextcloud 64 | rm ca-bundle.crt 65 | popd 66 | 67 | pushd $rootfsDir 68 | cp $script_dir/startup-nextcloud.sh sbin 69 | cp $script_dir/config.php etc/nextcloud 70 | cp $script_dir/00_mpm.conf etc/httpd/conf/modules.d 71 | cp $script_dir/wait-for-it.sh sbin 72 | chmod a+x sbin/startup-nextcloud.sh 73 | chmod a+x sbin/wait-for-it.sh 74 | chown apache:apache sbin/startup-nextcloud.sh 75 | 76 | #buildah run $container sudo /usr/sbin/nextcloud-install.sh 77 | 78 | dnf --installroot="$rootfsDir" -y \ 79 | autoremove nodejs git 80 | 81 | sed -i -e 's/Listen 80/Listen ${HTTP_PORT}/' etc/httpd/conf/httpd.conf 82 | 83 | cat > var/spool/cron/apache - < /dev/tcp/172.17.0.1/3128' ; then 4 | echo "running proxy" 5 | export http_proxy=http://172.17.0.1:3128/ 6 | export https_proxy=http://172.17.0.1:3128/ 7 | export ftp_proxy=http://172.17.0.1:3128/ 8 | export HTTP_PROXY=http://172.17.0.1:3128/ 9 | #cache with devpi-server 10 | export PIP_INDEX_URL=http://127.0.0.1:3141/root/pypi/+simple/ 11 | #cache with git-cache-http-server 12 | export GIT_PROXY=http://127.0.0.1:8080/ 13 | #cache with verdacchio 14 | export NPM_CONFIG_REGISTRY=http://127.0.0.1:4873/ 15 | export YARN_REGISTRY=http://127.0.0.1:4873/ 16 | #' 17 | fi 18 | -------------------------------------------------------------------------------- /nextcloud/startup-nextcloud.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 3 | INSTALLED_FILE=/var/lib/nextcloud/data/installed 4 | 5 | crond & 6 | sudo -u redis redis-server /etc/redis.conf --daemonize no >> /var/log/redis.log 2>&1 & 7 | 8 | echo "waiting..." 9 | /sbin/wait-for-it.sh db:5432 10 | echo "connecting..." 11 | 12 | mkdir -p /run/httpd 13 | mkdir -p /run/php-fpm 14 | chown apache:apache /run/php-fpm 15 | 16 | if [ ! -e $INSTALLED_FILE ] ; then 17 | touch /etc/nextcloud/CAN_INSTALL 18 | chown apache:apache -R /usr/share/nextcloud 19 | pushd /usr/share/nextcloud 20 | sudo -u apache php -d memory_limit=512M \ 21 | occ maintenance:install \ 22 | --database="pgsql" --database-name="nextcloud" \ 23 | --database-host=${NEXTCLOUD_DB:-db} --database-user="postgres" \ 24 | --database-pass="mypass" --admin-user="user" \ 25 | --admin-pass="cubswin:)" --data-dir="/var/lib/nextcloud/data" 26 | sudo -u apache php occ config:system:set \ 27 | trusted_domains 1 "--value=*" 28 | sudo -u apache php occ background:cron 29 | 30 | for app in \ 31 | onlyoffice \ 32 | calendar \ 33 | maps \ 34 | contacts \ 35 | tasks \ 36 | mail \ 37 | notes \ 38 | deck \ 39 | quicknotes \ 40 | groupfolders \ 41 | files_texteditor \ 42 | files_markdown \ 43 | files_mindmap \ 44 | user_external \ 45 | ldap_write_support \ 46 | cms_pico \ 47 | sociallogin \ 48 | drawio \ 49 | documentserver_community 50 | do 51 | sudo -u apache php -d memory_limit=512M \ 52 | occ app:enable $app 53 | done 54 | popd 55 | 56 | #update to nc19 57 | # 58 | # occweb 59 | 60 | touch $INSTALLED_FILE 61 | rm /etc/nextcloud/CAN_INSTALL 62 | echo "If you get a 'ONLYOFFICE cannot be contacted. Please contact admin.' error" 63 | echo "Go into Setting > ONLYOFFICE and unset 'Document Editing Service address'" 64 | fi 65 | 66 | chown apache:apache -R /usr/share/nextcloud /var/lib/nextcloud /etc/nextcloud 67 | 68 | echo "Restarting php-fpm" 69 | /usr/sbin/php-fpm --nodaemonize --fpm-config /etc/php-fpm.conf >> /var/log/php-fpm.log 2>&1 & 70 | /usr/sbin/httpd -DFOREGROUND 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /nextcloud/system.conf: -------------------------------------------------------------------------------- 1 | # mongodb can write the pid there 2 | # this range should match /etc/login.defs 3 | u mongod 184 "MongoDB Database Server" /var/lib/mongodb 4 | g mongod 184 - 5 | u apache 48 "system user for webserver" /var/www 6 | g apache 48 7 | 8 | 9 | -------------------------------------------------------------------------------- /nextcloud/wait-for-it.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Use this script to test if a given TCP host/port are available 3 | 4 | WAITFORIT_cmdname=${0##*/} 5 | 6 | echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } 7 | 8 | usage() 9 | { 10 | cat << USAGE >&2 11 | Usage: 12 | $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args] 13 | -h HOST | --host=HOST Host or IP under test 14 | -p PORT | --port=PORT TCP port under test 15 | Alternatively, you specify the host and port as host:port 16 | -s | --strict Only execute subcommand if the test succeeds 17 | -q | --quiet Don't output any status messages 18 | -t TIMEOUT | --timeout=TIMEOUT 19 | Timeout in seconds, zero for no timeout 20 | -- COMMAND ARGS Execute command with args after the test finishes 21 | USAGE 22 | exit 1 23 | } 24 | 25 | wait_for() 26 | { 27 | if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then 28 | echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" 29 | else 30 | echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout" 31 | fi 32 | WAITFORIT_start_ts=$(date +%s) 33 | while : 34 | do 35 | if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then 36 | nc -z $WAITFORIT_HOST $WAITFORIT_PORT 37 | WAITFORIT_result=$? 38 | else 39 | (echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 40 | WAITFORIT_result=$? 41 | fi 42 | if [[ $WAITFORIT_result -eq 0 ]]; then 43 | WAITFORIT_end_ts=$(date +%s) 44 | echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds" 45 | break 46 | fi 47 | sleep 1 48 | done 49 | return $WAITFORIT_result 50 | } 51 | 52 | wait_for_wrapper() 53 | { 54 | # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 55 | if [[ $WAITFORIT_QUIET -eq 1 ]]; then 56 | timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & 57 | else 58 | timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT & 59 | fi 60 | WAITFORIT_PID=$! 61 | trap "kill -INT -$WAITFORIT_PID" INT 62 | wait $WAITFORIT_PID 63 | WAITFORIT_RESULT=$? 64 | if [[ $WAITFORIT_RESULT -ne 0 ]]; then 65 | echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" 66 | fi 67 | return $WAITFORIT_RESULT 68 | } 69 | 70 | # process arguments 71 | while [[ $# -gt 0 ]] 72 | do 73 | case "$1" in 74 | *:* ) 75 | WAITFORIT_hostport=(${1//:/ }) 76 | WAITFORIT_HOST=${WAITFORIT_hostport[0]} 77 | WAITFORIT_PORT=${WAITFORIT_hostport[1]} 78 | shift 1 79 | ;; 80 | --child) 81 | WAITFORIT_CHILD=1 82 | shift 1 83 | ;; 84 | -q | --quiet) 85 | WAITFORIT_QUIET=1 86 | shift 1 87 | ;; 88 | -s | --strict) 89 | WAITFORIT_STRICT=1 90 | shift 1 91 | ;; 92 | -h) 93 | WAITFORIT_HOST="$2" 94 | if [[ $WAITFORIT_HOST == "" ]]; then break; fi 95 | shift 2 96 | ;; 97 | --host=*) 98 | WAITFORIT_HOST="${1#*=}" 99 | shift 1 100 | ;; 101 | -p) 102 | WAITFORIT_PORT="$2" 103 | if [[ $WAITFORIT_PORT == "" ]]; then break; fi 104 | shift 2 105 | ;; 106 | --port=*) 107 | WAITFORIT_PORT="${1#*=}" 108 | shift 1 109 | ;; 110 | -t) 111 | WAITFORIT_TIMEOUT="$2" 112 | if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi 113 | shift 2 114 | ;; 115 | --timeout=*) 116 | WAITFORIT_TIMEOUT="${1#*=}" 117 | shift 1 118 | ;; 119 | --) 120 | shift 121 | WAITFORIT_CLI=("$@") 122 | break 123 | ;; 124 | --help) 125 | usage 126 | ;; 127 | *) 128 | echoerr "Unknown argument: $1" 129 | usage 130 | ;; 131 | esac 132 | done 133 | 134 | if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then 135 | echoerr "Error: you need to provide a host and port to test." 136 | usage 137 | fi 138 | 139 | WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15} 140 | WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} 141 | WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} 142 | WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} 143 | 144 | # Check to see if timeout is from busybox? 145 | WAITFORIT_TIMEOUT_PATH=$(type -p timeout) 146 | WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) 147 | 148 | WAITFORIT_BUSYTIMEFLAG="" 149 | if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then 150 | WAITFORIT_ISBUSY=1 151 | # Check if busybox timeout uses -t flag 152 | # (recent Alpine versions don't support -t anymore) 153 | if timeout &>/dev/stdout | grep -q -e '-t '; then 154 | WAITFORIT_BUSYTIMEFLAG="-t" 155 | fi 156 | else 157 | WAITFORIT_ISBUSY=0 158 | fi 159 | 160 | if [[ $WAITFORIT_CHILD -gt 0 ]]; then 161 | wait_for 162 | WAITFORIT_RESULT=$? 163 | exit $WAITFORIT_RESULT 164 | else 165 | if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then 166 | wait_for_wrapper 167 | WAITFORIT_RESULT=$? 168 | else 169 | wait_for 170 | WAITFORIT_RESULT=$? 171 | fi 172 | fi 173 | 174 | if [[ $WAITFORIT_CLI != "" ]]; then 175 | if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then 176 | echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess" 177 | exit $WAITFORIT_RESULT 178 | fi 179 | exec "${WAITFORIT_CLI[@]}" 180 | else 181 | exit $WAITFORIT_RESULT 182 | fi 183 | -------------------------------------------------------------------------------- /online-campus/moo/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mageia:7 2 | COPY install.sh install-user.sh proxy.sh startup.sh /tmp/ 3 | RUN source /tmp/install.sh 4 | RUN sudo -u user /tmp/install-user.sh 5 | -------------------------------------------------------------------------------- /online-campus/moo/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | moo: 4 | image: "joequant/moo" 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | ports: 9 | - 7777:7777 10 | - 7000:7000 11 | - 8001:80 12 | command: /home/user/startup.sh 13 | -------------------------------------------------------------------------------- /online-campus/moo/install-user.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /home/user 4 | wget 'https://master.dl.sourceforge.net/project/ele/enCore%20Database/enCore%205.0b/enCore-5.0b.tar.gz' 5 | wget 'http://lingo.uib.no/v5/downloads/LambdaMOO-1.8.1-unicode.tar.gz' 6 | mkdir moo 7 | cd moo 8 | mkdir bin 9 | mkdir src 10 | cd .. 11 | tar xzvf LambdaMOO-1.8.1-unicode.tar.gz 12 | cd MOO-1.8.1 13 | chmod a+x ./configure 14 | ./configure 15 | make 16 | cd .. 17 | mv MOO-1.8.1/moo moo/bin 18 | tar xzf enCore-5.0b.tar.gz 19 | mv encore/enCore.db moo/bin 20 | mv encore moo 21 | 22 | -------------------------------------------------------------------------------- /online-campus/moo/install.sh: -------------------------------------------------------------------------------- 1 | set -e -v 2 | cat <> /etc/dnf/dnf.conf 3 | fastestmirror=true 4 | excludepkgs=filesystem,chkconfig 5 | max_parallel_downloads=10 6 | EOF 7 | 8 | source /tmp/proxy.sh 9 | 10 | dnf upgrade --best --nodocs --allowerasing --refresh -y -x chkconfig -x filesystem 11 | dnf --setopt=install_weak_deps=False --best --allowerasing install -v -y --nodocs \ 12 | apache sudo wget gcc make byacc 13 | useradd user 14 | cp /tmp/startup.sh /home/user/startup.sh 15 | chmod a+x /home/user/startup.sh 16 | chmod a+rx /home/user 17 | cd /var/www/html 18 | ln -s /home/user/moo/encore . 19 | -------------------------------------------------------------------------------- /online-campus/moo/proxy.sh: -------------------------------------------------------------------------------- 1 | #: ' 2 | export http_proxy=http://172.17.0.1:3128/ 3 | export https_proxy=http://172.17.0.1:3128/ 4 | export ftp_proxy=http://172.17.0.1:3128/ 5 | export HTTP_PROXY=http://172.17.0.1:3128/ 6 | #cache with devpi-server 7 | export PIP_INDEX_URL=http://127.0.0.1:3141/root/pypi/+simple/ 8 | #cache with git-cache-http-server 9 | export GIT_PROXY=http://127.0.0.1:8080/ 10 | #cache with verdacchio 11 | export NPM_CONFIG_REGISTRY=http://127.0.0.1:4873/ 12 | export YARN_REGISTRY=http://127.0.0.1:4873/ 13 | #' 14 | export MAKEFLAGS=-j4 15 | -------------------------------------------------------------------------------- /online-campus/moo/startup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd /home/user/moo/bin 4 | /usr/sbin/httpd 5 | ./moo enCore.db enCore-out.db 6 | 7 | -------------------------------------------------------------------------------- /online-campus/moodle/backup-moodle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -f 2 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 3 | DATE=$(date -u +'%Y%m%d.%H%M%S') 4 | CMD=docker 5 | dir=`pwd` 6 | while getopts 'c:d:' OPTION; do 7 | case "$OPTION" in 8 | c) 9 | CMD="$OPTARG" 10 | ;; 11 | d) 12 | dir="$OPTARG" 13 | if [ ! -d $dir ] ; then 14 | echo "cannot find directory $dir" 15 | exit 1 16 | fi 17 | ;; 18 | ?) 19 | echo "script usage: -c cmd image" >&2 20 | exit 1 21 | ;; 22 | esac 23 | done 24 | 25 | pushd $dir 26 | $SCRIPT_DIR/../../bitstation/util/containers-shell.sh -c $CMD moodle_mariadb 'mysqldump -A -u root --single-transaction' | xz > moodle-db.$DATE.dmp.xz 27 | $CMD run -v moodle_moodle_data:/volume --rm loomchild/volume-backup backup -c xz - > moodle-data.$DATE.tar.xz 28 | popd 29 | -------------------------------------------------------------------------------- /online-campus/moodle/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | mariadb: 4 | image: 'bitnami/mariadb:10.1' 5 | environment: 6 | - MARIADB_USER=bn_moodle 7 | - MARIADB_DATABASE=bitnami_moodle 8 | - ALLOW_EMPTY_PASSWORD=yes 9 | volumes: 10 | - 'mariadb_data:/bitnami' 11 | moodle: 12 | image: 'bitnami/moodle:3' 13 | environment: 14 | - MARIADB_HOST=mariadb 15 | - MARIADB_PORT_NUMBER=3306 16 | - MOODLE_DATABASE_USER=bn_moodle 17 | - MOODLE_DATABASE_NAME=bitnami_moodle 18 | - ALLOW_EMPTY_PASSWORD=yes 19 | ports: 20 | - '80:80' 21 | - '443:443' 22 | volumes: 23 | - 'moodle_data:/bitnami' 24 | depends_on: 25 | - mariadb 26 | volumes: 27 | mariadb_data: 28 | driver: local 29 | moodle_data: 30 | driver: local 31 | -------------------------------------------------------------------------------- /overleaf/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2.2' 2 | services: 3 | sharelatex: 4 | restart: always 5 | # Server Pro users: 6 | # image: quay.io/sharelatex/sharelatex-pro 7 | image: sharelatex/sharelatex 8 | container_name: sharelatex 9 | depends_on: 10 | mongo: 11 | condition: service_healthy 12 | redis: 13 | condition: service_started 14 | privileged: true 15 | ports: 16 | - 8089:80 17 | links: 18 | - mongo 19 | - redis 20 | volumes: 21 | - sharelatex_data:/var/lib/sharelatex 22 | ######################################################################## 23 | #### Server Pro: Un-comment the following line to mount the docker #### 24 | #### socket, required for Sibling Containers to work #### 25 | ######################################################################## 26 | # - /var/run/docker.sock:/var/run/docker.sock 27 | environment: 28 | 29 | SHARELATEX_APP_NAME: Overleaf Community Edition 30 | 31 | SHARELATEX_MONGO_URL: mongodb://mongo/sharelatex 32 | 33 | # Same property, unfortunately with different names in 34 | # different locations 35 | SHARELATEX_REDIS_HOST: redis 36 | REDIS_HOST: redis 37 | 38 | ENABLED_LINKED_FILE_TYPES: 'url,project_file' 39 | 40 | # Enables Thumbnail generation using ImageMagick 41 | ENABLE_CONVERSIONS: 'true' 42 | 43 | # Disables email confirmation requirement 44 | EMAIL_CONFIRMATION_DISABLED: 'true' 45 | 46 | ## Set for SSL via nginx-proxy 47 | #VIRTUAL_HOST: 103.112.212.22 48 | 49 | # SHARELATEX_SITE_URL: http://sharelatex.mydomain.com 50 | # SHARELATEX_NAV_TITLE: Our ShareLaTeX Instance 51 | # SHARELATEX_HEADER_IMAGE_URL: http://somewhere.com/mylogo.png 52 | # SHARELATEX_ADMIN_EMAIL: support@it.com 53 | 54 | # SHARELATEX_LEFT_FOOTER: '[{"text": "Powered by ShareLaTeX 2016"},{"text": "Another page I want to link to can be found here"} ]' 55 | # SHARELATEX_RIGHT_FOOTER: '[{"text": "Hello I am on the Right"} ]' 56 | 57 | # SHARELATEX_EMAIL_FROM_ADDRESS: "team@sharelatex.com" 58 | 59 | # SHARELATEX_EMAIL_AWS_SES_ACCESS_KEY_ID: 60 | # SHARELATEX_EMAIL_AWS_SES_SECRET_KEY: 61 | 62 | # SHARELATEX_EMAIL_SMTP_HOST: smtp.mydomain.com 63 | # SHARELATEX_EMAIL_SMTP_PORT: 587 64 | # SHARELATEX_EMAIL_SMTP_SECURE: false 65 | # SHARELATEX_EMAIL_SMTP_USER: 66 | # SHARELATEX_EMAIL_SMTP_PASS: 67 | # SHARELATEX_EMAIL_SMTP_TLS_REJECT_UNAUTH: true 68 | # SHARELATEX_EMAIL_SMTP_IGNORE_TLS: false 69 | # SHARELATEX_CUSTOM_EMAIL_FOOTER: "
This system is run by department x
" 70 | 71 | ################ 72 | ## Server Pro ## 73 | ################ 74 | 75 | # SANDBOXED_COMPILES: 'true' 76 | 77 | # SANDBOXED_COMPILES_SIBLING_CONTAINERS: 'true' 78 | # SANDBOXED_COMPILES_HOST_DIR: '/var/sharelatex_data/data/compiles' 79 | # SYNCTEX_BIN_HOST_PATH: '/var/sharelatex_data/bin/synctex' 80 | 81 | # DOCKER_RUNNER: 'false' 82 | 83 | ## Works with test LDAP server shown at bottom of docker compose 84 | # SHARELATEX_LDAP_URL: 'ldap://ldap:389' 85 | # SHARELATEX_LDAP_SEARCH_BASE: 'ou=people,dc=planetexpress,dc=com' 86 | # SHARELATEX_LDAP_SEARCH_FILTER: '(uid={{username}})' 87 | # SHARELATEX_LDAP_BIND_DN: 'cn=admin,dc=planetexpress,dc=com' 88 | # SHARELATEX_LDAP_BIND_CREDENTIALS: 'GoodNewsEveryone' 89 | # SHARELATEX_LDAP_EMAIL_ATT: 'mail' 90 | # SHARELATEX_LDAP_NAME_ATT: 'cn' 91 | # SHARELATEX_LDAP_LAST_NAME_ATT: 'sn' 92 | # SHARELATEX_LDAP_UPDATE_USER_DETAILS_ON_LOGIN: 'true' 93 | 94 | # SHARELATEX_TEMPLATES_USER_ID: "578773160210479700917ee5" 95 | # SHARELATEX_NEW_PROJECT_TEMPLATE_LINKS: '[ {"name":"All Templates","url":"/templates/all"}]' 96 | 97 | 98 | # SHARELATEX_PROXY_LEARN: "true" 99 | 100 | mongo: 101 | restart: always 102 | image: mongo 103 | container_name: mongo 104 | expose: 105 | - 27017 106 | volumes: 107 | - mongo_data:/data/db 108 | healthcheck: 109 | test: echo 'db.stats().ok' | mongo localhost:27017/test --quiet 110 | interval: 10s 111 | timeout: 10s 112 | retries: 5 113 | 114 | redis: 115 | restart: always 116 | image: redis 117 | container_name: redis 118 | expose: 119 | - 6379 120 | volumes: 121 | - redis_data:/data 122 | 123 | # ldap: 124 | # restart: always 125 | # image: rroemhild/test-openldap 126 | # container_name: ldap 127 | # expose: 128 | # - 389 129 | 130 | # See https://github.com/jwilder/nginx-proxy for documentation on how to configure the nginx-proxy container, 131 | # and https://github.com/overleaf/overleaf/wiki/HTTPS-reverse-proxy-using-Nginx for an example of some recommended 132 | # settings. We recommend using a properly managed nginx instance outside of the Overleaf Server Pro setup, 133 | # but the example here can be used if you'd prefer to run everything with docker-compose 134 | 135 | # nginx-proxy: 136 | # image: jwilder/nginx-proxy 137 | # container_name: nginx-proxy 138 | # ports: 139 | # #- "80:80" 140 | # - "443:443" 141 | # volumes: 142 | # - /var/run/docker.sock:/tmp/docker.sock:ro 143 | # - /home/sharelatex/tmp:/etc/nginx/certs 144 | volumes: 145 | sharelatex_data: 146 | mongo_data: 147 | redis_data: 148 | -------------------------------------------------------------------------------- /papers/article_template.tex: -------------------------------------------------------------------------------- 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 | % Journal Article 3 | % LaTeX Template 4 | % Version 1.3 (9/9/13) 5 | % 6 | % This template has been downloaded from: 7 | % http://www.LaTeXTemplates.com 8 | % 9 | % Original author: 10 | % Frits Wenneker (http://www.howtotex.com) 11 | % 12 | % License: 13 | % CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/) 14 | % 15 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 | 17 | %---------------------------------------------------------------------------------------- 18 | % PACKAGES AND OTHER DOCUMENT CONFIGURATIONS 19 | %---------------------------------------------------------------------------------------- 20 | 21 | \documentclass[twoside]{article} 22 | 23 | \usepackage{lipsum} % Package to generate dummy text throughout this template 24 | 25 | \usepackage[sc]{mathpazo} % Use the Palatino font 26 | \usepackage[T1]{fontenc} % Use 8-bit encoding that has 256 glyphs 27 | \linespread{1.05} % Line spacing - Palatino needs more space between lines 28 | \usepackage{microtype} % Slightly tweak font spacing for aesthetics 29 | 30 | \usepackage[hmarginratio=1:1,top=32mm,columnsep=20pt]{geometry} % Document margins 31 | \usepackage{multicol} % Used for the two-column layout of the document 32 | \usepackage[hang, small,labelfont=bf,up,textfont=it,up]{caption} % Custom captions under/above floats in tables or figures 33 | \usepackage{booktabs} % Horizontal rules in tables 34 | \usepackage{float} % Required for tables and figures in the multi-column environment - they need to be placed in specific locations with the [H] (e.g. \begin{table}[H]) 35 | \usepackage{hyperref} % For hyperlinks in the PDF 36 | 37 | \usepackage{lettrine} % The lettrine is the first enlarged letter at the beginning of the text 38 | \usepackage{paralist} % Used for the compactitem environment which makes bullet points with less space between them 39 | 40 | \usepackage{abstract} % Allows abstract customization 41 | \renewcommand{\abstractnamefont}{\normalfont\bfseries} % Set the "Abstract" text to bold 42 | \renewcommand{\abstracttextfont}{\normalfont\small\itshape} % Set the abstract itself to small italic text 43 | 44 | \usepackage{titlesec} % Allows customization of titles 45 | \renewcommand\thesection{\Roman{section}} % Roman numerals for the sections 46 | \renewcommand\thesubsection{\Roman{subsection}} % Roman numerals for subsections 47 | \titleformat{\section}[block]{\large\scshape\centering}{\thesection.}{1em}{} % Change the look of the section titles 48 | \titleformat{\subsection}[block]{\large}{\thesubsection.}{1em}{} % Change the look of the section titles 49 | 50 | \usepackage{fancyhdr} % Headers and footers 51 | \pagestyle{fancy} % All pages have headers and footers 52 | \fancyhead{} % Blank out the default header 53 | \fancyfoot{} % Blank out the default footer 54 | \fancyhead[C]{Running title $\bullet$ November 2012 $\bullet$ Vol. XXI, No. 1} % Custom header text 55 | \fancyfoot[RO,LE]{\thepage} % Custom footer text 56 | 57 | %---------------------------------------------------------------------------------------- 58 | % TITLE SECTION 59 | %---------------------------------------------------------------------------------------- 60 | 61 | \title{\vspace{-15mm}\fontsize{24pt}{10pt}\selectfont\textbf{Article Title}} % Article title 62 | 63 | \author{ 64 | \large 65 | \textsc{John Smith}\thanks{A thank you or further information}\\[2mm] % Your name 66 | \normalsize University of California \\ % Your institution 67 | \normalsize \href{mailto:john@smith.com}{john@smith.com} % Your email address 68 | \vspace{-5mm} 69 | } 70 | \date{} 71 | 72 | %---------------------------------------------------------------------------------------- 73 | 74 | \begin{document} 75 | 76 | \maketitle % Insert title 77 | 78 | \thispagestyle{fancy} % All pages have headers and footers 79 | 80 | %---------------------------------------------------------------------------------------- 81 | % ABSTRACT 82 | %---------------------------------------------------------------------------------------- 83 | 84 | \begin{abstract} 85 | 86 | \noindent \lipsum[1] % Dummy abstract text 87 | 88 | \end{abstract} 89 | 90 | %---------------------------------------------------------------------------------------- 91 | % ARTICLE CONTENTS 92 | %---------------------------------------------------------------------------------------- 93 | 94 | \begin{multicols}{2} % Two-column layout throughout the main article text 95 | 96 | \section{Introduction} 97 | 98 | \lettrine[nindent=0em,lines=3]{L} orem ipsum dolor sit amet, consectetur adipiscing elit. 99 | \lipsum[2-3] % Dummy text 100 | 101 | %------------------------------------------------ 102 | 103 | \section{Methods} 104 | 105 | Maecenas sed ultricies felis. Sed imperdiet dictum arcu a egestas. 106 | \begin{compactitem} 107 | \item Donec dolor arcu, rutrum id molestie in, viverra sed diam 108 | \item Curabitur feugiat 109 | \item turpis sed auctor facilisis 110 | \item arcu eros accumsan lorem, at posuere mi diam sit amet tortor 111 | \item Fusce fermentum, mi sit amet euismod rutrum 112 | \item sem lorem molestie diam, iaculis aliquet sapien tortor non nisi 113 | \item Pellentesque bibendum pretium aliquet 114 | \end{compactitem} 115 | \lipsum[4] % Dummy text 116 | 117 | %------------------------------------------------ 118 | 119 | \section{Results} 120 | 121 | \begin{table}[H] 122 | \caption{Example table} 123 | \centering 124 | \begin{tabular}{llr} 125 | \toprule 126 | \multicolumn{2}{c}{Name} \\ 127 | \cmidrule(r){1-2} 128 | First name & Last Name & Grade \\ 129 | \midrule 130 | John & Doe & $7.5$ \\ 131 | Richard & Miles & $2$ \\ 132 | \bottomrule 133 | \end{tabular} 134 | \end{table} 135 | 136 | \lipsum[5] % Dummy text 137 | 138 | \begin{equation} 139 | \label{eq:emc} 140 | e = mc^2 141 | \end{equation} 142 | 143 | \lipsum[6] % Dummy text 144 | 145 | %------------------------------------------------ 146 | 147 | \section{Discussion} 148 | 149 | \subsection{Subsection One} 150 | 151 | \lipsum[7] % Dummy text 152 | 153 | \subsection{Subsection Two} 154 | 155 | \lipsum[8] % Dummy text 156 | 157 | %---------------------------------------------------------------------------------------- 158 | % REFERENCE LIST 159 | %---------------------------------------------------------------------------------------- 160 | 161 | \begin{thebibliography}{99} % Bibliography - this is intentionally simple in this template 162 | 163 | \bibitem[Figueredo and Wolf, 2009]{Figueredo:2009dg} 164 | Figueredo, A.~J. and Wolf, P. S.~A. (2009). 165 | \newblock Assortative pairing and life history strategy - a cross-cultural 166 | study. 167 | \newblock {\em Human Nature}, 20:317--330. 168 | 169 | \end{thebibliography} 170 | 171 | %---------------------------------------------------------------------------------------- 172 | 173 | \end{multicols} 174 | 175 | \end{document} 176 | -------------------------------------------------------------------------------- /papers/financial-products.txt: -------------------------------------------------------------------------------- 1 | Using new technology for innovative financial products 2 | ------------------------------------------------------ 3 | 4 | Current technology requires that the project or funder invest several 5 | tens of millions of dollars to create an investment. To set up a fund 6 | your costs are USD 100k/year, assuming 1-5% fund management, you need 7 | AUM of 2 million to breakeven. 8 | 9 | Need to reduce backend processing costs to zero, so funds go into deal 10 | making and due dilligence 11 | 12 | Projects that are not funded 13 | ---------------------------- 14 | 1) Seed stage companies - Convertible bonds 15 | 2) Factoring and cash flow companies - gadget manufacturers in south 16 | China 17 | 3) Geographically diverse areas - Southeast Asia, Africa, Russia 18 | 19 | People who want to invest and can't 20 | ----------------------------------- 21 | 1) Mass affluent - People that want to invest USD 10k-50k in a project 22 | 2) People in various parts of the world - Southeast Asia, Africa, and 23 | Russia 24 | 25 | Use ICO technology to reduce backend costs 26 | ------------------------------------------ 27 | 28 | What to do: 29 | 30 | Create exchange for professional investors 31 | ------------------------------------------ 32 | 33 | Use bitcoin exchange infrastructure. Find an exchange which is 34 | already profitable trading bitcoin and add the ability to trade shares 35 | of hedge funds and innovative products. 36 | 37 | Exchange will charge USD 5k for listing. Regulatory/AML/KYC is done 38 | by the issuer. Exchange will display trades for products, but will 39 | only authorize an account for trading if approved by issuer. Issuer 40 | can sell new shares on exchange. Also transfers to and from exchange 41 | is done by exchange communicating with issuer. 42 | 43 | Since exchange is already profitable trading bitcoin, cost for adding 44 | new trading pair is small. 45 | 46 | Trading bitcoin will allow company to accept investors from all over 47 | the world. Opening accounts for companies authorized by issuer moves 48 | AML/KYC/regulation to issuer. Also allows for algo trading between 49 | non-traditional products. Also the exchange can be a marketing 50 | channel, as providing information and limiting trading will prevent 51 | the marketing from being seen as an offerring. 52 | 53 | What is different from existing exchanges: 54 | 55 | 1) all efforts at existing exchanges have been product centered. This 56 | is a problem because the exchange can't make money if the product 57 | isn't successful and the exchange cannot bootstrap listing of new 58 | products. In this system, the exchange is already making money 59 | trading bitcoin. they can amortize costs among many different 60 | products 61 | 62 | 2) AML/KYC/regulation is done by the issuer. Also the issuer pays for 63 | costs. 64 | 65 | Create HKD/CNH coin 66 | ------------------- 67 | 68 | Coin will be HKD/CNH token which is linked to an bank account. Allows 69 | user to store value, and buy and sell items 70 | 71 | Create standardized tradable products 72 | ------------------------------------- 73 | 74 | Set up convertible notes that are standarized for trading. 75 | 76 | Create coin-based registration 77 | ------------------------------ 78 | 79 | Set up coins so that possession of the coin gives you the ability to 80 | register ownership, and allows issuer to burn coins. Coins then 81 | become tokens that allow for registration rather than bearer shares. 82 | 83 | Create legal box to allow coin owners to hold assets 84 | ---------------------------------------------------- 85 | 86 | Create badges for AML/KYC/regulation 87 | ------------------------------------ 88 | -------------------------------------------------------------------------------- /papers/hkdx.txt: -------------------------------------------------------------------------------- 1 | HKDX Coin 2 | CNHX Coin 3 | 4 | Proposal: 5 | 6 | Create two coins. One is backed by the Hong Kong dollar. The other 7 | will be backed by Renminbi on deposit in Hong Kong. 8 | 9 | Who would be interested in this? 10 | 11 | 1) Hedge funds and VC's 12 | 1a) They need a reliable way of settling payments throughout the world 13 | 1b) Right now it is impossible to hedge CNH risk or develop 14 | CNH/HKD-based products because of a lack of a settlement mechanism. 15 | Current settlement mechanism require government-to-government 16 | negotiations and the creation of settlement mechanisms which can take 17 | years. The lack of a settlement mechanism makes it impossible for 18 | overseas investors to create CNH/HKD denominated products. 19 | 1c) Methods to automate back office systems and due dilgence. A fund 20 | can cryptographically verify that it has funds under control, and 21 | automate settlement and reconcilation 22 | 23 | 2) ICO's need 24 | 2a) a stable unit of exchange to receive funds. Using ethereum 25 | to onboard or off-board funds creates volatility in ICO worl 26 | 2b) a method of storing value that bypasses banks 27 | 2c) a way of transfering stable currencies via smart contracts. 28 | 29 | 3) Hong Kong businesses need: 30 | 3a) A way of storing funds that allows one to operate without an 31 | HK bank account 32 | 33 | 4) Hong Kong bitcoin exchanges need: 34 | 4a) A way of pooling liquidity and a mechanism to conduct 35 | interexchange transmission 36 | 37 | 5) Banks need: 38 | 5a) A way of getting this technology out. All of the major banks have 39 | developed this settlement technology, but they have been unable to 40 | deploy for regulatory reasons. A HK based token system will be 41 | subject to regulation only by HKMA, and once it is operational, it can 42 | be more easily adapted by the banks than developing internal systems 43 | 44 | 6) Hong Kong needs: 45 | 6a) A way of promoting the HK dollar. Having the HKD being used 46 | as the standard currency for raising money through ICO's will 47 | create a pool of liquidity that will promote HK. Once ICO's use 48 | the HKD as the basis for their activities, this will encourage 49 | them to use HK as a banking center. 50 | 6b) A way of promoting Renminbi products. The problem with RMB 51 | denominated products is that an asset manager in most places simply 52 | cannot deal settle in RMB. A Wall Street investment fund may love to 53 | buy dim-sum bonds but they simply cannot because they have no way of 54 | accepting/rejecting RMB 55 | 56 | 7) Everyone needs 57 | 7a) A way of reducing AML/KYC costs. Once the holder of one 58 | wallet has been identified, then law enforcement can trace the 59 | transactions through that wallet. It is therefore unnecessary to 60 | perform AML/KYC on all accounts You merely need to 61 | 62 | What is the technology? 63 | 64 | 1) OKLink has done this with the OKDollar a token that is pegging 65 | to the USD. Access to the OKDollar is limited to companies on 66 | the OKLink network which is restricted to institutions that are 67 | licensed to send/receive money 68 | 69 | 2) Tether has also has created a USD token 70 | 71 | Why HKD is better than USD: 72 | 73 | 1) Deposits to the Tether token has been shut down because the 74 | bank involved is located in Taiwan and the international 75 | correspondent banks have shut down wire transfers to the tether 76 | account. Deposits can only be made through local Taiwan banks, 77 | and Taiwan is not enough of a banking center for overseas 78 | companies to get bank accounts. 79 | 80 | 1a) The HKD token need only be redeemable for fiat in HK. In 81 | order to on-board or off-board fiat you need to do that in HK 82 | through local bank transfer, and other people will be able to hit 83 | it through 84 | 85 | 2) Tether and OKLink can't talk directly to the FBI, the Federal 86 | Reserve, and the SEC. An HK company that creates a HKD token can 87 | talk directly to HK Police, the HKMA, and the SFC. 88 | 89 | The killer coin - CNHX coin 90 | 91 | 1) Internationalize the RMB!!!!! 92 | 2) Create RMB denominated products!!!!! If someone in Peoria, 93 | Illinois or Johannesburg, South Africa wants to buy a dim-sum bond, 94 | they now can!!!! 95 | 96 | ------------------ 97 | 98 | Implementation: 99 | 100 | Central bank model. 101 | 102 | Create a company limited by guarantee with a set of members: 103 | 104 | 1) Members will be required to post a minimum deposit and pay a 105 | monthly membership fee. 106 | 107 | 2) Only members will be able to exchange HKD or CNH directly with the 108 | central foundation. The fiat currency exchanged for tokens will be 109 | subject to a minimum amount 110 | 111 | 3) The fact that you have a small number of members which can only do 112 | large infrequent transactions makes this easier to sell to bank 113 | compliance 114 | 115 | Types of members: 116 | 117 | 1) Initial members will include all of the major bitcoin exchanges in 118 | Hong Kong, since they will be responsible for circulating the coin to 119 | the general public 120 | 2) Hedge funds and VC funds that want to make token exchanges directly 121 | with the foundation 122 | 3) Money services companies that can now use the tokens to exchange 123 | directly with cash 124 | 125 | Member elect a board which appoints staff: 126 | 127 | The people who are necessary 128 | 129 | 1) legal/compliance 130 | 2) technical 131 | 3) business development 132 | 4) marketing/social media expert 133 | 134 | -------------------------------------------------------------------------------- /papers/its-obor.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/papers/its-obor.pdf -------------------------------------------------------------------------------- /papers/its-obor.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/papers/its-obor.pptx -------------------------------------------------------------------------------- /papers/joequant-qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/papers/joequant-qr.png -------------------------------------------------------------------------------- /papers/macro.bib: -------------------------------------------------------------------------------- 1 | @misc { irwin, 2 | author = "Neal Irwin", 3 | title = "Bitcoin is ludicrous, but it tells us something important about the nature of money", 4 | year = "2013", 5 | url = "http://www.washingtonpost.com/blogs/wonkblog/wp/2013/04/12/bitcoin-is-ludicrous-but-it-tells-us-something-important-about-the-nature-of-money/", 6 | note = "[Online; accessed 11-February-2014]" 7 | } 8 | 9 | @misc { krugman1, 10 | author = "Paul Krugman", 11 | title = "Adam Smith Hates Bitcoin", 12 | year = "2013", 13 | url = "http://krugman.blogs.nytimes.com/2013/04/12/adam-smith-hates-bitcoin/", 14 | note = "[Online; accessed 11-February-2014]" 15 | } 16 | 17 | @misc { krugman2, 18 | author = "Paul Krugman", 19 | title = "Baby sitting can't avoid recessions", 20 | year = "1997", 21 | url = "http://www.pkarchive.org/theory/BabySittingCantAvoidRecessions.html", 22 | note = "[Online; accessed 11-February-2014]" 23 | } 24 | -------------------------------------------------------------------------------- /papers/macro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/papers/macro.pdf -------------------------------------------------------------------------------- /papers/master.txt: -------------------------------------------------------------------------------- 1 | DRAFT 2 | 3 | Yoyodyne Space Products Ltd., a Hong Kong company and _________, a 4 | Delaware corporation have entered and/or anticipate entering into one 5 | or more transactions (each a “Transaction”) that are or will be 6 | governed by this agreement, which includes the ISDA Master Agreement 7 | ("ISDA Master Agreement"), the schedule (the “Schedule”), and the 8 | documents and other confirming evidence (each a “Confirmation”) 9 | exchanged between the parties confirming those Transactions. 10 | 11 | The Parties hereby agree to be bound by the terms of the 2002 Master 12 | Agreement published by the International Swaps and Derivatives 13 | Association, the contents of which are incorporated in full into this 14 | agreement. 15 | 16 | For reference purposes, a non-authoritative Chinese translation of the 17 | 2002 Master Agreement is available at . The Chinese transation is for 18 | reference only, and the English version of the Master Agreement is 19 | legally binding. 20 | 21 | For the purpose of Transactions, Parties agree to use the 2011 Equity 22 | Derivative Definitions published by the International Swaps and 23 | Derivatives Association. 24 | 25 | Schedule 26 | 27 | Part 1. 28 | 29 | "Party A" established as a Hong Kong Company with company number **** 30 | under the laws of *****. 31 | 32 | "Party B" a natural person. 33 | 34 | Part 2. Tax Representations 35 | 36 | (a) Payer Representations: For the purpose of Section 3(e) of this 37 | Agreement, Party A and Party B do not make any representations. 38 | 39 | (b) Payee Representations: For the purpose of Section 3(f) of this 40 | Agreement, Party A and Party B do not make any representations. 41 | 42 | Part 3. Agreement to Deliver Documents. 43 | 44 | For the purpose of Sections 4(a)(i) and 4(a)(ii) of this Agreement, 45 | each party agrees to deliver the following documents, as applicable: 46 | 47 | (a) Tax forms, documents or certificates to be delivered are none. 48 | 49 | (b) Other documents to be delivered are none. 50 | 51 | Part 4. Miscellaneous 52 | 53 | (a) Address for Notices. For the purpose of Section 12(a) of this 54 | Agreement: 55 | 56 | Address for notices or communications to Party A: 57 | 58 | Address: 59 | Attention: 60 | Telex No: 61 | Answerback: 62 | Facsimile No: 63 | Telephone No: 64 | E-mail: 65 | Electronic Messaging System Details: 66 | Specific Instructions: 67 | 68 | Address for notices or communications to Party B: 69 | 70 | Address: 71 | Attention: 72 | Telex No: 73 | Answerback: 74 | Facsimile No: 75 | Telephone No: 76 | E-mail: 77 | Electronic Messaging System Details: 78 | Specific Instructions: 79 | 80 | b) Process Agent. For the purpose of Section 13(c) of this Agreement 81 | 82 | Party A appoints as its Process Agent: non applicable 83 | Party B appoints as its Process Agent: non applicable 84 | 85 | c) The provisions of Section 10(a) will not apply to this Agreement 86 | 87 | d) For the purpose of Section 10(b) of this Agreement: 88 | 89 | Party A is not a multibranch Party. 90 | Party B is not a multibranch Party. 91 | 92 | e) The Calculation Agent is ..... 93 | 94 | f) Credit Support Dcoument: Details of any Credit Support Document: 95 | none 96 | 97 | g) Credit Support Provider: Credit Support Provider means in relation 98 | to Party A, none. Credit Support Provider means in relation to Party 99 | B, none. 100 | 101 | h) Governing Law. This Agreement will be governed by and construed in 102 | accordance with the law of the Hong Kong Special Administrative 103 | Region, China. 104 | 105 | i) Netting of Payments. "Multiple Transaction Payment Netting" will 106 | apply for the purpose of Section 2(c) of this Agreement to all 107 | Transaction. 108 | 109 | j) "Affilate" will have the meaning specified in Section 14 of this 110 | Agreement. 111 | 112 | k) Absence of Litigation: For the purpose of Section 3(c) 113 | 'Specified Entity" means in relation to Party A, no one 114 | "Specified Enitty" means in relation to Party B, no one 115 | 116 | l) No Agency. The provisions of Section 3(g) will not apply to this 117 | Agreement 118 | 119 | m) Additional representations will not apply. 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /papers/money-lender/privacy.txt: -------------------------------------------------------------------------------- 1 | Privacy Waiver 2 | 3 | In the event, that a loan is over 60 (sixty) days delinquent, I/we 4 | hereby authorize the borrower to disclose the amounts and nature of 5 | the loans delinquent for a period of 7 years after the deliquency, to 6 | any person or persons including but not limited publicly posting on 7 | the internet and disclosure on social media, provided that the lender 8 | informs the borrower as to the nature of the disclosure and the 9 | persons to whom the disclosure is made to. 10 | 11 | I further agree that the transaction logs containing conversations 12 | between the borrower and lender can be used by either side in order to 13 | resolve disputes concerning the loan. 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /papers/money-lender/references.txt: -------------------------------------------------------------------------------- 1 | Contact person list 2 | 3 | I am currently residing at: 4 | 5 | 6 | And am employed by: 7 | 8 | 9 | 10 | 11 | I am a member of the following social media groups: 12 | 13 | 14 | 15 | 16 | The following friends/relatives are contact persons: 17 | 18 | 19 | 20 | The lender agrees that this information is protected under the Privacy 21 | Ordinance, and will not use this information except for emergency 22 | contact, to perform security information, or to notice persons of 23 | payment delinquency as agreed by the borrower. 24 | 25 | 26 | -------------------------------------------------------------------------------- /papers/neutrino.tex: -------------------------------------------------------------------------------- 1 | \documentclass{beamer} 2 | \usepackage{beamerthemeshadow} 3 | \begin{document} 4 | \title{Neutrino Physics, Investment Banking, and Hong Kong} 5 | \author{Joseph C Wang - joequant@gmail.com - Wechat: joequant} 6 | \date{\today} 7 | 8 | \begin{frame} 9 | \titlepage 10 | \end{frame} 11 | 12 | \begin{frame}\frametitle{Table of contents}\tableofcontents 13 | \end{frame} 14 | 15 | \section{Background} 16 | \begin{frame}\frametitle{Background} 17 | \begin{itemize} 18 | \item Bachelor - MIT - 1991 19 | \item Ph.D. - Computational astrophysics - Supernova hydrodynamics 20 | - University of Texas Austin - 1998 - Craig Wheeler 21 | \item JPMorgan - NYC and Hong Kong 22 | \item Own company 23 | \end{itemize} 24 | \end{frame} 25 | 26 | \begin{frame}\frametitle{Great disappointments} 27 | \begin{itemize} 28 | \item Grew up in Florida in the 1970's - End of the space race 29 | \item Was a Ph.D. in Texas when the SSC was cancelled 30 | \item Was in NYC in 2008 when the world financial system collapsed, 31 | and watching as things keep falling apart 32 | \end{itemize} 33 | \end{frame} 34 | 35 | \begin{frame}\frametitle{Key question} 36 | \begin{itemize} 37 | \item The key limitation is not engineering, not science, the key 38 | interaction is finance 39 | \item So where to I learn about money 40 | \end{itemize} 41 | \end{frame} 42 | 43 | \begin{frame}\frametitle{Physicists in Investment banking} 44 | \begin{itemize} 45 | \item Typical investment bank employs 20000 46 | \item Quantitative finance group had 400 47 | \item Half people are computer programmers 48 | \item Half people are technical Ph.D.'s 49 | \item Typically 50 physics Ph.D.'s 50 | \end{itemize} 51 | \end{frame} 52 | 53 | \section{Some basic financial physics} 54 | 55 | \begin{frame}\frametitle{No arbitrage theorem} 56 | \begin{itemize} 57 | \item Kindergarten question - One banana costs one dollar. What 58 | is the cost of two bananas? 59 | \item High school question - What is the dependency between cost 60 | and quantity? 61 | \item The Ph.D. question. Why? 62 | \end{itemize} 63 | \end{frame} 64 | 65 | \begin{frame}\frametitle{Option pricing} 66 | \begin{itemize} 67 | \item Black-Scholes equation - Just a difusion equation 68 | \item Gauge invariance 69 | \item Can derive equations from fundamental symmetries 70 | \item We are dealing with people 71 | \end{itemize} 72 | \end{frame} 73 | 74 | \section{Work environment} 75 | \begin{frame}\frametitle{What do physicists to in banking?} 76 | \begin{itemize} 77 | \item Lots of mathematical problems and modelling 78 | \item Pricing equations and risk management 79 | \item High performance computing 80 | \item Mathematical mechanic 81 | \end{itemize} 82 | \end{frame} 83 | 84 | \begin{frame}\frametitle{Good parts} 85 | \begin{itemize} 86 | \item You are doing physics 87 | \item You are learning all these new things, and your knowledge 88 | becomes obsolete quickly 89 | \item Your managers are all physics/CS Ph.D.'s 90 | \item You see how the world works 91 | \item You are part of history 92 | \item The money isn't bad 93 | \end{itemize} 94 | \end{frame} 95 | 96 | \begin{frame}\frametitle{Bad parts} 97 | \begin{itemize} 98 | \item No one outside knows what you are doing 99 | \item You feel poor. 100 | \item The new stuff is happening outside of banks 101 | \end{itemize} 102 | \end{frame} 103 | 104 | \begin{frame}\frametitle{How to get in?} 105 | \begin{itemize} 106 | \item Jobs are highly concentrated - NYC, London, and Asia (Hong 107 | Kong, Singapore, Tokyo) 108 | \item NYC is an option if you can get into the US 109 | \item London is frozen right now 110 | \item Hong Kong - employment visa, QMAS, business investment visa 111 | \item Very open residency for non-Chinese Ph.D.'s 112 | \end{itemize} 113 | \end{frame} 114 | 115 | \begin{frame}\frametitle{Research} 116 | \begin{itemize} 117 | \item Applying bitcoin/blockchain to scientific computing 118 | \item Applying middleware 119 | \item Buying selling coffee 120 | \item Funding science and small high tech businesses 121 | \begin{itemize} 122 | \item USD 8 million for Golem 123 | \item USD 15 million for OpenANX, USD 150 million for EOS 124 | \end{itemize} 125 | \end{itemize} 126 | \end{frame} 127 | 128 | \begin{frame}\frametitle{Hong Kong} 129 | \begin{itemize} 130 | \item Economic and political transition 131 | \item Need high tech people 132 | \item Government has a different role 133 | \item Just do it 134 | \end{itemize} 135 | \end{frame} 136 | 137 | \begin{frame}\frametitle{HK as a Gateway} 138 | \begin{itemize} 139 | \item Gateway into global finance 140 | \item Gateway for businesses going out and businesses coming in 141 | \end{itemize} 142 | \end{frame} 143 | 144 | \begin{frame}\frametitle{Further references} 145 | \begin{itemize} 146 | \item Book by John Hull and Paul Wilmott 147 | \item The movie ``Margin Call'' 148 | \end{itemize} 149 | \includegraphics[scale=0.25]{joequant-qr.png} 150 | \end{frame} 151 | \end{document} 152 | -------------------------------------------------------------------------------- /papers/nyletter.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/papers/nyletter.odt -------------------------------------------------------------------------------- /papers/nyletter.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/papers/nyletter.pdf -------------------------------------------------------------------------------- /smart-contracts-2/disclaimer.txt: -------------------------------------------------------------------------------- 1 | NEITHER THIS CONVERTIBLE NOTE (THIS “NOTE”) NOR THE SECURITIES INTO 2 | WHICH THIS NOTE IS CONVERTIBLE HAVE BEEN REGISTERED UNDER THE 3 | U.S. SECURITIES ACT OF 1933, AS AMENDED (THE “ACT”), OR APPLICABLE 4 | STATE SECURITIES LAWS. THIS NOTE AND THE SECURITIES INTO WHICH IT IS 5 | CONVERTIBLE MAY NOT BE OFFERED FOR SALE, SOLD, TRANSFERRED, ASSIGNED 6 | OR PLEDGED (I) IN THE ABSENCE OF (A) AN EFFECTIVE REGISTRATION 7 | STATEMENT UNDER THE ACT, OR (B) AN OPINION OF COUNSEL, IN A FORM 8 | ACCEPTABLE TO THE ISSUER, THAT REGISTRATION IS NOT REQUIRED UNDER THE 9 | ACT OR (II) UNLESS SOLD PURSUANT TO AN EXEMPTION FROM REGISTRATION 10 | UNDER THE ACT. 11 | -------------------------------------------------------------------------------- /smart-contracts-2/display.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | View contract 14 |
15 |
16 |
17 | 22 | 23 | -------------------------------------------------------------------------------- /smart-contracts-2/notice.txt: -------------------------------------------------------------------------------- 1 | 2 | Company notice address: Kuaiwear Limited 3 | Unit A10, 6/F, Wong’s Building 4 | 33 Hung To Road 5 | Kwun Tong 6 | Kowloon 7 | Hong Kong 8 | 9 | Purchaser notice address: 10 | -------------------------------------------------------------------------------- /smart-contracts-2/viewer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var converter = new showdown.Converter(); 3 | class Viewer { 4 | constructor(schedule, terms) { 5 | this.schedule = schedule; 6 | this.terms = terms; 7 | } 8 | add_item(name, value, type) { 9 | var field_value = "value='" + value + "'"; 10 | if (type === "checkbox") { 11 | if (value === true) { 12 | field_value = "checked"; 13 | } else { 14 | field_value = ""; 15 | } 16 | } else if (type == 'money') { 17 | field_value = "value='" + value[1] + "'"; 18 | var r = 19 | ` (${value[0]})`; 20 | return r; 21 | } else if (type == 'percent') { 22 | type = "number"; 23 | } 24 | 25 | var r = 26 | ``; 27 | return r; 28 | } 29 | 30 | read_inputs(prefix, suffix, inputs, values) { 31 | inputs.forEach(function(y) { 32 | var id = `#${prefix}_${y.name}_${suffix}`; 33 | if (y.type == "checkbox") { 34 | values[y.name] = $(id).prop('checked'); 35 | return; 36 | } 37 | if (y.type == "money" || y.type == "percent" || 38 | y.type == "number") { 39 | var value = $(id).val(); 40 | if (value !== undefined && value !== "") { 41 | values[y.name] = Number(value); 42 | } 43 | return; 44 | } 45 | values[y.name] = $(id).val(); 46 | }); 47 | } 48 | 49 | handle_click() { 50 | var inputs = {}; 51 | var terms = {}; 52 | this.read_inputs(this.schedule.name, 'input', this.schedule.inputs, 53 | inputs); 54 | this.read_inputs(this.schedule.name, 'term', this.schedule.terms, 55 | terms); 56 | var outputs = this.schedule.calculate(inputs, terms); 57 | var html = ""; 58 | this.schedule.outputs.forEach(function(y) { 59 | html += `${y.display}: ${outputs[y.name]}
`; 60 | }); 61 | document.getElementById(this.schedule.name + "_output").innerHTML = html; 62 | } 63 | generate_inputs(plist, prefix, suffix, values) { 64 | var input = ""; 65 | var o = this; 66 | plist.forEach(function(y) { 67 | var value = ""; 68 | if (values[y.name] != undefined) { 69 | value = values[y.name]; 70 | } 71 | input += `${y.display}: 72 | ${o.add_item(prefix + "_" + y.name + "_" + suffix, 73 | value, y.type)}
`; 74 | }); 75 | return input; 76 | } 77 | 78 | view(div) { 79 | var o = this; 80 | var terms = {} 81 | this.terms.forEach(function(term) { 82 | if (term.type == "duration") { 83 | terms[term.name] = term.value[0]; 84 | } else { 85 | terms[term.name] = term.value; 86 | } 87 | }); 88 | 89 | var html = `

${this.schedule.display}

90 | ${this.schedule.description}

91 | Schedule terms
92 | ${this.generate_inputs(this.schedule.terms, this.schedule.name, 93 | 'term', terms)} 94 | Inputs
95 | ${this.generate_inputs(this.schedule.inputs, this.schedule.name, 96 | 'input', {})} 97 |
98 | 99 |

`; 100 | $(div).append(html); 101 | $(`#${this.schedule.name}_recalc`).click(function() {o.handle_click();}); 102 | } 103 | }; 104 | 105 | 106 | function show_text(div, contract) { 107 | var source = contract.template; 108 | var terms = contract.terms; 109 | var terms_display = {}; 110 | terms.forEach(function(term) { 111 | if (term.type == "money" || term.type == "duration") { 112 | terms_display[term.name] = 113 | term.value.map(function(x) { 114 | return x.toString().replace("_", " ")}).join(" "); 115 | } else { 116 | terms_display[term.name] = term.value; 117 | } 118 | }); 119 | var template = Handlebars.compile(source); 120 | $(div).html(converter.makeHtml(template(terms_display))); 121 | } 122 | 123 | function show_terms(div, contract) { 124 | var terms = contract.terms; 125 | var term_list = "

Contract Terms

"; 126 | terms.forEach(function(term) { 127 | if (term.type == "money" || term.type == "duration") { 128 | term_list += term.display + ": " + 129 | term.value.map(function(x) { 130 | return x.toString().replace("_", " ")}).join(" "); 131 | } else { 132 | term_list += term.display + ": " + term.value; 133 | } 134 | term_list += "
"; 135 | }); 136 | $(div).html(term_list); 137 | } 138 | 139 | function show_schedules(div, contract) { 140 | $(div).empty(); 141 | contract.schedules.forEach(function(x) { 142 | var s = new Viewer(x, contract.terms); 143 | s.view(div); 144 | }); 145 | } 146 | -------------------------------------------------------------------------------- /smart-contracts/README.md: -------------------------------------------------------------------------------- 1 | Here are some smart contracts. 2 | 3 | https://github.com/joequant/bitquant/tree/master/smart-contracts 4 | 5 | Here is a youtube presentation on smart contracts 6 | 7 | https://www.youtube.com/watch?v=0nzUZRDSwkk 8 | 9 | and some of the legal issues involved in smart contracts see [NOTES.md](NOTES.md) 10 | 11 | 12 | To see them in action: 13 | 14 | http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html 15 | 16 | This view can be used to see the contracts under models. 17 | 18 | http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/(contract-name) 19 | 20 | 21 | Model Contracts 22 | --------------- 23 | 24 | [loan](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/loan) - small business loans 25 | 26 | [credit-line](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/credit-line) 27 | - Credit line contract to SME's loaned against HK government grant 28 | 29 | [hk-money-lender](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/hk-money-lender) 30 | - Contract compliant with HK money lending rules - Note that this 31 | contract has been litigated in a HK court proceeding 32 | 33 | [hk-company-secured](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/hk-company-secured) 34 | - Contract for secured lending to HK company 35 | 36 | [hire-purchase](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/hire-purchase) 37 | - Contract for hire purchase of appliance 38 | 39 | [profit-share](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/profit-share) - a smart trust profit sharing agreement 40 | 41 | [simple-amortized](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/simple-amortized) - a simple amortized loan 42 | 43 | [subclass](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/subclass) - example of the use of subclassing 44 | 45 | Under construction 46 | ------------------ 47 | 48 | [equity-finance](http://joequant.github.io/bitquant/smart-contracts/contract_viewer.html?contract=models/equity-finance) - Working on convertible note example (still working) 49 | 50 | All contracts are licensed under the [Simplified BSD 51 | License](http://opensource.org/licenses/BSD-2-Clause). They may be 52 | used for any purpose without royalty or fee, but the user assumes all 53 | liabilities. 54 | 55 | Please note that there are as these contracts are under construction 56 | there are some known amd unknown major issues with the contracts in 57 | this directory. If you need professional assistance in using these 58 | contracts please contact [Crypto Law](http://www.crypto-law.com). 59 | 60 | Also, these contracts are being developed in Hong Kong. If you are a 61 | fintech or lawtech business looking to set up shop here, let me know. 62 | 63 | Please look at the [bug list](https://github.com/joequant/bitquant/issues) for issues. 64 | 65 | [NOTES.md](NOTES.md) contain legal notes (including why the 66 | jurisdiction is Hong Kong). [calc-contract](calc-contract.js) is a 67 | batch tool for analyzing the contracts. 68 | 69 | === TODO === 70 | 71 | * Make the contracts look nice 72 | * Add some sort of wiki markup feature 73 | -------------------------------------------------------------------------------- /smart-contracts/YEARFRAC.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 Sutoiku, Inc. (MIT License) 2 | if (typeof define !== 'function') { 3 | var define = require('amdefine')(module); 4 | } 5 | 6 | define(['moment'], function(moment) { 7 | return { 8 | "YEARFRAC" : function YEARFRAC(start_date, end_date, basis) { 9 | // Credits: David A. Wheeler [http://www.dwheeler.com/] 10 | 11 | // Initialize parameters 12 | var basis = (typeof basis === 'undefined') ? 0 : basis; 13 | var sdate = moment(new Date(start_date)); 14 | var edate = moment(new Date(end_date)); 15 | 16 | // Return error if either date is invalid 17 | if (!sdate.isValid() || !edate.isValid()) return '#VALUE!'; 18 | 19 | // Return error if basis is neither 0, 1, 2, 3, or 4 20 | if ([0,1,2,3,4].indexOf(basis) === -1) return '#NUM!'; 21 | 22 | // Return zero if start_date and end_date are the same 23 | if (sdate === edate) return 0; 24 | 25 | // Swap dates if start_date is later than end_date 26 | if (sdate.diff(edate) > 0) { 27 | var edate = moment(new Date(start_date)); 28 | var sdate = moment(new Date(end_date)); 29 | } 30 | 31 | // Lookup years, months, and days 32 | var syear = sdate.year(); 33 | var smonth = sdate.month(); 34 | var sday = sdate.date(); 35 | var eyear = edate.year(); 36 | var emonth = edate.month(); 37 | var eday = edate.date(); 38 | 39 | switch (basis) { 40 | case 0: 41 | // US (NASD) 30/360 42 | // Note: if eday == 31, it stays 31 if sday < 30 43 | if (sday === 31 && eday === 31) { 44 | sday = 30; 45 | eday = 30; 46 | } else if (sday === 31) { 47 | sday = 30; 48 | } else if (sday === 30 && eday === 31) { 49 | eday = 30; 50 | } else if (smonth === 1 && emonth === 1 && sdate.daysInMonth() === sday && edate.daysInMonth() === eday) { 51 | sday = 30; 52 | eday = 30; 53 | } else if (smonth === 1 && sdate.daysInMonth() === sday) { 54 | sday = 30; 55 | } 56 | return ((eday + emonth * 30 + eyear * 360) - (sday + smonth * 30 + syear * 360)) / 360; 57 | break; 58 | 59 | case 1: 60 | // Actual/actual 61 | var feb29Between = function(date1, date2) { 62 | // Requires year2 == (year1 + 1) or year2 == year1 63 | // Returns TRUE if February 29 is between the two dates (date1 may be February 29), with two possibilities: 64 | // year1 is a leap year and date1 <= Februay 29 of year1 65 | // year2 is a leap year and date2 > Februay 29 of year2 66 | 67 | var mar1year1 = moment(new Date(date1.year(), 2, 1)); 68 | if (moment([date1.year()]).isLeapYear() && date1.diff(mar1year1) < 0 && date2.diff(mar1year1) >= 0) { 69 | return true; 70 | } 71 | var mar1year2 = moment(new Date(date2.year(), 2, 1)); 72 | if (moment([date2.year()]).isLeapYear() && date2.diff(mar1year2) >= 0 && date1.diff(mar1year2) < 0) { 73 | return true; 74 | } 75 | return false; 76 | }; 77 | var ylength = 365; 78 | if (syear === eyear || ((syear + 1) === eyear) && ((smonth > emonth) || ((smonth === emonth) && (sday >= eday)))) { 79 | if (syear === eyear && moment([syear]).isLeapYear()) { 80 | ylength = 366; 81 | } else if (feb29Between(sdate, edate) || (emonth === 1 && eday === 29)) { 82 | ylength = 366; 83 | } 84 | return edate.diff(sdate, 'days') / ylength; 85 | } else { 86 | var years = (eyear - syear) + 1; 87 | var days = moment(new Date(eyear + 1, 0, 1)).diff(moment(new Date(syear, 0, 1)), 'days'); 88 | var average = days / years; 89 | return edate.diff(sdate, 'days') / average; 90 | } 91 | break; 92 | 93 | case 2: 94 | // Actual/360 95 | return edate.diff(sdate, 'days') / 360; 96 | break; 97 | 98 | case 3: 99 | // Actual/365 100 | return edate.diff(sdate, 'days') / 365; 101 | break; 102 | 103 | case 4: 104 | // European 30/360 105 | if (sday === 31) sday = 30; 106 | if (eday === 31) eday = 30; 107 | // Remarkably, do NOT change February 28 or February 29 at ALL 108 | return ((eday + emonth * 30 + eyear * 360) - (sday + smonth * 30 + syear * 360)) / 360; 109 | break; 110 | } 111 | } 112 | } 113 | }); 114 | -------------------------------------------------------------------------------- /smart-contracts/add-js-dependencies.sh: -------------------------------------------------------------------------------- 1 | npm install --save decimal 2 | npm install --save moment 3 | npm install --save requirejs 4 | npm install --save amdefine 5 | rm -r node_modules/moment/locale 6 | rm -r node_modules/moment/moment.js 7 | rm node_modules/moment/min/*locale* 8 | rm node_modules/moment/min/tests.js 9 | -------------------------------------------------------------------------------- /smart-contracts/calc-credit.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/node 2 | 3 | "use strict"; 4 | var requirejs = require('requirejs'); 5 | 6 | requirejs.config({ 7 | //Pass the top-level main.js/index.js require 8 | //function to requirejs so that node modules 9 | //are loaded relative to the top-level JS file. 10 | nodeRequire: require 11 | }); 12 | 13 | var directory = process.argv[2]; 14 | if (directory === undefined) { 15 | directory = "./models/credit-line" 16 | } else { 17 | directory = "./" + directory 18 | } 19 | 20 | var show_line = function(i) { 21 | var note = ""; 22 | if (i.note != undefined) { 23 | note = i.note; 24 | } 25 | if (i.event == "Note" || 26 | i.event == "Terminate" || 27 | i.event == "Action") { 28 | console.log(i.event, 29 | i.on.toDateString(), 30 | note); 31 | return; 32 | } 33 | 34 | if (i.event === "Transfer" || 35 | i.event === "Obligation") { 36 | var actual = i.actual; 37 | if (actual === undefined) { 38 | actual = i.on; 39 | } 40 | var item = i.item; 41 | if (item === undefined) { 42 | item = i.item; 43 | } 44 | console.log(i.event, 45 | i.on.toDateString(), 46 | i.from, 47 | i.to, 48 | Number(i.amount).toFixed(2), 49 | i.item, 50 | note, 51 | actual.toDateString()); 52 | return; 53 | 54 | } 55 | console.log(i.event, 56 | i.on.toDateString(), 57 | Number(i.principal).toFixed(2), 58 | Number(i.interest_accrued).toFixed(2), 59 | Number(i.balance).toFixed(2), 60 | Number(i.late_balance).toFixed(2), 61 | Number(i.principal_payment).toFixed(2), 62 | Number(i.interest_payment).toFixed(2), 63 | note); 64 | }; 65 | 66 | var show_apr = function(calculator, payments) { 67 | } 68 | 69 | var Calculator = require("./Calculator.js"); 70 | var TermSheet = require(directory + "/TermSheet.js"); 71 | 72 | var calculator = new Calculator(); 73 | calculator.test_wrapper() 74 | 75 | console.log("No draws") 76 | var my_term_sheet = new TermSheet(); 77 | var calculator = new Calculator() 78 | calculator.set_events(my_term_sheet, { 79 | "early_payment":[], 80 | "credit_request":[]}) 81 | var payment_schedule = calculator.calculate(my_term_sheet); 82 | console.log("event", "date", 83 | "principal", 84 | "interest", 85 | "balance", 86 | "late balance", 87 | "balance payment", 88 | "interest payment", 89 | "note"); 90 | payment_schedule.forEach(function(i) { 91 | my_term_sheet.process_payment(i); 92 | show_line(i) 93 | }); 94 | show_apr(calculator, payment_schedule); 95 | console.log(); 96 | 97 | 98 | 99 | console.log("Credit 1") 100 | my_term_sheet = new TermSheet(); 101 | calculator = new Calculator(); 102 | calculator.set_events(my_term_sheet, { 103 | "credit_request":[ 104 | {"on": "2015-06-15", 105 | "amount": "15000"} 106 | ]}) 107 | var payment_schedule = calculator.calculate(my_term_sheet); 108 | payment_schedule.forEach(function(i) { 109 | my_term_sheet.process_payment(i); 110 | show_line(i) 111 | }); 112 | show_apr(calculator, payment_schedule); 113 | console.log() 114 | 115 | console.log("Credit 2"); 116 | my_term_sheet = new TermSheet(); 117 | calculator = new Calculator(); 118 | calculator.set_events(my_term_sheet, { 119 | "credit_request":[ 120 | {"on": "2015-08-15", 121 | "amount": "15000"} 122 | ]}); 123 | var payment_schedule = calculator.calculate(my_term_sheet); 124 | payment_schedule.forEach(function(i) { 125 | my_term_sheet.process_payment(i); 126 | show_line(i) 127 | }); 128 | show_apr(calculator, payment_schedule); 129 | console.log() 130 | 131 | console.log("Credit 3 - Test limit"); 132 | my_term_sheet = new TermSheet(); 133 | calculator = new Calculator(); 134 | calculator.set_events(my_term_sheet, { 135 | "credit_request":[ 136 | {"on": "2015-08-15", 137 | "amount": "100000000"} 138 | ]}); 139 | var payment_schedule = calculator.calculate(my_term_sheet); 140 | payment_schedule.forEach(function(i) { 141 | my_term_sheet.process_payment(i); 142 | show_line(i) 143 | }); 144 | show_apr(calculator, payment_schedule); 145 | console.log(); 146 | 147 | console.log("Credit 3"); 148 | my_term_sheet = new TermSheet(); 149 | calculator = new Calculator(); 150 | calculator.set_events(my_term_sheet, { 151 | "payment_arrival" : [ 152 | {"on" : "2015-09-30", 153 | "actual" : "2015-11-20"} 154 | ], 155 | "credit_request":[ 156 | {"on": "2015-08-15", 157 | "amount": "15000"}, 158 | {"on": "2015-11-15", 159 | "amount": "15000"} 160 | ]}); 161 | var payment_schedule = calculator.calculate(my_term_sheet); 162 | payment_schedule.forEach(function(i) { 163 | my_term_sheet.process_payment(i); 164 | show_line(i) 165 | }); 166 | 167 | console.log("Credit 4"); 168 | my_term_sheet = new TermSheet(); 169 | calculator = new Calculator(); 170 | calculator.set_events(my_term_sheet, { 171 | "late_payment" : [ 172 | {"on" : "2015-11-14", 173 | "amount" : "2500" 174 | } 175 | ], 176 | "credit_request":[ 177 | {"on": "2015-08-15", 178 | "amount": "15000"}, 179 | {"on": "2015-11-15", 180 | "amount": "15000"} 181 | ]}); 182 | var payment_schedule = calculator.calculate(my_term_sheet); 183 | payment_schedule.forEach(function(i) { 184 | my_term_sheet.process_payment(i); 185 | show_line(i) 186 | }); 187 | 188 | show_apr(calculator, payment_schedule); 189 | console.log() 190 | 191 | -------------------------------------------------------------------------------- /smart-contracts/contract_viewer.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 42 | 43 | 46 | 47 | 48 |

Contract Viewer

49 | Copyright (c) 2015 - Bitquant Research Laboratories (Asia) Ltd.
50 | Redistributable under terms of the Simplified BSD License 51 |

52 |
53 |

54 |

55 |

56 | 57 |
58 |
59 |
60 |
61 |
62 | 63 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /smart-contracts/jquery.appendGrid-1.6.2.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery appendGrid v1.6.2 3 | * https://appendgrid.apphb.com/ 4 | * 5 | * Copyright 2016 Albert L. 6 | * Dual licensed under the LGPL (http://www.gnu.org/licenses/lgpl.html) 7 | * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. 8 | * 9 | * Depends: 10 | * jQuery v1.11.1+ 11 | * jQuery UI v1.11.1+ 12 | */div.appendGrid table.head,div.appendGrid table.body,div.appendGrid table.foot{border-collapse:collapse;width:auto}div.appendGrid table.head thead tr.columnHead td{width:auto;text-overflow:ellipsis}div.appendGrid table td{padding:1px}div.appendGrid table.head thead td{padding-top:4px;padding-bottom:4px;white-space:nowrap}div.appendGrid table thead td.caption{padding:4px;font-weight:bold}div.appendGrid table tbody input[type=text]{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}div.appendGrid table tbody td{white-space:pre-wrap}div.appendGrid table td.first{text-align:center;vertical-align:middle;min-width:32px}div.appendGrid table td.last{text-align:center;vertical-align:middle;white-space:nowrap;min-width:91px}div.appendGrid table tbody td.last button{min-height:20px;margin:1px}div.appendGrid table tbody td.last button.insert,div.appendGrid table tbody td.last button.remove,div.appendGrid table tbody td.last button.moveUp,div.appendGrid table tbody td.last button.moveDown{height:20px;width:20px}div.appendGrid table tbody td.last div.rowDrag{display:inline-block;vertical-align:middle;width:18px;height:18px;margin:1px}div.appendGrid table tfoot button{min-height:24px;min-width:28px}div.appendGrid table tfoot button.append,div.appendGrid table tfoot button.removeLast{height:24px;min-width:28px}div.appendGrid table input.double{text-align:right}div.appendGrid table tbody tr.empty td{text-align:center}div.appendGrid table td.invisible{display:none}div.appendGrid div.scroller{overflow:auto;display:block;padding:0;margin:0} -------------------------------------------------------------------------------- /smart-contracts/jquery.collapse.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Collapse plugin for jQuery 3 | * -- 4 | * source: http://github.com/danielstocks/jQuery-Collapse/ 5 | * site: http://webcloud.se/jQuery-Collapse 6 | * 7 | * @author Daniel Stocks (http://webcloud.se) 8 | * Copyright 2013, Daniel Stocks 9 | * Released under the MIT, BSD, and GPL Licenses. 10 | */ 11 | 12 | (function($, exports) { 13 | 14 | // Constructor 15 | function Collapse (el, options) { 16 | options = options || {}; 17 | var _this = this, 18 | query = options.query || "> :even"; 19 | 20 | $.extend(_this, { 21 | $el: el, 22 | options : options, 23 | sections: [], 24 | isAccordion : options.accordion || false, 25 | db : options.persist ? jQueryCollapseStorage(el.get(0).id) : false 26 | }); 27 | 28 | // Figure out what sections are open if storage is used 29 | _this.states = _this.db ? _this.db.read() : []; 30 | 31 | // For every pair of elements in given 32 | // element, create a section 33 | _this.$el.find(query).each(function() { 34 | new jQueryCollapseSection($(this), _this); 35 | }); 36 | 37 | // Capute ALL the clicks! 38 | (function(scope) { 39 | _this.$el.on("click", "[data-collapse-summary] " + (scope.options.clickQuery || ""), 40 | $.proxy(_this.handleClick, scope)); 41 | 42 | _this.$el.bind("toggle close open", 43 | $.proxy(_this.handleEvent, scope)); 44 | 45 | }(_this)); 46 | } 47 | 48 | Collapse.prototype = { 49 | handleClick: function(e, state) { 50 | e.preventDefault(); 51 | state = state || "toggle"; 52 | var sections = this.sections, 53 | l = sections.length; 54 | while(l--) { 55 | if($.contains(sections[l].$summary[0], e.target)) { 56 | sections[l][state](); 57 | break; 58 | } 59 | } 60 | }, 61 | handleEvent: function(e) { 62 | if(e.target == this.$el.get(0)) return this[e.type](); 63 | this.handleClick(e, e.type); 64 | }, 65 | open: function(eq) { 66 | this._change("open", eq); 67 | }, 68 | close: function(eq) { 69 | this._change("close", eq); 70 | }, 71 | toggle: function(eq) { 72 | this._change("toggle", eq); 73 | }, 74 | _change: function(action, eq) { 75 | if(isFinite(eq)) return this.sections[eq][action](); 76 | $.each(this.sections, function(i, section) { 77 | section[action](); 78 | }); 79 | } 80 | }; 81 | 82 | // Section constructor 83 | function Section($el, parent) { 84 | 85 | if(!parent.options.clickQuery) $el.wrapInner(''); 86 | 87 | $.extend(this, { 88 | isOpen : false, 89 | $summary : $el.attr("data-collapse-summary",""), 90 | $details : $el.next(), 91 | options: parent.options, 92 | parent: parent 93 | }); 94 | parent.sections.push(this); 95 | 96 | // Check current state of section 97 | var state = parent.states[this._index()]; 98 | 99 | if(state === 0) { 100 | this.close(true); 101 | } 102 | else if(this.$summary.is(".open") || state === 1) { 103 | this.open(true); 104 | } else { 105 | this.close(true); 106 | } 107 | } 108 | 109 | Section.prototype = { 110 | toggle : function() { 111 | this.isOpen ? this.close() : this.open(); 112 | }, 113 | close: function(bypass) { 114 | this._changeState("close", bypass); 115 | }, 116 | open: function(bypass) { 117 | var _this = this; 118 | if(_this.options.accordion && !bypass) { 119 | $.each(_this.parent.sections, function(i, section) { 120 | section.close(); 121 | }); 122 | } 123 | _this._changeState("open", bypass); 124 | }, 125 | _index: function() { 126 | return $.inArray(this, this.parent.sections); 127 | }, 128 | _changeState: function(state, bypass) { 129 | 130 | var _this = this; 131 | _this.isOpen = state == "open"; 132 | if($.isFunction(_this.options[state]) && !bypass) { 133 | _this.options[state].apply(_this.$details); 134 | } else { 135 | _this.$details[_this.isOpen ? "show" : "hide"](); 136 | } 137 | 138 | _this.$summary.toggleClass("open", state !== "close"); 139 | _this.$details.attr("aria-hidden", state === "close"); 140 | _this.$summary.attr("aria-expanded", state === "open"); 141 | _this.$summary.trigger(state === "open" ? "opened" : "closed", _this); 142 | if(_this.parent.db) { 143 | _this.parent.db.write(_this._index(), _this.isOpen); 144 | } 145 | } 146 | }; 147 | 148 | // Expose in jQuery API 149 | $.fn.extend({ 150 | collapse: function(options, scan) { 151 | var nodes = (scan) ? $("body").find("[data-collapse]") : $(this); 152 | return nodes.each(function() { 153 | var settings = (scan) ? {} : options, 154 | values = $(this).attr("data-collapse") || ""; 155 | $.each(values.split(" "), function(i,v) { 156 | if(v) settings[v] = true; 157 | }); 158 | new Collapse($(this), settings); 159 | }); 160 | } 161 | }); 162 | 163 | // Expose constructor to 164 | // global namespace 165 | exports.jQueryCollapse = Collapse; 166 | exports.jQueryCollapseSection = Section; 167 | 168 | //jQuery DOM Ready 169 | $(function() { 170 | $.fn.collapse(false, true); 171 | }); 172 | 173 | })(window.jQuery, window); 174 | -------------------------------------------------------------------------------- /smart-contracts/make-pkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -v 3 | set -e 4 | ITEM=$1 5 | DATE=$(date +'%Y%m%d') 6 | ZIPDIR=$(basename $ITEM)-$DATE 7 | ITEMDIR=$(dirname $ITEM) 8 | 9 | if [ -e ~/$ZIPDIR.zip ] ; then 10 | echo "package ~/$ZIPDIR.zip already exists. ending" 11 | exit 1 12 | fi 13 | 14 | if [ -e ~/$ZIPDIR ] ; then 15 | mv ~/$ZIPDIR ~/$ZIPDIR.old 16 | fi 17 | 18 | mkdir ~/$ZIPDIR 19 | cp *.sh *.js *.css *.md *.html ~/$ZIPDIR 20 | cp -r node_modules ~/$ZIPDIR 21 | rm -f $ITEM/*~ 22 | mkdir -p ~/$ZIPDIR/$ITEMDIR 23 | cp -r $ITEM ~/$ZIPDIR/$ITEMDIR 24 | sed -i -e s!models/loan!$ITEM! ~/$ZIPDIR/contract_viewer.html 25 | sed -i -e s!models/loan!$ITEM! ~/$ZIPDIR/calc-contract.js 26 | rm -rf ~/$ZIPDIR/node_modules/moment/min/tests.js 27 | rm -rf ~/$ZIPDIR/node_modules/requirejs/bin 28 | 29 | cd ~ 30 | zip -r ~/$ZIPDIR $ZIPDIR 31 | echo 32 | pushd ~/$ZIPDIR/$ITEM > /dev/null 33 | for i in *.js ; do 34 | echo `md5sum $i` 35 | done 36 | popd > /dev/null 37 | rm -rf $ZIPDIR 38 | 39 | -------------------------------------------------------------------------------- /smart-contracts/misc/execution-sheet.txt: -------------------------------------------------------------------------------- 1 | We the undersigned agree to the terms of the contract in the file 2 | TermSheet.js which was exchanged on 22 January 2015 containing the 3 | md5sum 4 | 5 | db11507dce7dd2ac1e9da508bbe13adc TermSheet.js 6 | 7 | Signed 8 | 9 | 10 | 11 | XYZ 12 | Bitquant Research Laboratories (Asia) Ltd. 13 | 14 | 15 | 16 | 17 | XYZ 18 | XYZ CORP. 19 | 20 | -------------------------------------------------------------------------------- /smart-contracts/misc/warranty.txt: -------------------------------------------------------------------------------- 1 | The lender hereby warranties to the borrower that the terms of the 2 | contract as viewed by the contract viewer are a reasonable 3 | representation of the machine executable contract. 4 | 5 | The borrower shall receive: 6 | 7 | 1) a machine copy of the contract 8 | 2) a written paper copy of the contract viewer 9 | 10 | -------------------------------------------------------------------------------- /smart-contracts/models/convertible-note-old/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | Schedule A states that the interest rate is {{annual_interest_rate}} 22 | percent per year, compounded {{compound_per_year}} per year, using the 23 | {{day_count_convention}} day count convention. The initial loan 24 | amount is {{currency}} {{initial_loan_amount}}. The credit limit 25 | consists of an additional {{currency}} {{additional_credit_limit}}. 26 | 27 | Schedule B states that the late interest rate is 28 | {{late_additional_interest_rate}} percent per annum more than the 29 | standard interest rate. 30 | 31 | Schedule C S.1 states that the lender will provide the inital loan 32 | amount on the date of the contract. 33 | 34 | Schedule C S.2 states that early payments are allowed. 35 | 36 | Schedule C S.3 states that any payments will be applied first to late 37 | fees, then to interest, then to principal. In the event that the 38 | borrower fails to make a required payment, the interest will accrue at 39 | 5% above the basic interest rate, compounded daily, and will be added 40 | to the required balance. S.5 also states that the borrower may skip 41 | the a principal payment before the end of the termination of the loan 42 | without penalty. 43 | 44 | Schedule C S.4 The borrower intends to pay back the loan over as {{number_payments}} equal installments with an interval of {{interval}}. 45 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 46 | } 47 | return Notes; 48 | }); 49 | -------------------------------------------------------------------------------- /smart-contracts/models/convertible-note-old/Parties.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define(function() { 11 | return {"set" : function(obj) { 12 | obj.parties = { 13 | roles : ["borrower", "lender"], 14 | borrower : { 15 | type: "corporation", 16 | name : "Yoyodyne Propulsion Systems Limited", 17 | domicile : "Hong Kong", 18 | company_number : "1234552", 19 | registered_office : "3/F, Nam Wo Hong Building, 148 Wing Lok Street, Sheung Wan, Hong Kong", 20 | contact : { 21 | name: "John Bigboote", 22 | address: "Yoyodyne Propulsion Systems, 1938 Cranbury Road, Grovers Mills, New Jersey", 23 | email: "bigboote@example.com" 24 | } 25 | }, 26 | lender: { 27 | type: "corporation", 28 | name : "Banzai Institute for Biomedical Engineering and Strategic Information Limited", 29 | domicile : "Hong Kong", 30 | company_number : "2334455", 31 | registered_office : "3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 32 | contact : { 33 | name: "Dr. Buckaroo Banzai", 34 | address: "Banzai Institute, 1 Banzai Road, Holland Township, New Jersey", 35 | email: "buckaroo@example.com" 36 | } 37 | } 38 | }; 39 | } 40 | }; 41 | }); 42 | -------------------------------------------------------------------------------- /smart-contracts/models/convertible-note/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | Schedule A states that the interest rate is {{annual_interest_rate}} 22 | percent per year, compounded {{compound_per_year}} per year, using the 23 | {{day_count_convention}} day count convention. The initial loan 24 | amount is {{currency}} {{initial_loan_amount}}. The credit limit 25 | consists of an additional {{currency}} {{additional_credit_limit}}. 26 | 27 | Schedule B states that the late interest rate is 28 | {{late_additional_interest_rate}} percent per annum more than the 29 | standard interest rate. 30 | 31 | Schedule C S.1 states that the lender will provide the inital loan 32 | amount on the date of the contract. 33 | 34 | Schedule C S.2 states that early payments are allowed. 35 | 36 | Schedule C S.3 states that any payments will be applied first to late 37 | fees, then to interest, then to principal. In the event that the 38 | borrower fails to make a required payment, the interest will accrue at 39 | 5% above the basic interest rate, compounded daily, and will be added 40 | to the required balance. S.5 also states that the borrower may skip 41 | the a principal payment before the end of the termination of the loan 42 | without penalty. 43 | 44 | Schedule C S.4 The borrower intends to pay back the loan over as {{number_payments}} equal installments with an interval of {{interval}}. 45 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 46 | } 47 | return Notes; 48 | }); 49 | -------------------------------------------------------------------------------- /smart-contracts/models/convertible-note/Parties.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define(function() { 11 | return {"set" : function(obj) { 12 | obj.parties = { 13 | roles : ["borrower", "lender"], 14 | borrower : { 15 | type: "corporation", 16 | name : "Yoyodyne Propulsion Systems Limited", 17 | domicile : "Hong Kong", 18 | company_number : "1234552", 19 | registered_office : "3/F, Nam Wo Hong Building, 148 Wing Lok Street, Sheung Wan, Hong Kong", 20 | contact : { 21 | name: "John Bigboote", 22 | address: "Yoyodyne Propulsion Systems, 1938 Cranbury Road, Grovers Mills, New Jersey", 23 | email: "bigboote@example.com" 24 | } 25 | }, 26 | lender: { 27 | type: "corporation", 28 | name : "Banzai Institute for Biomedical Engineering and Strategic Information Limited", 29 | domicile : "Hong Kong", 30 | company_number : "2334455", 31 | registered_office : "3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 32 | contact : { 33 | name: "Dr. Buckaroo Banzai", 34 | address: "Banzai Institute, 1 Banzai Road, Holland Township, New Jersey", 35 | email: "buckaroo@example.com" 36 | } 37 | } 38 | }; 39 | } 40 | }; 41 | }); 42 | -------------------------------------------------------------------------------- /smart-contracts/models/convertible-note/note.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joequant/bitquant/38476d3bb035dc83a7073ddc22d7e55052a42158/smart-contracts/models/convertible-note/note.docx -------------------------------------------------------------------------------- /smart-contracts/models/credit-line/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | Schedule A states that there is no time based interest rate, and that 22 | the total credit limit for the duration of the credit line is HKD 23 | {{credit_limit}}. 24 | 25 | Section 17 of the contract states that Principal shall be paid in 26 | either HKD or XBT. Interest and late fees must be paid via bitcoin 27 | based on the XBT exchange rate which is defined as the conversion rate 28 | for exchange of bitcoin at either ANXBTC or bitcashout. 29 | 30 | Schedule B states that the late interest rate is 31 | {{late_additional_interest_rate}} percent per annum. 32 | 33 | Schedule C S.1 states that the lender will provide a payment on 34 | request up to the maximum credit limit. 35 | 36 | Schedule C S.2 states that if the borrower misses a deadline that 37 | there will be a late interest charge due immediately. 38 | 39 | Schedule C S.3 states that the borrower agrees to pay back the any 40 | remaining balance and a finance charge of {{finance_charge}} percent, 41 | each quarter. This payment will normally be due 45 days after the end 42 | of the quarter. In the event, that the borrower fails to receive a 43 | grant payment from the HKSAR government, this deadline will be 44 | extended to three days after the borrower receives the grant payment 45 | or 90 days after the end of the quarter. 46 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 47 | } 48 | return Notes; 49 | }); 50 | -------------------------------------------------------------------------------- /smart-contracts/models/hire-purchase/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | Schedule 1 states that lessor will pay {{number_payments}} payments at an interest rate of {{annual_interest_rate}} against an initial amount of {{initial_amount}} for {{equipment}}. The lessor may take ownership of the equipment at anytime during the lease period by paying off the balance of the loan. 22 | 23 | The lessor agrees that the loan made between Bitquant Research Laboratories (Asia) Limited and lessee dated 26 November 2014 which was assigned to the lessor shall be deemed to be paid off if lessee pays the lessor the difference between the amount of that loan and the initial value of this agreement which is the sum of 33200 HKD. 24 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 25 | } 26 | return Notes; 27 | }); 28 | -------------------------------------------------------------------------------- /smart-contracts/models/hk-company-secured/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | Schedule A states that the interest rate is {{annual_interest_rate}} 22 | percent per year, compounded {{compound_per_year}} per year, using the 23 | {{day_count_convention}} day count convention. The initial loan 24 | amount is {{currency}} {{initial_loan_amount}}. The credit limit 25 | consists of an additional {{currency}} {{additional_credit_limit}}. 26 | 27 | Schedule B states that the late interest rate is 28 | {{late_additional_interest_rate}} percent per annum more than the 29 | standard interest rate. 30 | 31 | Schedule C S.1 states that the lender will provide the inital loan 32 | amount on the date of the contract. 33 | 34 | Schedule C S.2 states that early payments are allowed. 35 | 36 | Schedule C S.3 states that any payments will be applied first to late 37 | fees, then to interest, then to principal. In the event that the 38 | borrower fails to make a required payment, the interest will accrue at 39 | 5% above the basic interest rate, compounded daily, and will be added 40 | to the required balance. S.5 also states that the borrower may skip 41 | the a principal payment before the end of the termination of the loan 42 | without penalty. 43 | 44 | Schedule C S.4 The borrower intends to pay back the loan over as {{number_payments}} equal installments with an interval of {{interval}}. 45 | 46 | {{additional_provisions}} 47 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 48 | } 49 | return Notes; 50 | }); 51 | -------------------------------------------------------------------------------- /smart-contracts/models/hk-company-secured/Parties.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define(function() { 11 | return {"set" : function(obj) { 12 | obj.parties = { 13 | roles : ["borrower", "lender"], 14 | borrower : { 15 | type: "corporation", 16 | name : "Yoyodyne Propulsion Systems Limited", 17 | domicile : "Hong Kong", 18 | company_number : "1234552", 19 | registered_office : "3/F, Nam Wo Hong Building, 148 Wing Lok Street, Sheung Wan, Hong Kong", 20 | contact : { 21 | name: "John Bigboote", 22 | address: "Yoyodyne Propulsion Systems, 1938 Cranbury Road, Grovers Mills, New Jersey", 23 | email: "bigboote@example.com" 24 | } 25 | }, 26 | lender: { 27 | type: "corporation", 28 | name : "Banzai Institute for Biomedical Engineering and Strategic Information Limited", 29 | domicile : "Hong Kong", 30 | company_number : "2334455", 31 | registered_office : "3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 32 | contact : { 33 | name: "Dr. Buckaroo Banzai", 34 | address: "Banzai Institute, 1 Banzai Road, Holland Township, New Jersey", 35 | email: "buckaroo@example.com" 36 | } 37 | } 38 | }; 39 | } 40 | }; 41 | }); 42 | -------------------------------------------------------------------------------- /smart-contracts/models/hk-money-lender-2/Parties.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define(function() { 11 | return {"set" : function(obj) { 12 | obj.parties = { 13 | roles : ["borrower", "lender"], 14 | borrower : { 15 | type: "individual", 16 | name : "B1", 17 | domicile : "Hong Kong", 18 | address: "", 19 | extra: "", 20 | contact : { 21 | name: "B1", 22 | address: "A1", 23 | email: "b1@a.com" 24 | } 25 | }, 26 | lender: { 27 | type: "corporation", 28 | name : "Bitquant Research Laboratories (Asia) Limited", 29 | domicile : "Hong Kong", 30 | company_number : "2022190", 31 | registered_office : "B-25, 3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 32 | contact : { 33 | name: "Joseph Wang", 34 | address: "B-25, 3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 35 | email: "joequant@gmail.com" 36 | }, 37 | extra : ", a licensed Hong Kong Money Lender with license 811/2015" 38 | } 39 | }; 40 | } 41 | }; 42 | }); 43 | -------------------------------------------------------------------------------- /smart-contracts/models/hk-money-lender/Parties.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define(function() { 11 | return {"set" : function(obj) { 12 | obj.parties = { 13 | roles : ["borrower", "lender"], 14 | borrower : { 15 | type: "corporation", 16 | name : "Yoyodyne Propulsion Systems Limited", 17 | domicile : "Hong Kong", 18 | company_number : "1234552", 19 | registered_office : "3/F, Nam Wo Hong Building, 148 Wing Lok Street, Sheung Wan, Hong Kong", 20 | contact : { 21 | name: "John Bigboote", 22 | address: "Yoyodyne Propulsion Systems, 1938 Cranbury Road, Grovers Mills, New Jersey", 23 | email: "bigboote@example.com" 24 | } 25 | }, 26 | lender: { 27 | type: "corporation", 28 | name : "Bitquant Research Laboratories (Asia) Limited", 29 | domicile : "Hong Kong", 30 | company_number : "2022190", 31 | registered_office : "B-25, 3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 32 | contact : { 33 | name: "Joseph Wang", 34 | address: "B-25, 3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 35 | email: "joequant@gmail.com" 36 | }, 37 | extra : ", a licensed Hong Kong Money Lender with license 811/2015" 38 | } 39 | }; 40 | } 41 | }; 42 | }); 43 | -------------------------------------------------------------------------------- /smart-contracts/models/loan/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | This loan contract is a for use within Hong Kong for a company which 22 | exports or imports goods and services into or out of Hong Kong and is 23 | therefore exempt from the Money Lenders Ordinance under Cap 163 24 | Schedule 1, Part 2, Paragraph 11. It is not suitable for non-exempt 25 | loans as the provisions for late fees and compound interest are 26 | inconsistent with Sections 22 and 23 of the MLO. 27 | 28 | Schedule A states that the interest rate is {{annual_interest_rate}} 29 | percent per year, compounded monthly, using the 30 | {{day_count_convention}} day count convention. The initial loan 31 | amount is {{currency}} {{initial_loan_amount}}. The credit limit 32 | consists of an additional {{currency}} {{additional_credit_limit}}. 33 | There are two revenue targets for the accelerated payment. The first 34 | target occurs at HKD 750,000 and causes an accelerated payment of one 35 | half of the loan. The other target occurs at HKD 1,500,000 and 36 | results an in accelerated payment of the full loan. 37 | 38 | Revenue is defined in section 17 of the contract and includes receipts 39 | due to sales of the product and licensing fees resulting from the 40 | product. The borrower is required to provide monthly updates as to 41 | the receipts of the product, and it inform the lender within three 42 | days if the borrower reasonably believes that the revenue targets has 43 | been hit. 44 | 45 | Section 17 of the contract states that Principal shall be paid in 46 | either HKD or XBT. Interest and late fees must be paid via bitcoin 47 | based on the XBT exchange rate which is defined as the conversion rate 48 | for exchange of bitcoin at either ANXBTC or bitcashout. 49 | 50 | Schedule B states that the late interest rate is 51 | {{late_additional_interest_rate}} percent per annum more than the 52 | standard interest rate. 53 | 54 | Schedule C S.1 states that the lender will provide the inital loan 55 | amount on the date of the contract. 56 | 57 | Schedule C S.2 states that the borrower may request up to an 58 | additional amount up to the credit limit during the duration of the 59 | loan. 60 | 61 | Schedule C S.3 states that the borrower agrees to pay back the any 62 | remaining principal and accrued interest on the first of the month 63 | following the after one year of the date of the loan. This agreement 64 | will terminate following this payment. 65 | 66 | Schedule C S.4 states that the borrower may make early payments at any 67 | time. 68 | 69 | Schedule C S.5 states that any payments will be applied first to late 70 | fees, then to interest, then to principal. In the event that the 71 | borrower fails to make a required payment, the interest will accrue at 72 | 5% above the basic interest rate, compounded daily, and will be added 73 | to the required balance. S.5 also states that the borrower may skip 74 | the a principal payment before the end of the termination of the loan 75 | without penalty. 76 | 77 | Schedule C S.6 describes the standard payments schedule - The borrower 78 | intends to pay back the loan over as 8 equal installments and 79 | completed in 8 months. The payback will begin in the first 1st of the 80 | month on or after the fifth month after the start of the loan. 81 | 82 | Schedule C S.7 describes the accelerated payment schedule - If the 83 | total revenues from the product exceeds the revenue target, the 84 | borrower the will be required to pay a specified fraction of the 85 | outstanding balance in addition to a specified fraction of the 86 | interest had the balance been carried to the end of the contract. 87 | This payment will be due on the first of the month on or following two 88 | weeks after the revenue target is reached or the final payment date, 89 | whichever is first. 90 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 91 | } 92 | return Notes; 93 | }); 94 | -------------------------------------------------------------------------------- /smart-contracts/models/simple-amortized/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (function() { 11 | function Notes() { 12 | this.header = (function () {/* 13 | The lender represents that the explanatory notes are a good faith 14 | explanation of the terms of the agreement entered into by the parties. 15 | 16 | Nevertheless, these explanatory notes do not form part of the 17 | contract, and in case of a conflict between the code and these notes, 18 | the code shall prevail. 19 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 20 | this.terms = (function () {/* 21 | Schedule A states that the interest rate is {{annual_interest_rate}} 22 | percent per year, compounded {{compound_per_year}} per year, using the 23 | {{day_count_convention}} day count convention. The initial loan 24 | amount is {{currency}} {{initial_loan_amount}}. The credit limit 25 | consists of an additional {{currency}} {{additional_credit_limit}}. 26 | 27 | Schedule B states that the late interest rate is 28 | {{late_additional_interest_rate}} percent per annum more than the 29 | standard interest rate. 30 | 31 | Schedule C S.1 states that the lender will provide the inital loan 32 | amount on the date of the contract. 33 | 34 | Schedule C S.2 states that early payments are allowed. 35 | 36 | Schedule C S.3 states that any payments will be applied first to late 37 | fees, then to interest, then to principal. In the event that the 38 | borrower fails to make a required payment, the interest will accrue at 39 | 5% above the basic interest rate, compounded daily, and will be added 40 | to the required balance. S.5 also states that the borrower may skip 41 | the a principal payment before the end of the termination of the loan 42 | without penalty. 43 | 44 | Schedule C S.4 The borrower intends to pay back the loan over as {{number_payments}} equal installments with an interval of {{interval}}. 45 | */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1]; 46 | } 47 | return Notes; 48 | }); 49 | -------------------------------------------------------------------------------- /smart-contracts/models/simple-amortized/Parties.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define(function() { 11 | return {"set" : function(obj) { 12 | obj.parties = { 13 | roles : ["borrower", "lender"], 14 | borrower : { 15 | type: "corporation", 16 | name : "Yoyodyne Propulsion Systems Limited", 17 | domicile : "Hong Kong", 18 | company_number : "1234552", 19 | registered_office : "3/F, Nam Wo Hong Building, 148 Wing Lok Street, Sheung Wan, Hong Kong", 20 | contact : { 21 | name: "John Bigboote", 22 | address: "Yoyodyne Propulsion Systems, 1938 Cranbury Road, Grovers Mills, New Jersey", 23 | email: "bigboote@example.com" 24 | } 25 | }, 26 | lender: { 27 | type: "corporation", 28 | name : "Banzai Institute for Biomedical Engineering and Strategic Information Limited", 29 | domicile : "Hong Kong", 30 | company_number : "2334455", 31 | registered_office : "3/F, Citicorp Centre, 18 Whitfield Road, Tin Hau, Hong Kong", 32 | contact : { 33 | name: "Dr. Buckaroo Banzai", 34 | address: "Banzai Institute, 1 Banzai Road, Holland Township, New Jersey", 35 | email: "buckaroo@example.com" 36 | } 37 | } 38 | }; 39 | } 40 | }; 41 | }); 42 | -------------------------------------------------------------------------------- /smart-contracts/models/subclass/Notes.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | "use strict"; 4 | 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | define (["../loan/Notes"], function(Notes) { 11 | function SubClass() { 12 | Notes.call(this); 13 | } 14 | SubClass.prototype = Object.create(Notes.prototype); 15 | return SubClass; 16 | }); 17 | -------------------------------------------------------------------------------- /smart-contracts/models/subclass/TermSheet.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014, Bitquant Research Laboratories (Asia) Ltd. 2 | // Licensed under the Simplified BSD License 3 | 4 | "use strict"; 5 | 6 | if (typeof define !== 'function') { 7 | var define = require('amdefine')(module); 8 | } 9 | 10 | 11 | define(["../loan/TermSheet"], function(TermSheet) { 12 | function SubClass() { 13 | TermSheet.call(this); 14 | this.borrower.name = "TEST CHANGE"; 15 | } 16 | SubClass.prototype = Object.create(TermSheet.prototype); 17 | return SubClass; 18 | }); 19 | -------------------------------------------------------------------------------- /smart-contracts/node_modules/moment/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2016 Tim Wood, Iskren Chernev, Moment.js contributors 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /smart-contracts/node_modules/moment/README.md: -------------------------------------------------------------------------------- 1 | [![Join the chat at https://gitter.im/moment/moment](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/moment/moment?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 2 | 3 | [![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url] 4 | [![Coverage Status](https://coveralls.io/repos/moment/moment/badge.svg?branch=develop)](https://coveralls.io/r/moment/moment?branch=develop) 5 | 6 | A lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates. 7 | 8 | ## [Documentation](http://momentjs.com/docs/) 9 | 10 | ## Port to ECMAScript 6 (version 2.10.0) 11 | 12 | Moment 2.10.0 does not bring any new features, but the code is now written in 13 | ECMAScript 6 modules and placed inside `src/`. Previously `moment.js`, `locale/*.js` and 14 | `test/moment/*.js`, `test/locale/*.js` contained the source of the project. Now 15 | the source is in `src/`, temporary build (ECMAScript 5) files are placed under 16 | `build/umd/` (for running tests during development), and the `moment.js` and 17 | `locale/*.js` files are updated only on release. 18 | 19 | If you want to use a particular revision of the code, make sure to run 20 | `grunt transpile update-index`, so `moment.js` and `locales/*.js` are synced 21 | with `src/*`. We might place that in a commit hook in the future. 22 | 23 | ## Upgrading to 2.0.0 24 | 25 | There are a number of small backwards incompatible changes with version 2.0.0. [See the full descriptions here](https://gist.github.com/timrwood/e72f2eef320ed9e37c51#backwards-incompatible-changes) 26 | 27 | * Changed language ordinal method to return the number + ordinal instead of just the ordinal. 28 | 29 | * Changed two digit year parsing cutoff to match strptime. 30 | 31 | * Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`. 32 | 33 | * Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`. 34 | 35 | * Removed the lang data objects from the top level namespace. 36 | 37 | * Duplicate `Date` passed to `moment()` instead of referencing it. 38 | 39 | ## [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md) 40 | 41 | ## [Contributing](https://github.com/moment/moment/blob/develop/CONTRIBUTING.md) 42 | 43 | We're looking for co-maintainers! If you want to become a master of time please 44 | write to [ichernev](https://github.com/ichernev). 45 | 46 | ## License 47 | 48 | Moment.js is freely distributable under the terms of the [MIT license](https://github.com/moment/moment/blob/develop/LICENSE). 49 | 50 | [license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat 51 | [license-url]: LICENSE 52 | 53 | [npm-url]: https://npmjs.org/package/moment 54 | [npm-version-image]: http://img.shields.io/npm/v/moment.svg?style=flat 55 | [npm-downloads-image]: http://img.shields.io/npm/dm/moment.svg?style=flat 56 | 57 | [travis-url]: http://travis-ci.org/moment/moment 58 | [travis-image]: http://img.shields.io/travis/moment/moment/develop.svg?style=flat 59 | -------------------------------------------------------------------------------- /smart-contracts/node_modules/moment/ender.js: -------------------------------------------------------------------------------- 1 | $.ender({ moment: require('moment') }) 2 | -------------------------------------------------------------------------------- /smart-contracts/node_modules/moment/package.js: -------------------------------------------------------------------------------- 1 | var profile = { 2 | resourceTags: { 3 | ignore: function(filename, mid){ 4 | // only include moment/moment 5 | return mid != "moment/moment"; 6 | }, 7 | amd: function(filename, mid){ 8 | return /\.js$/.test(filename); 9 | } 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /smart-contracts/node_modules/moment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_args": [ 3 | [ 4 | "moment", 5 | "/home/joe/git/bitquant/smart-contracts" 6 | ] 7 | ], 8 | "_from": "moment@latest", 9 | "_id": "moment@2.11.2", 10 | "_inCache": true, 11 | "_installable": true, 12 | "_location": "/moment", 13 | "_npmOperationalInternal": { 14 | "host": "packages-5-east.internal.npmjs.com", 15 | "tmp": "tmp/moment-2.11.2.tgz_1454539675038_0.8288003103807569" 16 | }, 17 | "_npmUser": { 18 | "email": "iskren.chernev@gmail.com", 19 | "name": "ichernev" 20 | }, 21 | "_npmVersion": "1.4.6", 22 | "_phantomChildren": {}, 23 | "_requested": { 24 | "name": "moment", 25 | "raw": "moment", 26 | "rawSpec": "", 27 | "scope": null, 28 | "spec": "latest", 29 | "type": "tag" 30 | }, 31 | "_requiredBy": [ 32 | "/" 33 | ], 34 | "_resolved": "https://registry.npmjs.org/moment/-/moment-2.11.2.tgz", 35 | "_shasum": "87968e5f95ac038c2e42ac959c75819cd3f52901", 36 | "_shrinkwrap": null, 37 | "_spec": "moment", 38 | "_where": "/home/joe/git/bitquant/smart-contracts", 39 | "author": { 40 | "email": "iskren.chernev@gmail.com", 41 | "name": "Iskren Ivov Chernev", 42 | "url": "https://github.com/ichernev" 43 | }, 44 | "bugs": { 45 | "url": "https://github.com/moment/moment/issues" 46 | }, 47 | "contributors": [ 48 | { 49 | "name": "Tim Wood", 50 | "email": "washwithcare@gmail.com", 51 | "url": "http://timwoodcreates.com/" 52 | }, 53 | { 54 | "name": "Rocky Meza", 55 | "url": "http://rockymeza.com" 56 | }, 57 | { 58 | "name": "Matt Johnson", 59 | "email": "mj1856@hotmail.com", 60 | "url": "http://codeofmatt.com" 61 | }, 62 | { 63 | "name": "Isaac Cambron", 64 | "email": "isaac@isaaccambron.com", 65 | "url": "http://isaaccambron.com" 66 | }, 67 | { 68 | "name": "Andre Polykanine", 69 | "email": "andre@oire.org", 70 | "url": "https://github.com/oire" 71 | } 72 | ], 73 | "dependencies": {}, 74 | "description": "Parse, validate, manipulate, and display dates", 75 | "devDependencies": { 76 | "benchmark": "latest", 77 | "coveralls": "^2.11.2", 78 | "es6-promise": "latest", 79 | "esperanto": "latest", 80 | "grunt": "latest", 81 | "grunt-benchmark": "latest", 82 | "grunt-cli": "latest", 83 | "grunt-contrib-clean": "latest", 84 | "grunt-contrib-concat": "latest", 85 | "grunt-contrib-copy": "latest", 86 | "grunt-contrib-jshint": "latest", 87 | "grunt-contrib-uglify": "latest", 88 | "grunt-contrib-watch": "latest", 89 | "grunt-env": "latest", 90 | "grunt-exec": "latest", 91 | "grunt-jscs": "latest", 92 | "grunt-karma": "latest", 93 | "grunt-nuget": "latest", 94 | "grunt-string-replace": "latest", 95 | "karma": "latest", 96 | "karma-chrome-launcher": "latest", 97 | "karma-firefox-launcher": "latest", 98 | "karma-qunit": "latest", 99 | "karma-sauce-launcher": "latest", 100 | "load-grunt-tasks": "latest", 101 | "nyc": "^2.1.4", 102 | "qunit": "^0.7.5", 103 | "qunit-cli": "^0.1.4", 104 | "spacejam": "latest", 105 | "uglify-js": "latest" 106 | }, 107 | "directories": {}, 108 | "dist": { 109 | "shasum": "87968e5f95ac038c2e42ac959c75819cd3f52901", 110 | "tarball": "http://registry.npmjs.org/moment/-/moment-2.11.2.tgz" 111 | }, 112 | "dojoBuild": "package.js", 113 | "ender": "./ender.js", 114 | "engines": { 115 | "node": "*" 116 | }, 117 | "homepage": "http://momentjs.com", 118 | "jspm": { 119 | "buildConfig": { 120 | "uglify": true 121 | }, 122 | "files": [ 123 | "locale", 124 | "moment.js" 125 | ], 126 | "map": { 127 | "moment": "./moment" 128 | } 129 | }, 130 | "keywords": [ 131 | "date", 132 | "ender", 133 | "format", 134 | "i18n", 135 | "l10n", 136 | "moment", 137 | "parse", 138 | "time", 139 | "validate" 140 | ], 141 | "license": "MIT", 142 | "main": "./moment.js", 143 | "maintainers": [ 144 | { 145 | "name": "timrwood", 146 | "email": "washwithcare@gmail.com" 147 | }, 148 | { 149 | "name": "ichernev", 150 | "email": "iskren.chernev@gmail.com" 151 | } 152 | ], 153 | "name": "moment", 154 | "optionalDependencies": {}, 155 | "readme": "ERROR: No README data found!", 156 | "repository": { 157 | "type": "git", 158 | "url": "git+https://github.com/moment/moment.git" 159 | }, 160 | "scripts": { 161 | "coverage": "nyc npm test && nyc report", 162 | "coveralls": "nyc npm test && nyc report --reporter=text-lcov | coveralls", 163 | "test": "grunt test" 164 | }, 165 | "spm": { 166 | "main": "moment.js", 167 | "output": [ 168 | "locale/*.js" 169 | ] 170 | }, 171 | "version": "2.11.2" 172 | } 173 | --------------------------------------------------------------------------------