├── .dir-locals.el ├── .dockerignore ├── .editorconfig ├── .github └── workflows │ ├── ci.yml │ └── pr.yml ├── .gitignore ├── README.md ├── bundel ├── bundel-compile-adv.sh ├── bundel-compile.sh ├── release.edn ├── resources └── src ├── clj-kondo.edn ├── cljfmt.edn ├── codecov.yml ├── deps.edn ├── karma.conf.js ├── profiles ├── dev │ └── src │ │ ├── datafy.clj │ │ └── infer-specs.clj └── webly │ ├── resources │ ├── creds-sample.edn │ └── demo.edn │ └── src │ └── demo │ ├── app.clj │ ├── app.cljs │ ├── pages │ └── examples.cljs │ ├── routes.cljc │ └── views │ ├── completion.cljs │ ├── datafy.cljs │ ├── main.cljs │ ├── notebook.cljs │ ├── sidebar.cljs │ └── stacktrace.cljs ├── release.edn ├── resources ├── broken │ ├── loom-test.cljg │ └── sparkling.cljg ├── notebook-bundel.edn ├── notebook-core.edn ├── notebooks │ └── notebook │ │ ├── cljs-demo.cljg │ │ ├── clojure │ │ ├── core_async.cljg │ │ ├── diff.cljg │ │ ├── multimethods.cljg │ │ ├── pprint docstrings.cljg │ │ └── zmqping.cljg │ │ ├── goldly-click-counter.cljg │ │ ├── hiccup │ │ ├── clock-and-table.cljg │ │ ├── html-script.cljg │ │ ├── image-table.cljg │ │ ├── svg-circle.cljg │ │ └── tailwind.cljg │ │ ├── notebook-welcome.cljg │ │ └── specs.cljg └── public │ └── notebook-ui │ ├── bootstrap.css │ ├── punk.css │ └── re-com.css ├── scripts ├── clear.sh ├── copy-md.sh ├── copy_res.sh ├── jar.sh ├── prep-res.sh ├── show-resources.sh └── test-cljs.sh ├── src-unused ├── b.sh ├── bundel-deploy.sh ├── code.cljs ├── deps.edn ├── events_snippets.cljs └── scroll.cljs ├── src ├── deps.cljs └── pinkgorilla │ ├── bconfig.clj │ ├── notebook_bundel.clj │ └── notebook_ui │ ├── app │ ├── app.clj │ ├── app.cljs │ ├── css.cljs │ ├── events.cljs │ ├── keybindings.cljc │ ├── notebook.cljs │ ├── pages │ │ ├── about.cljs │ │ ├── document.cljs │ │ ├── explorer.cljs │ │ ├── goldly.cljs │ │ └── nrepl.cljs │ ├── routes.clj │ ├── services.clj │ └── site.cljs │ ├── completion │ ├── component.cljs │ ├── docstring.cljs │ ├── events.cljs │ └── view.cljs │ ├── datafy │ ├── dialog.cljs │ ├── events_dialog.cljs │ ├── events_nrepl.cljs │ ├── events_punk.cljs │ ├── test.edn │ ├── view.cljs │ └── views.cljs │ ├── schema │ ├── interceptor.cljs │ ├── sample.cljc │ └── schema.cljc │ ├── settings │ ├── component.cljs │ ├── default.cljs │ └── events.cljs │ ├── sniffer │ ├── dump.clj │ ├── dump.cljs │ └── events.cljs │ └── views │ └── meta.cljs └── test └── pinkgorilla ├── core_test.clj └── hydration_test.cljc /.dir-locals.el: -------------------------------------------------------------------------------- 1 | ;;; Directory Local Variables 2 | ;;; For more information see (info "(emacs) Directory Variables") 3 | 4 | ((clojure-mode 5 | (clojure-indent-style . :always-align) 6 | (indent-tabs-mode . nil) 7 | (fill-column . 80))) 8 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .idea 2 | docker/*/* 3 | attic 4 | *.sh 5 | *.md 6 | dev-resources 7 | env 8 | favicon 9 | index.html 10 | LICENCE.txt 11 | out 12 | README.md 13 | script 14 | target/classes 15 | target/cljsbuild 16 | target/cljsbuild-crossover 17 | target/stale 18 | test 19 | ws 20 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Learn more about EditorConfig at http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | [*.{clj,cljs,cljc}] 12 | indent_style = space 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | with: 15 | fetch-depth: 0 16 | - name: Use Node.js 12.x 17 | uses: actions/setup-node@v2.1.5 18 | with: 19 | node-version: 12.x 20 | - name: Prepare java 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: 1.14 24 | - name: Install clojure tools 25 | uses: DeLaGuardo/setup-clojure@3.5 26 | with: 27 | # Install just one or all simultaneously 28 | cli: 1.10.3.882 # Clojure CLI based on tools.deps 29 | #lein: 2.9.1 # or use 'latest' to always provision latest version of leiningen 30 | #boot: 2.8.3 # or use 'latest' to always provision latest version of boot 31 | #- name: Execute clojure code on Linux and MacOS 32 | # if: ${{ matrix.os != 'windows-latest' }} 33 | # run: clojure -e "(+ 1 1)" 34 | # shell: bash 35 | - name: clj-fmt 36 | if: ${{ matrix.os != 'windows-latest' }} 37 | run: clojure -M:cljfmt 38 | shell: bash 39 | #- name: show git tag 40 | # run: clojure -M:garamond 41 | - name: npm-install 42 | run: | 43 | clojure -X:notebook-core :profile '"npm-install"' 44 | ./scripts/prep-res.sh 45 | #- name: clj-kondo 46 | # run: clojure -M:lint 47 | - name: test-clj 48 | run: clojure -M:test 49 | - name: test-cljs 50 | run: ./scripts/test-cljs.sh 51 | #- name: cloverage 52 | # run: clojure -M:cloverage 53 | - name: Release 54 | if: success() 55 | # if: github.event_name == 'push' 56 | env: 57 | CLOJARS_USERNAME: ${{ secrets.ReleaseUsername }} 58 | CLOJARS_PASSWORD: ${{ secrets.ReleasePassword }} 59 | CODECOV_TOKEN: ${{ secrets.CodecovToken }} 60 | run: | 61 | git config --global user.email "ci@pinkgorilla.org" 62 | git config --global user.name "CI/CD" 63 | clojure -M:release tag --patch 64 | clojure -M:spit 65 | clojure -M:release 66 | git push --tags 67 | # clojure -M:release --patch 68 | # clojure -M:release tag --minor 69 | # clojure -M:release pom 70 | # clojure -M:release jar 71 | # clojure -M:release deploy 72 | # bash <(curl -s https://codecov.io/bash) 73 | - name: Release-Bundel 74 | env: 75 | CLOJARS_USERNAME: ${{ secrets.ReleaseUsername }} 76 | CLOJARS_PASSWORD: ${{ secrets.ReleasePassword }} 77 | run: | 78 | git config --global user.email "ci@pinkgorilla.org" 79 | git config --global user.name "CI/CD" 80 | clojure -X:bundel-config 81 | cd bundel 82 | ./bundel-compile-adv.sh 83 | clojure -M:release -------------------------------------------------------------------------------- /.github/workflows/pr.yml: -------------------------------------------------------------------------------- 1 | name: Validate Pull Request 2 | 3 | on: 4 | pull_request: 5 | 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: Cache Maven dependencies 15 | uses: actions/cache@v1 16 | with: 17 | path: ~/.m2/repository 18 | key: ${{ runner.os }}-maven-${{ hashFiles('**/project.clj') }} 19 | restore-keys: | 20 | ${{ runner.os }}-maven- 21 | - name: Check formatting 22 | run: clojure -M:cljfmt 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .shadow-cljs 3 | target 4 | .nrepl-port 5 | .lein-repl-history 6 | /.calva 7 | /.lsp 8 | shadow-cljs.edn 9 | package.json 10 | package-lock.json 11 | creds.edn 12 | goldly_bindings_generated.cljs 13 | .webly 14 | .cpcache 15 | pom.xml 16 | karma.conf.js 17 | bundel/deps.edn 18 | notebook_version.edn 19 | .sniffer.edn -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pink Gorilla Notebook [![GitHub Actions status |pink-gorilla/notebook](https://github.com/pink-gorilla/notebook/workflows/CI/badge.svg)](https://github.com/pink-gorilla/notebook/actions?workflow=CI) 2 | [![Clojars Project](https://img.shields.io/clojars/v/org.pinkgorilla/notebook.svg)](https://clojars.org/org.pinkgorilla/notebook) 3 | [![Clojars Project](https://img.shields.io/clojars/v/org.pinkgorilla/notebook-bundel.svg)](https://clojars.org/org.pinkgorilla/notebook-bundel) 4 | 5 | Pink Gorilla Notebook is a rich browser based notebook REPL for Clojure and ClojureScript, which aims at extensibility 6 | (development- and runtime) and user experience while being very lightweight. Extensibility primarily revolves around 7 | UI vizulisations and data. 8 | 9 | ### Use cases 10 | - Data science 11 | - Persistent experiments and demos (Clojure/ClojureScript libraries) 12 | - Courses and education on all matters related to clojure 13 | 14 | ### Web Interface 15 | 16 | Whichever method you use to start the notebook, you should reach it at [`http://localhost:8000/`](http://localhost:8000/). 17 | 18 | ## Run Notebook standalone 19 | 20 | The easiest way to run the notebook locally is leveraging the `clojure` cli 21 | 22 | ``` 23 | clojure -Sdeps '{:deps {org.pinkgorilla/notebook-bundel {:mvn/version "RELEASE"}}}' -m pinkgorilla.notebook-bundel 24 | ``` 25 | 26 | ## Run Notebook with **default bundel** 27 | 28 | Since the default bundel ships many default ui extensions, you want to use the **notebook-bundel** 29 | artefact, because the javascript frotend app has already been precompiled, which results in faster startup-time. 30 | 31 | ### in your deps.edn project 32 | 33 | We recommend to use tools.deps over leiningen fortwo reasons: 34 | - no dependency coflicts with tools.deps (tools deps resolves to the highest dependency version, vs leiningen which depends on the position in the project.clj 35 | - use RELEASE so you always get the most recent notebook) 36 | 37 | One way to configure the notebook is to pass it a edn configuration file. An example is 38 | [notebook edn config](https://github.com/pink-gorilla/notebook/blob/master/resources/notebook-core.edn) 39 | 40 | In your deps.edn add this alias: 41 | ``` 42 | :notebook {:extra-deps {org.pinkgorilla/notebook-bundel {:mvn/version "RELEASE"}} 43 | :exec-fn pinkgorilla.notebook-bundel/run 44 | :exec-args {:config "notebook-config.edn"}} 45 | ``` 46 | then run it with `clojure -X:notebook`. 47 | 48 | [trateg](https://github.com/clojure-quant/trateg) uses notebook-bundel with deps.edn: 49 | Clone trateg and run `clojure -X:notebook` 50 | 51 | ### in your leiningen project 52 | 53 | ** We don't recommend leiningen use with notebook, as leiningen does not use the highest version of dependencies. ** 54 | 55 | ## Run Notebook with **custom bundel** 56 | 57 | If you define your own ui extensions, you need to compile the javascript bundel. 58 | This requires some extra initial compilation time. 59 | 60 | ### in your deps.edn project 61 | 62 | [ui-quil](https://github.com/pink-gorilla/ui-quil) use deps.edn to build a custom notebook 63 | bundel (that includes the library that gets built). 64 | 65 | ### in your leiningen project 66 | 67 | [gorilla-ui](https://github.com/pink-gorilla/gorilla-ui) and 68 | [ui-vega](https://github.com/pink-gorilla/ui-vega) use leiningen to run notebooks with a 69 | custom build bundel, and with custom notebook folder. 70 | 71 | 72 | ## Run Notebook in Docker Image 73 | 74 | Documentation has been moved [over here](https://pink-gorilla.github.io/) 75 | 76 | 77 | [![](https://images.microbadger.com/badges/version/pinkgorillawb/gorilla-notebook.svg)](https://microbadger.com/images/pinkgorillawb/gorilla-notebook "Get your own version badge on microbadger.com") 78 | [![](https://images.microbadger.com/badges/image/pinkgorillawb/gorilla-notebook.svg)](https://microbadger.com/images/pinkgorillawb/gorilla-notebook "Get your own image badge on microbadger.com") 79 | 80 | ## Run Notebook from cloned git repo 81 | 82 | This option is mainly there for development of notebook. 83 | For regular use, the long compile-times are not really sensible. 84 | 85 | Run `clojure -X:notebook` to run the notebook. 86 | 87 | This runs the notebook with ui libraries bundled: 88 | - gorilla ui 89 | - gorilla plot 90 | 91 | ## Run Development UI 92 | 93 | Run `clojure -X:develop` to run the develop ui. 94 | 95 | ## Licence 96 | 97 | Gorilla is licensed to you under the MIT licence. See LICENCE.txt for details. 98 | 99 | Copyright © 2019- Jony Hudson, Andreas Steffan and contributors 100 | -------------------------------------------------------------------------------- /bundel/bundel-compile-adv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # npm-install has to run, because shadow-cljs 3release· does not update package.json 4 | # in comparison shadow-cljs "watch" does update package.json 5 | clojure -X:notebook :profile '"npm-install"' 6 | clojure -X:notebook :profile '"release-adv"' 7 | -------------------------------------------------------------------------------- /bundel/bundel-compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # npm-install has to run, because shadow-cljs 3release· does not update package.json 4 | # in comparison shadow-cljs "watch" does update package.json 5 | clojure -X:notebook :profile '"npm-install"' 6 | clojure -X:notebook :profile '"release"' 7 | -------------------------------------------------------------------------------- /bundel/release.edn: -------------------------------------------------------------------------------- 1 | {:group-id "org.pinkgorilla" 2 | :artifact-id "notebook-bundel" 3 | :scm-url "https://github.com/pink-gorilla/notebook/" 4 | } -------------------------------------------------------------------------------- /bundel/resources: -------------------------------------------------------------------------------- 1 | ../resources -------------------------------------------------------------------------------- /bundel/src: -------------------------------------------------------------------------------- 1 | ../src -------------------------------------------------------------------------------- /clj-kondo.edn: -------------------------------------------------------------------------------- 1 | {:linters 2 | {; see here for all options 3 | ;https://github.com/clj-kondo/clj-kondo/blob/master/src/clj_kondo/impl/config.clj 4 | 5 | ;:lint-as 6 | ;{org.httpkit.server/with-channel clj-kondo.lint-as/def-catch-all} 7 | 8 | :unused-namespace 9 | ; namespaces in this list are those we get for side-effects. 10 | ; it is also possible to do regex search here: 11 | ; https://github.com/borkdude/clj-kondo/blob/master/doc/config.md 12 | {:level :info 13 | :exclude [clojure.core.async 14 | cljs.core.async 15 | cljs.core.async.macros 16 | ]} 17 | 18 | :unused-referred-var 19 | {:level :info 20 | :exclude {taoensso.timbre [trace tracef ; dont be strict in referring to logging functions 21 | debug debugf 22 | info infof 23 | warn warnf 24 | error errorf] 25 | clojure.core.async [! >!! put! chan go go-loop] 26 | cljs.core.async [! >!! put! chan go go-loop] 27 | cljs.core.async.macros [go go-loop] 28 | re-frame.core [reg-event-db dispatch] 29 | 30 | } 31 | 32 | } 33 | 34 | :unused-binding 35 | {:level :info} 36 | 37 | :unused-private-var 38 | {:level :info} 39 | 40 | 41 | :unresolved-symbol 42 | {:level :info 43 | ;:creates-vars {org.httpkit.server/with-channel [con]} 44 | ;:exclude [; needed for: pinkgorilla/routes.cljs app-routes 45 | ;(secretary.core/defroute [query-params projects-path renderer-path]) 46 | ; (org.httpkit.server/with-channel [con]) 47 | ; (pinkgorilla.nrepl.ws.httpkit-ws-relay [con]) 48 | ; ] 49 | } 50 | 51 | ;:redundant-let 52 | ;{:level :info 53 | ; :exclude [pinkgorilla.events/kernel [kernel]]} 54 | 55 | :redundant-do 56 | {:level :info ; because the line below does not work, at least make them not ci breaking 57 | :exclude [pinkgorilla.nrepl.ws.relay/process-message-mem] ; TODO: this does not work 58 | } 59 | 60 | 61 | 62 | 63 | ; linters end 64 | }} 65 | -------------------------------------------------------------------------------- /cljfmt.edn: -------------------------------------------------------------------------------- 1 | {as-> [[:inner 0]] 2 | with-debug-bindings [[:inner 0]] 3 | merge-meta [[:inner 0]] 4 | try-if-let [[:block 1]]} -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | bot: "codecov-io" 3 | require_ci_to_pass: no 4 | 5 | coverage: 6 | status: 7 | project: 8 | default: 9 | # Project must always have at least 78% coverage (by line) 10 | target: 0% 11 | # Whole-project test coverage is allowed to drop up to 5%. (For situtations where we delete code with full coverage) 12 | threshold: 5% 13 | patch: 14 | default: 15 | # Changes must have at least 75% test coverage (by line) 16 | target: 0% -------------------------------------------------------------------------------- /deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["src" 2 | "resources" ; snippets + notebooks 3 | "target/webly" ; compiled bundel (if any) 4 | ] 5 | :deps {org.clojure/clojure {:mvn/version "1.10.3"} 6 | org.clojure/core.async {:mvn/version "1.3.618"} 7 | ; cljs 8 | thi.ng/strf {:mvn/version "0.2.2"} 9 | com.taoensso/timbre {:mvn/version "5.1.2"} ; clj/cljs logging. awb99: this fucks up kernel-cljs-shadowdeps 10 | com.lucasbradstreet/cljs-uuid-utils {:mvn/version "1.0.2"} ;; awb99: in encoding, and clj/cljs proof 11 | day8.re-frame/http-fx {:mvn/version "0.2.3"} 12 | day8.re-frame/undo {:mvn/version "0.3.3"} 13 | re-com/re-com {:mvn/version "2.13.2"} 14 | ;pink-gorilla 15 | org.pinkgorilla/picasso {:mvn/version "3.1.45"} ; used by nrepl-middleware + goldly cljs kernel 16 | org.pinkgorilla/gorilla-explore {:mvn/version "0.2.64"} ; brings notebook-encoding 17 | org.pinkgorilla/nrepl-middleware {:mvn/version "0.3.48"} ; brings picasso 18 | org.pinkgorilla/pinkie {:mvn/version "0.3.3"} 19 | org.pinkgorilla/goldly {:mvn/version "0.2.97"} 20 | org.pinkgorilla/webly {:mvn/version "0.3.8"} 21 | 22 | ; core-bundel 23 | org.pinkgorilla/ui-site {:mvn/version "0.0.6"} 24 | org.pinkgorilla/ui-repl {:mvn/version "0.0.10"} 25 | org.pinkgorilla/ui-code {:mvn/version "0.0.13"} 26 | org.pinkgorilla/ui-markdown {:mvn/version "0.0.9"}} 27 | :aliases 28 | {;; Developer tooling 29 | 30 | ;https://github.com/applied-science/deps-library 31 | :release 32 | {:extra-deps {applied-science/deps-library {:mvn/version "0.4.0"}} 33 | :main-opts ["-m" "applied-science.deps-library"]} 34 | 35 | ; https://github.com/weavejester/cljfmt 36 | :cljfmt 37 | {:extra-deps {cljfmt/cljfmt {:mvn/version "RELEASE"}} 38 | :main-opts ["-m" "cljfmt.main" "check" "--indents" "cljfmt.edn"]} 39 | :cljfmt-fix 40 | {:extra-deps {cljfmt/cljfmt {:mvn/version "RELEASE"}} 41 | :main-opts ["-m" "cljfmt.main" "fix" "--indents" "cljfmt.edn"]} 42 | 43 | ; https://github.com/clj-kondo/clj-kondo/blob/master/doc/jvm.md 44 | :lint 45 | {:extra-deps {clj-kondo/clj-kondo {:mvn/version "RELEASE"}} 46 | :main-opts ["-m" "clj-kondo.main" "--lint" "src"]} 47 | 48 | :outdated 49 | {:extra-deps {com.github.liquidz/antq {:mvn/version "RELEASE"}} 50 | :main-opts ["-m" "antq.core"]} 51 | 52 | :check 53 | {:extra-deps {athos/clj-check {:git/url "https://github.com/athos/clj-check.git" 54 | :sha "0ca84df1357d71429243b99908303f45a934654c"}} 55 | :main-opts ["-m" "clj-check.check"]} 56 | 57 | :test {:extra-paths ["test"] 58 | :extra-deps {io.github.cognitect-labs/test-runner 59 | {:git/url "https://github.com/cognitect-labs/test-runner.git" 60 | :sha "9e35c979860c75555adaff7600070c60004a0f44"}} 61 | :main-opts ["-m" "cognitect.test-runner"] 62 | :exec-fn cognitect.test-runner.api/test} 63 | 64 | :garamond 65 | {:extra-deps {com.workframe/garamond {:mvn/version "0.4.0"}} 66 | :main-opts ["-m" "garamond.main"]} 67 | 68 | :graph-deps 69 | {:replace-paths [] 70 | :replace-deps {org.clojure/tools.deps.graph {:mvn/version "1.0.63"}} 71 | :main-opts ["-m" "clojure.tools.deps.graph"] ;; deprecated 72 | :ns-default clojure.tools.deps.graph 73 | :exec-fn graph 74 | :exec-args {:output "target/dependencies-graph.png" 75 | :size true}} 76 | 77 | ; https://github.com/jgrodziski/metav#spit-or-render-current-version-in-a-file 78 | :spit {:extra-deps {metav/metav {:mvn/version "1.6.7"}} 79 | :main-opts ["-m" "metav.spit" 80 | "--output-dir" "resources" 81 | "--namespace" "notebook-version" 82 | "--formats" "edn"]} 83 | 84 | ; notebook 85 | 86 | :ci {:extra-paths ["test"] 87 | :exec-fn pinkgorilla.notebook-ui.app.app/notebook-run! 88 | :exec-args {:profile "ci" 89 | :config nil}} 90 | 91 | :develop {:extra-paths ["profiles/webly/src" 92 | "profiles/webly/resources"] 93 | :exec-fn demo.app/demo! 94 | :exec-args {:profile "watch" 95 | :config "demo.edn"}} 96 | 97 | ; used by github-ci 98 | :notebook-core {:exec-fn pinkgorilla.notebook-ui.app.app/notebook-run! 99 | :exec-args {:profile "watch" 100 | :config nil}} 101 | 102 | :notebook ; notebook with bundeled dependencies 103 | {:extra-paths ["target/webly"] 104 | :extra-deps {; extra-deps get added to bundel/deps.edn for artefact notebook-bundel 105 | org.pinkgorilla/ui-input {:mvn/version "0.0.4"} 106 | org.pinkgorilla/ui-vega {:mvn/version "0.0.8"} 107 | org.pinkgorilla/ui-highcharts {:mvn/version "0.0.3"} 108 | org.pinkgorilla/gorilla-ui {:mvn/version "0.3.39"} 109 | ;org.pinkgorilla/ui-binaryclock {:mvn/version "0.0.6"} 110 | org.pinkgorilla/ui-quil {:mvn/version "0.1.7"}} 111 | :exec-fn pinkgorilla.notebook-ui.app.app/notebook-run! 112 | :exec-args {:profile "watch" 113 | ; we use edn config, because deps.edn alias settings cannot be saved as resource 114 | ; and we wat to avoid duplication of the config. 115 | :config "notebook-bundel.edn" ; in resources/notebook-bundel.edn 116 | }} 117 | ;; 118 | 119 | :bundel-config {:exec-fn pinkgorilla.bconfig/generate-bundle-config} 120 | 121 | ;; different ways to start the bundel - for testing 122 | ; need to be run in the bundel folder. 123 | 124 | ;:run {:extra-deps {org.pinkgorilla/gorilla-ui {:mvn/version "0.3.30"} 125 | ; org.pinkgorilla/gorilla-plot {:mvn/version "1.2.11"} 126 | ; org.pinkgorilla/ui-quil {:mvn/version "0.1.5"}} 127 | ; :main-opts ["-m" "pinkgorilla.notebook-bundel"]} 128 | 129 | ;:runxna {:extra-deps {org.pinkgorilla/gorilla-ui {:mvn/version "0.3.28"} 130 | ; org.pinkgorilla/gorilla-plot {:mvn/version "1.2.11"} 131 | ; org.pinkgorilla/ui-quil {:mvn/version "0.1.5"}} 132 | ; :exec-fn pinkgorilla.notebook-bundel/run} 133 | 134 | ;:runx {:extra-deps {org.pinkgorilla/gorilla-ui {:mvn/version "0.3.28"} 135 | ; org.pinkgorilla/gorilla-plot {:mvn/version "1.2.11"} 136 | ; org.pinkgorilla/ui-quil {:mvn/version "0.1.5"}} 137 | ; :exec-fn pinkgorilla.notebook-bundel/run 138 | ; :exec-args {:config "notebook-config.edn"}} 139 | 140 | 141 | ; 142 | }} 143 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // automatically copied from webly resources 2 | module.exports = function (config) { 3 | config.set({ 4 | browsers: ['ChromiumHeadless'], 5 | // The directory where the output file lives 6 | basePath: 'target', 7 | // The file itself 8 | files: ['ci.js'], 9 | frameworks: ['cljs-test'], 10 | plugins: ['karma-cljs-test', 'karma-chrome-launcher'], 11 | colors: true, 12 | logLevel: config.LOG_INFO, 13 | client: { 14 | args: ["shadow.test.karma.init"], 15 | singleRun: true 16 | } 17 | }) 18 | }; 19 | -------------------------------------------------------------------------------- /profiles/dev/src/datafy.clj: -------------------------------------------------------------------------------- 1 | (ns demo.datafy 2 | "Sample code demonstrating naving around a random graph of data. 3 | The graph very likely will have circular references, which is not a problem. 4 | To see the results, execute the entire file. 5 | Each step in the nav process will be printed out, as well as the initial db. 6 | Subsequent executions will generate a new random db." 7 | (:require [clojure.datafy :refer [datafy nav]])) 8 | 9 | (defn generate-db 10 | "Generate a random database of users and departments. 11 | It is ENTIRELY possible for this database to contain 12 | circular links, but that is not a problem with the lazy 13 | nature of datafy/nav." 14 | [] 15 | (let [user-ids (take 5 (shuffle (range 100))) 16 | department-ids (take 3 (shuffle (range 100))) 17 | new-user (fn [id] 18 | (let [department-id (rand-nth department-ids) 19 | manager-id (rand-nth user-ids)] 20 | {:id id 21 | :name (str "User " id) 22 | :department-id department-id 23 | :manager-id manager-id})) 24 | new-department (fn [id] 25 | (let [deptartment-head-id (rand-nth user-ids)] 26 | {:id id 27 | :name (str "Department " id) 28 | :department-head-user-id deptartment-head-id}))] 29 | {:users (zipmap user-ids (map new-user user-ids)) 30 | :departments (zipmap department-ids (map new-department department-ids))})) 31 | 32 | (comment 33 | ;sample generated db 34 | {:users 35 | {65 {:id 65, :name "User 65", :department-id 96, :manager-id 58} 36 | 58 {:id 58, :name "User 58", :department-id 85, :manager-id 58}} 37 | :departments 38 | {96 {:id 96, :name "Department 96", :department-head-user-id 65} 39 | 85 {:id 85, :name "Department 85", :department-head-user-id 65}}}) 40 | 41 | 42 | (defn lookup-user 43 | "Convenience function to get user by id" 44 | [db id] 45 | (get-in db [:users id])) 46 | 47 | (defn lookup-department 48 | "Convenience function to get department by id" 49 | [db id] 50 | (get-in db [:departments id])) 51 | 52 | (declare datafy-ready-user) 53 | (declare datafy-ready-department) 54 | 55 | (defn navize-user 56 | [db user] 57 | (when user 58 | (with-meta 59 | user 60 | {'clojure.core.protocols/nav (fn [coll k v] 61 | (case k 62 | ;; by returning a datafy-ed object, 63 | ;; the db is propagated to further datafy/nav calls 64 | :manager-id (datafy-ready-user db (lookup-user db v)) 65 | :department-id (datafy-ready-department db (lookup-department db v)) 66 | v))}))) 67 | 68 | (defn navize-department 69 | [db department] 70 | (when department 71 | (with-meta 72 | department 73 | {'clojure.core.protocols/nav (fn [coll k v] 74 | (case k 75 | :department-head-user-id (datafy-ready-user db (lookup-user db v)) 76 | v))}))) 77 | 78 | (defn datafy-ready-user 79 | [db user] 80 | (when user 81 | (with-meta 82 | user 83 | {'clojure.core.protocols/datafy (fn [x] (navize-user db x))}))) 84 | 85 | (defn datafy-ready-department 86 | [db department] 87 | (when department 88 | (with-meta 89 | department 90 | {'clojure.core.protocols/datafy (fn [x] (navize-department db x))}))) 91 | 92 | ;-------------------------------------------------------------- 93 | ; The rest of the code creates the db and navs around the graph 94 | ;-------------------------------------------------------------- 95 | 96 | (def user1 97 | (let [db (generate-db) 98 | _ (clojure.pprint/pprint db) 99 | ;; grab a random user-id from which to start nav-ing 100 | user-id (-> db :users keys first) 101 | user (lookup-user db user-id)] 102 | (println "\nuser1:" user "\n") 103 | 104 | ;; this step kicks off the datafy/nav process 105 | (datafy (datafy-ready-user db user)) 106 | 107 | ;; just for fun, uncomment this and see what happens 108 | ;; if a plain (non-datafy-ready object) is used 109 | #_(datafy user))) 110 | 111 | ;; new let-block, notice db is out of scope, 112 | ;; but navigating the graph is still possible 113 | (let [nav-to-link (fn [record k] 114 | (println "nav-ing to" (name k) ":" (get record k)) 115 | (when record 116 | (datafy (nav record k (get record k))))) 117 | 118 | user2 (nav-to-link user1 :manager-id) 119 | _ (println "user2:" user2 "\n") 120 | 121 | user3 (nav-to-link user2 :manager-id) 122 | _ (println "user3:" user3 "\n") 123 | 124 | ;; nav-ing to :name works, but ends up at leaf in graph 125 | name3 (nav-to-link user3 :name) 126 | _ (println "name3:" name3 "\n") 127 | 128 | department3 (nav-to-link user3 :department-id) 129 | _ (println "department3:" department3 "\n") 130 | 131 | user4 132 | (nav-to-link department3 :department-head-user-id) 133 | _ (println "user4:" user4 "\n")]) 134 | 135 | 136 | ; Sample output: 137 | ;{:users 138 | ; {65 {:id 65, :name "User 65", :department-id 96, :manager-id 9}, 139 | ; 22 {:id 22, :name "User 22", :department-id 85, :manager-id 65}, 140 | ; 56 {:id 56, :name "User 56", :department-id 85, :manager-id 56}, 141 | ; 9 {:id 9, :name "User 9", :department-id 96, :manager-id 65}, 142 | ; 58 {:id 58, :name "User 58", :department-id 85, :manager-id 58}}, 143 | ; :departments 144 | ; {96 {:id 96, :name "Department 96", :department-head-user-id 65}, 145 | ; 9 {:id 9, :name "Department 9", :department-head-user-id 58}, 146 | ; 85 {:id 85, :name "Department 85", :department-head-user-id 65}}} 147 | ; 148 | ;user1: {:id 65, :name User 65, :department-id 96, :manager-id 9} 149 | ; 150 | ;nav-ing to manager-id : 9 151 | ;user2: {:id 9, :name User 9, :department-id 96, :manager-id 65} 152 | ; 153 | ;nav-ing to manager-id : 65 154 | ;user3: {:id 65, :name User 65, :department-id 96, :manager-id 9} 155 | ; 156 | ;nav-ing to name : User 65 157 | ;name3: User 65 158 | ; 159 | ;nav-ing to department-id : 96 160 | ;department3: {:id 96, :name Department 96, :department-head-user-id 65} 161 | ; 162 | ;nav-ing to department-head-user-id : 65 163 | ;user4: {:id 65, :name User 65, :department-id 96, :manager-id 9} -------------------------------------------------------------------------------- /profiles/dev/src/infer-specs.clj: -------------------------------------------------------------------------------- 1 | (ns user2) 2 | (require '[spec-provider.provider :as sp]) 3 | (require '[pinkgorilla.notebook-ui.schema :as x]) 4 | (require '[pinkgorilla.notebook-ui.schema-sample :as d]) 5 | (require '[clojure.spec.alpha :as s]) 6 | 7 | ; https://github.com/stathissideris/spec-provider 8 | 9 | 10 | (def ddd d/keybindings) 11 | ;; => #'user2/ddd 12 | 13 | (println "data" ddd) 14 | 15 | (def inferred-specs 16 | (sp/infer-specs 17 | ;s/settings 18 | ;s/document 19 | ddd 20 | :gorilla/db 21 | )) 22 | 23 | ;(clojure.pprint/pprint db) 24 | (sp/pprint-specs inferred-specs 'gorilla 's) 25 | 26 | 27 | (s/valid? :pinkgorilla.notebook-ui.schema/db d/db) 28 | -------------------------------------------------------------------------------- /profiles/webly/resources/creds-sample.edn: -------------------------------------------------------------------------------- 1 | ;; Copy to creds.edn and set your private values. 2 | {:oauth2 {:github {:client-id "" 3 | :client-secret ""} 4 | :google {:client-id "" 5 | :client-secret ""}}} -------------------------------------------------------------------------------- /profiles/webly/resources/demo.edn: -------------------------------------------------------------------------------- 1 | {:webly {:title "PinkGorilla Notebook" 2 | :icon "/r/webly/pink-gorilla-32.png" 3 | :lein-cljs-profile "+demo" 4 | :ns-cljs-app [demo.app] 5 | :bundle-entry "demo.app.start ();" 6 | :start-user-app [:notebook/start] 7 | :user-routes-app "demo.routes/routes-app" 8 | :user-routes-api "demo.routes/routes-api"} 9 | 10 | :google-analytics {:enabled true} ; set to false to disable google-analytics tracking. 11 | 12 | :timbre-loglevel [[#{"org.eclipse.jetty.*"} :info] 13 | [#{"org.apache.http.*"} :info] ; shadow-cljs 14 | [#{"org.eclipse.aether.*"} :info] 15 | ; webly 16 | [#{"webly.ws.msg-handler"} :warn] 17 | [#{"webly.ws.*"} :info] 18 | [#{"webly.user.*"} :info] 19 | ; goldly 20 | [#{"goldly.runner.clj-fn"} :warn] 21 | [#{"goldly.*"} :info] 22 | [#{"systems.*"} :warn] ; otherwise we see timestamp sender 23 | ; notebook 24 | [#{"pinkgorilla.nrepl.client.*"} :info] 25 | [#{"pinkgorilla.nrepl.relay.*"} :warn] ; gets sent to notebook/console otherwise 26 | [#{"pinkgorilla.document.*"} :info] 27 | [#{"pinkgorilla.storage.*"} :info] 28 | [#{"pinkgorilla.explore.*"} :info] 29 | [#{"pinkgorilla.notebook.*"} :debug] 30 | [#{"pinkgorilla.notebook-ui.*"} :debug] 31 | ;[#{"pinkgorilla.notebook-ui.codemirror.*"} :info] 32 | [#{"*"} :debug]] 33 | 34 | :explorer {:client {:repositories [{:name "local" :url "/api/explorer" :save true} 35 | {:name "public" :url "https://raw.githubusercontent.com/pink-gorilla/gorilla-explore/master/resources/list.json"}]} 36 | :server {:resource-root-path "notebooks" 37 | :exclude #{".git" ".svn"} 38 | :roots {:app "./resources/notebooks" 39 | ;:gorilla-ui "../gorilla-ui/resources/notebooks" 40 | }}} 41 | 42 | :nrepl {;:ws-endpoint "ws://localhost:9000/api/nrepl" 43 | :connect? true ; false ; should browser auto connect? 44 | :enabled true ; run nrepl relay in this app 45 | :server {:bind "127.0.0.1" 46 | :port 9100} 47 | :relay {:host "127.0.0.1" 48 | ;:transport-fn 49 | :port 9100}} 50 | 51 | :jetty-ws {"/api/chsk" :ws/chsk-get 52 | "/api/nrepl" :ws/nrepl} 53 | 54 | ; notebook 55 | 56 | :keybindings "pinkgorilla.notebook-ui.app.keybindings/keybindings-default" 57 | 58 | :settings {; settings can be changed by user (via dialog) 59 | ; :use-localstorage is true: load settings from localstorage, and only use 60 | ; config-settings to initialize the app when localstorage is empty 61 | :use-localstorage false 62 | :default-kernel :clj 63 | :layout :vertical ; :horizontal :single :flow 64 | :codemirror-theme "paraiso-dark" ; "default" 65 | } 66 | 67 | :goldly {:enabled true 68 | :systems-ns [systems.click-counter 69 | systems.greeter 70 | systems.fortune 71 | systems.time 72 | systems.error 73 | ] 74 | }} -------------------------------------------------------------------------------- /profiles/webly/src/demo/app.clj: -------------------------------------------------------------------------------- 1 | (ns demo.app 2 | (:require 3 | [webly.config :refer [load-config!]] 4 | [webly.profile :refer [server?]] 5 | [webly.user.app.app :refer [webly-run!]] 6 | [pinkgorilla.notebook-ui.app.app :refer [run-notebook-services!]] 7 | [demo.routes])) 8 | 9 | (defn -main 10 | [profile] 11 | (let [config "notebook-demo.edn"] 12 | (when (server? profile) 13 | (load-config! config) 14 | (run-notebook-services!)) 15 | (webly-run! profile config))) -------------------------------------------------------------------------------- /profiles/webly/src/demo/app.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.app 2 | (:require 3 | [re-frame.core :as rf] 4 | [taoensso.timbre :as timbre :refer [info warn]] 5 | [webly.user.app.app :refer [webly-run!]] 6 | ; side-effects 7 | ;[pinkgorilla.ui.default-renderer] ; add ui renderer definitions 8 | [pinkgorilla.notebook-ui.app.app] 9 | [demo.pages.examples] 10 | [demo.routes :refer [routes-api routes-app]])) 11 | 12 | (defn ^:export start [] 13 | (webly-run! routes-api routes-app)) 14 | 15 | (rf/reg-event-db 16 | :webly/before-load 17 | (fn [db [_]] 18 | (warn "webly/before-load: customize your app for lein webly watch..") 19 | db)) 20 | 21 | (rf/reg-event-db 22 | :notebook/start 23 | (fn [db [_]] 24 | (info "notebook-init") 25 | (rf/dispatch [:notebook/init [:webly/status :running]]) 26 | db)) -------------------------------------------------------------------------------- /profiles/webly/src/demo/pages/examples.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.pages.examples 2 | (:require 3 | [webly.web.handler :refer [reagent-page]] 4 | ; examples 5 | [demo.views.notebook :refer [codemirror-demo]] 6 | [demo.views.completion :refer [completion-demo]] 7 | [demo.views.stacktrace :refer [stacktrace-demo]] 8 | [demo.views.datafy :refer [datafy-demo]] 9 | [demo.views.main :refer [main-view]] 10 | )) 11 | 12 | 13 | (defmethod reagent-page :demo/main [{:keys [route-params query-params handler] :as route}] 14 | [main-view]) 15 | 16 | (defmethod reagent-page :demo/stacktrace [{:keys [route-params query-params handler] :as route}] 17 | [stacktrace-demo] 18 | ) 19 | 20 | (defmethod reagent-page :demo/completion [{:keys [route-params query-params handler] :as route}] 21 | [completion-demo]) 22 | 23 | (defmethod reagent-page :demo/datafy [{:keys [route-params query-params handler] :as route}] 24 | [ datafy-demo]) 25 | 26 | (defmethod reagent-page :demo/codemirror [{:keys [route-params query-params handler] :as route}] 27 | [codemirror-demo]) -------------------------------------------------------------------------------- /profiles/webly/src/demo/routes.cljc: -------------------------------------------------------------------------------- 1 | (ns demo.routes 2 | (:require 3 | [pinkgorilla.notebook-ui.app.routes])) 4 | 5 | (def routes-app 6 | (assoc pinkgorilla.notebook-ui.app.routes/routes-app 7 | "" :notebook/about 8 | )) 9 | 10 | (def routes-api 11 | pinkgorilla.notebook-ui.app.routes/routes-api) 12 | -------------------------------------------------------------------------------- /profiles/webly/src/demo/views/completion.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.views.completion 2 | (:require 3 | [taoensso.timbre :refer-macros [info]] 4 | [re-frame.core :as rf] 5 | [pinkgorilla.notebook-ui.completion.component :refer [completion-component]])) 6 | 7 | (rf/reg-event-db 8 | :nrepl/completion-demo 9 | (fn [db [_]] 10 | (assoc-in db [:completion] 11 | {:docstring "clojure.core/doseq\n([seq-exprs & body])\nMacro\n Repeatedly executes body (presumably for side-effects) with\n bindings and filtering as provided by \"for\". Does not retain\n the head of the sequence. Returns nil.\n" 12 | :candidates [{:candidate "map", :type :function, :ns "clojure.core"} 13 | {:candidate "max", :type :function, :ns "clojure.core"} 14 | {:candidate "map?", :type :function, :ns "clojure.core"} 15 | {:candidate "mapv", :type :function, :ns "clojure.core"} 16 | {:candidate "mapcat", :type :function, :ns "clojure.core"} 17 | {:candidate "max-key", :type :function, :ns "clojure.core"} 18 | {:candidate "make-array", :type :function, :ns "clojure.core"} 19 | {:candidate "map-entry?", :type :function, :ns "clojure.core"} 20 | {:candidate "macroexpand", :type :function, :ns "clojure.core"} 21 | {:candidate "map-indexed", :type :function, :ns "clojure.core"} 22 | {:candidate "macroexpand-1", :type :function, :ns "clojure.core"} 23 | {:candidate "make-hierarchy", :type :function, :ns "clojure.core"}]}))) 24 | 25 | 26 | (def docstring-res 27 | "clojure.core/doseq\n([seq-exprs & body])\nMacro\n Repeatedly executes body (presumably for side-effects) with\n bindings and filtering as provided by \"for\". Does not retain\n the head of the sequence. Returns nil.\n") 28 | 29 | 30 | (defn completion-demo [] 31 | (rf/dispatch [:nrepl/completion-demo]) 32 | [:div {:class "text-red-500 text-lg"} 33 | [:p "For this to work nrepl needs to be connected!"] 34 | [:input {:on-change (fn [s evt] 35 | (println "evt:" evt) 36 | ;(dispatch [:nrepl/completion (:text @state) "user" ""]) 37 | )}] 38 | 39 | [completion-component]]) 40 | 41 | 42 | -------------------------------------------------------------------------------- /profiles/webly/src/demo/views/datafy.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.views.datafy 2 | (:require 3 | [re-frame.core :refer [dispatch]] 4 | [pinkgorilla.notebook-ui.datafy.views :refer [browser]])) 5 | 6 | 7 | (defn action [{:keys [on-click href]} text] 8 | [:div.w-48.h-8.p-5.border-2.border-solid.border-gray-500.rounded.text-center.text-lg.cursor-pointer.bg-pink-100.hover:bg-pink-400 9 | {:on-click on-click 10 | :href href} 11 | (if href 12 | [:a {:href href} text] 13 | text)]) 14 | 15 | 16 | 17 | (defn datafy-demo [] 18 | [:div.bg-red-500 19 | [:h1 "datafy demo (click on the links)"] 20 | 21 | [:div.bg-green-300 22 | [:p "eval in nrepl:"] 23 | [action {:on-click #(dispatch [:datafy/tap "{:a 1 :b 777}"])} 24 | "a map"] 25 | [action {:on-click #(dispatch [:datafy/tap "*ns*"])} 26 | "*ns*"] 27 | [action {:on-click #(dispatch [:datafy/tap "(in-ns 'clojure.pprint)"])} 28 | "namespace pprint"] 29 | [action {:on-click #(dispatch [:datafy/tap "(picasso.datafy.file/make-path \"/\")"])} 30 | "path"]] 31 | [browser]]) 32 | 33 | 34 | -------------------------------------------------------------------------------- /profiles/webly/src/demo/views/main.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.views.main 2 | (:require 3 | [taoensso.timbre :as timbre :refer [info]] 4 | 5 | [re-frame.core :refer [dispatch]] 6 | )) 7 | 8 | 9 | (defn action [{:keys [on-click href]} text] 10 | [:div.w-48.h-12.p-5.border-2.border-solid.border-gray-500.rounded.text-center.text-lg.cursor-pointer.bg-pink-100.hover:bg-pink-400 11 | {:on-click on-click 12 | :href href} 13 | (if href 14 | [:a {:href href} text] 15 | text)]) 16 | 17 | 18 | (defn add-new-notebooks [nr] 19 | (doall (for [i (range nr)] 20 | (do 21 | (info "creating new document " i ) 22 | (dispatch [:document/new]) 23 | ) 24 | ))) 25 | 26 | 27 | (defn main-view [] 28 | [:div 29 | [:h1 "notebook-ui demo"] 30 | [action {:href "/explorer"} "explorer"] 31 | [action {:on-click #(add-new-notebooks 5)} "5 new notebooks"] 32 | 33 | 34 | ]) -------------------------------------------------------------------------------- /profiles/webly/src/demo/views/notebook.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.views.notebook 2 | (:require 3 | [re-frame.core :as rf] 4 | [pinkgorilla.notebook-ui.views.notebook :refer [notebook-component]] 5 | )) 6 | 7 | 8 | (def snippets 9 | ["(+ 1 1)(println 1)\n {:a 5 :b \"ttt\"}" 10 | "(+ 2 2)(println 2)" 11 | "(+ 3 3)(println 3)"]) 12 | 13 | 14 | (defn codemirror-demo [] 15 | (fn [] 16 | (rf/dispatch [:document/load-snippets snippets]) 17 | [notebook-component] 18 | )) 19 | 20 | -------------------------------------------------------------------------------- /profiles/webly/src/demo/views/sidebar.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.views.sidebar 2 | (:require 3 | [reagent.core :as r] 4 | ;[pinkgorilla.ui.config :refer [link-css]] 5 | )) 6 | 7 | ; from: 8 | ; https://github.com/tailwindtoolbox/Sidebar-Bottom/blob/master/index.html 9 | 10 | ; https://tailwindcomponents.com/component/app-sidebar 11 | ; https://github.com/creativetimofficial/tailwind-starter-kit/blob/master/Dashboard%20Page/react-dashboard-page/src/components/Sidebar.js 12 | 13 | 14 | (defn sidebar-item [{:as item 15 | :keys [name fas page active? goto-page] 16 | :or {fas "link"}}] 17 | (let [active? (active? item)] 18 | [:li {:class "mr-3 flex-1"} 19 | [:a {;:href "#" 20 | :on-click (fn [& _] (goto-page item)) 21 | :class (str "block py-1 md:py-3 pl-1 align-middle no-underline border-b-2 " 22 | (if active? 23 | "text-white hover:text-white border-pink-600" 24 | "text-gray-600 hover:text-pink-500 border-gray-800 md:border-gray-900 hover:border-pink-500"))} 25 | [:i {:class (str "fas fa-" fas " pr-0 md:pr-3 " 26 | (if active? 27 | "text-pink-500" 28 | ""))}] 29 | [:span {:class (str "pb-1 md:pb-0 text-xs md:text-base block md:inline-block " 30 | (if active? 31 | "text-white md:font-bold" 32 | "text-gray-600 md:text-gray-400"))} name]]])) 33 | 34 | (defn sidebar 35 | "a sidebar menu; on mobile moves to bottom" 36 | [items default-name] 37 | (let [pg (first (filter #(= (:name %) default-name) items)) 38 | active-name (r/atom (:name pg)) 39 | active-page (r/atom (:page pg)) 40 | goto-page (fn [item] 41 | (println "page selected: " (:name item)) 42 | (reset! active-page (:page item)) 43 | (reset! active-name (:name item))) 44 | active? (fn [item] 45 | ;(println "active? " (:name item) (= (:name item) @active-name)) 46 | (= (:name item) @active-name))] 47 | (fn [] 48 | [:div 49 | ;flexbox container 50 | [:div {:class (str "flex flex-wrap h-screen w-screen " 51 | "md:flex-row-reverse")} 52 | ; Main Content 53 | [:div {:class (str "w-full h-full bg-blue-100 " ; sm: w-full 54 | "lg:w-5/6 " 55 | "md:w-4/5 ")} 56 | [:div {:class "p-0 m-0"} ; "pt-16 px-6"} ; bg-gray-100 container 57 | (when @active-page 58 | @active-page)]] 59 | ; Sidebar 60 | [:div {:class (str "w-full bg-blue-500 px-2 text-center fixed bottom-0 " ; sm: w-full bg-blue-500 61 | "lg:w-1/6 " 62 | "md:w-1/5 md:pt-8 md:top-0 md:left-0 h-16 md:h-screen md:border-r-4 md:border-pink-600 md:bg-teal-800 ")} 63 | [:div {:class (str " mx-auto " 64 | "lg:float-right lg:px-6 " 65 | "md:relative")} 66 | (into [:ul {:class (str "list-reset flex flex-row text-center " 67 | "md:flex-col md:text-left")}] 68 | (map (fn [item] 69 | [sidebar-item (assoc item 70 | :goto-page goto-page 71 | :active? active?)]) items))]]]]))) 72 | 73 | 74 | 75 | #_(defn example-menu [{:keys [name goto-page] :as example}] 76 | [:a {:href "#" 77 | :on-click #(goto-page example) 78 | :class "block text-left xl:flex xl:items-center shadow xl:shadow-none py-3 px-3 xl:px-4 border-l-4 border-transparent text-red hover:text-blue-300 hover:bg-green-300 text-xs"} 79 | name]) 80 | 81 | #_(defn sidebar [{:keys [examples goto-page]}] 82 | [:div {:class "bg-yellow-300 h-full w-1/12 min-h-screen xl:py-2"} 83 | [:div {:class "xl:block uppercase font-bold text-grey-darker text-xs px-4 py-2"} 84 | 85 | (map-indexed 86 | (fn [i example] 87 | ^{:key i} 88 | [example-menu (assoc example :goto-page goto-page)]) 89 | examples)]]) 90 | 91 | #_[:div.flex.font-sans.antialiased.h-screen 92 | [sidebar {:examples @examples :goto-page goto-page}] 93 | [:div.bg-white.h-full.w-full.text-center.text-grey-darkest 94 | [@current]]] 95 | 96 | ; [:div.flex.font-sans.antialiased.h-screen 97 | ; [sidebar {:examples @examples :goto-page goto-page}] 98 | ; [:div.bg-white.h-full.w-full.text-center.text-grey-darkest 99 | -------------------------------------------------------------------------------- /profiles/webly/src/demo/views/stacktrace.cljs: -------------------------------------------------------------------------------- 1 | (ns demo.views.stacktrace 2 | (:require [pinkgorilla.notebook-ui.eval-result.stacktrace :refer [stacktrace-table]])) 3 | 4 | (def res-stacktrace 5 | {:path "NO_SOURCE_PATH" 6 | :file "NO_SOURCE_PATH" 7 | :file-url nil 8 | :column 1 9 | :line 1 10 | :id "778c1acf-01b2-426c-a866-a037e820b753" 11 | :class "clojure.lang.Compiler$CompilerException" 12 | :stacktrace [{:name "clojure.lang.Compiler/analyzeSeq", :file "Compiler.java", :line 7115, :class "clojure.lang.Compiler", :method "analyzeSeq", :type :java, :flags #{:tooling :java}, :file-url nil} 13 | {:name "clojure.lang.Compiler/analyze", :file "Compiler.java", :line 6789, :class "clojure.lang.Compiler", :method "analyze", :type :java, :flags #{:tooling :java}, :file-url nil} 14 | {:name "clojure.lang.Compiler/analyze", :file "Compiler.java", :line 6745, :class "clojure.lang.Compiler", :method "analyze", :type :java, :flags #{:dup :tooling :java}, :file-url nil} 15 | {:name "clojure.lang.Compiler$BodyExpr$Parser/parse", :file "Compiler.java", :line 6120, :class "clojure.lang.Compiler$BodyExpr$Parser", :method "parse", :type :java, :flags #{:tooling :java}, :file-url nil} 16 | {:name "clojure.lang.Compiler$FnMethod/parse", :file "Compiler.java", :line 5467, :class "clojure.lang.Compiler$FnMethod", :method "parse", :type :java, :flags #{:tooling :java}, :file-url nil} 17 | {:name "clojure.lang.Compiler$FnExpr/parse", :file "Compiler.java", :line 4029, :class "clojure.lang.Compiler$FnExpr", :method "parse", :type :java, :flags #{:tooling :java}, :file-url nil} 18 | {:name "clojure.lang.Compiler/analyzeSeq", :file "Compiler.java", :line 7105, :class "clojure.lang.Compiler", :method "analyzeSeq", :type :java, :flags #{:tooling :java}, :file-url nil} 19 | {:name "clojure.lang.Compiler/analyze", :file "Compiler.java", :line 6789, :class "clojure.lang.Compiler", :method "analyze", :type :java, :flags #{:tooling :java}, :file-url nil} 20 | {:name "clojure.lang.Compiler/eval", :file "Compiler.java", :line 7174, :class "clojure.lang.Compiler", :method "eval", :type :java, :flags #{:tooling :java}, :file-url nil} 21 | {:name "clojure.lang.Compiler/eval", :file "Compiler.java", :line 7132, :class "clojure.lang.Compiler", :method "eval", :type :java, :flags #{:dup :tooling :java}, :file-url nil} 22 | {:fn "eval", :method "invokeStatic", :ns "clojure.core", :name "clojure.core$eval/invokeStatic", :file "core.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/core.clj", :line 3214, :var "clojure.core/eval", :class "clojure.core$eval", :flags #{:clj}} 23 | {:fn "eval", :method "invoke", :ns "clojure.core", :name "clojure.core$eval/invoke", :file "core.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/core.clj", :line 3210, :var "clojure.core/eval", :class "clojure.core$eval", :flags #{:clj}} 24 | {:fn "evaluate/fn", :method "invoke", :ns "nrepl.middleware.interruptible-eval", :name "nrepl.middleware.interruptible_eval$evaluate$fn__13093/invoke", :file "interruptible_eval.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/nrepl/nrepl/0.7.0/nrepl-0.7.0.jar!/nrepl/middleware/interruptible_eval.clj", :line 91, :var "nrepl.middleware.interruptible-eval/evaluate", :class "nrepl.middleware.interruptible_eval$evaluate$fn__13093", :flags #{:tooling :clj}} 25 | {:fn "repl/read-eval-print/fn", :method "invoke", :ns "clojure.main", :name "clojure.main$repl$read_eval_print__9086$fn__9089/invoke", :file "main.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/main.clj", :line 437, :var "clojure.main/repl", :class "clojure.main$repl$read_eval_print__9086$fn__9089", :flags #{:clj}} 26 | {:fn "repl/read-eval-print", :method "invoke", :ns "clojure.main", :name "clojure.main$repl$read_eval_print__9086/invoke", :file "main.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/main.clj", :line 437, :var "clojure.main/repl", :class "clojure.main$repl$read_eval_print__9086", :flags #{:dup :clj}} 27 | {:fn "repl/fn", :method "invoke", :ns "clojure.main", :name "clojure.main$repl$fn__9095/invoke", :file "main.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/main.clj", :line 458, :var "clojure.main/repl", :class "clojure.main$repl$fn__9095", :flags #{:clj}} 28 | {:fn "repl", :method "invokeStatic", :ns "clojure.main", :name "clojure.main$repl/invokeStatic", :file "main.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/main.clj", :line 458, :var "clojure.main/repl", :class "clojure.main$repl", :flags #{:dup :clj}} 29 | {:fn "repl", :method "doInvoke", :ns "clojure.main", :name "clojure.main$repl/doInvoke", :file "main.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.jar!/clojure/main.clj", :line 368, :var "clojure.main/repl", :class "clojure.main$repl", :flags #{:clj}} 30 | {:name "clojure.lang.RestFn/invoke", :file "RestFn.java", :line 1523, :class "clojure.lang.RestFn", :method "invoke", :type :java, :flags #{:java}, :file-url nil} 31 | {:fn "evaluate", :method "invokeStatic", :ns "nrepl.middleware.interruptible-eval", :name "nrepl.middleware.interruptible_eval$evaluate/invokeStatic", :file "interruptible_eval.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/nrepl/nrepl/0.7.0/nrepl-0.7.0.jar!/nrepl/middleware/interruptible_eval.clj", :line 84, :var "nrepl.middleware.interruptible-eval/evaluate", :class "nrepl.middleware.interruptible_eval$evaluate", :flags #{:tooling :clj}} 32 | {:fn "evaluate", :method "invoke", :ns "nrepl.middleware.interruptible-eval", :name "nrepl.middleware.interruptible_eval$evaluate/invoke", :file "interruptible_eval.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/nrepl/nrepl/0.7.0/nrepl-0.7.0.jar!/nrepl/middleware/interruptible_eval.clj", :line 56, :var "nrepl.middleware.interruptible-eval/evaluate", :class "nrepl.middleware.interruptible_eval$evaluate", :flags #{:tooling :clj}} 33 | {:fn "interruptible-eval/fn/fn", :method "invoke", :ns "nrepl.middleware.interruptible-eval", :name "nrepl.middleware.interruptible_eval$interruptible_eval$fn__13119$fn__13123/invoke", :file "interruptible_eval.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/nrepl/nrepl/0.7.0/nrepl-0.7.0.jar!/nrepl/middleware/interruptible_eval.clj", :line 155, :var "nrepl.middleware.interruptible-eval/interruptible-eval", :class "nrepl.middleware.interruptible_eval$interruptible_eval$fn__13119$fn__13123", :flags #{:tooling :clj}} 34 | {:name "clojure.lang.AFn/run", :file "AFn.java", :line 22, :class "clojure.lang.AFn", :method "run", :type :java, :flags #{:java}, :file-url nil} {:fn "session-exec/main-loop/fn", :method "invoke", :ns "nrepl.middleware.session", :name "nrepl.middleware.session$session_exec$main_loop__13220$fn__13224/invoke", :file "session.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/nrepl/nrepl/0.7.0/nrepl-0.7.0.jar!/nrepl/middleware/session.clj", :line 190, :var "nrepl.middleware.session/session-exec", :class "nrepl.middleware.session$session_exec$main_loop__13220$fn__13224", :flags #{:tooling :clj}} 35 | {:fn "session-exec/main-loop", :method "invoke", :ns "nrepl.middleware.session", :name "nrepl.middleware.session$session_exec$main_loop__13220/invoke", :file "session.clj", :type :clj, :file-url "jar:file:/home/andreas/.m2/repository/nrepl/nrepl/0.7.0/nrepl-0.7.0.jar!/nrepl/middleware/session.clj", :line 189, :var "nrepl.middleware.session/session-exec", :class "nrepl.middleware.session$session_exec$main_loop__13220", :flags #{:tooling :clj}} 36 | {:name "clojure.lang.AFn/run", :file "AFn.java", :line 22, :class "clojure.lang.AFn", :method "run", :type :java, :flags #{:java}, :file-url nil} 37 | {:name "java.lang.Thread/run", :file "Thread.java", :line 834, :class "java.lang.Thread", :method "run", :type :java, :flags #{:java}, :file-url nil}] 38 | :location {:clojure.error/line 1 39 | :clojure.error/column 1 40 | :clojure.error/phase :compile-syntax-check 41 | :clojure.error/source "NO_SOURCE_PATH" 42 | :clojure.error/symbol "throw"} 43 | :message "Syntax error compiling throw at (1:1)." 44 | :session "4f44bee8-78d1-47da-a757-65e721a55a14" 45 | :data "{:clojure.error/phase :compile-syntax-check, :clojure.error/line 1, :clojure.error/column 1, :clojure.error/source \"NO_SOURCE_PATH\", :clojure.error/symbol throw}"}) 46 | 47 | 48 | (defn stacktrace-demo [] 49 | [stacktrace-table (:stacktrace res-stacktrace)]) 50 | 51 | 52 | -------------------------------------------------------------------------------- /release.edn: -------------------------------------------------------------------------------- 1 | {:group-id "org.pinkgorilla" 2 | :artifact-id "notebook" 3 | :scm-url "https://github.com/pink-gorilla/notebook/" 4 | } -------------------------------------------------------------------------------- /resources/broken/sparkling.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:name "sparkling-demo", :tagline "sparkling demo", :tags "clj, demo, sparkling,deas"} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # Sparkling Demo 10 | ;; ** 11 | 12 | ;; @@ [clj] 13 | 14 | (use '[pinkgorilla.notebook.repl]) 15 | (pinkgorilla.notebook.repl/add-dependencies '[[gorillalabs/sparkling "1.2.5"] [org.apache.spark/spark-core_2.10 "1.5.1"]]) 16 | ;; @@ 17 | ;; => 18 | ;;; ["^ ","~:type","~:html","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"],"~:value","nil"] 19 | ;; <= 20 | 21 | ;; @@ [clj] 22 | (require '[sparkling.conf :as conf]) 23 | ;; @@ 24 | 25 | ;; @@ [clj] 26 | (require '[sparkling.core :as spark]) 27 | ;; @@ 28 | 29 | ;; @@ [clj] 30 | (require '[sparkling.destructuring :as s-de]) 31 | ;; @@ 32 | 33 | ;; @@ [clj] 34 | (require '[sparkling.serialization :as required-to-have-serializer-class-read]) 35 | ;; @@ 36 | 37 | ;; @@ [clj] 38 | (def c (-> (conf/spark-conf) 39 | (conf/master "local") 40 | (conf/app-name "sparkling-example"))) 41 | ;; @@ 42 | 43 | ;; @@ [clj] 44 | (def sc (spark/spark-context c)) 45 | ;; @@ 46 | 47 | ;; @@ [clj] 48 | (def data (spark/parallelize sc ["a" "b" "c" "d" "e"])) 49 | ;; @@ 50 | 51 | ;; @@ [clj] 52 | (spark/first data) 53 | ;; @@ 54 | -------------------------------------------------------------------------------- /resources/notebook-bundel.edn: -------------------------------------------------------------------------------- 1 | {:goldly {:enabled true 2 | :extensions []} 3 | :explorer {:server {:resource-root-path "notebooks"}} ; notebook-bundel should add example notebooks from resources 4 | 5 | } 6 | 7 | -------------------------------------------------------------------------------- /resources/notebook-core.edn: -------------------------------------------------------------------------------- 1 | {:webly {:title "PinkGorilla Notebook" 2 | :icon "/r/webly/pink-gorilla-32.png" 3 | :ns-cljs [pinkgorilla.notebook-ui.app.app] 4 | :start-user-app [:notebook/start] 5 | :routes pinkgorilla.notebook-ui.app.routes/routes} 6 | 7 | :google-analytics {:enabled true} ; set to false to disable google-analytics tracking. 8 | 9 | :timbre-loglevel [[#{"org.eclipse.jetty.*"} :info] 10 | [#{"org.apache.http.*"} :info] ; shadow-cljs 11 | [#{"org.eclipse.aether.*"} :info] 12 | ; webly 13 | [#{"webly.ws.msg-handler"} :warn] 14 | [#{"webly.ws.*"} :info] 15 | [#{"webly.user.*"} :info] 16 | [#{"webly.*"} :info] 17 | ; goldly 18 | [#{"goldly.runner.clj-fn"} :warn] 19 | [#{"goldly.*"} :info] 20 | [#{"systems.*"} :warn] ; otherwise we see timestamp sender 21 | ; notebook 22 | [#{"pinkgorilla.nrepl.client.*"} :info] 23 | [#{"pinkgorilla.nrepl.relay.*"} :warn] ; gets sent to notebook/console otherwise 24 | [#{"pinkgorilla.notebook.*"} :info] 25 | [#{"pinkgorilla.document.*"} :info] 26 | [#{"pinkgorilla.storage.*"} :info] 27 | [#{"pinkgorilla.explore.*"} :info] 28 | [#{"notebook.*"} :info] 29 | [#{"ui.notebook.*"} :info] 30 | [#{"ui.codemirror.*"} :info] 31 | ; catch all 32 | [#{"*"} :debug] 33 | ] 34 | 35 | :explorer {:client {:repositories [{:name "local" :url "/api/explorer" :save true} 36 | #_{:name "public" :url "https://raw.githubusercontent.com/pink-gorilla/gorilla-explore/master/resources/list.json"}]} 37 | :server {:resource-root-path "notebooks-none" ; no notebooks in resources (this happens only in bundel) 38 | :exclude #{".git" ".svn"} 39 | :roots {:project "./notebooks" 40 | }}} 41 | 42 | :nrepl {;:ws-endpoint "ws://localhost:9000/api/nrepl" 43 | :connect? true ; false ; should browser auto connect? 44 | :enabled true ; run nrepl relay in this app 45 | :server {:bind "127.0.0.1" 46 | :port 9100} 47 | :relay {:host "127.0.0.1" 48 | ;:transport-fn 49 | :port 9100}} 50 | 51 | :jetty-ws {"/api/chsk" :ws/chsk-get 52 | "/api/nrepl" :ws/nrepl} 53 | 54 | ; notebook 55 | 56 | :keybindings "pinkgorilla.notebook-ui.app.keybindings/keybindings-default" 57 | 58 | :settings {; settings can be changed by user (via dialog) 59 | ; :use-localstorage is true: load settings from localstorage, and only use 60 | ; config-settings to initialize the app when localstorage is empty 61 | :use-localstorage false 62 | :default-kernel :clj 63 | :layout :vertical ; :horizontal :single :flow 64 | :codemirror-theme "paraiso-dark" ; "default" 65 | } 66 | 67 | :goldly {:enabled true}} 68 | 69 | -------------------------------------------------------------------------------- /resources/notebooks/notebook/cljs-demo.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:id :e610241c-b934-49f5-9796-697f74487ace} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # clojurescript 10 | ;; ** 11 | 12 | ;; @@ [cljs] 13 | (listplot (range 10) ) 14 | ;; @@ 15 | ;; => 16 | ;;; ["^ ","~:type","~:reagent","~:content",["^ ","~:hiccup",["~:p/vega",["^ ","~:$schema","https://vega.github.io/schema/vega/v5.json","~:width",400,"~:height",247.2187886279357,"~:padding",["^ ","~:top",10,"~:left",55,"~:bottom",40,"~:right",10],"~:data",[["^ ","~:name","1b2a6935-8b30-4e68-b836-b8040445c837","~:values",[["^ ","~:x",0,"~:y",0],["^ ","~:x",1,"~:y",1],["^ ","~:x",2,"~:y",2],["^ ","~:x",3,"~:y",3],["^ ","~:x",4,"~:y",4],["^ ","~:x",5,"~:y",5],["^ ","~:x",6,"~:y",6],["^ ","~:x",7,"~:y",7],["^ ","~:x",8,"~:y",8],["^ ","~:x",9,"~:y",9]]]],"~:marks",[["^ ","^0","symbol","~:from",["^ ","^=","1b2a6935-8b30-4e68-b836-b8040445c837"],"~:encode",["^ ","~:enter",["^ ","~:x",["^ ","~:scale","x","~:field","x"],"~:y",["^ ","^D","y","^E","y"],"~:fill",["^ ","~:value","steelblue"],"~:fillOpacity",["^ ","^G",1]],"~:update",["^ ","~:shape","circle","~:size",["^ ","^G",70],"~:stroke",["^ ","^G","transparent"]],"~:hover",["^ ","^K",["^ ","^G",210],"^L",["^ ","^G","white"]]]]],"~:scales",[["^ ","^>","x","^0","linear","~:range","width","~:zero",false,"~:domain",["^ ","^=","1b2a6935-8b30-4e68-b836-b8040445c837","^E","x"]],["^ ","^>","y","^0","linear","^O","height","~:nice",true,"^P",false,"^Q",["^ ","^=","1b2a6935-8b30-4e68-b836-b8040445c837","^E","y"]]],"~:axes",[["^ ","~:orient","bottom","^D","x"],["^ ","^T","left","^D","y"]]]],"~:map-keywords",true]] 17 | ;; <= 18 | -------------------------------------------------------------------------------- /resources/notebooks/notebook/clojure/core_async.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:tagline "core async demo", :tags "trateg,clj,quant", :id :eb1480cd-310e-40f8-ad6e-187a5460eac2} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # Core.async test 10 | ;; ** 11 | 12 | ;; @@ [clj] 13 | (ns example.pingpong 14 | (:require 15 | [clojure.pprint :refer :all] 16 | [clojure.core.async :as async :refer [>! !! go chan]] 17 | ;:reload-all 18 | )) 19 | ;; @@ 20 | ;; -> 21 | ;;; 22 | ;; <- 23 | ;; => 24 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 25 | ;; <= 26 | 27 | ;; @@ [clj] 28 | ;; From Advanced Go Concurrency Patterns 29 | ;; http://talks.golang.org/2013/advconc.slide#6 30 | 31 | (defn player [name table] 32 | (go (while true 33 | (let [ball (! table ball))))) 38 | 39 | (defn runner [] 40 | (let [table (chan) 41 | ball 0 42 | player-1 (player "O ping" table) 43 | player-2 (player "X pong" table)] 44 | (>!! table ball) 45 | (Thread/sleep 1000) 46 | ( 52 | ;;; 53 | ;; <- 54 | ;; => 55 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-var"],"#'example.pingpong/player"]],["^ ","^0","^1","^2",["^3",["^ ","^4","clj-var"],"#'example.pingpong/runner"]]] 56 | ;; <= 57 | 58 | ;; @@ [clj] 59 | (runner) 60 | ;; @@ 61 | ;; -> 62 | ;;; "X pong 1" 63 | ;;; "O ping 2" 64 | ;;; "X pong 3" 65 | ;;; "O ping 4" 66 | ;;; "X pong 5" 67 | ;;; "O ping 6" 68 | ;;; "X pong 7" 69 | ;;; "O ping 8" 70 | ;;; "X pong 9" 71 | ;;; "O ping 10" 72 | ;;; "X pong 11" 73 | ;;; "Done." 74 | ;; <- 75 | ;; => 76 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 77 | ;; <= 78 | 79 | ;; @@ [clj] 80 | (runner) 81 | ;; @@ 82 | ;; -> 83 | ;;; "O ping 1" 84 | ;;; "X pong 2" 85 | ;;; "O ping 3" 86 | ;;; "X pong 4" 87 | ;;; "O ping 5" 88 | ;;; "X pong 6" 89 | ;;; "O ping 7" 90 | ;;; "X pong 8" 91 | ;;; "O ping 9" 92 | ;;; "X pong 10" 93 | ;;; "O ping 11" 94 | ;;; "Done." 95 | ;; <- 96 | ;; => 97 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 98 | ;; <= 99 | -------------------------------------------------------------------------------- /resources/notebooks/notebook/clojure/multimethods.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:id :624c4d1b-cccf-4a30-827e-bba8efc8eb9a} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # Clojure MultiMethods 10 | ;; ** 11 | 12 | ;; @@ [clj] 13 | (defmulti foo class) 14 | (defmethod foo clojure.lang.Associative [c] :a-collection) 15 | (defmethod foo String [s] :a-string) 16 | 17 | ;(foo []) 18 | ;:a-collection 19 | 20 | ;(foo (java.util.HashMap.)) 21 | ;:a-collection 22 | 23 | ;(foo "bar") 24 | ;:a-string 25 | ;; @@ 26 | ;; -> 27 | ;;; 28 | ;; <- 29 | ;; => 30 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-var"],"#'render-newline/foo"]],["^ ","^0","^1","^2",["^3",["^ ","^4","clj-unknown"],"#multifn[foo 0x280bfc1c]"]],["^ ","^0","^1","^2",["^3",["^ ","^4","clj-unknown"],"#multifn[foo 0x280bfc1c]"]]] 31 | ;; <= 32 | 33 | ;; @@ [clj] 34 | (methods foo) 35 | 36 | ;; @@ 37 | ;; -> 38 | ;;; 39 | ;; <- 40 | ;; => 41 | ;;; [["^ ","~:type","~:list-like","~:content",["^ ","~:class","clj-map","~:open","{","~:close","}","~:separator"," ","~:items",["~#list",[["^ ","^0","~:hiccup","^2",["~:span",["^ ","^3","clj-class"],"java.lang.String"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-unknown"],"#function[render-newline/eval49927/fn--49928]"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Associative"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-unknown"],"#function[render-newline/eval49923/fn--49924]"]]]],"~:value","{java.lang.String #function[render-newline/eval49927/fn--49928], clojure.lang.Associative #function[render-newline/eval49923/fn--49924]}"]]] 42 | ;; <= 43 | 44 | ;; @@ [clj] 45 | (foo "bar") 46 | ;; @@ 47 | ;; -> 48 | ;;; 49 | ;; <- 50 | ;; => 51 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-keyword"],":a-string"]]] 52 | ;; <= 53 | 54 | ;; @@ [clj] 55 | (foo []) 56 | ;; @@ 57 | ;; -> 58 | ;;; 59 | ;; <- 60 | ;; => 61 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-keyword"],":a-collection"]]] 62 | ;; <= 63 | 64 | ;; @@ [clj] 65 | (type []) 66 | ;; @@ 67 | ;; -> 68 | ;;; 69 | ;; <- 70 | ;; => 71 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-class"],"clojure.lang.PersistentVector"]]] 72 | ;; <= 73 | 74 | ;; @@ [clj] 75 | (foo {}) 76 | ;; @@ 77 | ;; -> 78 | ;;; 79 | ;; <- 80 | ;; => 81 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-keyword"],":a-collection"]]] 82 | ;; <= 83 | 84 | ;; @@ [clj] 85 | (ancestors clojure.lang.PersistentVector) 86 | ;; @@ 87 | ;; -> 88 | ;;; 89 | ;; <- 90 | ;; => 91 | ;;; [["^ ","~:type","~:list-like","~:content",["^ ","~:class","clj-set","~:open","#{","~:close","}","~:separator"," ","~:items",["~#list",[["^ ","^0","~:hiccup","^2",["~:span",["^ ","^3","clj-class"],"java.util.RandomAccess"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IFn"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IObj"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.util.List"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IReduceInit"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Seqable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.lang.Runnable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IPersistentVector"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Counted"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.APersistentVector"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.io.Serializable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Sequential"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IKVReduce"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Indexed"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.lang.Comparable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Reversible"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.util.concurrent.Callable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.Associative"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IPersistentStack"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.lang.Iterable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IMeta"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.AFn"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.util.Collection"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.lang.Object"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IPersistentCollection"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IHashEq"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.ILookup"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IReduce"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"clojure.lang.IEditableCollection"]]]],"~:value","#{java.util.RandomAccess clojure.lang.IFn clojure.lang.IObj java.util.List clojure.lang.IReduceInit clojure.lang.Seqable java.lang.Runnable clojure.lang.IPersistentVector clojure.lang.Counted clojure.lang.APersistentVector java.io.Serializable clojure.lang.Sequential clojure.lang.IKVReduce clojure.lang.Indexed java.lang.Comparable clojure.lang.Reversible java.util.concurrent.Callable clojure.lang.Associative clojure.lang.IPersistentStack java.lang.Iterable clojure.lang.IMeta clojure.lang.AFn java.util.Collection java.lang.Object clojure.lang.IPersistentCollection clojure.lang.IHashEq clojure.lang.ILookup clojure.lang.IReduce clojure.lang.IEditableCollection}"]]] 92 | ;; <= 93 | 94 | ;; @@ [clj] 95 | (ancestors java.util.HashMap) 96 | ;; @@ 97 | ;; -> 98 | ;;; 99 | ;; <- 100 | ;; => 101 | ;;; [["^ ","~:type","~:list-like","~:content",["^ ","~:class","clj-set","~:open","#{","~:close","}","~:separator"," ","~:items",["~#list",[["^ ","^0","~:hiccup","^2",["~:span",["^ ","^3","clj-class"],"java.util.AbstractMap"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.io.Serializable"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.util.Map"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.lang.Object"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-class"],"java.lang.Cloneable"]]]],"~:value","#{java.util.AbstractMap java.io.Serializable java.util.Map java.lang.Object java.lang.Cloneable}"]]] 102 | ;; <= 103 | 104 | ;; @@ [clj] 105 | 106 | ;; @@ 107 | ;; -> 108 | ;;; 109 | ;; <- 110 | ;; => 111 | ;;; [] 112 | ;; <= 113 | -------------------------------------------------------------------------------- /resources/notebooks/notebook/clojure/pprint docstrings.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:tags "", :tagline "pprint repl/doc", :name "", :id :30c9aeb8-7bed-440f-852c-b178ed8d9837} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # render string with newline character 10 | ;; ** 11 | 12 | ;; @@ [clj] 13 | (ns render-newline 14 | (:require 15 | [clojure.pprint])) 16 | ;; @@ 17 | ;; -> 18 | ;;; 19 | ;; <- 20 | ;; => 21 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 22 | ;; <= 23 | 24 | ;; @@ [clj] 25 | (def data 26 | [{:name "william shakespeare" :speciality "novels"} 27 | {:name "rich hickie" :speciality "clojure"} 28 | {:name "christian" :speciality "replikativ"}]) 29 | ;; @@ 30 | ;; -> 31 | ;;; 32 | ;; <- 33 | ;; => 34 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-var"],"#'render-newline/data"]]] 35 | ;; <= 36 | 37 | ;; @@ [clj] 38 | (clojure.pprint/print-table data) 39 | ;; @@ 40 | ;; -> 41 | ;;; 42 | ;;; | :name | :speciality | 43 | ;;; |---------------------+-------------| 44 | ;;; | william shakespeare | novels | 45 | ;;; | rich hickie | clojure | 46 | ;;; | christian | replikativ | 47 | ;; <- 48 | ;; => 49 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 50 | ;; <= 51 | 52 | ;; @@ [clj] 53 | ^:R [:p/text (clojure.pprint/print-table data)] 54 | ;; @@ 55 | ;; -> 56 | ;;; 57 | ;;; | :name | :speciality | 58 | ;;; |---------------------+-------------| 59 | ;;; | william shakespeare | novels | 60 | ;;; | rich hickie | clojure | 61 | ;;; | christian | replikativ | 62 | ;; <- 63 | ;; => 64 | ;;; [["^ ","~:type","~:reagent","~:content",["^ ","~:hiccup",["~:p/text",null],"~:map-keywords",true]]] 65 | ;; <= 66 | 67 | ;; @@ [clj] 68 | (println (with-out-str (clojure.pprint/print-table data))) 69 | ;; @@ 70 | ;; -> 71 | ;;; 72 | ;;; | :name | :speciality | 73 | ;;; |---------------------+-------------| 74 | ;;; | william shakespeare | novels | 75 | ;;; | rich hickie | clojure | 76 | ;;; | christian | replikativ | 77 | ;; <- 78 | ;; => 79 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 80 | ;; <= 81 | 82 | ;; @@ [clj] 83 | ; with-out-str redirects the stdout and returns stdout as a string 84 | ; 85 | (with-out-str (clojure.pprint/print-table data)) 86 | ;; @@ 87 | ;; -> 88 | ;;; 89 | ;; <- 90 | ;; => 91 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-string"],"\"\\n| :name | :speciality |\\n|---------------------+-------------|\\n| william shakespeare | novels |\\n| rich hickie | clojure |\\n| christian | replikativ |\\n\""]]] 92 | ;; <= 93 | 94 | ;; @@ [clj] 95 | (printf (with-out-str (clojure.pprint/print-table data))) 96 | ;; @@ 97 | ;; -> 98 | ;;; 99 | ;;; | :name | :speciality | 100 | ;;; |---------------------+-------------| 101 | ;;; | william shakespeare | novels | 102 | ;;; | rich hickie | clojure | 103 | ;;; | christian | replikativ | 104 | ;; <- 105 | ;; => 106 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 107 | ;; <= 108 | 109 | ;; @@ [clj] 110 | (print (clojure.string/replace (with-out-str (clojure.pprint/print-table data)) #"\n" "\r\n")) 111 | ;; @@ 112 | ;; -> 113 | ;;; 114 | ;;; | :name | :speciality | 115 | ;;; |---------------------+-------------| 116 | ;;; | william shakespeare | novels | 117 | ;;; | rich hickie | clojure | 118 | ;;; | christian | replikativ | 119 | ;; <- 120 | ;; => 121 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 122 | ;; <= 123 | 124 | ;; @@ [clj] 125 | (clojure.pprint/print-table [:name] data) 126 | ;; @@ 127 | ;; -> 128 | ;;; 129 | ;;; | :name | 130 | ;;; |---------------------| 131 | ;;; | william shakespeare | 132 | ;;; | rich hickie | 133 | ;;; | christian | 134 | ;; <- 135 | ;; => 136 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 137 | ;; <= 138 | 139 | ;; @@ [clj] 140 | (clojure.repl/doc clojure.pprint/print-table) 141 | ;; @@ 142 | ;; -> 143 | ;;; ------------------------- 144 | ;;; clojure.pprint/print-table 145 | ;;; ([ks rows] [rows]) 146 | ;;; Prints a collection of maps in a textual table. Prints table headings 147 | ;;; ks, and then a line of output for each row, corresponding to the keys 148 | ;;; in ks. If ks are not specified, use the keys of the first item in rows. 149 | ;; <- 150 | ;; => 151 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 152 | ;; <= 153 | 154 | ;; @@ [cljs] 155 | ;clojurescript: 156 | (with-out-str (clojure.repl/doc inc)) 157 | ;; @@ 158 | ;; => 159 | ;;; ["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-string"],"\"-------------------------\\nclojure.core/inc\\n([x])\\n Returns a number one greater than num.\\n\""]] 160 | ;; <= 161 | -------------------------------------------------------------------------------- /resources/notebooks/notebook/goldly-click-counter.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:id :f8d848fd-3f08-4f2a-8f1c-26593c1c48cb} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # Goldly - Click Counter 10 | ;;; 11 | ;;; Goldly systems are not persisted in the notebook. But it might be easier to develop them using the notebook. 12 | ;;; 13 | ;;; Please run evaluate all! 14 | ;; ** 15 | 16 | ;; @@ [clj] 17 | (require 18 | '[goldly.runner :refer [system-start!]] 19 | '[goldly.system :as goldly :refer [def-ui]]) 20 | ;; @@ 21 | ;; -> 22 | ;;; 23 | ;; <- 24 | ;; => 25 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-nil"],"nil"]]] 26 | ;; <= 27 | 28 | ;; @@ [clj] 29 | (def-ui pink-panther 30 | [:p "Pink panther is here (demonstates ui components via def-ui)!"]) 31 | ;; @@ 32 | ;; -> 33 | ;;; 34 | ;; <- 35 | ;; => 36 | ;;; [["^ ","~:type","~:hiccup","~:content",["~:span",["^ ","~:class","clj-var"],"#'solitary-autumn/pink-panther"]]] 37 | ;; <= 38 | 39 | ;; @@ [clj] 40 | (system-start! 41 | (goldly/system 42 | {:id :notebook-click-counter 43 | :state 42 44 | :html [:div.border-blue-300.border.m-8.p-2 45 | pink-panther 46 | [:div 47 | "Clicked " 48 | [:button {:class "border m-2 p-3 border-pink-500" 49 | :on-click ?incr} @state] 50 | " times"]] 51 | :fns {:incr (fn [_ s] (inc s))}} 52 | {:fns {}})) 53 | ;; @@ 54 | ;; -> 55 | ;;; 2021-06-04T04:39:50.948Z UnknownHost INFO [goldly.runner:15] - starting system :notebook-click-counter 56 | ;; <- 57 | ;; => 58 | ;;; [["^ ","~:type","~:pinkie","~:content",["~:p/goldly","~:notebook-click-counter"]]] 59 | ;; <= 60 | -------------------------------------------------------------------------------- /resources/notebooks/notebook/hiccup/html-script.cljg: -------------------------------------------------------------------------------- 1 | ;; gorilla-repl.fileformat = 2 2 | 3 | ;; @@ [meta] 4 | {:id :604d1e74-806d-41f7-b4d4-d2d897e9189f} 5 | 6 | ;; @@ 7 | 8 | ;; ** 9 | ;;; # Hiccup html rendering and html scripts 10 | ;; ** 11 | 12 | ;; @@ [clj] 13 | ^:R [:div 14 | [:h1 "hello"] 15 | [:h3 {:style {:color "green" :font-weight "bold"}} "World!"]] 16 | ;; @@ 17 | ;; -> 18 | ;;; 19 | ;; <- 20 | ;; => 21 | ;;; [["^ ","~:type","~:reagent","~:content",["^ ","~:hiccup",["~:div",["~:h1","hello"],["~:h3",["^ ","~:style",["^ ","~:color","green","~:font-weight","bold"]],"World!"]],"~:map-keywords",true]]] 22 | ;; <= 23 | 24 | ;; @@ [clj] 25 | ^:R 26 | [:ol 27 | [:li "The Pinkie"] 28 | [:li "The Pinkie and the Brain"] 29 | [:li [:b "brain brain brain"]] 30 | [:li "What are we doing today?"]] 31 | ;; @@ 32 | ;; -> 33 | ;;; 34 | ;; <- 35 | ;; => 36 | ;;; [["^ ","~:type","~:reagent","~:content",["^ ","~:hiccup",["~:ol",["~:li","The Pinkie"],["^5","The Pinkie and the Brain"],["^5",["~:b","brain brain brain"]],["^5","What are we doing today?"]],"~:map-keywords",true]]] 37 | ;; <= 38 | 39 | ;; @@ [clj] 40 | (map #(assoc {} :a %) (range 10)) 41 | ;; @@ 42 | ;; -> 43 | ;;; 44 | ;; <- 45 | ;; => 46 | ;;; [["^ ","~:type","~:list-like","~:content",["^ ","~:class","clj-lazy-seq","~:open","(","~:close",")","~:separator"," ","~:items",["~#list",[["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","~:hiccup","^2",["~:span",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"0"]]]],"~:value","{:a 0}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"1"]]]],"^;","{:a 1}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"2"]]]],"^;","{:a 2}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"3"]]]],"^;","{:a 3}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"4"]]]],"^;","{:a 4}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"5"]]]],"^;","{:a 5}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"6"]]]],"^;","{:a 6}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"7"]]]],"^;","{:a 7}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"8"]]]],"^;","{:a 8}"]],["^ ","^0","^1","^2",["^ ","^3","clj-map","^4","{","^5","}","^6"," ","^7",["^8",[["^ ","^0","^9","^2",["^:",["^ ","^3","clj-keyword"],":a"]],["^ ","^0","^9","^2",["^:",["^ ","^3","clj-long"],"9"]]]],"^;","{:a 9}"]]]],"^;","({:a 0} {:a 1} {:a 2} {:a 3} {:a 4} {:a 5} {:a 6} {:a 7} {:a 8} {:a 9})"]]] 47 | ;; <= 48 | 49 | ;; @@ [clj] 50 | ; to check out that the script has been injected, please check out the developer tools in your web browser. 51 | ; the outut of this cell is a reagent structure. 52 | ^:R 53 | [:div 54 | [:h1"jquery gets loaded below .. jippie "] 55 | [:p/phtml "