summaryrefslogtreecommitdiff
path: root/srv/src/http/static/viz/2/quil/middlewares
diff options
context:
space:
mode:
authorBrian Picciano <mediocregopher@gmail.com>2022-05-20 13:37:43 -0600
committerBrian Picciano <mediocregopher@gmail.com>2022-05-20 13:37:43 -0600
commit16cfbd19157df76e7296dddb287412f1099feb33 (patch)
treee4bbf892066cceeaeeaee4c25e5365152412a1c3 /srv/src/http/static/viz/2/quil/middlewares
parent3cdee89c961ae9c836234f5aec87174a04a800a8 (diff)
Move static assets to within srv
Diffstat (limited to 'srv/src/http/static/viz/2/quil/middlewares')
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc26
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc.cache.json1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js95
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js.map1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc78
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc.cache.json1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/fun_mode.js142
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/fun_mode.js.map1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc89
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc.cache.json1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js116
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js.map1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc188
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc.cache.json1
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js261
-rw-r--r--srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js.map1
16 files changed, 1003 insertions, 0 deletions
diff --git a/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc
new file mode 100644
index 0000000..6ed40d2
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc
@@ -0,0 +1,26 @@
+(ns quil.middlewares.deprecated-options)
+
+(def ^:private deprecated
+ {:decor ["2.0" "Try :features [:present] for similar effect"]
+ :target ["2.0" "Use :features [:keep-on-top] instead."]
+ :safe-draw-fn ["2.0" "Use :features [:no-safe-fns] instead."]})
+
+(defn- check-features-vector [features]
+ (let [features (set features)]
+ (when (features :no-safe-draw)
+ (println "Feature :no-safe-draw was renamed to :no-safe-fns in Quil 2.1."
+ "Use :feature [:no-safe-fns] now."))
+ (disj features :no-safe-draw)))
+
+(defn deprecated-options
+ "Checks if options map contains deprected options and removes them.
+ Prints messages how to fix deprecated functions."
+ [options]
+ (let [options (update-in options [:features] check-features-vector)]
+ (->> (for [[name value] options]
+ (if-let [[version message] (deprecated name)]
+ (do (println name "option was removed in Quil" version "." message)
+ nil)
+ [name value]))
+ (remove nil?)
+ (into {}))))
diff --git a/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc.cache.json b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc.cache.json
new file mode 100644
index 0000000..b0ba153
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.cljc.cache.json
@@ -0,0 +1 @@
+["^ ","~:rename-macros",["^ "],"~:renames",["^ "],"~:use-macros",["^ "],"~:excludes",["~#set",[]],"~:name","~$quil.middlewares.deprecated-options","~:imports",null,"~:requires",null,"~:cljs.spec/speced-vars",[],"~:uses",null,"~:defs",["^ ","~$deprecated",["^ ","^5","~$quil.middlewares.deprecated-options/deprecated","~:file","out/quil/middlewares/deprecated_options.cljc","~:line",3,"~:column",1,"~:end-line",3,"~:end-column",26,"~:private",true,"~:meta",["^ ","^>","/home/mediocregopher/src/viz/out/quil/middlewares/deprecated_options.cljc","^?",3,"^@",16,"^A",3,"^B",26,"^C",true],"~:tag","~$cljs.core/IMap"],"~$check-features-vector",["^ ","~:protocol-inline",null,"^D",["^ ","^>","/home/mediocregopher/src/viz/out/quil/middlewares/deprecated_options.cljc","^?",8,"^@",8,"^A",8,"^B",29,"^C",true,"~:arglists",["~#list",["~$quote",["^J",[["~$features"]]]]]],"^C",true,"^5","~$quil.middlewares.deprecated-options/check-features-vector","^>","out/quil/middlewares/deprecated_options.cljc","^B",29,"~:method-params",["^J",[["^L"]]],"~:protocol-impl",null,"~:arglists-meta",["^J",[null,null]],"^@",1,"~:variadic?",false,"^?",8,"~:ret-tag","~$any","^A",8,"~:max-fixed-arity",1,"~:fn-var",true,"^I",["^J",["^K",["^J",[["^L"]]]]]],"~$deprecated-options",["^ ","^H",null,"^D",["^ ","^>","/home/mediocregopher/src/viz/out/quil/middlewares/deprecated_options.cljc","^?",15,"^@",7,"^A",15,"^B",25,"^I",["^J",["^K",["^J",[["~$options"]]]]],"~:doc","Checks if options map contains deprected options and removes them.\n Prints messages how to fix deprecated functions."],"^5","~$quil.middlewares.deprecated-options/deprecated-options","^>","out/quil/middlewares/deprecated_options.cljc","^B",25,"^N",["^J",[["^W"]]],"^O",null,"^P",["^J",[null,null]],"^@",1,"^Q",false,"^?",15,"^R","^S","^A",15,"^T",1,"^U",true,"^I",["^J",["^K",["^J",[["^W"]]]]],"^X","Checks if options map contains deprected options and removes them.\n Prints messages how to fix deprecated functions."]],"~:cljs.spec/registry-ref",[],"~:require-macros",null,"~:cljs.analyzer/constants",["^ ","~:seen",["^4",["~:features","~:decor","~:safe-draw-fn","~:no-safe-draw","~:target"]],"~:order",["^13","^16","^14","^15","^12"]],"^X",null] \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js
new file mode 100644
index 0000000..e80614c
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js
@@ -0,0 +1,95 @@
+// Compiled by ClojureScript 1.10.439 {}
+goog.provide('quil.middlewares.deprecated_options');
+goog.require('cljs.core');
+quil.middlewares.deprecated_options.deprecated = new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"decor","decor",-1730969431),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, ["2.0","Try :features [:present] for similar effect"], null),new cljs.core.Keyword(null,"target","target",253001721),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, ["2.0","Use :features [:keep-on-top] instead."], null),new cljs.core.Keyword(null,"safe-draw-fn","safe-draw-fn",1454900202),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, ["2.0","Use :features [:no-safe-fns] instead."], null)], null);
+quil.middlewares.deprecated_options.check_features_vector = (function quil$middlewares$deprecated_options$check_features_vector(features){
+var features__$1 = cljs.core.set.call(null,features);
+if(cljs.core.truth_(features__$1.call(null,new cljs.core.Keyword(null,"no-safe-draw","no-safe-draw",-1157778157)))){
+cljs.core.println.call(null,"Feature :no-safe-draw was renamed to :no-safe-fns in Quil 2.1.","Use :feature [:no-safe-fns] now.");
+} else {
+}
+
+return cljs.core.disj.call(null,features__$1,new cljs.core.Keyword(null,"no-safe-draw","no-safe-draw",-1157778157));
+});
+/**
+ * Checks if options map contains deprected options and removes them.
+ * Prints messages how to fix deprecated functions.
+ */
+quil.middlewares.deprecated_options.deprecated_options = (function quil$middlewares$deprecated_options$deprecated_options(options){
+var options__$1 = cljs.core.update_in.call(null,options,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"features","features",-1146962336)], null),quil.middlewares.deprecated_options.check_features_vector);
+return cljs.core.into.call(null,cljs.core.PersistentArrayMap.EMPTY,cljs.core.remove.call(null,cljs.core.nil_QMARK_,(function (){var iter__4434__auto__ = ((function (options__$1){
+return (function quil$middlewares$deprecated_options$deprecated_options_$_iter__1106(s__1107){
+return (new cljs.core.LazySeq(null,((function (options__$1){
+return (function (){
+var s__1107__$1 = s__1107;
+while(true){
+var temp__4657__auto__ = cljs.core.seq.call(null,s__1107__$1);
+if(temp__4657__auto__){
+var s__1107__$2 = temp__4657__auto__;
+if(cljs.core.chunked_seq_QMARK_.call(null,s__1107__$2)){
+var c__4432__auto__ = cljs.core.chunk_first.call(null,s__1107__$2);
+var size__4433__auto__ = cljs.core.count.call(null,c__4432__auto__);
+var b__1109 = cljs.core.chunk_buffer.call(null,size__4433__auto__);
+if((function (){var i__1108 = (0);
+while(true){
+if((i__1108 < size__4433__auto__)){
+var vec__1110 = cljs.core._nth.call(null,c__4432__auto__,i__1108);
+var name = cljs.core.nth.call(null,vec__1110,(0),null);
+var value = cljs.core.nth.call(null,vec__1110,(1),null);
+cljs.core.chunk_append.call(null,b__1109,(function (){var temp__4655__auto__ = quil.middlewares.deprecated_options.deprecated.call(null,name);
+if(cljs.core.truth_(temp__4655__auto__)){
+var vec__1113 = temp__4655__auto__;
+var version = cljs.core.nth.call(null,vec__1113,(0),null);
+var message = cljs.core.nth.call(null,vec__1113,(1),null);
+cljs.core.println.call(null,name,"option was removed in Quil",version,".",message);
+
+return null;
+} else {
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [name,value], null);
+}
+})());
+
+var G__1122 = (i__1108 + (1));
+i__1108 = G__1122;
+continue;
+} else {
+return true;
+}
+break;
+}
+})()){
+return cljs.core.chunk_cons.call(null,cljs.core.chunk.call(null,b__1109),quil$middlewares$deprecated_options$deprecated_options_$_iter__1106.call(null,cljs.core.chunk_rest.call(null,s__1107__$2)));
+} else {
+return cljs.core.chunk_cons.call(null,cljs.core.chunk.call(null,b__1109),null);
+}
+} else {
+var vec__1116 = cljs.core.first.call(null,s__1107__$2);
+var name = cljs.core.nth.call(null,vec__1116,(0),null);
+var value = cljs.core.nth.call(null,vec__1116,(1),null);
+return cljs.core.cons.call(null,(function (){var temp__4655__auto__ = quil.middlewares.deprecated_options.deprecated.call(null,name);
+if(cljs.core.truth_(temp__4655__auto__)){
+var vec__1119 = temp__4655__auto__;
+var version = cljs.core.nth.call(null,vec__1119,(0),null);
+var message = cljs.core.nth.call(null,vec__1119,(1),null);
+cljs.core.println.call(null,name,"option was removed in Quil",version,".",message);
+
+return null;
+} else {
+return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [name,value], null);
+}
+})(),quil$middlewares$deprecated_options$deprecated_options_$_iter__1106.call(null,cljs.core.rest.call(null,s__1107__$2)));
+}
+} else {
+return null;
+}
+break;
+}
+});})(options__$1))
+,null,null));
+});})(options__$1))
+;
+return iter__4434__auto__.call(null,options__$1);
+})()));
+});
+
+//# sourceMappingURL=deprecated_options.js.map
diff --git a/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js.map b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js.map
new file mode 100644
index 0000000..fdcedf9
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/deprecated_options.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/deprecated_options.js","sources":["deprecated_options.cljc"],"lineCount":95,"mappings":";AAAA;;AAEA,iDAAA,2CAAA,wDAAA,mFAAA,MAAA,sDAAA,wDAAA,mFAAA,MAAA,gDAAA,qEAAA,mFAAA,MAAA,loBAAeA;AAKf,4DAAA,5DAAOC,gIAAuB;AAA9B,AACE,IAAM,eAAS,AAACC,wBAAIC;AAApB,AACE,oBAAM,uBAAA,vBAACA;AAAP,AACE,4BAAA,iEAAA,7FAACC;;AADH;;AAGA,6CAAA,tCAACC,yBAAKF;;AAEV;;;;yDAAA,zDAAMG,0HAGH;AAHH,AAIE,IAAM,cAAQ,sCAAA,mFAAA,zHAACC,8BAAUC,iKAAoBP;AAA7C,mHACO,iBAAA,qBAAA,tFAKA,AAACuC,2BAAOC,9FACR,gCAAA,zBAACC;qFAND;AAAA,AAAA,YAAAjC,kBAAA,KAAA;;AAAA,AAAA,IAAA,cAAAC;;AAAA,AAAA,IAAA,qBAAA,AAAAC,wBAAAD;AAAA,AAAA,GAAAE;AAAA,AAAA,IAAA,cAAAA;AAAA,AAAA,GAAA,AAAAC,uCAAAH;AAAA,IAAA,kBA61E0C,AAAAiC,gCAAAjC;IA71E1C,qBAAA,AAAAI,0BAAAC;IAAA,UAAA,AAAAC,iCAAAC;AAAA,AAAA,GAAA,AAAA,iBAAA,UAAA;;AAAA,AAAA,GAAA,CAAAC,UAAAD;AAAA,IAAA,YAAA,AAAAE,yBAAAJ,gBAAAG;WAAA,AAAAE,wBAAAC,UAAA,IAAA,7CAAO;YAAP,AAAAD,wBAAAC,UAAA,IAAA,9CAAY;AAAZ,AAAA,AAAA,AAAAC,iCAAAC,QACE,iBAAA,qBAA2B,AAACvB,yDAAWoC;AAAvC,AAAA,oBAAAH;AAAA,IAAA,YAAAA;cAAA,AAAAb,wBAAAc,UAAA,IAAA,hDAAU;cAAV,AAAAd,wBAAAc,UAAA,IAAA,hDAAkB;AAAlB,AACE,AAAI,iCAAA,qCAAA,tEAAC9B,4BAAQgC,kCAAkCC,YAAYC;;AAA3D;;AADF,0FAGGF,KAAKG;;;;AAJV,cAAA,CAAArB,UAAA;;;;AAAA;;;;;AAAA,OAAAM,+BAAA,AAAAC,0BAAAF,SAAA,AAAAG,8EAAA,AAAAC,+BAAAjB;;AAAA,OAAAc,+BAAA,AAAAC,0BAAAF,SAAA;;;AAAA,IAAA,YAAA,AAAAK,0BAAAlB;WAAA,AAAAU,wBAAAS,UAAA,IAAA,7CAAO;YAAP,AAAAT,wBAAAS,UAAA,IAAA,9CAAY;AAAZ,AAAA,OAAAC,yBACE,iBAAA,qBAA2B,AAAC9B,yDAAWoC;AAAvC,AAAA,oBAAAH;AAAA,IAAA,YAAAA;cAAA,AAAAb,wBAAAe,UAAA,IAAA,hDAAU;cAAV,AAAAf,wBAAAe,UAAA,IAAA,hDAAkB;AAAlB,AACE,AAAI,iCAAA,qCAAA,tEAAC\/B,4BAAQgC,kCAAkCC,YAAYC;;AAA3D;;AADF,0FAGGF,KAAKG;;KAJV,AAAAb,8EAAA,AAAAK,yBAAArB;;;AAAA;;;;;CAAA,KAAA;;;AAAA,AAAA,OAAAsB,6BAAmBxB","names":["quil.middlewares.deprecated-options\/deprecated","quil.middlewares.deprecated-options\/check-features-vector","cljs.core\/set","features","cljs.core\/println","cljs.core\/disj","quil.middlewares.deprecated-options\/deprecated-options","cljs.core\/update-in","options","cljs.core\/LazySeq","s__1107","cljs.core\/seq","temp__4657__auto__","cljs.core\/chunked-seq?","cljs.core\/count","c__4432__auto__","cljs.core\/chunk-buffer","size__4433__auto__","i__1108","cljs.core\/-nth","cljs.core\/nth","vec__1110","cljs.core\/chunk-append","b__1109","cljs.core\/chunk-cons","cljs.core\/chunk","iter__1106","cljs.core\/chunk-rest","cljs.core\/first","vec__1116","cljs.core\/cons","cljs.core\/rest","iter__4434__auto__","temp__4655__auto__","vec__1113","vec__1119","name","version","message","value","cljs.core\/remove","cljs.core\/nil?","cljs.core\/into","cljs.core\/chunk-first"]} \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc
new file mode 100644
index 0000000..14330c7
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc
@@ -0,0 +1,78 @@
+(ns quil.middlewares.fun-mode
+ (:require [quil.core :as q]))
+
+(defn- wrap-setup [options]
+ (let [setup (:setup options (fn [] nil))]
+ (assoc options
+ :setup #(reset! (q/state-atom) (setup)))))
+
+(defn- wrap-draw-update [options]
+ (let [draw (:draw options (fn [_]))
+ update (:update options identity)
+ quil-draw #(-> (q/state-atom)
+ (swap! (if (= (q/frame-count) 1)
+ identity
+ update))
+ (draw))]
+ (-> options
+ (dissoc :update)
+ (assoc :draw quil-draw))))
+
+(defn- mouse-event []
+ {:x (q/mouse-x)
+ :y (q/mouse-y)})
+
+(defn- mouse-event-full []
+ {:x (q/mouse-x)
+ :y (q/mouse-y)
+ :button (q/mouse-button)})
+
+(defn- key-event []
+ {:key (q/key-as-keyword)
+ :key-code (q/key-code)
+ :raw-key (q/raw-key)
+ #?@(:clj [:modifiers (q/key-modifiers)])})
+
+(defn- wrap-handler
+ ([options handler-key]
+ (wrap-handler options handler-key nil))
+ ([options handler-key event-fn]
+ (if-let [handler (options handler-key)]
+ (assoc options handler-key
+ (if event-fn
+ #(swap! (q/state-atom) handler (event-fn))
+ #(swap! (q/state-atom) handler)))
+ options)))
+
+(defn- wrap-handlers [options & handlers]
+ (reduce (fn [options handler]
+ (if (keyword? handler)
+ (wrap-handler options handler)
+ (apply wrap-handler options handler)))
+ options handlers))
+
+(defn- wrap-mouse-wheel [options]
+ (if-let [handler (:mouse-wheel options)]
+ (assoc options :mouse-wheel
+ (fn [rotation]
+ (swap! (q/state-atom) handler rotation)))
+ options))
+
+(defn fun-mode
+ "Introduces function mode making all handlers (setup, draw, mouse-click, etc)
+ state-aware. Adds support for 'update' function."
+ [options]
+ (-> options
+ wrap-setup
+ wrap-draw-update
+ (wrap-handlers :focus-gained :focus-lost [:mouse-entered mouse-event]
+ [:mouse-exited mouse-event] [:mouse-pressed mouse-event-full]
+ [:mouse-released mouse-event] [:mouse-clicked mouse-event-full]
+ [:mouse-moved (fn [] {:x (q/mouse-x) :y (q/mouse-y)
+ :p-x (q/pmouse-x) :p-y (q/pmouse-y)})]
+ [:mouse-dragged (fn [] {:x (q/mouse-x) :y (q/mouse-y)
+ :p-x (q/pmouse-x) :p-y (q/pmouse-y)
+ :button (q/mouse-button)})]
+ [:key-pressed key-event] :key-released [:key-typed key-event]
+ :on-close)
+ wrap-mouse-wheel))
diff --git a/srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc.cache.json b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc.cache.json
new file mode 100644
index 0000000..26e797e
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.cljc.cache.json
@@ -0,0 +1 @@
+["^ ","~:rename-macros",["^ "],"~:renames",["^ "],"~:externs",["^ ","~$Error",["^ "]],"~:use-macros",["^ "],"~:excludes",["~#set",[]],"~:name","~$quil.middlewares.fun-mode","~:imports",null,"~:requires",["^ ","~$q","~$quil.core","^;","^;"],"~:cljs.spec/speced-vars",[],"~:uses",null,"~:defs",["^ ","~$wrap-setup",["^ ","~:protocol-inline",null,"~:meta",["^ ","~:file","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","~:line",4,"~:column",8,"~:end-line",4,"~:end-column",18,"~:private",true,"~:arglists",["~#list",["~$quote",["^I",[["~$options"]]]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/wrap-setup","^B","out/quil/middlewares/fun_mode.cljc","^F",18,"~:method-params",["^I",[["^K"]]],"~:protocol-impl",null,"~:arglists-meta",["^I",[null,null]],"^D",1,"~:variadic?",false,"^C",4,"~:ret-tag","~$any","^E",4,"~:max-fixed-arity",1,"~:fn-var",true,"^H",["^I",["^J",["^I",[["^K"]]]]]],"~$wrap-draw-update",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",9,"^D",8,"^E",9,"^F",24,"^G",true,"^H",["^I",["^J",["^I",[["^K"]]]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/wrap-draw-update","^B","out/quil/middlewares/fun_mode.cljc","^F",24,"^M",["^I",[["^K"]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",9,"^Q","^R","^E",9,"^S",1,"^T",true,"^H",["^I",["^J",["^I",[["^K"]]]]]],"~$mouse-event",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",21,"^D",8,"^E",21,"^F",19,"^G",true,"^H",["^I",["^J",["^I",[[]]]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/mouse-event","^B","out/quil/middlewares/fun_mode.cljc","^F",19,"^M",["^I",[[]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",21,"^Q","~$cljs.core/IMap","^E",21,"^S",0,"^T",true,"^H",["^I",["^J",["^I",[[]]]]]],"~$mouse-event-full",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",25,"^D",8,"^E",25,"^F",24,"^G",true,"^H",["^I",["^J",["^I",[[]]]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/mouse-event-full","^B","out/quil/middlewares/fun_mode.cljc","^F",24,"^M",["^I",[[]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",25,"^Q","^Y","^E",25,"^S",0,"^T",true,"^H",["^I",["^J",["^I",[[]]]]]],"~$key-event",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",30,"^D",8,"^E",30,"^F",17,"^G",true,"^H",["^I",["^J",["^I",[[]]]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/key-event","^B","out/quil/middlewares/fun_mode.cljc","^F",17,"^M",["^I",[[]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",30,"^Q","^Y","^E",30,"^S",0,"^T",true,"^H",["^I",["^J",["^I",[[]]]]]],"~$wrap-handler",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",36,"^D",8,"^E",36,"^F",20,"^G",true,"^H",["^I",["^J",["^I",[["^K","~$handler-key"],["^K","^13","~$event-fn"]]]]],"~:top-fn",["^ ","^P",false,"^S",3,"^M",["^I",[["^K","^13"],["^K","^13","^14"]]],"^H",["^I",[["^K","^13"],["^K","^13","^14"]]],"^O",["^I",[null,null]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/wrap-handler","^B","out/quil/middlewares/fun_mode.cljc","^F",20,"^15",["^ ","^P",false,"^S",3,"^M",["^I",[["^K","^13"],["^K","^13","^14"]]],"^H",["^I",[["^K","^13"],["^K","^13","^14"]]],"^O",["^I",[null,null]]],"^M",["^I",[["^K","^13"],["^K","^13","^14"]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",36,"^E",36,"^S",3,"^T",true,"^H",["^I",[["^K","^13"],["^K","^13","^14"]]]],"~$wrap-handlers",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",47,"^D",8,"^E",47,"^F",21,"^G",true,"^H",["^I",["^J",["^I",[["^K","~$&","~$handlers"]]]]],"^15",["^ ","^P",true,"^S",1,"^M",[["^I",["^K","^18"]]],"^H",["^I",[["^K","~$&","^18"]]],"^O",["^I",[null]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/wrap-handlers","^B","out/quil/middlewares/fun_mode.cljc","^F",21,"^15",["^ ","^P",true,"^S",1,"^M",[["^I",["^K","^18"]]],"^H",["^I",[["^K","~$&","^18"]]],"^O",["^I",[null]]],"^M",[["^I",["^K","^18"]]],"^N",null,"^O",["^I",[null]],"^D",1,"^P",true,"^C",47,"^Q","^R","^E",47,"^S",1,"^T",true,"^H",["^I",[["^K","~$&","^18"]]]],"~$wrap-mouse-wheel",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",54,"^D",8,"^E",54,"^F",24,"^G",true,"^H",["^I",["^J",["^I",[["^K"]]]]]],"^G",true,"^7","~$quil.middlewares.fun-mode/wrap-mouse-wheel","^B","out/quil/middlewares/fun_mode.cljc","^F",24,"^M",["^I",[["^K"]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",54,"^Q",["^6",[null,"^R"]],"^E",54,"^S",1,"^T",true,"^H",["^I",["^J",["^I",[["^K"]]]]]],"~$fun-mode",["^ ","^@",null,"^A",["^ ","^B","/home/mediocregopher/src/viz/out/quil/middlewares/fun_mode.cljc","^C",61,"^D",7,"^E",61,"^F",15,"^H",["^I",["^J",["^I",[["^K"]]]]],"~:doc","Introduces function mode making all handlers (setup, draw, mouse-click, etc)\n state-aware. Adds support for 'update' function."],"^7","~$quil.middlewares.fun-mode/fun-mode","^B","out/quil/middlewares/fun_mode.cljc","^F",15,"^M",["^I",[["^K"]]],"^N",null,"^O",["^I",[null,null]],"^D",1,"^P",false,"^C",61,"^Q",["^6",[null,"^R"]],"^E",61,"^S",1,"^T",true,"^H",["^I",["^J",["^I",[["^K"]]]]],"^1=","Introduces function mode making all handlers (setup, draw, mouse-click, etc)\n state-aware. Adds support for 'update' function."]],"~:cljs.spec/registry-ref",[],"~:require-macros",null,"~:cljs.analyzer/constants",["^ ","~:seen",["^6",["~:y","~:key-code","~:p-y","~:key-typed","~:mouse-clicked","~:mouse-released","~:mouse-exited","~:key","~:on-close","~:button","~:mouse-wheel","~:mouse-moved","~:update","~:setup","~:mouse-pressed","~:focus-gained","~:mouse-entered","~:focus-lost","~:key-pressed","~:key-released","~:p-x","~:x","~:raw-key","~:draw","~:mouse-dragged"]],"~:order",["^1O","^1X","^1N","~:x","~:y","^1K","^1I","^1C","^1W","^1L","^1Q","^1S","^1R","^1H","^1P","^1G","^1F","^1M","^1V","^1D","^1Y","^1T","^1U","^1E","^1J"]],"^1=",null] \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/fun_mode.js b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.js
new file mode 100644
index 0000000..5eabdf8
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.js
@@ -0,0 +1,142 @@
+// Compiled by ClojureScript 1.10.439 {}
+goog.provide('quil.middlewares.fun_mode');
+goog.require('cljs.core');
+goog.require('quil.core');
+quil.middlewares.fun_mode.wrap_setup = (function quil$middlewares$fun_mode$wrap_setup(options){
+var setup = new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$2(options,(function (){
+return null;
+}));
+return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"setup","setup",1987730512),((function (setup){
+return (function (){
+return cljs.core.reset_BANG_.call(null,quil.core.state_atom.call(null),setup.call(null));
+});})(setup))
+);
+});
+quil.middlewares.fun_mode.wrap_draw_update = (function quil$middlewares$fun_mode$wrap_draw_update(options){
+var draw = new cljs.core.Keyword(null,"draw","draw",1358331674).cljs$core$IFn$_invoke$arity$2(options,(function (_){
+return null;
+}));
+var update = new cljs.core.Keyword(null,"update","update",1045576396).cljs$core$IFn$_invoke$arity$2(options,cljs.core.identity);
+var quil_draw = ((function (draw,update){
+return (function (){
+return draw.call(null,cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),((cljs.core._EQ_.call(null,quil.core.frame_count.call(null),(1)))?cljs.core.identity:update)));
+});})(draw,update))
+;
+return cljs.core.assoc.call(null,cljs.core.dissoc.call(null,options,new cljs.core.Keyword(null,"update","update",1045576396)),new cljs.core.Keyword(null,"draw","draw",1358331674),quil_draw);
+});
+quil.middlewares.fun_mode.mouse_event = (function quil$middlewares$fun_mode$mouse_event(){
+return new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null)], null);
+});
+quil.middlewares.fun_mode.mouse_event_full = (function quil$middlewares$fun_mode$mouse_event_full(){
+return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null),new cljs.core.Keyword(null,"button","button",1456579943),quil.core.mouse_button.call(null)], null);
+});
+quil.middlewares.fun_mode.key_event = (function quil$middlewares$fun_mode$key_event(){
+return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"key","key",-1516042587),quil.core.key_as_keyword.call(null),new cljs.core.Keyword(null,"key-code","key-code",-1732114304),quil.core.key_code.call(null),new cljs.core.Keyword(null,"raw-key","raw-key",-162482279),quil.core.raw_key.call(null)], null);
+});
+quil.middlewares.fun_mode.wrap_handler = (function quil$middlewares$fun_mode$wrap_handler(var_args){
+var G__2134 = arguments.length;
+switch (G__2134) {
+case 2:
+return quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$2((arguments[(0)]),(arguments[(1)]));
+
+break;
+case 3:
+return quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$3((arguments[(0)]),(arguments[(1)]),(arguments[(2)]));
+
+break;
+default:
+throw (new Error(["Invalid arity: ",cljs.core.str.cljs$core$IFn$_invoke$arity$1(arguments.length)].join('')));
+
+}
+});
+
+quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$2 = (function (options,handler_key){
+return quil.middlewares.fun_mode.wrap_handler.call(null,options,handler_key,null);
+});
+
+quil.middlewares.fun_mode.wrap_handler.cljs$core$IFn$_invoke$arity$3 = (function (options,handler_key,event_fn){
+var temp__4655__auto__ = options.call(null,handler_key);
+if(cljs.core.truth_(temp__4655__auto__)){
+var handler = temp__4655__auto__;
+return cljs.core.assoc.call(null,options,handler_key,(cljs.core.truth_(event_fn)?((function (handler,temp__4655__auto__){
+return (function (){
+return cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),handler,event_fn.call(null));
+});})(handler,temp__4655__auto__))
+:((function (handler,temp__4655__auto__){
+return (function (){
+return cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),handler);
+});})(handler,temp__4655__auto__))
+));
+} else {
+return options;
+}
+});
+
+quil.middlewares.fun_mode.wrap_handler.cljs$lang$maxFixedArity = 3;
+
+quil.middlewares.fun_mode.wrap_handlers = (function quil$middlewares$fun_mode$wrap_handlers(var_args){
+var args__4647__auto__ = [];
+var len__4641__auto___2138 = arguments.length;
+var i__4642__auto___2139 = (0);
+while(true){
+if((i__4642__auto___2139 < len__4641__auto___2138)){
+args__4647__auto__.push((arguments[i__4642__auto___2139]));
+
+var G__2140 = (i__4642__auto___2139 + (1));
+i__4642__auto___2139 = G__2140;
+continue;
+} else {
+}
+break;
+}
+
+var argseq__4648__auto__ = ((((1) < args__4647__auto__.length))?(new cljs.core.IndexedSeq(args__4647__auto__.slice((1)),(0),null)):null);
+return quil.middlewares.fun_mode.wrap_handlers.cljs$core$IFn$_invoke$arity$variadic((arguments[(0)]),argseq__4648__auto__);
+});
+
+quil.middlewares.fun_mode.wrap_handlers.cljs$core$IFn$_invoke$arity$variadic = (function (options,handlers){
+return cljs.core.reduce.call(null,(function (options__$1,handler){
+if((handler instanceof cljs.core.Keyword)){
+return quil.middlewares.fun_mode.wrap_handler.call(null,options__$1,handler);
+} else {
+return cljs.core.apply.call(null,quil.middlewares.fun_mode.wrap_handler,options__$1,handler);
+}
+}),options,handlers);
+});
+
+quil.middlewares.fun_mode.wrap_handlers.cljs$lang$maxFixedArity = (1);
+
+/** @this {Function} */
+quil.middlewares.fun_mode.wrap_handlers.cljs$lang$applyTo = (function (seq2136){
+var G__2137 = cljs.core.first.call(null,seq2136);
+var seq2136__$1 = cljs.core.next.call(null,seq2136);
+var self__4628__auto__ = this;
+return self__4628__auto__.cljs$core$IFn$_invoke$arity$variadic(G__2137,seq2136__$1);
+});
+
+quil.middlewares.fun_mode.wrap_mouse_wheel = (function quil$middlewares$fun_mode$wrap_mouse_wheel(options){
+var temp__4655__auto__ = new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439).cljs$core$IFn$_invoke$arity$1(options);
+if(cljs.core.truth_(temp__4655__auto__)){
+var handler = temp__4655__auto__;
+return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439),((function (handler,temp__4655__auto__){
+return (function (rotation){
+return cljs.core.swap_BANG_.call(null,quil.core.state_atom.call(null),handler,rotation);
+});})(handler,temp__4655__auto__))
+);
+} else {
+return options;
+}
+});
+/**
+ * Introduces function mode making all handlers (setup, draw, mouse-click, etc)
+ * state-aware. Adds support for 'update' function.
+ */
+quil.middlewares.fun_mode.fun_mode = (function quil$middlewares$fun_mode$fun_mode(options){
+return quil.middlewares.fun_mode.wrap_mouse_wheel.call(null,quil.middlewares.fun_mode.wrap_handlers.call(null,quil.middlewares.fun_mode.wrap_draw_update.call(null,quil.middlewares.fun_mode.wrap_setup.call(null,options)),new cljs.core.Keyword(null,"focus-gained","focus-gained",-857086384),new cljs.core.Keyword(null,"focus-lost","focus-lost",-554849613),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-entered","mouse-entered",811350322),quil.middlewares.fun_mode.mouse_event], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-exited","mouse-exited",-483205244),quil.middlewares.fun_mode.mouse_event], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-pressed","mouse-pressed",736955536),quil.middlewares.fun_mode.mouse_event_full], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-released","mouse-released",-664480061),quil.middlewares.fun_mode.mouse_event], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-clicked","mouse-clicked",-199339421),quil.middlewares.fun_mode.mouse_event_full], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-moved","mouse-moved",-1918152310),(function (){
+return new cljs.core.PersistentArrayMap(null, 4, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null),new cljs.core.Keyword(null,"p-x","p-x",-1721211211),quil.core.pmouse_x.call(null),new cljs.core.Keyword(null,"p-y","p-y",-530704830),quil.core.pmouse_y.call(null)], null);
+})], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441),(function (){
+return new cljs.core.PersistentArrayMap(null, 5, [new cljs.core.Keyword(null,"x","x",2099068185),quil.core.mouse_x.call(null),new cljs.core.Keyword(null,"y","y",-1757859776),quil.core.mouse_y.call(null),new cljs.core.Keyword(null,"p-x","p-x",-1721211211),quil.core.pmouse_x.call(null),new cljs.core.Keyword(null,"p-y","p-y",-530704830),quil.core.pmouse_y.call(null),new cljs.core.Keyword(null,"button","button",1456579943),quil.core.mouse_button.call(null)], null);
+})], null),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364),quil.middlewares.fun_mode.key_event], null),new cljs.core.Keyword(null,"key-released","key-released",215919828),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"key-typed","key-typed",-876037597),quil.middlewares.fun_mode.key_event], null),new cljs.core.Keyword(null,"on-close","on-close",-761178394)));
+});
+
+//# sourceMappingURL=fun_mode.js.map
diff --git a/srv/src/http/static/viz/2/quil/middlewares/fun_mode.js.map b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.js.map
new file mode 100644
index 0000000..459ff6e
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/fun_mode.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/fun_mode.js","sources":["fun_mode.cljc"],"lineCount":142,"mappings":";AAAA;;;AAGA,uCAAA,vCAAOA,sFAAY;AAAnB,AACE,IAAM,QAAM,AAAA,qFAAQC,QAAQ;AAAA,AAAA;;AAA5B,AACE,yCAAA,uDAAA,zFAACC,0BAAMD;;AAAP,AACU,OAACE,gCAAO,AAACC,gCAAc,AAACC;;;;AAEtC,6CAAA,7CAAOC,kGAAkB;AAAzB,AACE,IAAM,OAAK,AAAA,mFAAOL,QAAQ,WAAK;AAAL,AAAA;;IACpB,SAAO,AAAA,uFAASA,QAAQM;gBAD9B,ZAEM;;AAFN,qDAEqB,AAACH,\/BACD,AAACI,+DAAM,EAAI,0DAAA,1DAACC,yBAAE,AAACC,uCACNH,mBACAI,1KACT,OAACC;;;AANtB,4DAOMX,3BACA,mCAAA,nCAACY,jCACD,8HAAA,vHAACX,4KAAYY;;AAErB,wCAAA,xCAAOC;AAAP,AAAA,kDAAA,4EAAA,7BACM,AAACC,6EACD,AAACC;;AAEP,6CAAA,7CAAOC;AAAP,AAAA,kDAAA,4EAAA,6EAAA,1GACM,AAACF,6EACD,AAACC,sFACI,AAACE;;AAEZ,sCAAA,tCAAOC;AAAP,AAAA,kDAAA,wFAAA,4FAAA,hIACQ,AAACC,kGACI,AAACC,yFACF,AAACC;;AAGb,AAAA,yCAAA,iDAAA,1FAAOE;AAAP,AAAA,IAAA,UAAA,AAAA;AAAA,AAAA,QAAAD;KAAA;AAAA,OAAAC,qEAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;KAAA;AAAA,OAAAA,qEAAA,CAAA,UAAA,MAAA,CAAA,UAAA,MAAA,CAAA,UAAA;;;;AAAA,MAAA,KAAAC,MAAA,CAAA,8DAAA,AAAA;;;;;AAAA,AAAA,uEAAA,vEAAOD,kFACH,QAAQ;AADZ,AAEK,4EAAA,rEAACA,iDAAaxB,QAAQ0B;;;AAF3B,AAAA,uEAAA,vEAAOF,kFAGH,QAAQ,YAAY;AAHxB,AAIK,IAAA,qBAAiB,AAACxB,kBAAQ0B;AAA1B,AAAA,oBAAAC;AAAA,cAAAA,VAAS;AAAT,AACE,OAAC1B,0BAAMD,QAAQ0B,YACR,4BAAA,VAAIE;;AAAJ,AACG,OAACrB,+BAAM,AAACJ,gCAAc0B,QAAQ,AAACD;;CADlC;;AAAA,AAEG,OAACrB,+BAAM,AAACJ,gCAAc0B;;;;AAChC7B;;;;AATP,AAAA,iEAAA,jEAAOwB;;AAAP,AAWA,AAAA,0CAAA,kDAAA,5FAAOU;AAAP,AAAA,IAAA,qBAAA;AAAA,AAAA,IAAA,yBAAA,AAAA;AAAA,AAAA,IAAA,uBAAA;;AAAA,AAAA,GAAA,CAAAJ,uBAAAC;AAAA,AAAA,AAAAC,wBAAA,CAAA,UAAAF;;AAAA,cAAA,CAAAA,uBAAA;;;;AAAA;;;;AAAA,IAAA,uBAAA,EAAA,CAAA,MAAA,AAAAE,4BAAA,AAAA,KAAAC,qBAAA,AAAAD,yBAAA,KAAA,IAAA,OAAA;AAAA,AAAA,OAAAE,6EAAA,CAAA,UAAA,MAAAC;;;AAAA,AAAA,AAAA,AAAAD,+EAAA,WAAsB,QAAU;AAAhC,AACE,OAACO,2BAAO,WAAK,YAAQ;AAAb,AACE,GAAI,oBAAAC,nBAAUb;AACZ,OAACL,iDAAaxB,YAAQ6B;;AACtB,OAACc,0BAAMnB,uCAAaxB,YAAQ6B;;GAChC7B,QAAQ4C;;;AALlB,AAAA,AAAAV,kEAAA;;AAAA;AAAA,AAAA,AAAAA,4DAAA,WAAA;AAAA,AAAA,IAAA,UAAA,AAAAE,0BAAAC;IAAA,cAAA,AAAAC,yBAAAD;AAAA,AAAA,IAAA,qBAAA;AAAA,AAAA,OAAAE,wDAAAC,QAAAH;;;AAAA,AAOA,6CAAA,7CAAOQ,kGAAkB;AAAzB,AACE,IAAA,qBAAiB,AAAA,iGAAc7C;AAA\/B,AAAA,oBAAA2B;AAAA,cAAAA,VAAS;AAAT,AACE,yCAAA,lCAAC1B,0BAAMD,2EACA;kBAAK;AAAL,AACE,OAACO,+BAAM,AAACJ,gCAAc0B,QAAQiB;;;;AACvC9C;;;AAEJ;;;;qCAAA,rCAAM+C,kFAGH;AAHH,AAIE,kNAAI\/C,\/CACAD,rDACAM,lDACA,kDAAA,qDAAA,yDAAA,qEAAA,iEAAA,mFAAA,oHAAA,mFAAA,mHAAA,mFAAA,yHAAA,mFAAA,uHAAA,mFAAA,0HAAA,mFAAA,z2CAAC6B,+bAAwDpB,sMAC3BA,uMAA6BG,+MAC3BH,wMAA6BG,0MAChC,l+CAO7B4B;AAP6B,AAAA,kDAAA,4EAAA,6EAAA,kFAAA,5LAAW,AAAC9B,6EAAc,AAACC,iFACd,AAACgC,iFAAiB,AAACC;WAJ7D,mFAAA,wEAK+B;AAAA,AAAA,kDAAA,4EAAA,6EAAA,kFAAA,iFAAA,7QAAW,AAAClC,6EAAc,AAACC,iFACd,AAACgC,iFAAiB,AAACC,uFAChB,AAAC\/B;WAPhD,mFAAA,+GAAA,oEAAA,mFAAA,2GAAA,9SAQ6BC,kQAAqCA","names":["quil.middlewares.fun-mode\/wrap-setup","options","cljs.core\/assoc","cljs.core\/reset!","quil.core\/state-atom","setup","quil.middlewares.fun-mode\/wrap-draw-update","cljs.core\/identity","cljs.core\/swap!","cljs.core\/=","quil.core\/frame-count","update","draw","cljs.core\/dissoc","quil-draw","quil.middlewares.fun-mode\/mouse-event","quil.core\/mouse-x","quil.core\/mouse-y","quil.middlewares.fun-mode\/mouse-event-full","quil.core\/mouse-button","quil.middlewares.fun-mode\/key-event","quil.core\/key-as-keyword","quil.core\/key-code","quil.core\/raw-key","G__2134","quil.middlewares.fun-mode\/wrap-handler","js\/Error","handler-key","temp__4655__auto__","event-fn","handler","i__4642__auto__","len__4641__auto__","args__4647__auto__","cljs.core\/IndexedSeq","quil.middlewares.fun-mode\/wrap-handlers","argseq__4648__auto__","cljs.core\/first","seq2136","cljs.core\/next","self__4628__auto__","G__2137","cljs.core\/reduce","cljs.core\/Keyword","cljs.core\/apply","handlers","quil.middlewares.fun-mode\/wrap-mouse-wheel","rotation","quil.middlewares.fun-mode\/fun-mode","quil.core\/pmouse-x","quil.core\/pmouse-y"]} \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc
new file mode 100644
index 0000000..cd03710
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc
@@ -0,0 +1,89 @@
+(ns quil.middlewares.navigation-2d
+ (:require [quil.core :as q :include-macros true]))
+
+(def ^:private missing-navigation-key-error
+ (str "state map is missing :navigation-2d key. "
+ "Did you accidentally removed it from the state in "
+ ":update or any other handler?"))
+
+(defn- assert-state-has-navigation
+ "Asserts that state map contains :navigation-2d object."
+ [state]
+ (when-not (:navigation-2d state)
+ (throw #?(:clj (RuntimeException. missing-navigation-key-error)
+ :cljs (js/Error. missing-navigation-key-error)))))
+
+(defn- default-position
+ "Default position configuration: zoom is neutral and central point is
+ width/2, height/2."
+ []
+ {:position [(/ (q/width) 2.0)
+ (/ (q/height) 2.0)]
+ :zoom 1})
+
+(defn- setup-2d-nav
+ "Custom 'setup' function which creates initial position
+ configuration and puts it to the state map."
+ [user-setup user-settings]
+ (let [initial-state (-> user-settings
+ (select-keys [:position :zoom])
+ (->> (merge (default-position))))]
+ (update-in (user-setup) [:navigation-2d]
+ #(merge initial-state %))))
+
+(defn- mouse-dragged
+ "Changes center of the sketch depending on the last mouse move. Takes
+ zoom into account as well."
+ [state event]
+ (assert-state-has-navigation state)
+ (let [dx (- (:p-x event) (:x event))
+ dy (- (:p-y event) (:y event))
+ zoom (-> state :navigation-2d :zoom)]
+ (-> state
+ (update-in [:navigation-2d :position 0] + (/ dx zoom))
+ (update-in [:navigation-2d :position 1] + (/ dy zoom)))))
+
+(defn- mouse-wheel
+ "Changes zoom settings based on scroll."
+ [state event]
+ (assert-state-has-navigation state)
+ (update-in state [:navigation-2d :zoom] * (+ 1 (* -0.1 event))))
+
+(defn- draw
+ "Calls user draw function with necessary all transformations (position
+ and zoom) applied."
+ [user-draw state]
+ (assert-state-has-navigation state)
+ (q/push-matrix)
+ (let [nav-2d (:navigation-2d state)
+ zoom (:zoom nav-2d)
+ pos (:position nav-2d)]
+ (q/scale zoom)
+ (q/with-translation [(- (/ (q/width) 2 zoom) (first pos))
+ (- (/ (q/height) 2 zoom) (second pos))]
+ (user-draw state)))
+ (q/pop-matrix))
+
+(defn navigation-2d
+ "Enables navigation over 2D sketch. Dragging mouse will move center of the
+ skecth and mouse wheel controls zoom."
+ [options]
+ (let [; 2d-navigation related user settings
+ user-settings (:navigation-2d options)
+
+ ; user-provided handlers which will be overridden
+ ; by 3d-navigation
+ user-draw (:draw options (fn [state]))
+ user-mouse-dragged (:mouse-dragged options (fn [state _] state))
+ user-mouse-wheel (:mouse-wheel options (fn [state _] state))
+ setup (:setup options (fn [] {}))]
+ (assoc options
+
+ :setup (partial setup-2d-nav setup user-settings)
+
+ :draw (partial draw user-draw)
+
+ :mouse-dragged (fn [state event]
+ (user-mouse-dragged (mouse-dragged state event) event))
+ :mouse-wheel (fn [state event]
+ (user-mouse-wheel (mouse-wheel state event) event)))))
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc.cache.json b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc.cache.json
new file mode 100644
index 0000000..664f7ef
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.cljc.cache.json
@@ -0,0 +1 @@
+["^ ","~:rename-macros",["^ "],"~:renames",["^ "],"~:externs",["^ ","~$Error",["^ "]],"~:use-macros",["^ "],"~:excludes",["~#set",[]],"~:name","~$quil.middlewares.navigation-2d","~:imports",null,"~:requires",["^ ","~$q","~$quil.core","^;","^;"],"~:cljs.spec/speced-vars",[],"~:uses",null,"~:defs",["^ ","~$missing-navigation-key-error",["^ ","^7","~$quil.middlewares.navigation-2d/missing-navigation-key-error","~:file","out/quil/middlewares/navigation_2d.cljc","~:line",4,"~:column",1,"~:end-line",4,"~:end-column",44,"~:private",true,"~:meta",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",4,"^C",16,"^D",4,"^E",44,"^F",true],"~:tag","~$any"],"~$assert-state-has-navigation",["^ ","~:protocol-inline",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",9,"^C",8,"^D",9,"^E",35,"^F",true,"~:arglists",["~#list",["~$quote",["^M",[["~$state"]]]]],"~:doc","Asserts that state map contains :navigation-2d object."],"^F",true,"^7","~$quil.middlewares.navigation-2d/assert-state-has-navigation","^A","out/quil/middlewares/navigation_2d.cljc","^E",35,"~:method-params",["^M",[["^O"]]],"~:protocol-impl",null,"~:arglists-meta",["^M",[null,null]],"^C",1,"~:variadic?",false,"^B",9,"~:ret-tag","~$clj-nil","^D",9,"~:max-fixed-arity",1,"~:fn-var",true,"^L",["^M",["^N",["^M",[["^O"]]]]],"^P","Asserts that state map contains :navigation-2d object."],"~$default-position",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",16,"^C",8,"^D",16,"^E",24,"^F",true,"^L",["^M",["^N",["^M",[[]]]]],"^P","Default position configuration: zoom is neutral and central point is\n width/2, height/2."],"^F",true,"^7","~$quil.middlewares.navigation-2d/default-position","^A","out/quil/middlewares/navigation_2d.cljc","^E",24,"^R",["^M",[[]]],"^S",null,"^T",["^M",[null,null]],"^C",1,"^U",false,"^B",16,"^V","~$cljs.core/IMap","^D",16,"^X",0,"^Y",true,"^L",["^M",["^N",["^M",[[]]]]],"^P","Default position configuration: zoom is neutral and central point is\n width/2, height/2."],"~$setup-2d-nav",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",24,"^C",8,"^D",24,"^E",20,"^F",true,"^L",["^M",["^N",["^M",[["~$user-setup","~$user-settings"]]]]],"^P","Custom 'setup' function which creates initial position\n configuration and puts it to the state map."],"^F",true,"^7","~$quil.middlewares.navigation-2d/setup-2d-nav","^A","out/quil/middlewares/navigation_2d.cljc","^E",20,"^R",["^M",[["^12","^13"]]],"^S",null,"^T",["^M",[null,null]],"^C",1,"^U",false,"^B",24,"^V","^I","^D",24,"^X",2,"^Y",true,"^L",["^M",["^N",["^M",[["^12","^13"]]]]],"^P","Custom 'setup' function which creates initial position\n configuration and puts it to the state map."],"~$mouse-dragged",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",34,"^C",8,"^D",34,"^E",21,"^F",true,"^L",["^M",["^N",["^M",[["^O","~$event"]]]]],"^P","Changes center of the sketch depending on the last mouse move. Takes\n zoom into account as well."],"^F",true,"^7","~$quil.middlewares.navigation-2d/mouse-dragged","^A","out/quil/middlewares/navigation_2d.cljc","^E",21,"^R",["^M",[["^O","^16"]]],"^S",null,"^T",["^M",[null,null]],"^C",1,"^U",false,"^B",34,"^V","^I","^D",34,"^X",2,"^Y",true,"^L",["^M",["^N",["^M",[["^O","^16"]]]]],"^P","Changes center of the sketch depending on the last mouse move. Takes\n zoom into account as well."],"~$mouse-wheel",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",46,"^C",8,"^D",46,"^E",19,"^F",true,"^L",["^M",["^N",["^M",[["^O","^16"]]]]],"^P","Changes zoom settings based on scroll."],"^F",true,"^7","~$quil.middlewares.navigation-2d/mouse-wheel","^A","out/quil/middlewares/navigation_2d.cljc","^E",19,"^R",["^M",[["^O","^16"]]],"^S",null,"^T",["^M",[null,null]],"^C",1,"^U",false,"^B",46,"^V","^I","^D",46,"^X",2,"^Y",true,"^L",["^M",["^N",["^M",[["^O","^16"]]]]],"^P","Changes zoom settings based on scroll."],"~$draw",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",52,"^C",8,"^D",52,"^E",12,"^F",true,"^L",["^M",["^N",["^M",[["~$user-draw","^O"]]]]],"^P","Calls user draw function with necessary all transformations (position\n and zoom) applied."],"^F",true,"^7","~$quil.middlewares.navigation-2d/draw","^A","out/quil/middlewares/navigation_2d.cljc","^E",12,"^R",["^M",[["^1;","^O"]]],"^S",null,"^T",["^M",[null,null]],"^C",1,"^U",false,"^B",52,"^V","^I","^D",52,"^X",2,"^Y",true,"^L",["^M",["^N",["^M",[["^1;","^O"]]]]],"^P","Calls user draw function with necessary all transformations (position\n and zoom) applied."],"~$navigation-2d",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_2d.cljc","^B",67,"^C",7,"^D",67,"^E",20,"^L",["^M",["^N",["^M",[["~$options"]]]]],"^P","Enables navigation over 2D sketch. Dragging mouse will move center of the\n skecth and mouse wheel controls zoom."],"^7","~$quil.middlewares.navigation-2d/navigation-2d","^A","out/quil/middlewares/navigation_2d.cljc","^E",20,"^R",["^M",[["^1>"]]],"^S",null,"^T",["^M",[null,null]],"^C",1,"^U",false,"^B",67,"^V","^I","^D",67,"^X",1,"^Y",true,"^L",["^M",["^N",["^M",[["^1>"]]]]],"^P","Enables navigation over 2D sketch. Dragging mouse will move center of the\n skecth and mouse wheel controls zoom."]],"~:cljs.spec/registry-ref",[],"~:require-macros",["^ ","~$q","^;","^;","^;"],"~:cljs.analyzer/constants",["^ ","~:seen",["^6",["~:y","~:p-y","~:zoom","~:mouse-wheel","~:setup","~:p-x","~:position","~:x","~:draw","~:navigation-2d","~:mouse-dragged"]],"~:order",["^1K","^1I","^1E","^1H","~:x","^1D","~:y","^1J","^1L","^1F","^1G"]],"^P",null] \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js
new file mode 100644
index 0000000..9403a91
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js
@@ -0,0 +1,116 @@
+// Compiled by ClojureScript 1.10.439 {}
+goog.provide('quil.middlewares.navigation_2d');
+goog.require('cljs.core');
+goog.require('quil.core');
+quil.middlewares.navigation_2d.missing_navigation_key_error = ["state map is missing :navigation-2d key. ","Did you accidentally removed it from the state in ",":update or any other handler?"].join('');
+/**
+ * Asserts that state map contains :navigation-2d object.
+ */
+quil.middlewares.navigation_2d.assert_state_has_navigation = (function quil$middlewares$navigation_2d$assert_state_has_navigation(state){
+if(cljs.core.truth_(new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(state))){
+return null;
+} else {
+throw (new Error(quil.middlewares.navigation_2d.missing_navigation_key_error));
+}
+});
+/**
+ * Default position configuration: zoom is neutral and central point is
+ * width/2, height/2.
+ */
+quil.middlewares.navigation_2d.default_position = (function quil$middlewares$navigation_2d$default_position(){
+return new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"position","position",-2011731912),new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(quil.core.width.call(null) / 2.0),(quil.core.height.call(null) / 2.0)], null),new cljs.core.Keyword(null,"zoom","zoom",-1827487038),(1)], null);
+});
+/**
+ * Custom 'setup' function which creates initial position
+ * configuration and puts it to the state map.
+ */
+quil.middlewares.navigation_2d.setup_2d_nav = (function quil$middlewares$navigation_2d$setup_2d_nav(user_setup,user_settings){
+var initial_state = cljs.core.merge.call(null,quil.middlewares.navigation_2d.default_position.call(null),cljs.core.select_keys.call(null,user_settings,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"position","position",-2011731912),new cljs.core.Keyword(null,"zoom","zoom",-1827487038)], null)));
+return cljs.core.update_in.call(null,user_setup.call(null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611)], null),((function (initial_state){
+return (function (p1__2126_SHARP_){
+return cljs.core.merge.call(null,initial_state,p1__2126_SHARP_);
+});})(initial_state))
+);
+});
+/**
+ * Changes center of the sketch depending on the last mouse move. Takes
+ * zoom into account as well.
+ */
+quil.middlewares.navigation_2d.mouse_dragged = (function quil$middlewares$navigation_2d$mouse_dragged(state,event){
+quil.middlewares.navigation_2d.assert_state_has_navigation.call(null,state);
+
+var dx = (new cljs.core.Keyword(null,"p-x","p-x",-1721211211).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"x","x",2099068185).cljs$core$IFn$_invoke$arity$1(event));
+var dy = (new cljs.core.Keyword(null,"p-y","p-y",-530704830).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"y","y",-1757859776).cljs$core$IFn$_invoke$arity$1(event));
+var zoom = new cljs.core.Keyword(null,"zoom","zoom",-1827487038).cljs$core$IFn$_invoke$arity$1(new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(state));
+return cljs.core.update_in.call(null,cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611),new cljs.core.Keyword(null,"position","position",-2011731912),(0)], null),cljs.core._PLUS_,(dx / zoom)),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611),new cljs.core.Keyword(null,"position","position",-2011731912),(1)], null),cljs.core._PLUS_,(dy / zoom));
+});
+/**
+ * Changes zoom settings based on scroll.
+ */
+quil.middlewares.navigation_2d.mouse_wheel = (function quil$middlewares$navigation_2d$mouse_wheel(state,event){
+quil.middlewares.navigation_2d.assert_state_has_navigation.call(null,state);
+
+return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611),new cljs.core.Keyword(null,"zoom","zoom",-1827487038)], null),cljs.core._STAR_,((1) + (-0.1 * event)));
+});
+/**
+ * Calls user draw function with necessary all transformations (position
+ * and zoom) applied.
+ */
+quil.middlewares.navigation_2d.draw = (function quil$middlewares$navigation_2d$draw(user_draw,state){
+quil.middlewares.navigation_2d.assert_state_has_navigation.call(null,state);
+
+quil.core.push_matrix.call(null);
+
+var nav_2d_2127 = new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(state);
+var zoom_2128 = new cljs.core.Keyword(null,"zoom","zoom",-1827487038).cljs$core$IFn$_invoke$arity$1(nav_2d_2127);
+var pos_2129 = new cljs.core.Keyword(null,"position","position",-2011731912).cljs$core$IFn$_invoke$arity$1(nav_2d_2127);
+quil.core.scale.call(null,zoom_2128);
+
+var tr__2049__auto___2130 = new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [(((quil.core.width.call(null) / (2)) / zoom_2128) - cljs.core.first.call(null,pos_2129)),(((quil.core.height.call(null) / (2)) / zoom_2128) - cljs.core.second.call(null,pos_2129))], null);
+quil.core.push_matrix.call(null);
+
+try{quil.core.translate.call(null,tr__2049__auto___2130);
+
+user_draw.call(null,state);
+}finally {quil.core.pop_matrix.call(null);
+}
+return quil.core.pop_matrix.call(null);
+});
+/**
+ * Enables navigation over 2D sketch. Dragging mouse will move center of the
+ * skecth and mouse wheel controls zoom.
+ */
+quil.middlewares.navigation_2d.navigation_2d = (function quil$middlewares$navigation_2d$navigation_2d(options){
+var user_settings = new cljs.core.Keyword(null,"navigation-2d","navigation-2d",-1924168611).cljs$core$IFn$_invoke$arity$1(options);
+var user_draw = new cljs.core.Keyword(null,"draw","draw",1358331674).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings){
+return (function (state){
+return null;
+});})(user_settings))
+);
+var user_mouse_dragged = new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,user_draw){
+return (function (state,_){
+return state;
+});})(user_settings,user_draw))
+);
+var user_mouse_wheel = new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,user_draw,user_mouse_dragged){
+return (function (state,_){
+return state;
+});})(user_settings,user_draw,user_mouse_dragged))
+);
+var setup = new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,user_draw,user_mouse_dragged,user_mouse_wheel){
+return (function (){
+return cljs.core.PersistentArrayMap.EMPTY;
+});})(user_settings,user_draw,user_mouse_dragged,user_mouse_wheel))
+);
+return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"setup","setup",1987730512),cljs.core.partial.call(null,quil.middlewares.navigation_2d.setup_2d_nav,setup,user_settings),new cljs.core.Keyword(null,"draw","draw",1358331674),cljs.core.partial.call(null,quil.middlewares.navigation_2d.draw,user_draw),new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441),((function (user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup){
+return (function (state,event){
+return user_mouse_dragged.call(null,quil.middlewares.navigation_2d.mouse_dragged.call(null,state,event),event);
+});})(user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup))
+,new cljs.core.Keyword(null,"mouse-wheel","mouse-wheel",1811662439),((function (user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup){
+return (function (state,event){
+return user_mouse_wheel.call(null,quil.middlewares.navigation_2d.mouse_wheel.call(null,state,event),event);
+});})(user_settings,user_draw,user_mouse_dragged,user_mouse_wheel,setup))
+);
+});
+
+//# sourceMappingURL=navigation_2d.js.map
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js.map b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js.map
new file mode 100644
index 0000000..34afb3c
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_2d.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/navigation_2d.js","sources":["navigation_2d.cljc"],"lineCount":116,"mappings":";AAAA;;;AAGA,AAAeA,8DACb,CAAA,4CAAA,qDAAA;AAIF;;;6DAAA,7DAAOC,kIAEJ;AAFH,AAGE,oBAAU,AAAA,sGAAgBC;AAA1B;;AAAA,AACE,MACgB,KAAAC,MAAWH;;;AAE\/B;;;;kDAAA,lDAAOI;AAAP,AAAA,kDAAA,8DAAA,kKAAA,sDAAA,rIAIc,8BAAA,7BAAG,AAACC,kCACJ,+BAAA,9BAAG,AAACC;;AAGlB;;;;8CAAA,9CAAOC,oGAGJ,WAAW;AAHd,AAIE,IAAM,qIAAkBC,hCACA,8CAAA,mFAAA,8DAAA,\/LAACC,rFACI,AAACC,0BAAM,AAACN;AAFrC,AAGE,2DAAA,mFAAA,gFAAA,vNAACO,8BAAU,AAACC;kBAAZ;AAAA,AACY,+CAAAC,xCAACH,0BAAMI;;;;AAEvB;;;;+CAAA,\/CAAOC,sGAGJ,MAAM;AAHT,AAIE,AAACd,qEAA4BC;;AAC7B,IAAM,KAAG,CAAG,AAAA,kFAAMc,SAAO,AAAA,6EAAIA;IACvB,KAAG,CAAG,AAAA,iFAAMA,SAAO,AAAA,8EAAIA;IACvB,OAAK,AAAA,oFAAA,AAAA,sGAAId;AAFf,mEAGKA,9BACA,oCAAA,mFAAA,wEAAA,8DAAA,7PAACS,yQAAuCM,iBAAE,CAAGC,KAAGC,rUAChD,4UAAA,mFAAA,wEAAA,8DAAA,9hBAACR,0iBAAuCM,iBAAE,CAAGG,KAAGD;;AAEvD;;;6CAAA,7CAAOE,kGAEJ,MAAM;AAFT,AAGE,AAACpB,qEAA4BC;;AAC7B,2CAAA,mFAAA,wEAAA,\/LAACS,8BAAUT,+NAA6BoB,iBAAE,CAAA,MAAK,CAAA,OAAQN;;AAEzD;;;;sCAAA,tCAAOO,oFAGJ,UAAU;AAHb,AAIE,AAACtB,qEAA4BC;;AAC7B,AAACsB;;AACD,IAAM,cAAO,AAAA,sGAAgBtB;IACvB,YAAK,AAAA,oFAAOuB;IACZ,WAAI,AAAA,4FAAWA;AAFrB,AAGE,AAACC,0BAAQP;;AACT,IAAA,wBAAA,mFAAqB,CAAG,CAAA,8BAAA,7BAAG,AAACd,oCAAWc,aAAM,AAACW,0BAAMC,WAC\/B,CAAG,CAAA,+BAAA,9BAAG,AAACzB,qCAAYa,aAAM,AAACa,2BAAOD;AADtD,AAAA,AAAAP;;AAAA,IAAA,AAAA,AAAAG,8BAAAC;;AAEE,AAACK,oBAAU\/B;UAFb,AAAA,AAAA2B;;AAGF,OAACA;;AAEH;;;;+CAAA,\/CAAMK,sGAGH;AAHH,AAIE,IACM,gBAAc,AAAA,sGAAgBC;IAI9B,YAAU,AAAA,mFAAOA,QAAQ;kBAAK;AAAL,AAAA;;;IACzB,qBAAmB,AAAA,sGAAgBA,QAAQ;kBAAK,MAAM;AAAX,AAAcjC;;;IACzD,mBAAiB,AAAA,iGAAciC,QAAQ;kBAAK,MAAM;AAAX,AAAcjC;;;IACrD,QAAM,AAAA,qFAAQiC,QAAQ;;AAAA,AAAA;;;AAR5B,AASE,yCAAA,oJAAA,gIAAA,tTAACC,0BAAMD,+DAEE,AAACE,4BAAQ9B,4CAAa+B,MAAM9B,oEAE7B,AAAC6B,4BAAQd,oCAAKU,mFAEL;kBAAK,MAAM;AAAX,AACE,OAACM,6BAAmB,AAACxB,uDAAcb,MAAMc,OAAOA;;CAPnE,mEAQe;kBAAK,MAAM;AAAX,AACE,OAACwB,2BAAiB,AAACnB,qDAAYnB,MAAMc,OAAOA","names":["quil.middlewares.navigation-2d\/missing-navigation-key-error","quil.middlewares.navigation-2d\/assert-state-has-navigation","state","js\/Error","quil.middlewares.navigation-2d\/default-position","quil.core\/width","quil.core\/height","quil.middlewares.navigation-2d\/setup-2d-nav","user-settings","cljs.core\/select-keys","cljs.core\/merge","cljs.core\/update-in","user-setup","p1__2126#","initial-state","quil.middlewares.navigation-2d\/mouse-dragged","event","cljs.core\/+","dx","zoom","dy","quil.middlewares.navigation-2d\/mouse-wheel","cljs.core\/*","quil.middlewares.navigation-2d\/draw","quil.core\/push-matrix","nav-2d","quil.core\/scale","quil.core\/translate","tr__2049__auto__","quil.core\/pop-matrix","cljs.core\/first","pos","cljs.core\/second","user-draw","quil.middlewares.navigation-2d\/navigation-2d","options","cljs.core\/assoc","cljs.core\/partial","setup","user-mouse-dragged","user-mouse-wheel"]} \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc
new file mode 100644
index 0000000..3471cfd
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc
@@ -0,0 +1,188 @@
+(ns quil.middlewares.navigation-3d
+ (:require [quil.core :as q]))
+
+(def ^:private missing-navigation-key-error
+ (str "state map is missing :navigation-3d key. "
+ "Did you accidentally removed it from the state in "
+ ":update or any other handler?"))
+
+(defn- assert-state-has-navigation
+ "Asserts that state map contains :navigation-2d object."
+ [state]
+ (when-not (:navigation-3d state)
+ (throw #?(:clj (RuntimeException. missing-navigation-key-error)
+ :cljs (js/Error. missing-navigation-key-error)))))
+
+(defn- default-position
+ "Default position configuration. Check default configuration in
+ 'camera' function."
+ []
+ {:position [(/ (q/width) 2.0)
+ (/ (q/height) 2.0)
+ (/ (q/height) 2.0 (q/tan (/ (* q/PI 60.0) 360.0)))]
+ :straight [0 0 -1]
+ :up [0 1 0]})
+
+(defn- rotate-by-axis-and-angle
+ "Rotates vector v by angle with axis.
+ Formula is taken from wiki:
+ http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle"
+ [v axis angle]
+ (let [[a-x a-y a-z] axis
+ [x y z] v
+ cs (q/cos angle)
+ -cs (- 1 cs)
+ sn (q/sin angle)
+ ; Matrix is
+ ; [a b c]
+ ; [d e f]
+ ; [g h i]
+ a (+ cs (* a-x a-x -cs))
+ b (- (* a-x a-y -cs)
+ (* a-z sn))
+ c (+ (* a-x a-z -cs)
+ (* a-y sn))
+ d (+ (* a-x a-y -cs)
+ (* a-z sn))
+ e (+ cs (* a-y a-y -cs))
+ f (- (* a-y a-z -cs)
+ (* a-x sn))
+ g (- (* a-x a-z -cs)
+ (* a-y sn))
+ h (+ (* a-y a-z -cs)
+ (* a-x sn))
+ i (+ cs (* a-z a-z -cs))]
+ [(+ (* a x) (* b y) (* c z))
+ (+ (* d x) (* e y) (* f z))
+ (+ (* g x) (* h y) (* i z))]))
+
+(defn- rotate-lr
+ "Rotates nav-3d configuration left-right. angle positive - rotate right,
+ negative - left."
+ [nav-3d angle]
+ (update-in nav-3d [:straight] rotate-by-axis-and-angle (:up nav-3d) angle))
+
+(defn- cross-product
+ "Vector cross-product: http://en.wikipedia.org/wiki/Cross_product"
+ [[u1 u2 u3] [v1 v2 v3]]
+ [(- (* u2 v3) (* u3 v2))
+ (- (* u3 v1) (* u1 v3))
+ (- (* u1 v2) (* u2 v1))])
+
+(defn- v-mult
+ "Multiply vector v by scalar mult."
+ [v mult]
+ (mapv #(* % mult) v))
+
+(defn- v-plus
+ "Sum of 2 vectors."
+ [v1 v2]
+ (mapv + v1 v2))
+
+(defn- v-opposite
+ "Returns vector opposite to vector v."
+ [v]
+ (v-mult v -1))
+
+(defn- v-normalize
+ "Normalize vector, returning vector
+ which has same direction but with norm equals to 1."
+ [v]
+ (let [norm (->> (map q/sq v)
+ (apply +)
+ (q/sqrt))]
+ (v-mult v (/ norm))))
+
+(defn- rotate-ud
+ "Rotates nav-3d configuration up-down."
+ [nav-3d angle]
+ (let [axis (cross-product (:straight nav-3d) (:up nav-3d))
+ rotate #(rotate-by-axis-and-angle % axis angle)]
+ (-> nav-3d
+ (update-in [:straight] rotate)
+ (update-in [:up] rotate))))
+
+(defn- rotate
+ "Mouse handler function which rotates nav-3d configuration.
+ It uses mouse from event object and pixels-in-360 to calculate
+ angles to rotate."
+ [state event pixels-in-360]
+ (assert-state-has-navigation state)
+ (if (= 0 (:p-x event) (:p-y event))
+ state
+ (let [dx (- (:p-x event) (:x event))
+ dy (- (:y event) (:p-y event))
+ angle-lr (q/map-range dx 0 pixels-in-360 0 q/TWO-PI)
+ angle-ud (q/map-range dy 0 pixels-in-360 0 q/TWO-PI)]
+ (update-in state [:navigation-3d]
+ #(-> %
+ (rotate-lr angle-lr)
+ (rotate-ud angle-ud))))))
+
+(def ^:private space (keyword " "))
+
+(defn- move
+ "Keyboard handler function which moves nav-3d configuration.
+ It uses keyboard key from event object to determing in which
+ direction to move."
+ [state event step-size]
+ (assert-state-has-navigation state)
+ (let [{:keys [up straight]} (:navigation-3d state)]
+ (if-let [dir (condp = (:key event)
+ :w straight
+ :s (v-opposite straight)
+ space (v-opposite up)
+ :z up
+ :d (cross-product straight up)
+ :a (cross-product up straight)
+ nil)]
+ (update-in state [:navigation-3d :position]
+ #(v-plus % (v-mult dir step-size)))
+ state)))
+
+(defn- setup-3d-nav
+ "Custom 'setup' function which creates initial position
+ configuration and puts it to the state map."
+ [user-setup user-settings]
+ (let [initial-state (-> user-settings
+ (select-keys [:straight :up :position])
+ (->> (merge (default-position)))
+ (update-in [:straight] v-normalize)
+ (update-in [:up] v-normalize))]
+ (update-in (user-setup) [:navigation-3d]
+ #(merge initial-state %))))
+
+(defn navigation-3d
+ "Enables navigation in 3D space. Similar to how it is done in
+ shooters: WASD navigation, space is go up, z is go down,
+ drag mouse to look around."
+ [options]
+ (let [; 3d-navigation related user settings
+ user-settings (:navigation-3d options)
+ pixels-in-360 (:pixels-in-360 user-settings 1000)
+ step-size (:step-size user-settings 20)
+ rotate-on (:rotate-on user-settings :mouse-dragged)
+
+ ; user-provided handlers which will be overridden
+ ; by 3d-navigation
+ draw (:draw options (fn [state]))
+ key-pressed (:key-pressed options (fn [state _] state))
+ rotate-on-fn (rotate-on options (fn [state _] state))
+ setup (:setup options (fn [] {}))]
+ (assoc options
+
+ :setup (partial setup-3d-nav setup user-settings)
+
+ :draw (fn [state]
+ (assert-state-has-navigation state)
+ (let [{[c-x c-y c-z] :straight
+ [u-x u-y u-z] :up
+ [p-x p-y p-z] :position} (:navigation-3d state)]
+ (q/camera p-x p-y p-z (+ p-x c-x) (+ p-y c-y) (+ p-z c-z) u-x u-y u-z))
+ (draw state))
+
+ :key-pressed (fn [state event]
+ (key-pressed (move state event step-size) event))
+
+ rotate-on (fn [state event]
+ (rotate-on-fn (rotate state event pixels-in-360) event)) )))
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc.cache.json b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc.cache.json
new file mode 100644
index 0000000..2edb582
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.cljc.cache.json
@@ -0,0 +1 @@
+["^ ","~:rename-macros",["^ "],"~:renames",["^ "],"~:externs",["^ ","~$Error",["^ "]],"~:use-macros",["^ "],"~:excludes",["~#set",[]],"~:name","~$quil.middlewares.navigation-3d","~:imports",null,"~:requires",["^ ","~$q","~$quil.core","^;","^;"],"~:cljs.spec/speced-vars",[],"~:uses",null,"~:defs",["^ ","~$missing-navigation-key-error",["^ ","^7","~$quil.middlewares.navigation-3d/missing-navigation-key-error","~:file","out/quil/middlewares/navigation_3d.cljc","~:line",4,"~:column",1,"~:end-line",4,"~:end-column",44,"~:private",true,"~:meta",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",4,"^C",16,"^D",4,"^E",44,"^F",true],"~:tag","~$any"],"~$v-normalize",["^ ","~:protocol-inline",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",87,"^C",8,"^D",87,"^E",19,"^F",true,"~:arglists",["~#list",["~$quote",["^M",[["~$v"]]]]],"~:doc","Normalize vector, returning vector\n which has same direction but with norm equals to 1."],"^F",true,"^7","~$quil.middlewares.navigation-3d/v-normalize","^A","out/quil/middlewares/navigation_3d.cljc","^E",19,"~:method-params",["^M",[["~$v"]]],"~:protocol-impl",null,"~:arglists-meta",["^M",[null,null]],"^C",1,"~:variadic?",false,"^B",87,"~:ret-tag","^I","^D",87,"~:max-fixed-arity",1,"~:fn-var",true,"^L",["^M",["^N",["^M",[["~$v"]]]]],"^O","Normalize vector, returning vector\n which has same direction but with norm equals to 1."],"~$v-opposite",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",82,"^C",8,"^D",82,"^E",18,"^F",true,"^L",["^M",["^N",["^M",[["~$v"]]]]],"^O","Returns vector opposite to vector v."],"^F",true,"^7","~$quil.middlewares.navigation-3d/v-opposite","^A","out/quil/middlewares/navigation_3d.cljc","^E",18,"^Q",["^M",[["~$v"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",82,"^U","^I","^D",82,"^V",1,"^W",true,"^L",["^M",["^N",["^M",[["~$v"]]]]],"^O","Returns vector opposite to vector v."],"~$v-plus",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",77,"^C",8,"^D",77,"^E",14,"^F",true,"^L",["^M",["^N",["^M",[["~$v1","~$v2"]]]]],"^O","Sum of 2 vectors."],"^F",true,"^7","~$quil.middlewares.navigation-3d/v-plus","^A","out/quil/middlewares/navigation_3d.cljc","^E",14,"^Q",["^M",[["^[","^10"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",77,"^U","^I","^D",77,"^V",2,"^W",true,"^L",["^M",["^N",["^M",[["^[","^10"]]]]],"^O","Sum of 2 vectors."],"~$v-mult",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",72,"^C",8,"^D",72,"^E",14,"^F",true,"^L",["^M",["^N",["^M",[["~$v","~$mult"]]]]],"^O","Multiply vector v by scalar mult."],"^F",true,"^7","~$quil.middlewares.navigation-3d/v-mult","^A","out/quil/middlewares/navigation_3d.cljc","^E",14,"^Q",["^M",[["~$v","^13"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",72,"^U","^I","^D",72,"^V",2,"^W",true,"^L",["^M",["^N",["^M",[["~$v","^13"]]]]],"^O","Multiply vector v by scalar mult."],"~$space",["^ ","^7","~$quil.middlewares.navigation-3d/space","^A","out/quil/middlewares/navigation_3d.cljc","^B",122,"^C",1,"^D",122,"^E",21,"^F",true,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",122,"^C",16,"^D",122,"^E",21,"^F",true],"^H","^I"],"~$setup-3d-nav",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",143,"^C",8,"^D",143,"^E",20,"^F",true,"^L",["^M",["^N",["^M",[["~$user-setup","~$user-settings"]]]]],"^O","Custom 'setup' function which creates initial position\n configuration and puts it to the state map."],"^F",true,"^7","~$quil.middlewares.navigation-3d/setup-3d-nav","^A","out/quil/middlewares/navigation_3d.cljc","^E",20,"^Q",["^M",[["^18","^19"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",143,"^U","^I","^D",143,"^V",2,"^W",true,"^L",["^M",["^N",["^M",[["^18","^19"]]]]],"^O","Custom 'setup' function which creates initial position\n configuration and puts it to the state map."],"~$move",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",124,"^C",8,"^D",124,"^E",12,"^F",true,"^L",["^M",["^N",["^M",[["~$state","~$event","~$step-size"]]]]],"^O","Keyboard handler function which moves nav-3d configuration.\n It uses keyboard key from event object to determing in which\n direction to move."],"^F",true,"^7","~$quil.middlewares.navigation-3d/move","^A","out/quil/middlewares/navigation_3d.cljc","^E",12,"^Q",["^M",[["^1<","^1=","^1>"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",124,"^U",["^6",[null,"^I"]],"^D",124,"^V",3,"^W",true,"^L",["^M",["^N",["^M",[["^1<","^1=","^1>"]]]]],"^O","Keyboard handler function which moves nav-3d configuration.\n It uses keyboard key from event object to determing in which\n direction to move."],"~$rotate-lr",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",59,"^C",8,"^D",59,"^E",17,"^F",true,"^L",["^M",["^N",["^M",[["~$nav-3d","~$angle"]]]]],"^O","Rotates nav-3d configuration left-right. angle positive - rotate right,\n negative - left."],"^F",true,"^7","~$quil.middlewares.navigation-3d/rotate-lr","^A","out/quil/middlewares/navigation_3d.cljc","^E",17,"^Q",["^M",[["^1A","^1B"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",59,"^U","^I","^D",59,"^V",2,"^W",true,"^L",["^M",["^N",["^M",[["^1A","^1B"]]]]],"^O","Rotates nav-3d configuration left-right. angle positive - rotate right,\n negative - left."],"~$cross-product",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",65,"^C",8,"^D",65,"^E",21,"^F",true,"^L",["^M",["^N",["^M",[[["~$u1","~$u2","~$u3"],["^[","^10","~$v3"]]]]]],"^O","Vector cross-product: http://en.wikipedia.org/wiki/Cross_product"],"^F",true,"^7","~$quil.middlewares.navigation-3d/cross-product","^A","out/quil/middlewares/navigation_3d.cljc","^E",21,"^Q",["^M",[["~$p__1626","~$p__1627"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",65,"^U","~$cljs.core/IVector","^D",65,"^V",2,"^W",true,"^L",["^M",["^N",["^M",[[["^1E","^1F","^1G"],["^[","^10","^1H"]]]]]],"^O","Vector cross-product: http://en.wikipedia.org/wiki/Cross_product"],"~$rotate-by-axis-and-angle",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",26,"^C",8,"^D",26,"^E",32,"^F",true,"^L",["^M",["^N",["^M",[["~$v","~$axis","^1B"]]]]],"^O","Rotates vector v by angle with axis.\n Formula is taken from wiki:\n http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle"],"^F",true,"^7","~$quil.middlewares.navigation-3d/rotate-by-axis-and-angle","^A","out/quil/middlewares/navigation_3d.cljc","^E",32,"^Q",["^M",[["~$v","^1N","^1B"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",26,"^U","^1L","^D",26,"^V",3,"^W",true,"^L",["^M",["^N",["^M",[["~$v","^1N","^1B"]]]]],"^O","Rotates vector v by angle with axis.\n Formula is taken from wiki:\n http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle"],"~$assert-state-has-navigation",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",9,"^C",8,"^D",9,"^E",35,"^F",true,"^L",["^M",["^N",["^M",[["^1<"]]]]],"^O","Asserts that state map contains :navigation-2d object."],"^F",true,"^7","~$quil.middlewares.navigation-3d/assert-state-has-navigation","^A","out/quil/middlewares/navigation_3d.cljc","^E",35,"^Q",["^M",[["^1<"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",9,"^U","~$clj-nil","^D",9,"^V",1,"^W",true,"^L",["^M",["^N",["^M",[["^1<"]]]]],"^O","Asserts that state map contains :navigation-2d object."],"~$navigation-3d",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",155,"^C",7,"^D",155,"^E",20,"^L",["^M",["^N",["^M",[["~$options"]]]]],"^O","Enables navigation in 3D space. Similar to how it is done in\n shooters: WASD navigation, space is go up, z is go down,\n drag mouse to look around."],"^7","~$quil.middlewares.navigation-3d/navigation-3d","^A","out/quil/middlewares/navigation_3d.cljc","^E",20,"^Q",["^M",[["^1T"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",155,"^U","^I","^D",155,"^V",1,"^W",true,"^L",["^M",["^N",["^M",[["^1T"]]]]],"^O","Enables navigation in 3D space. Similar to how it is done in\n shooters: WASD navigation, space is go up, z is go down,\n drag mouse to look around."],"~$default-position",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",16,"^C",8,"^D",16,"^E",24,"^F",true,"^L",["^M",["^N",["^M",[[]]]]],"^O","Default position configuration. Check default configuration in\n 'camera' function."],"^F",true,"^7","~$quil.middlewares.navigation-3d/default-position","^A","out/quil/middlewares/navigation_3d.cljc","^E",24,"^Q",["^M",[[]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",16,"^U","~$cljs.core/IMap","^D",16,"^V",0,"^W",true,"^L",["^M",["^N",["^M",[[]]]]],"^O","Default position configuration. Check default configuration in\n 'camera' function."],"~$rotate",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",105,"^C",8,"^D",105,"^E",14,"^F",true,"^L",["^M",["^N",["^M",[["^1<","^1=","~$pixels-in-360"]]]]],"^O","Mouse handler function which rotates nav-3d configuration.\n It uses mouse from event object and pixels-in-360 to calculate\n angles to rotate."],"^F",true,"^7","~$quil.middlewares.navigation-3d/rotate","^A","out/quil/middlewares/navigation_3d.cljc","^E",14,"^Q",["^M",[["^1<","^1=","^1Z"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",105,"^U",["^6",[null,"^I"]],"^D",105,"^V",3,"^W",true,"^L",["^M",["^N",["^M",[["^1<","^1=","^1Z"]]]]],"^O","Mouse handler function which rotates nav-3d configuration.\n It uses mouse from event object and pixels-in-360 to calculate\n angles to rotate."],"~$rotate-ud",["^ ","^K",null,"^G",["^ ","^A","/home/mediocregopher/src/viz/out/quil/middlewares/navigation_3d.cljc","^B",96,"^C",8,"^D",96,"^E",17,"^F",true,"^L",["^M",["^N",["^M",[["^1A","^1B"]]]]],"^O","Rotates nav-3d configuration up-down."],"^F",true,"^7","~$quil.middlewares.navigation-3d/rotate-ud","^A","out/quil/middlewares/navigation_3d.cljc","^E",17,"^Q",["^M",[["^1A","^1B"]]],"^R",null,"^S",["^M",[null,null]],"^C",1,"^T",false,"^B",96,"^U","^I","^D",96,"^V",2,"^W",true,"^L",["^M",["^N",["^M",[["^1A","^1B"]]]]],"^O","Rotates nav-3d configuration up-down."]],"~:cljs.spec/registry-ref",[],"~:require-macros",null,"~:cljs.analyzer/constants",["^ ","~:seen",["^6",["~:y","~:pixels-in-360","~:p-y","~:step-size","~:key","~:w","~:s","~:rotate-on","~:up","~:setup","~:z","~:straight","~:key-pressed","~:p-x","~:navigation-3d","~:position","~:d","~:x","~:draw","~:a","~:mouse-dragged"]],"~:order",["^2@","^2A","^2=","^2;","^2?","^27","~:x","~:y","^29","~:w","~:s","~:z","~:d","~:a","^26","^28","^2:","^2C","^2B","^2>","^2<"]],"^O",null] \ No newline at end of file
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js
new file mode 100644
index 0000000..d80d58a
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js
@@ -0,0 +1,261 @@
+// Compiled by ClojureScript 1.10.439 {}
+goog.provide('quil.middlewares.navigation_3d');
+goog.require('cljs.core');
+goog.require('quil.core');
+quil.middlewares.navigation_3d.missing_navigation_key_error = ["state map is missing :navigation-3d key. ","Did you accidentally removed it from the state in ",":update or any other handler?"].join('');
+/**
+ * Asserts that state map contains :navigation-2d object.
+ */
+quil.middlewares.navigation_3d.assert_state_has_navigation = (function quil$middlewares$navigation_3d$assert_state_has_navigation(state){
+if(cljs.core.truth_(new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(state))){
+return null;
+} else {
+throw (new Error(quil.middlewares.navigation_3d.missing_navigation_key_error));
+}
+});
+/**
+ * Default position configuration. Check default configuration in
+ * 'camera' function.
+ */
+quil.middlewares.navigation_3d.default_position = (function quil$middlewares$navigation_3d$default_position(){
+return new cljs.core.PersistentArrayMap(null, 3, [new cljs.core.Keyword(null,"position","position",-2011731912),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(quil.core.width.call(null) / 2.0),(quil.core.height.call(null) / 2.0),((quil.core.height.call(null) / 2.0) / quil.core.tan.call(null,((quil.core.PI * 60.0) / 360.0)))], null),new cljs.core.Keyword(null,"straight","straight",-1252567854),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(0),(-1)], null),new cljs.core.Keyword(null,"up","up",-269712113),new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(0),(1),(0)], null)], null);
+});
+/**
+ * Rotates vector v by angle with axis.
+ * Formula is taken from wiki:
+ * http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
+ */
+quil.middlewares.navigation_3d.rotate_by_axis_and_angle = (function quil$middlewares$navigation_3d$rotate_by_axis_and_angle(v,axis,angle){
+var vec__1620 = axis;
+var a_x = cljs.core.nth.call(null,vec__1620,(0),null);
+var a_y = cljs.core.nth.call(null,vec__1620,(1),null);
+var a_z = cljs.core.nth.call(null,vec__1620,(2),null);
+var vec__1623 = v;
+var x = cljs.core.nth.call(null,vec__1623,(0),null);
+var y = cljs.core.nth.call(null,vec__1623,(1),null);
+var z = cljs.core.nth.call(null,vec__1623,(2),null);
+var cs = quil.core.cos.call(null,angle);
+var _cs = ((1) - cs);
+var sn = quil.core.sin.call(null,angle);
+var a = (cs + ((a_x * a_x) * _cs));
+var b = (((a_x * a_y) * _cs) - (a_z * sn));
+var c = (((a_x * a_z) * _cs) + (a_y * sn));
+var d = (((a_x * a_y) * _cs) + (a_z * sn));
+var e = (cs + ((a_y * a_y) * _cs));
+var f = (((a_y * a_z) * _cs) - (a_x * sn));
+var g = (((a_x * a_z) * _cs) - (a_y * sn));
+var h = (((a_y * a_z) * _cs) + (a_x * sn));
+var i = (cs + ((a_z * a_z) * _cs));
+return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [(((a * x) + (b * y)) + (c * z)),(((d * x) + (e * y)) + (f * z)),(((g * x) + (h * y)) + (i * z))], null);
+});
+/**
+ * Rotates nav-3d configuration left-right. angle positive - rotate right,
+ * negative - left.
+ */
+quil.middlewares.navigation_3d.rotate_lr = (function quil$middlewares$navigation_3d$rotate_lr(nav_3d,angle){
+return cljs.core.update_in.call(null,nav_3d,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854)], null),quil.middlewares.navigation_3d.rotate_by_axis_and_angle,new cljs.core.Keyword(null,"up","up",-269712113).cljs$core$IFn$_invoke$arity$1(nav_3d),angle);
+});
+/**
+ * Vector cross-product: http://en.wikipedia.org/wiki/Cross_product
+ */
+quil.middlewares.navigation_3d.cross_product = (function quil$middlewares$navigation_3d$cross_product(p__1626,p__1627){
+var vec__1628 = p__1626;
+var u1 = cljs.core.nth.call(null,vec__1628,(0),null);
+var u2 = cljs.core.nth.call(null,vec__1628,(1),null);
+var u3 = cljs.core.nth.call(null,vec__1628,(2),null);
+var vec__1631 = p__1627;
+var v1 = cljs.core.nth.call(null,vec__1631,(0),null);
+var v2 = cljs.core.nth.call(null,vec__1631,(1),null);
+var v3 = cljs.core.nth.call(null,vec__1631,(2),null);
+return new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [((u2 * v3) - (u3 * v2)),((u3 * v1) - (u1 * v3)),((u1 * v2) - (u2 * v1))], null);
+});
+/**
+ * Multiply vector v by scalar mult.
+ */
+quil.middlewares.navigation_3d.v_mult = (function quil$middlewares$navigation_3d$v_mult(v,mult){
+return cljs.core.mapv.call(null,(function (p1__1634_SHARP_){
+return (p1__1634_SHARP_ * mult);
+}),v);
+});
+/**
+ * Sum of 2 vectors.
+ */
+quil.middlewares.navigation_3d.v_plus = (function quil$middlewares$navigation_3d$v_plus(v1,v2){
+return cljs.core.mapv.call(null,cljs.core._PLUS_,v1,v2);
+});
+/**
+ * Returns vector opposite to vector v.
+ */
+quil.middlewares.navigation_3d.v_opposite = (function quil$middlewares$navigation_3d$v_opposite(v){
+return quil.middlewares.navigation_3d.v_mult.call(null,v,(-1));
+});
+/**
+ * Normalize vector, returning vector
+ * which has same direction but with norm equals to 1.
+ */
+quil.middlewares.navigation_3d.v_normalize = (function quil$middlewares$navigation_3d$v_normalize(v){
+var norm = quil.core.sqrt.call(null,cljs.core.apply.call(null,cljs.core._PLUS_,cljs.core.map.call(null,quil.core.sq,v)));
+return quil.middlewares.navigation_3d.v_mult.call(null,v,((1) / norm));
+});
+/**
+ * Rotates nav-3d configuration up-down.
+ */
+quil.middlewares.navigation_3d.rotate_ud = (function quil$middlewares$navigation_3d$rotate_ud(nav_3d,angle){
+var axis = quil.middlewares.navigation_3d.cross_product.call(null,new cljs.core.Keyword(null,"straight","straight",-1252567854).cljs$core$IFn$_invoke$arity$1(nav_3d),new cljs.core.Keyword(null,"up","up",-269712113).cljs$core$IFn$_invoke$arity$1(nav_3d));
+var rotate = ((function (axis){
+return (function (p1__1635_SHARP_){
+return quil.middlewares.navigation_3d.rotate_by_axis_and_angle.call(null,p1__1635_SHARP_,axis,angle);
+});})(axis))
+;
+return cljs.core.update_in.call(null,cljs.core.update_in.call(null,nav_3d,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854)], null),rotate),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"up","up",-269712113)], null),rotate);
+});
+/**
+ * Mouse handler function which rotates nav-3d configuration.
+ * It uses mouse from event object and pixels-in-360 to calculate
+ * angles to rotate.
+ */
+quil.middlewares.navigation_3d.rotate = (function quil$middlewares$navigation_3d$rotate(state,event,pixels_in_360){
+quil.middlewares.navigation_3d.assert_state_has_navigation.call(null,state);
+
+if(cljs.core._EQ_.call(null,(0),new cljs.core.Keyword(null,"p-x","p-x",-1721211211).cljs$core$IFn$_invoke$arity$1(event),new cljs.core.Keyword(null,"p-y","p-y",-530704830).cljs$core$IFn$_invoke$arity$1(event))){
+return state;
+} else {
+var dx = (new cljs.core.Keyword(null,"p-x","p-x",-1721211211).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"x","x",2099068185).cljs$core$IFn$_invoke$arity$1(event));
+var dy = (new cljs.core.Keyword(null,"y","y",-1757859776).cljs$core$IFn$_invoke$arity$1(event) - new cljs.core.Keyword(null,"p-y","p-y",-530704830).cljs$core$IFn$_invoke$arity$1(event));
+var angle_lr = quil.core.map_range.call(null,dx,(0),pixels_in_360,(0),quil.core.TWO_PI);
+var angle_ud = quil.core.map_range.call(null,dy,(0),pixels_in_360,(0),quil.core.TWO_PI);
+return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301)], null),((function (dx,dy,angle_lr,angle_ud){
+return (function (p1__1636_SHARP_){
+return quil.middlewares.navigation_3d.rotate_ud.call(null,quil.middlewares.navigation_3d.rotate_lr.call(null,p1__1636_SHARP_,angle_lr),angle_ud);
+});})(dx,dy,angle_lr,angle_ud))
+);
+}
+});
+quil.middlewares.navigation_3d.space = cljs.core.keyword.call(null," ");
+/**
+ * Keyboard handler function which moves nav-3d configuration.
+ * It uses keyboard key from event object to determing in which
+ * direction to move.
+ */
+quil.middlewares.navigation_3d.move = (function quil$middlewares$navigation_3d$move(state,event,step_size){
+quil.middlewares.navigation_3d.assert_state_has_navigation.call(null,state);
+
+var map__1638 = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(state);
+var map__1638__$1 = (((((!((map__1638 == null))))?(((((map__1638.cljs$lang$protocol_mask$partition0$ & (64))) || ((cljs.core.PROTOCOL_SENTINEL === map__1638.cljs$core$ISeq$))))?true:false):false))?cljs.core.apply.call(null,cljs.core.hash_map,map__1638):map__1638);
+var up = cljs.core.get.call(null,map__1638__$1,new cljs.core.Keyword(null,"up","up",-269712113));
+var straight = cljs.core.get.call(null,map__1638__$1,new cljs.core.Keyword(null,"straight","straight",-1252567854));
+var temp__4655__auto__ = (function (){var pred__1640 = cljs.core._EQ_;
+var expr__1641 = new cljs.core.Keyword(null,"key","key",-1516042587).cljs$core$IFn$_invoke$arity$1(event);
+if(cljs.core.truth_(pred__1640.call(null,new cljs.core.Keyword(null,"w","w",354169001),expr__1641))){
+return straight;
+} else {
+if(cljs.core.truth_(pred__1640.call(null,new cljs.core.Keyword(null,"s","s",1705939918),expr__1641))){
+return quil.middlewares.navigation_3d.v_opposite.call(null,straight);
+} else {
+if(cljs.core.truth_(pred__1640.call(null,quil.middlewares.navigation_3d.space,expr__1641))){
+return quil.middlewares.navigation_3d.v_opposite.call(null,up);
+} else {
+if(cljs.core.truth_(pred__1640.call(null,new cljs.core.Keyword(null,"z","z",-789527183),expr__1641))){
+return up;
+} else {
+if(cljs.core.truth_(pred__1640.call(null,new cljs.core.Keyword(null,"d","d",1972142424),expr__1641))){
+return quil.middlewares.navigation_3d.cross_product.call(null,straight,up);
+} else {
+if(cljs.core.truth_(pred__1640.call(null,new cljs.core.Keyword(null,"a","a",-2123407586),expr__1641))){
+return quil.middlewares.navigation_3d.cross_product.call(null,up,straight);
+} else {
+return null;
+}
+}
+}
+}
+}
+}
+})();
+if(cljs.core.truth_(temp__4655__auto__)){
+var dir = temp__4655__auto__;
+return cljs.core.update_in.call(null,state,new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301),new cljs.core.Keyword(null,"position","position",-2011731912)], null),((function (dir,temp__4655__auto__,map__1638,map__1638__$1,up,straight){
+return (function (p1__1637_SHARP_){
+return quil.middlewares.navigation_3d.v_plus.call(null,p1__1637_SHARP_,quil.middlewares.navigation_3d.v_mult.call(null,dir,step_size));
+});})(dir,temp__4655__auto__,map__1638,map__1638__$1,up,straight))
+);
+} else {
+return state;
+}
+});
+/**
+ * Custom 'setup' function which creates initial position
+ * configuration and puts it to the state map.
+ */
+quil.middlewares.navigation_3d.setup_3d_nav = (function quil$middlewares$navigation_3d$setup_3d_nav(user_setup,user_settings){
+var initial_state = cljs.core.update_in.call(null,cljs.core.update_in.call(null,cljs.core.merge.call(null,quil.middlewares.navigation_3d.default_position.call(null),cljs.core.select_keys.call(null,user_settings,new cljs.core.PersistentVector(null, 3, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854),new cljs.core.Keyword(null,"up","up",-269712113),new cljs.core.Keyword(null,"position","position",-2011731912)], null))),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"straight","straight",-1252567854)], null),quil.middlewares.navigation_3d.v_normalize),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"up","up",-269712113)], null),quil.middlewares.navigation_3d.v_normalize);
+return cljs.core.update_in.call(null,user_setup.call(null),new cljs.core.PersistentVector(null, 1, 5, cljs.core.PersistentVector.EMPTY_NODE, [new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301)], null),((function (initial_state){
+return (function (p1__1643_SHARP_){
+return cljs.core.merge.call(null,initial_state,p1__1643_SHARP_);
+});})(initial_state))
+);
+});
+/**
+ * Enables navigation in 3D space. Similar to how it is done in
+ * shooters: WASD navigation, space is go up, z is go down,
+ * drag mouse to look around.
+ */
+quil.middlewares.navigation_3d.navigation_3d = (function quil$middlewares$navigation_3d$navigation_3d(options){
+var user_settings = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(options);
+var pixels_in_360 = new cljs.core.Keyword(null,"pixels-in-360","pixels-in-360",1789567298).cljs$core$IFn$_invoke$arity$2(user_settings,(1000));
+var step_size = new cljs.core.Keyword(null,"step-size","step-size",1545609922).cljs$core$IFn$_invoke$arity$2(user_settings,(20));
+var rotate_on = new cljs.core.Keyword(null,"rotate-on","rotate-on",-1282225937).cljs$core$IFn$_invoke$arity$2(user_settings,new cljs.core.Keyword(null,"mouse-dragged","mouse-dragged",-1220073441));
+var draw = new cljs.core.Keyword(null,"draw","draw",1358331674).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,pixels_in_360,step_size,rotate_on){
+return (function (state){
+return null;
+});})(user_settings,pixels_in_360,step_size,rotate_on))
+);
+var key_pressed = new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,pixels_in_360,step_size,rotate_on,draw){
+return (function (state,_){
+return state;
+});})(user_settings,pixels_in_360,step_size,rotate_on,draw))
+);
+var rotate_on_fn = rotate_on.call(null,options,((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed){
+return (function (state,_){
+return state;
+});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed))
+);
+var setup = new cljs.core.Keyword(null,"setup","setup",1987730512).cljs$core$IFn$_invoke$arity$2(options,((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn){
+return (function (){
+return cljs.core.PersistentArrayMap.EMPTY;
+});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn))
+);
+return cljs.core.assoc.call(null,options,new cljs.core.Keyword(null,"setup","setup",1987730512),cljs.core.partial.call(null,quil.middlewares.navigation_3d.setup_3d_nav,setup,user_settings),new cljs.core.Keyword(null,"draw","draw",1358331674),((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup){
+return (function (state){
+quil.middlewares.navigation_3d.assert_state_has_navigation.call(null,state);
+
+var map__1644_1655 = new cljs.core.Keyword(null,"navigation-3d","navigation-3d",682305301).cljs$core$IFn$_invoke$arity$1(state);
+var map__1644_1656__$1 = (((((!((map__1644_1655 == null))))?(((((map__1644_1655.cljs$lang$protocol_mask$partition0$ & (64))) || ((cljs.core.PROTOCOL_SENTINEL === map__1644_1655.cljs$core$ISeq$))))?true:false):false))?cljs.core.apply.call(null,cljs.core.hash_map,map__1644_1655):map__1644_1655);
+var vec__1645_1657 = cljs.core.get.call(null,map__1644_1656__$1,new cljs.core.Keyword(null,"straight","straight",-1252567854));
+var c_x_1658 = cljs.core.nth.call(null,vec__1645_1657,(0),null);
+var c_y_1659 = cljs.core.nth.call(null,vec__1645_1657,(1),null);
+var c_z_1660 = cljs.core.nth.call(null,vec__1645_1657,(2),null);
+var vec__1648_1661 = cljs.core.get.call(null,map__1644_1656__$1,new cljs.core.Keyword(null,"up","up",-269712113));
+var u_x_1662 = cljs.core.nth.call(null,vec__1648_1661,(0),null);
+var u_y_1663 = cljs.core.nth.call(null,vec__1648_1661,(1),null);
+var u_z_1664 = cljs.core.nth.call(null,vec__1648_1661,(2),null);
+var vec__1651_1665 = cljs.core.get.call(null,map__1644_1656__$1,new cljs.core.Keyword(null,"position","position",-2011731912));
+var p_x_1666 = cljs.core.nth.call(null,vec__1651_1665,(0),null);
+var p_y_1667 = cljs.core.nth.call(null,vec__1651_1665,(1),null);
+var p_z_1668 = cljs.core.nth.call(null,vec__1651_1665,(2),null);
+quil.core.camera.call(null,p_x_1666,p_y_1667,p_z_1668,(p_x_1666 + c_x_1658),(p_y_1667 + c_y_1659),(p_z_1668 + c_z_1660),u_x_1662,u_y_1663,u_z_1664);
+
+return draw.call(null,state);
+});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup))
+,new cljs.core.Keyword(null,"key-pressed","key-pressed",-757100364),((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup){
+return (function (state,event){
+return key_pressed.call(null,quil.middlewares.navigation_3d.move.call(null,state,event,step_size),event);
+});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup))
+,rotate_on,((function (user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup){
+return (function (state,event){
+return rotate_on_fn.call(null,quil.middlewares.navigation_3d.rotate.call(null,state,event,pixels_in_360),event);
+});})(user_settings,pixels_in_360,step_size,rotate_on,draw,key_pressed,rotate_on_fn,setup))
+);
+});
+
+//# sourceMappingURL=navigation_3d.js.map
diff --git a/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js.map b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js.map
new file mode 100644
index 0000000..6668288
--- /dev/null
+++ b/srv/src/http/static/viz/2/quil/middlewares/navigation_3d.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"\/home\/mediocregopher\/src\/viz\/out\/quil\/middlewares\/navigation_3d.js","sources":["navigation_3d.cljc"],"lineCount":261,"mappings":"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","names":["quil.middlewares.navigation-3d\/missing-navigation-key-error","quil.middlewares.navigation-3d\/assert-state-has-navigation","state","js\/Error","quil.middlewares.navigation-3d\/default-position","quil.core\/width","quil.core\/height","quil.core\/tan","quil.core\/PI","quil.middlewares.navigation-3d\/rotate-by-axis-and-angle","cljs.core\/nth","vec__1620","vec__1623","axis","v","quil.core\/cos","angle","cs","quil.core\/sin","a-x","-cs","a-y","a-z","sn","a","x","b","y","c","z","d","e","f","g","h","i","quil.middlewares.navigation-3d\/rotate-lr","cljs.core\/update-in","nav-3d","p__1626","vec__1628","p__1627","vec__1631","quil.middlewares.navigation-3d\/cross-product","u2","v3","u3","v2","v1","u1","quil.middlewares.navigation-3d\/v-mult","cljs.core\/mapv","p1__1634#","mult","quil.middlewares.navigation-3d\/v-plus","cljs.core\/+","quil.middlewares.navigation-3d\/v-opposite","quil.middlewares.navigation-3d\/v-normalize","cljs.core\/map","quil.core\/sq","cljs.core\/apply","quil.core\/sqrt","norm","quil.middlewares.navigation-3d\/rotate-ud","p1__1635#","rotate","quil.middlewares.navigation-3d\/rotate","cljs.core\/=","event","quil.core\/map-range","dx","pixels-in-360","quil.core\/TWO-PI","dy","p1__1636#","angle-lr","angle-ud","quil.middlewares.navigation-3d\/space","cljs.core\/keyword","quil.middlewares.navigation-3d\/move","map__1638","cljs.core\/PROTOCOL_SENTINEL","cljs.core\/hash-map","cljs.core\/get","temp__4655__auto__","pred__1640","expr__1641","straight","up","p1__1637#","dir","step-size","quil.middlewares.navigation-3d\/setup-3d-nav","user-settings","cljs.core\/select-keys","cljs.core\/merge","user-setup","p1__1643#","initial-state","quil.middlewares.navigation-3d\/navigation-3d","options","rotate-on","cljs.core\/assoc","cljs.core\/partial","setup","map__1644","vec__1645","vec__1648","vec__1651","quil.core\/camera","p-x","p-y","p-z","c-x","c-y","c-z","u-x","u-y","u-z","draw","key-pressed","rotate-on-fn"]} \ No newline at end of file