Update indexeddb to new protocols.

Update indexeddb to new protocols.

--- src/konserve/indexeddb.cljs
+++ src/konserve/indexeddb.cljs
@@ -1,27 +1,26 @@
 (ns konserve.indexeddb
-  #_(:require [incognito.edn :refer [read-string-safe]]
+  (:require [incognito.edn :refer [read-string-safe]]
             [konserve.core :as k]
             [konserve.serializers :as ser]
-            [konserve.protocols :refer [PEDNAsyncKeyValueStore -exists? -get-in -update-in
-                                        PJSONAsyncKeyValueStore -jget-in -jassoc-in -jupdate-in
+            [konserve.protocols :refer [PEDNAsyncKeyValueStore -exists? -get -update-in -assoc-in -get-meta
                                         PBinaryAsyncKeyValueStore -bget -bassoc
-                                        -serialize -deserialize]]
+                                        PStoreSerializer -serialize -deserialize]]
             [cljs.core.async :as async :refer (take! <! >! put! close! chan poll!)])
-  #_(:require-macros [cljs.core.async.macros :refer [go go-loop]]))
-
-#_(comment
-  (defrecord IndexedDBKeyValueStore [db store-name serializer read-handlers write-handlers locks]
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]]))
+
+
+  (defrecord IndexedDBKeyValueStore [db store-name serializer read-handlers write-handlers locks version]
     PEDNAsyncKeyValueStore
     (-exists? [this key]
-      (let [res (chan)
-            tx (.transaction db #js [store-name])
-            obj-store (.objectStore tx store-name)
-            req (.openCursor obj-store (pr-str key))]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name])
+            obj-store (.objectStore tx store-name)
+            req       (.openCursor obj-store (pr-str key))]
         (set! (.-onerror req)
               (fn [e]
                 (put! res (ex-info "Cannot check for existence."
-                                   {:type :access-error
-                                    :key key
+                                   {:type  :access-error
+                                    :key   key
                                     :error (.-target e)}))
                 (close! res)))
         (set! (.-onsuccess req)
@@ -31,84 +30,101 @@
                 (close! res)))
         res))

-    (-get-in [this key-vec]
+    (-get-meta [this key]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name])
+            obj-store (.objectStore tx store-name)
+            req       (.get obj-store (pr-str key))]
+        (set! (.-onerror req)
+              (fn [e]
+                (put! res (ex-info "Cannot read edn value."
+                                   {:type  :read-error
+                                    :key   key
+                                    :error (.-target e)}))
+                (close! res)))
+        (set! (.-onsuccess req)
+              (fn [e] (when-let [r (.-result req)]
+                        (put! res (-deserialize serializer read-handlers (aget r "meta"))))
+                (close! res)))
+        res))
+
+    (-get [this key]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name])
+            obj-store (.objectStore tx store-name)
+            req       (.get obj-store (pr-str key))]
+        (set! (.-onerror req)
+              (fn [e]
+                (put! res (ex-info "Cannot read edn value."
+                                   {:type  :read-error
+                                    :key   key
+                                    :error (.-target e)}))
+                (close! res)))
+        (set! (.-onsuccess req)
+              (fn [e] (when-let [r (.-result req)]
+                        (put! res (-deserialize serializer read-handlers (aget r "edn_value"))))
+                (close! res)))
+        res))
+
+    (-assoc-in [this key-vec meta-up val] (-update-in this key-vec meta-up (fn [_] val) []))
+    (-update-in [this key-vec meta-up up-fn args]
       (let [[fkey & rkey] key-vec
-            res (chan)
-            tx (.transaction db #js [store-name])
-            obj-store (.objectStore tx store-name)
-            req (.get obj-store (pr-str fkey))]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot read edn value."
-                                   {:type :read-error
-                                    :key key-vec
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn [e] (when-let [r (.-result req)]
-                        (put! res (get-in (-deserialize serializer read-handlers (aget r "edn_value"))
-                                          rkey)))
-                ;; returns nil
-                (close! res)))
-        res))
-
-    (-update-in [this key-vec up-fn] (-update-in this key-vec up-fn []))
-    (-update-in [this key-vec up-fn up-fn-args]
-      (let [[fkey & rkey] key-vec
-            res (chan)
-            tx (.transaction db #js [store-name] "readwrite")
-            obj-store (.objectStore tx store-name)
-            req (.get obj-store (pr-str fkey))]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot read edn value."
-                                   {:type :read-error
-                                    :key key-vec
+            res           (chan)
+            tx            (.transaction db #js [store-name] "readwrite")
+            obj-store     (.objectStore tx store-name)
+            req           (.get obj-store (pr-str fkey))]
+        (set! (.-onerror req)
+              (fn [e]
+                (put! res (ex-info "Cannot read edn value."
+                                   {:type  :read-error
+                                    :key   key-vec
                                     :error (.-target e)}))
                 (close! res)))
         (set! (.-onsuccess req)
               (fn read-old [e]
                 (try
-                  (let [old (when-let [r (.-result req)]
-                              (-deserialize serializer read-handlers (aget r "edn_value")))
-                        up (if-not (empty? rkey)
-                             (apply update-in old rkey up-fn up-fn-args)
-                             (apply up-fn old up-fn-args))]
+                  (let [[old-meta old] (when-let [r (.-result req)]
+                                         [(-deserialize serializer read-handlers (aget r "meta")) (-deserialize serializer read-handlers (aget r "edn_value"))])
+                        edn-meta       (meta-up old-meta)
+                        edn-value      (if-not (empty? rkey)
+                                         (apply update-in old rkey up-fn args)
+                                         (apply up-fn old args))]
                     (let [up-req (.put obj-store
                                        (clj->js {:key (pr-str fkey)
+                                                 :version version
+                                                 :meta
+                                                 (-serialize serializer nil write-handlers edn-meta)
                                                  :edn_value
-                                                 (-serialize serializer nil write-handlers up)}))]
+                                                 (-serialize serializer nil write-handlers edn-value)}))]
                       (set! (.-onerror up-req)
                             (fn [e]
                               (put! res (ex-info "Cannot write edn value."
-                                                 {:type :write-error
-                                                  :key key-vec
+                                                 {:type  :write-error
+                                                  :key   key-vec
                                                   :error (.-target e)}))
                               (close! res)))
                       (set! (.-onsuccess up-req)
                             (fn [e]
-                              (put! res [(get-in old rkey) up])
+                              (put! res [(get-in old rkey) edn-value])
                               (close! res)))))
                   (catch :default e
                     (put! res (ex-info "Cannot parse edn value."
-                                       {:type :read-error
-                                        :key key-vec
+                                       {:type  :read-error
+                                        :key   key-vec
                                         :error e}))
                     (close! res)))))
         res))

-    (-assoc-in [this key-vec val] (-update-in this key-vec (fn [_] val)))
-
     (-dissoc [this key]
-      (let [res (chan)
-            tx (.transaction db #js [store-name] "readwrite")
-            obj-store (.objectStore tx store-name)
-            up-req (.delete obj-store (pr-str key))]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name] "readwrite")
+            obj-store (.objectStore tx store-name)
+            up-req    (.delete obj-store (pr-str key))]
         (set! (.-onerror up-req)
               (fn [e]
                 (put! res (ex-info "Cannot write edn value."
-                                   {:type :write-error
-                                    :key key
+                                   {:type  :write-error
+                                    :key   key
                                     :error (.-target e)}))
                 (close! res)))
         (set! (.-onsuccess up-req)
@@ -118,17 +134,17 @@

     PBinaryAsyncKeyValueStore
     (-bget [this key lock-cb]
-      (let [res (chan)
-            tx (.transaction db #js [store-name])
-            obj-store (.objectStore tx store-name)
-            req (.get obj-store (pr-str key))]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name])
+            obj-store (.objectStore tx store-name)
+            req       (.get obj-store (pr-str key))]
         (set! (.-onerror req)
               (fn [e]
                 (go
                   (>! res (<!
                            (lock-cb (ex-info "Cannot read binary value."
-                                             {:type :read-error
-                                              :key key
+                                             {:type  :read-error
+                                              :key   key
                                               :error (.-target e)}))))
                   (close! res))))
         (set! (.-onsuccess req)
@@ -137,117 +153,45 @@
                 ;; returns nil
                 (close! res)))
         res))
-    (-bassoc [this key blob]
-      (let [res (chan)
-            tx (.transaction db #js [store-name] "readwrite")
-            obj-store (.objectStore tx store-name)
-            req (.put obj-store #js {:key (pr-str key)
-                                     :value blob})]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot write binary value."
-                                   {:type :write-error
-                                    :key key
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn [e] (close! res)))
-        res))
-
-    PJSONAsyncKeyValueStore
-    (-jget-in [this key-vec]
-      (let [[fkey & rkey] key-vec
-            res (chan)
-            tx (.transaction db #js [store-name])
-            obj-store (.objectStore tx store-name)
-            req (.get obj-store (pr-str fkey))]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot write json value."
-                                   {:type :write-error
-                                    :key key
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn [e] (when-let [r (.-result req)]
-                        (put! res (-> r
-                                      (aget "json_value")
-                                      js->clj
-                                      (get-in rkey))))
-                ;; returns nil
-                (close! res)))
-        res))
-    (-jassoc-in [this key-vec value]
-      (let [[fkey & rkey] key-vec
-            res (chan)
-            tx (.transaction db #js [store-name] "readwrite")
-            obj-store (.objectStore tx store-name)
-            req (.get obj-store (pr-str fkey))]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot write json value."
-                                   {:type :write-error
-                                    :key key
+    (-bassoc [this key meta-up blob]
+      (let [res       (chan)
+            tx        (.transaction db #js [store-name] "readwrite")
+            obj-store (.objectStore tx store-name)
+            req       (.get obj-store (pr-str key))]
+        (set! (.-onerror req)
+              (fn [e]
+                (put! res (ex-info "Cannot read edn value."
+                                   {:type  :read-error
+                                    :key   key
                                     :error (.-target e)}))
                 (close! res)))
         (set! (.-onsuccess req)
               (fn read-old [e]
-                (let [old (when-let [r (.-result req)]
-                            (js->clj (-> r (aget "json_value"))))
-                      up-req (if (or value (not (empty? rkey)))
-                               (.put obj-store
-                                     #js {:key (pr-str fkey)
-                                          :json_value (if-not (empty? rkey)
-                                                        (clj->js (assoc-in old rkey value))
-                                                        value)})
-                               (.delete obj-store (pr-str fkey)))]
-                  (set! (.-onerror up-req)
-                        (fn [e]
-                          (put! res (ex-info "Cannot write json value."
-                                             {:type :write-error
-                                              :key key
-                                              :error (.-target e)}))
-                          (close! res)))
-                  (set! (.-onsuccess up-req)
-                        (fn [e] (close! res))))))
-        res))
-    (-jupdate-in [this key-vec up-fn]
-      (let [[fkey & rkey] key-vec
-            res (chan)
-            tx (.transaction db #js [store-name] "readwrite")
-            obj-store (.objectStore tx store-name)
-            req (.get obj-store (pr-str fkey))]
-        (set! (.-onerror req)
-              (fn [e]
-                (put! res (ex-info "Cannot write json value."
-                                   {:type :write-error
-                                    :key key
-                                    :error (.-target e)}))
-                (close! res)))
-        (set! (.-onsuccess req)
-              (fn read-old [e]
-                (let [old (when-let [r (.-result req)]
-                            (-> r (aget "json_value")))
-                      new (if-not (empty? rkey)
-                            (update-in old rkey up-fn)
-                            (up-fn old))
-                      up-req (if new
-                               (.put obj-store
-                                     (clj->js {:key (pr-str fkey)
-                                               :json_value
-                                               (pr-str new)}))
-                               (.delete obj-store (pr-str fkey)))]
-                  (set! (.-onerror up-req)
-                        (fn [e]
-                          (put! res (ex-info "Cannot write json value."
-                                             {:type :write-error
-                                              :key key
-                                              :error (.-target e)}))
-                          (close! res)))
-                  (set! (.-onsuccess up-req)
-                        (fn [e]
-                          (put! res [(get-in old rkey) (get-in new rkey)])
-                          (close! res))))))
+                (try
+                  (let [old-meta (when-let [r (.-result req)]
+                                   (-deserialize serializer read-handlers (aget r "meta")))
+                        edn-meta (meta-up old-meta)]
+                    (let [up-req (.put obj-store
+                                       (clj->js {:key   (pr-str key)
+                                                 :meta
+                                                 (-serialize serializer nil write-handlers edn-meta)
+                                                 :version version
+                                                 :value blob}))]
+                      (set! (.-onerror up-req)
+                            (fn [e]
+                              (put! res (ex-info "Cannot write binary value."
+                                                 {:type  :write-error
+                                                  :key   key
+                                                  :error (.-target e)}))
+                              (close! res)))
+                      (set! (.-onsuccess up-req)
+                            (fn [e] (close! res)))))
+                  (catch :default e
+                    (put! res (ex-info "Cannot parse edn value."
+                                       {:type  :read-error
+                                        :key   key
+                                        :error e}))
+                    (close! res)))))
         res)))

@@ -256,10 +200,11 @@
   incognito.

   Be careful not to mix up edn and JSON values."
-    [name & {:keys [read-handlers write-handlers serializer]
+    [name & {:keys [read-handlers write-handlers serializer version]
              :or {read-handlers (atom {})
                   write-handlers (atom {})
-                  serializer (ser/string-serializer)}}]
+                  serializer (ser/string-serializer)
+                  version 1}}]
     (let [res (chan)
           req (.open js/window.indexedDB name 1)]
       (set! (.-onerror req)
@@ -275,7 +220,8 @@
                                                       :store-name name
                                                       :read-handlers read-handlers
                                                       :write-handlers write-handlers
-                                                      :locks (atom {})}))))
+                                                      :locks (atom {})
+                                                      :version version}))))
       (set! (.-onupgradeneeded req)
             (fn upgrade-handler [e]
               (let [db (-> e .-target .-result)]
@@ -283,7 +229,6 @@
       res))

-
   (comment
     ;; jack in figwheel cljs REPL
     (require 'figwheel-sidecar.repl-api)
@@ -297,6 +242,7 @@
                                                :read-handlers
                                                (atom {'konserve.indexeddb.Test
                                                       map->Test})))))
+
     ;; or
     (-jassoc-in my-store ["test" "bar"] #js {:a 3})
     (go (println (<! (-jget-in my-store ["test"]))))
@@ -310,21 +256,36 @@
            (<! (-update-in my-store [i] (fn [_] (inc i)))))
          #_(doseq [i (range 10)]
              (println (<! (-get-in my-store [i]))))))
-    (go (println (<! (-get-in my-store [999]))))
+    (go (println (<! (-get my-store 999))))
+
+    (go (prn (<! (-update-in my-store ["foo"] (fn [_] {:meta "META"}) (fn [_] 0) []))))
+
+    (go (prn (<! (-update-in my-store ["foo"] (fn [_] {:meta "META"}) inc []))))
+
+    (go (println (<! (-get-meta my-store "foo"))))
+
+    (go (println (<! (-get my-store "foo"))))
+

     (go (println (<! (-assoc-in my-store ["rec-test"] (Test. 5)))))
-    (go (println (<! (-get-in my-store ["rec-test"]))))
+    (go (println (<! (-get my-store "rec-test"))))

     (go (println (<! (-assoc-in my-store ["test2"] {:a 1 :b 4.2}))))

     (go (println (<! (-assoc-in my-store ["test"] {:a 43}))))

     (go (println (<! (-update-in my-store ["test" :a] inc))))
-    (go (println (<! (-get-in my-store ["test2"]))))
+    (go (println (<! (-get my-store "test2"))))

     (go (println (<! (-bassoc my-store
                               "blob-fun"
+                              (fn [_] "my meta")
                               (new js/Blob #js ["hello worlds"], #js {"type" "text/plain"})))))
+
+    (go (println (<! (-get-meta my-store "blob-fun"))))
+
     (go (.log js/console (<! (-bget my-store "blob-fun" identity))))
-    ))
+
+
+    )


add some default access rules

add some default access rules

--- src/clj/closerve/state.clj
+++ src/clj/closerve/state.clj
@@ -5,7 +5,10 @@

 (defonce root-dir (atom nil))
 (defonce ws-chan (chan))
-(defonce access-rules (atom []))
+(defonce access-rules (atom [[#"^/\..*$" (fn [req] false)]
+                             [#"^.*~$" (fn [req] false)]
+                             [#"^/templates-hidden.*$" (fn [req] false)]
+                             ]))

 (defonce session-manager (atom nil))


Add color-mode to util

Add color-mode to util

--- src/clj/genartlib/util.clj
+++ src/clj/genartlib/util.clj
@@ -1,5 +1,5 @@
 (ns genartlib.util
-  (:use [quil.core :only [height width PI]])
+  (:use [quil.core :only [height width PI color-mode]])
   (:use [incanter.core :only [$=]]))

   (defn h
@@ -27,3 +27,6 @@
     "Returns true if value is between end1 and end2"
     (and ($= value >= ((min end1 end2)))
          ($= value <= ((max end1 end2)))))
+
+  (defn set-color-mode []
+    (color-mode :hsb 360 100 100 1.0))


Begin gathering tweets

Begin gathering tweets

--- src/clj/skytwit/server.clj
+++ src/clj/skytwit/server.clj
@@ -16,16 +16,20 @@
             [cheshire.core :as json]
             [taoensso.sente :as sente]
             [taoensso.sente.server-adapters.http-kit
-             :refer [sente-web-server-adapter]])
+             :refer [sente-web-server-adapter]]
+            [clojure.core.async :as async :refer [go go-loop >! <!]])
   (:import (twitter.callbacks.protocols AsyncStreamingCallback))
   (:gen-class))

-(def credentials (oauth/make-oauth-creds (env :oauth-consumer-key)
-                                         (env :oauth-consumer-secret)
-                                         (env :oauth-app-key)
-                                         (env :oauth-app-secret)))
+(defn get-credentials-from-env
+  []
+  (oauth/make-oauth-creds (env :oauth-consumer-key)
+                          (env :oauth-consumer-secret)
+                          (env :oauth-app-key)
+                          (env :oauth-app-secret)))

 (comment
+  (def credentials (get-credentials-from-env))
 (->> (tr/statuses-user-timeline
        :oauth-creds credentials
        :params {:screen-name "AdamJWynne"})
@@ -80,8 +84,48 @@
   )

 (comment
-(chsk-send! 1 {:text "hello"})
+(chsk-send! 1 [:a/ping "hello"])
 )
+
+(comment
+
+  (def creds (get-credentials-from-env))
+
+  (try
+    (let [user (-> (tr/users-show :oauth-creds creds
+                                  :params {:screen-name "InternetRadio"})
+                   :body)]
+      {:name (:screen_name user)
+       :number-of-tweets (:statuses_count user)
+       :last-tweet-id (-> user :status :id)})
+    (catch Exception _ nil))
+  {:name "InternetRadio",
+   :number-of-tweets 3787133,
+   :last-tweet-id 696388911019462656}
+
+  (->> (tr/statuses-user-timeline :oauth-creds creds
+                                  :params {:screen-name "InternetRadio"
+                                           :max-id 696388911019462656
+                                           :trim-user true
+                                           :exclude-replies true
+                                           :count 200})
+      :body (map :id))
+
+  )
+
+(defn get-tweets-before-tweet-id
+  [creds screen-name id]
+  (let [tweets (->> (tr/statuses-user-timeline :oauth-creds creds
+                                               :params {:screen-name screen-name
+                                                        :max-id id
+                                                        :trim-user true
+                                                        :exclude-replies true
+                                                        :count 200})
+                    :body (map (juxt :id (comp (partial mapv :text)
+                                               :hashtags :entities))))]
+    (if (= id (ffirst tweets))
+      (rest tweets)
+      tweets)))

 (defroutes routes
   (GET "/" _


add descriptive error for bad coercion call

--- src/clj_money/coercion.clj
+++ src/clj_money/coercion.clj
@@ -57,6 +57,8 @@
 (defn coerce
   "Given a model and a list of coercion rules, applies the rules to the model"
   [model coercions]
+  (when-not (sequential? coercions)
+    (throw (ex-info "The coercions must be a sequence" {:coercisons coercions})))
   (reduce (fn [result {:keys [path coerce-fn]}]
             (if (nil? (get-in result path))
               result


Added checkbox & text input helpers

Added checkbox & text input helpers

--- src/cljs/asols/client.cljs
+++ src/cljs/asols/client.cljs
@@ -20,13 +20,45 @@
                     :remove-nodes? false}
          :solvings []}))

+(defn- checkbox
+  "Simple checkbox which binds its value to path in cursor"
+  [cursor path label-text]
+  {:pre [(om/cursor? cursor)
+         (coll? path)
+         (string? label-text)]}
+  [:.form-group
+   [:.col-sm-12
+    [:label.checkbox
+     [:input.custom-checkbox
+      {:type      "checkbox"
+       :checked   (when (get-in cursor path) "checked")
+       :on-change #(om/update! cursor path (.. % -target -checked))}]
+     [:span.icons
+      [:span.icon-checked]
+      [:span.icon-unchecked]]
+     label-text]]])
+
+(defn- text-input
+  "Simple text input which binds its value to path in cursor"
+  [cursor path label-text label-params input-params]
+  {:pre [(om/cursor? cursor)
+         (coll? path)
+         (string? label-text)
+         (map? label-params) (map? input-params)]}
+  [:.form-group
+   [:label.control-label label-params label-text]
+   [:div input-params
+    [:input.form-control
+     {:value (get-in cursor path)
+      :on-change #(om/update! cursor path (.. % -target -value))}]]])
+
 (defn settings-panel [{:keys [start-chan running? settings]} owner]
   (reify
     om/IRender
     (render [_]
       (let [[label-width field-width] [6 6]
-            label-class (str "col-sm-" label-width)
-            field-class (str "col-sm-" field-width)]
+            label-params {:class (str "col-sm-" label-width)}
+            input-params {:class (str "col-sm-" field-width)}]
         (html
           [:.panel.panel-default.settings
            [:.panel-heading "Settings"]
@@ -34,32 +66,12 @@
             [:.row
              [:.col-sm-6
               [:form.form-horizontal
+               (text-input settings [:learning-rate] "Learning rate" label-params input-params)
+               (text-input settings [:momentum] "Momentum" label-params input-params)
+               (text-input settings [:iter-count] "Iterations" label-params input-params)
+
                [:.form-group
-                [:label.control-label {:class label-class :for :input-lr}
-                 "Learning rate"]
-                [:div {:class field-class}
-                 [:input.form-control#input-lr
-                  {:value     (:learning-rate settings)
-                   :on-change #(om/update! settings :learning-rate (.. % -target -value))}]]]
-
-               [:.form-group
-                [:label.control-label {:class label-class :for :input-momentum}
-                 "Momentum"]
-                [:div {:class field-class}
-                 [:input.form-control#input-momentum
-                  {:value     (:momentum settings)
-                   :on-change #(om/update! settings :momentum (.. % -target -value))}]]]
-
-               [:.form-group
-                [:label.control-label {:class label-class :for :input-iters}
-                 "Iterations"]
-                [:div {:class field-class}
-                 [:input.form-control#input-iters
-                  {:value     (:iter-count settings)
-                   :on-change #(om/update! settings :iter-count (.. % -target -value))}]]]
-
-               [:.form-group
-                [:div {:class [field-class (str "col-sm-offset-" label-width)]}
+                [:div {:class [input-params (str "col-sm-offset-" label-width)]}
                  [:button.btn.btn-primary.btn-block
                   {:type     "button"
                    :disabled (when running? "disabled")
@@ -67,28 +79,8 @@
                   "Start"]]]]]
              [:.col-sm-6
               [:form.form-horizontal
-               [:.form-group
-                [:.col-sm-12
-                 [:label.checkbox
-                  [:input.custom-checkbox
-                   {:type      "checkbox"
-                    :checked   (when (:remove-edges? settings) "checked")
-                    :on-change #(om/update! settings :remove-edges? (.. % -target -checked))}]
-                  [:span.icons
-                   [:span.icon-checked]
-                   [:span.icon-unchecked]]
-                  "Remove edges?"]]]
-               [:.form-group
-                [:.col-sm-12
-                 [:label.checkbox
-                  [:input.custom-checkbox
-                   {:type      "checkbox"
-                    :checked   (when (:remove-nodes? settings) "checked")
-                    :on-change #(om/update! settings :remove-nodes? (.. % -target -checked))}]
-                  [:span.icons
-                   [:span.icon-checked]
-                   [:span.icon-unchecked]]
-                  "Remove nodes?"]]]]]]]])))))
+               (checkbox settings [:remove-edges?] "Remove edges?")
+               (checkbox settings [:remove-nodes?] "Remove nodes?")]]]]])))))

 (defmulti mutation-view :operation)

@@ -178,7 +170,7 @@
                                                     :momentum (js/parseFloat (:momentum settings))
                                                     :iter-count (js/parseInt (:iter-count settings))
                                                     :remove-edges? (:remove-edges? settings)
-                                                    :remove-nodes? (:remove-nodes settings)))
+                                                    :remove-nodes? (:remove-nodes? settings)))
                (recur))
       (go-loop [frame (<! connection)]
                (if-not (nil? frame)


Time format is 24 hour, not 12 hour

Time format is 24 hour, not 12 hour

--- src/cljs/herder/slots.cljs
+++ src/cljs/herder/slots.cljs
@@ -25,7 +25,7 @@
                    ""
                    value))}])
     :component-did-mount #(->
-                           (.timepicker (js/$ (r/dom-node %)) (js-obj "timeFormat" "h:i"))
+                           (.timepicker (js/$ (r/dom-node %)) (js-obj "timeFormat" "H:i"))
                            (.bind "changeTime"
                                   (fn [event obj]
                                     (swap! val assoc key


still depends on node

still depends on node

--- src/cljs/server/jokes.cljs
+++ src/cljs/server/jokes.cljs
@@ -1,6 +1,9 @@
 (ns server.jokes
-  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
-  (:require [cljs.core.async :as async :refer [chan close! put!]]))
+  (:require-macros
+   [cljs.core.async.macros :refer [go go-loop]])
+  (:require
+   [cljs.nodejs :as nodejs]
+   [cljs.core.async :as async :refer [chan close! put!]]))

 (def http (nodejs/require "http"))


cljs/skyport.core: Move some code around

--- src/cljs/skyport/core.cljs
+++ src/cljs/skyport/core.cljs
@@ -244,8 +244,9 @@
          ;; path correctly we move the point up one hexagon each turn
          ;; around the point, including the first round. We then take
          ;; the current coordinate and add move it around the
-         ;; path. Lastly, because the each circle is completes back at
-         ;; its origin we remove all the extra points.
+         ;; path. Lastly, because the each circle completes back at
+         ;; the same place it started we remove these all the extra
+         ;; points.
          hits (->> circle
                    repeat
                    (reductions interleave)
@@ -263,20 +264,6 @@
                           :label "D"
                           :position [j k]})
                        {:key :position})])))
-
-(defn player-view [{:keys [name position text]} owner]
-  (reify
-    om/IRender
-    (render [_]
-      (let [[x y] (coords-to-pixel position)]
-        (html
-         [:g {:id name
-              :class "player"}
-          [:circle {:fill "blue"
-                    :cx x
-                    :cy y
-                    :r (/ TILE-SIZE 2)}]])))))
-
 (defn droid-shot [{:keys [sequence from]} owner]
   (reify
     om/IInitState
@@ -328,6 +315,19 @@
 (defmethod action-view :default [_ _]
   (html [:g]))

+(defn player-view [{:keys [name position text]} owner]
+  (reify
+    om/IRender
+    (render [_]
+      (let [[x y] (coords-to-pixel position)]
+        (html
+         [:g {:id name
+              :class "player"}
+          [:circle {:fill "blue"
+                    :cx x
+                    :cy y
+                    :r (/ TILE-SIZE 2)}]])))))
+
 (defn world-view [state owner]
   (reify
     om/IRender


fix path name when scanning directories

fix path name when scanning directories

--- src/cljs/smgui/search.cljs
+++ src/cljs/smgui/search.cljs
@@ -42,8 +42,8 @@
                (close! out)))
     out))

-(defn download-path [path] (download path (smgui.settings/languages)))
-(defn download-chan [path] (state-download (download-path path)))
+(defn download-chan [path]
+  (state-download (download path (smgui.settings/languages))))

 (defn status-icon [icon]
   (dom/img #js {:src (str "images/icon-" icon ".svg") :className "status"}))
@@ -121,9 +121,9 @@
     (om/build smgui.components/file-dropper searches {:state {:view view
                                                               :channel c}})))

-(defmethod flux-handler :add-search [{:keys [path]}]
-  (dochan [channel (->> (dir/show-lookup path)
-                        (r/map download-chan))]
+(defmethod flux-handler :add-search [{source-path :path}]
+  (dochan [{:keys [path channel]} (->> (dir/show-lookup source-path)
+                                       (r/map #(hash-map :path % :channel (download-chan %))))]
     (go
       (let [id (rand)]
         (loop [state {:status :init}]


parse defcurried (close #35)

parse defcurried (close #35)

--- src/cljs_api_gen/parse.clj
+++ src/cljs_api_gen/parse.clj
@@ -130,6 +130,15 @@
     {:docstring docstring
      :type (if dynamic? "dynamic var" "var")}))

+(defn parse-defcurried
+  [form]
+  (let [[_ name- docstring attr-map args] form
+        cargs (vec (butlast args))
+        signatures [cargs args]]
+    {:docstring docstring
+     :signature signatures
+     :type "function"}))
+
 (defmulti parse-form*
   (fn [form]
     (cond
@@ -152,6 +161,10 @@
            (not (:private (meta (second form)))))
       "var"

+      (and (= 'defcurried (first form))
+           (not (:private (nth form 3 nil))))
+      "defcurried"
+
       :else nil)))

 (defmethod parse-form* "var"
@@ -169,6 +182,10 @@
 (defmethod parse-form* "defmacro"
   [form]
   (parse-defn-or-macro form))
+
+(defmethod parse-form* "defcurried"
+  [form]
+  (parse-defcurried form))

 (defmethod parse-form* nil
   [form]


Add docs to with-check-shape macros in clojure/gpu/matrix.clj

--- src/clojure/gpu/matrix.clj
+++ src/clojure/gpu/matrix.clj
@@ -59,21 +59,73 @@
         (aget shape dimension-number)))))

 (defn- all?
+  "returns true if every element in coll (or the mapped version, if
+  a map function is provided) is true. Truthyness is tested using true?, so
+  only the Bolean true will be tested as positive."
   ([coll]
    (every? true? coll))
   ([f coll]
    (every? true? (mapv f coll))))

 (defn- make-index-type-hints [syms]
+  "Make index type hints.
+  eg: Converts the list
+
+  '(a b c d)
+
+  into
+
+  '[a (long a) b (long b) c (long c)]
+
+  which can be used together with other bindings (or even on its own)
+  in macros"
   (vec
     (mapcat (fn [sym]
-              `[~sym (long ~sym)])
+              (if (symbol? sym)
+                `[~sym (long ~sym)]
+                `[]))
             syms)))

-(defn- in-bound? [^long idx ^long len]
+(defn- in-bound?
+  "Returns true if the matrix is in bound, i.e:
+  0 <= idx < len"
+  [^long idx ^long len]
   (and (>= idx 0) (< idx len)))

-(defmacro with-check-indices [ndims m & args]
+(defmacro with-check-indices
+  "
+  Check the indices (third or more arguments) based on the provided
+  matrix (second argument). Throws an error if it is out of bound.
+
+  The way the third and more arguments is interpreted depends on the
+  symbol ndims. If it is a number (note, not a symbol that points to
+  a number) and is equals to 1 , then the third argument will be
+  the row number. If it is equals to 2, then third argument will
+  be the row number and fourth argument will be the col number.
+  Otherwise, the third number is treated as an array of indices.
+
+  In all cases, the other arguments will be treated as the body.
+
+  This macro also does some autocasting for certain symbols (only for
+  ndims = 1 or 2). For eg, if the row / col number is a symbol rather
+  than a number, then the symbol will be casted to a long explicitly,
+  preventing the usage of the reflection API where possible.
+
+  usage:
+  (with-check-indices 1 m row
+    (println (.get m row)))
+
+  (with-check-indices 2 m row col
+    (println (.get m row)))
+
+  ; When the first argument (ndims) is not 1 or 2
+  (with-check-indices (inc 0) m [row]
+    (println (.get m row)))
+
+  (with-check-ndims 3 m [i j k]
+    (println (.get m i j k)))
+  "
+  [ndims m & args]
    (let [row-sym (gensym "row_")
          col-sym (gensym "col_")
          indexes-sym (gensym "indexes_")
@@ -146,6 +198,9 @@
              "\n"))))))

 (defmacro with-check-ndims [ndims m & body]
+  "macro to check the dimensionality of the m against ndims.
+  If it is equal, the body will be executed. Otherwise, a runtime error
+  will be thrown."
   `(if (= ~ndims (.dimensionality ~m))
      (do ~@body)
      (error
@@ -153,6 +208,18 @@
             "but got " ~ndims " instead"))))

 (defmacro with-check-shape [ndims [m-sym m] & body]
+  "Binds m-sym to m, with a type hinting indicating NDArray. Executes body
+  after running with-check-ndims and with-check-indices. Note that
+  body will have to adhere to the format expected by with-check-indices.
+  See (source with-check-indices) for more details
+
+  Usage:
+
+  (with-check-shape 2 [m (mp/construct-matrix (NDArray.) [ [1 2 3]])] row col
+    (println (.get m row col)))
+
+  Note that explicit type hinting is not required if row and col are symbols,
+  this macro will automatically cast 'row and 'col to long types"
   `(let [~(with-meta m-sym {:tag NDArray}) ~m]
      (with-check-ndims ~ndims ~m-sym
        (with-check-indices ~ndims ~m-sym


Added an evolution function and a DNA mutation function.

--- src/clojure_robby/core.clj
+++ src/clojure_robby/core.clj
@@ -12,6 +12,8 @@
 (def tiles [\w \p \g]) ; Tiles that populate the map: wall, path, and gold.
 (def actions [\u \d \l \r \p]) ; Actions the robot can take: up, down, left, right, pick up.
 (def dir-vects ['(1 0) '(-1 0) '(-1 0) '(0 1) '(0 0)]) ; Direction vectors, corresponding to the actions.
+
+(def mutation-prob 2) ; Probability in 100 that a gene will mutate.
 (def action-penalty 5) ; How many points robot loses when hitting the wall or picking up when it shouldn't.
 (def gold-value 10) ; How many points picking up gold is worth.

@@ -27,7 +29,13 @@
   "Crosses two vectors of DNA."
   (defn choose-rand [x y]
     (if (< (rand-int 100) 50) x y))
-  (map choose-rand a b))
+  (mapv choose-rand a b))
+
+(defn mutate [dna]
+  "Randomly replace some genes in the DNA."
+  (defn mutate-gene [gene]
+    (if (< (rand-int 100) mutation-prob) (rand-gene) gene))
+  (mapv mutate-gene dna))

 ; Fitness evaluation functions
@@ -85,6 +93,16 @@
   (nth final-state 2))

+; Evolution functions
+(defn evolve [individuals]
+  "Takes a bunch of individuals (DNAs) and cross-breeds by fitness."
+  (def the-map (rand-map))
+  (def ordered (reverse (sort-by (fn[dna] (simulate dna the-map)) individuals)))
+  (def crossed (map (fn [pair]
+         (let [[a b] (vec pair)] (cross a b)))
+       (partition 2 ordered)))
+  (concat crossed (map mutate crossed)))
+
 (defn -main
   "I don't do a whole lot ... yet."
   [& args]


[Fix] print into dorun

[Fix] print into dorun

--- src/clj_elm/core.clj
+++ src/clj_elm/core.clj
@@ -146,7 +146,7 @@
          groupn (quot numd k)]                ; number of one group's element
      (->> (take k (iterate #(+ % groupn) 0))
           (pmap #(let [[eva exp-data] (_cross-validate norm-dataset % (+ % (dec groupn)) L)]
-                   (println exp-data)
+                   (dorun (println exp-data))
                    eva))
           (reduce +)
           (* (/ 1 k))))))


Explode hiccup children seqs in place.

Explode hiccup children seqs in place.

--- src/cljs/c2/dom.cljs
+++ src/cljs/c2/dom.cljs
@@ -147,10 +147,16 @@
                                                                   {:id (or id nil)
                                                                    :class (if class (string/replace class #"\." " "))}))
                                    map-attrs        (first content)]
-
-                               (if (map? map-attrs)
-                                 {:nsp nsp :tag tag :attr (merge tag-attrs map-attrs) :children  (map cannonicalize (next content))}
-                                 {:nsp nsp :tag tag :attr tag-attrs :children  (map cannonicalize content)}))))
+
+                               (let [[attr raw-children] (if (map? map-attrs)
+                                                                [(merge tag-attrs map-attrs) (next content)]
+                                                                [tag-attrs content])
+                                     ;;Explode children seqs in place
+                                     children (mapcat #(if (and (not (vector? %)) (seq? %))
+                                                         (map cannonicalize %)
+                                                         [(cannonicalize %)])
+                                                      raw-children)]
+                                 {:nsp nsp :tag tag :attr attr :children children}))))

 (defn create-elem [nsp tag]
   (.createElementNS js/document nsp (name tag)))


Another fix for the regular expression for csv format

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/io/contexts.clj
+++ src/conexp/io/contexts.clj
@@ -339,7 +339,7 @@
           (make-context-nc (set-of g [[g m] inz])
                            (set-of m [[g m] inz])
                            inz)
-          (let [[_ g m] (re-matches #"^([^,]+),([^,]+)$" line)]
+          (let [[r g m] (re-matches #"^((?:[^,]+|\".*\")),((?:[^,]+|\".*\"))$" line)]
             (recur (conj inz [g m]))))))))

 (define-context-output-format :csv


Korjattu cas-client construktointiin caller-id

--- clj-cas/src/clj_cas/cas.clj
+++ clj-cas/src/clj_cas/cas.clj
@@ -5,7 +5,7 @@

 (defn cas-params [uri user passwd] (CasParams/apply uri user passwd))

-(defn cas-client [^String uri] (CasClient. uri cl/client))
+(defn cas-client [^String uri ^String caller-id] (CasClient. uri cl/client caller-id))

 (defn cassableclient [^CasClient cc ^CasParams cp caller-id session-cookie-name]
   (CasAuthenticatingClient. cc cp cl/client caller-id session-cookie-name))


Adds test for Brain Chip.

Adds test for Brain Chip.

--- src/clj/test/cards-hardware.clj
+++ src/clj/test/cards-hardware.clj
@@ -23,6 +23,22 @@
     (core/play state :corp {:card (first (:hand (get-corp))) :server "Server 0"})
     (is (= 5 (count (:hand (get-runner)))) "Did not draw")
     (is (= 1 (count (:deck (get-runner)))) "1 card left in deck")))
+
+(deftest brain-chip
+  "Brain Chip handsize and memory limit"
+  (do-game
+   (new-game (default-corp) (default-runner [(qty "Brain Chip" 1)]))
+   (take-credits state :corp)
+   (play-from-hand state :runner "Brain Chip")
+   (swap! state assoc-in [:runner :agenda-point] -2) ; hard set ap
+   (is (= (get-in @state [:runner :max-hand-size]) 5) "Hand size unaffected")
+   (is (= (get-in @state [:runner :memory]) 4) "Memory limit unaffected")
+   (swap! state assoc-in [:runner :agenda-point] 2)
+   (is (= (get-in @state [:runner :max-hand-size]) 7) "Hand size increased by 2")
+   (is (= (get-in @state [:runner :memory]) 6) "Memory limit increased by 2")
+   (core/move state :runner (get-in @state [:runner :rig :hardware 0]) :discard)
+   (is (= (get-in @state [:runner :max-hand-size]) 5) "Hand size reset")
+   (is (= (get-in @state [:runner :memory]) 4) "Memory limit reset")))

 (deftest clone-chip
   "Test clone chip usage- outside and during run"


Name all the secretary routes

Name all the secretary routes

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -8,13 +8,13 @@
                             :refer-macros [defroute]]))

 ;; Have secretary pull apart URL's and then dispatch with re-frame
-(defroute "/" []
+(defroute sites-path "/" []
   (rf/dispatch [:sites]))

-(defroute "/comics/:site" [site]
+(defroute comics-path "/comics/:site" [site]
   (rf/dispatch [:comics site]))

-(defroute "/read/:comic/:volume/:page" {:as location}
+(defroute read-path "/read/:comic/:volume/:page" {:as location}
   (rf/dispatch [:read location]))


Move key from inside component to call to component

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -48,8 +48,7 @@
   [(if (= cl-filter letter)
      :dd.active
      :dd)
-   {:key (str "filter-" letter)
-    :role "menuitem"}
+   {:role "menuitem"}
    [:a.button.success.radius
     {:href (r/comics-path
             {:site site
@@ -85,7 +84,8 @@
    [:dl.sub-nav {:role "menu" :title "Comics Filter List"}
     (->> "#ABCDEFGHIJKLMNOPQRSTUVWXYZ"
          seq
-         (map #(conj [filter-element site cl-filter]
+         (map #(conj ^{:key (str "filter-" %)}
+                     [filter-element site cl-filter]
                      %)))]
    [:a.tiny.secondary.button
     {:href (r/comics-path


Play the pitches as a melody.

Play the pitches as a melody.

--- src/cljs/leipzig_live/core.cljs
+++ src/cljs/leipzig_live/core.cljs
@@ -29,8 +29,8 @@
       #(:value %)))

 (defonce context (js/window.AudioContext.))
-(defn beep [freq dur]
-  (let [start (.-currentTime context)
+(defn beep! [freq start dur]
+  (let [start (+ start (.-currentTime context))
         stop (+ start dur)]
     (doto (.createOscillator context)
       (.connect (.-destination context))
@@ -44,9 +44,10 @@
   (when-let [value (evaluate expr-str)]
     (swap! state assoc-in [:music] value)))

+(defn note [t p] {:time t :pitch p})
 (defn play []
-  (doseq [freq (:music @state)]
-    (beep freq 1)))
+  (doseq [{seconds :time hertz :pitch} (map note (range) (:music @state))]
+    (beep! hertz seconds 1)))

 ;; -------------------------
 ;; Views


Support spaces in file names for full screen images

--- src/dashportal/handler.clj
+++ src/dashportal/handler.clj
@@ -63,7 +63,7 @@
   (load-template "iframe-page.html" "**TITLE**" dashboard))

 (defn full-screen-image [board-name image-file-name]
-  (load-template "full-screen-image.html" "**IMAGE**" (str board-name "/" image-file-name)))
+  (load-template "full-screen-image.html" "**IMAGE**" (str board-name "/" (clojure.string/replace image-file-name #" " "%20"))))

 (defn now-in-seconds []
   (int (/ (.getTime (java.util.Date.)) 1000)))


Type hints for GUI REPL

Type hints for GUI REPL

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/contrib/gui/repl.clj
+++ src/conexp/contrib/gui/repl.clj
@@ -9,8 +9,9 @@
 (ns conexp.contrib.gui.repl
   (:import [javax.swing.text PlainDocument]
            [java.io PushbackReader StringReader PipedWriter PipedReader
-                    PrintWriter CharArrayWriter]
-           [javax.swing KeyStroke AbstractAction JTextArea JScrollPane JFrame]
+                    PrintWriter CharArrayWriter PrintStream]
+           [javax.swing KeyStroke AbstractAction JTextArea JScrollPane JFrame
+                        JComponent]
            [java.awt Font Color])
   (:use [conexp.base :only (defvar-)]
         conexp.contrib.gui.util)
@@ -65,9 +66,9 @@
                                       (in-ns 'user)
                                       (use 'conexp.main)
                                       (require '[conexp.contrib.gui.repl-utils :as gui]))
-                              :caught (fn [e]
+                              :caught (fn [^Throwable e]
                                         (if *print-stack-trace-on-error*
-                                          (.printStackTrace e *out*)
+                                          (.printStackTrace e ^PrintStream *out*)
                                           (prn (clojure.main/repl-exception e)))
                                         (when (eof-ex? e)
                                           (throw e))
@@ -180,19 +181,19 @@
   "Adds a given input-event for the given key-sequence to
   component. key-sequence must be a string describing a valid key
   sequence and input-event must be a string."
-  [component key-sequence input-event]
+  [^JComponent component, ^String key-sequence, ^String input-event]
   (.. component getInputMap (put (KeyStroke/getKeyStroke key-sequence) input-event)))

 (defn- add-action-event
   "Adds to component for a given input-event the callback to be called
   when input-event is triggered. input must be a string describing an
   input event and callback must be a function of no arguments."
-  [component input-event callback]
+  [^JComponent component, ^String input-event, callback]
   (.. component getActionMap (put input-event (proxy [AbstractAction] []
                                                 (actionPerformed [_]
                                                   (callback))))))

-(defn- into-text-area
+(defn- ^JTextArea into-text-area
   "Puts repl-container (a PlainDocument) into a JTextArea adding some hotkeys."
   [repl-container repl-thread]
   (let [^JTextArea repl-window (JTextArea. ^javax.swing.text.Document repl-container)]
@@ -210,7 +211,7 @@
   embedded REPL (in a JScrollPane) and the corresponding output
   thread."
   [frame]
-  (let [[repl-container repl-thread output-thread] (make-clojure-repl frame),
+  (let [[repl-container, ^Thread repl-thread, ^Thread output-thread] (make-clojure-repl frame),
         rpl (into-text-area repl-container repl-thread)]
     (doto rpl
       (.setFont (Font. "Monospaced" Font/PLAIN 16))
@@ -223,11 +224,12 @@
 (defn get-repl-thread
   "Returns for a given frame its corresponding repl-thread, if existent."
   [frame]
-  (let [repl-container (get-component frame
-                                      (fn [thing]
-                                        (and (= (class thing) JTextArea)
-                                             (implements-interface? (class (.getDocument thing))
-                                                                    conexp.contrib.gui.repl.ReplProcess))))]
+  (let [^JTextArea repl-container (get-component
+                                   frame
+                                   (fn [thing]
+                                     (and (= (class thing) JTextArea)
+                                          (implements-interface? (class (.getDocument ^JTextArea thing))
+                                                                 conexp.contrib.gui.repl.ReplProcess))))]
     (when repl-container
       (.. repl-container getDocument getReplThreadMap))))


refactor using list* instead of concat

refactor using list* instead of concat

--- src/main/clojure/org/dada/core.clj
+++ src/main/clojure/org/dada/core.clj
@@ -246,11 +246,9 @@
 	version-type (get-attribute-type version-key)
 	attribute-types (map get-attribute-type attribute-keys)
 	attribute-getters
-	(concat
-	 (list
-	  (.getAttributeGetter model-metadata (name key-key))
-	  (.getAttributeGetter model-metadata (name version-key))
-	  )
+	(list*
+	 (.getAttributeGetter model-metadata (name key-key))
+	 (.getAttributeGetter model-metadata (name version-key))
 	 (map (fn [attribute-key] (.getAttributeGetter model-metadata (name attribute-key))) attribute-keys))
 	attributes (interleave attribute-keys attribute-types)
 	class-name (name (gensym "org.dada.demo.whales.Transform"))
@@ -259,7 +257,6 @@
 	view-name (str (.getName src-model) "." suffix)
 	view (model view-name view-metadata)
 	transformer (make-transformer attribute-getters view-metadata view)]
-    ;; the connection between src and view needs to apply the transform...
     (connect src-model transformer)
     view))


Only recurse into join target queries if they are real subqueries

--- src/main/workflo/macros/query.cljc
+++ src/main/workflo/macros/query.cljc
@@ -180,7 +180,7 @@
               (update subquery :parameters bind-params)
               subquery))
           (follow-and-bind-joins [subquery]
-            (if (contains? subquery :join-target)
+            (if (vector? (get subquery :join-target))
               (update subquery :join-target
                       (partial mapv bind-query-params))
               subquery))]


add helpers for 400 responses.

add helpers for 400 responses.

--- src/metabase/api/common.clj
+++ src/metabase/api/common.clj
@@ -87,6 +87,14 @@
 ;;; GENERIC RESPONSE HELPERS
 ;; These are basically the same as the `api-` versions but with RESPONSE-PAIR already bound

+;; GENERIC 400 RESPONSE HELPERS
+;; If you can't be bothered to write a custom error message
+(def generic-400 [400 "Invalid Request."])
+(defn     check-400 [test]    (check test generic-400))
+(defmacro let-400   [& args] `(api-let   ~generic-400 ~@args))
+(defmacro ->400     [& args] `(api->     ~generic-400 ~@args))
+(defmacro ->>400    [& args] `(api->>    ~generic-400 ~@args))
+
 ;; GENERIC 404 RESPONSE HELPERS
 (def generic-404 [404 "Not found."])
 (defn     check-404 [test]    (check test generic-404))


Minor cleanup :shower:

Minor cleanup :shower:

--- src/metabase/middleware.clj
+++ src/metabase/middleware.clj
@@ -54,24 +54,26 @@
                     request))))

+(defn- add-current-user-id [{:keys [metabase-session-id] :as request}]
+  (or (when (and metabase-session-id ((resolve 'metabase.core/initialized?)))
+        (when-let [session (db/select-one [Session :created_at :user_id (db/qualify User :is_superuser)]
+                             (db/join [Session :user_id] [User :id])
+                             (db/qualify User :is_active) true
+                             (db/qualify Session :id) metabase-session-id)]
+          (let [session-age-ms (- (System/currentTimeMillis) (or (when-let [^java.util.Date created-at (:created_at session)]
+                                                                   (.getTime created-at))
+                                                                 0))]
+            ;; If the session exists and is not expired (max-session-age > session-age) then validation is good
+            (when (and session (> (config/config-int :max-session-age) (quot session-age-ms 60000)))
+              (assoc request
+                :metabase-user-id (:user_id session)
+                :is-superuser?    (:is_superuser session))))))
+      request))
+
 (defn wrap-current-user-id
   "Add `:metabase-user-id` to the request if a valid session token was passed."
   [handler]
-  (comp handler (fn [{:keys [metabase-session-id] :as request}]
-                  (or (when (and metabase-session-id ((resolve 'metabase.core/initialized?)))
-                        (when-let [session (db/select-one [Session :created_at :user_id (db/qualify User :is_superuser)]
-                                             (db/join [Session :user_id] [User :id])
-                                             (db/qualify User :is_active) true
-                                             (db/qualify Session :id) metabase-session-id)]
-                          (let [session-age-ms (- (System/currentTimeMillis) (or (when-let [^java.util.Date created-at (:created_at session)]
-                                                                                (.getTime created-at))
-                                                                                0))]
-                            ;; If the session exists and is not expired (max-session-age > session-age) then validation is good
-                            (when (and session (> (config/config-int :max-session-age) (quot session-age-ms 60000)))
-                              (assoc request
-                                :metabase-user-id (:user_id session)
-                                :is-superuser?    (:is_superuser session))))))
-                      request))))
+  (comp handler add-current-user-id))

 (defn enforce-authentication


Prioritize route-params over query params

--- src/nube/app.clj
+++ src/nube/app.clj
@@ -215,7 +215,7 @@

 (defn controller-app [{:keys [params uri] :as req}]
   (if-let [{:keys [handler route-params] :as all} (match-route routes uri)]
-    (let [params (merge route-params (into {} (map (fn [[k v]] [(keyword k) v]) params)))
+    (let [params (merge (into {} (map (fn [[k v]] [(keyword k) v]) params)) route-params)
           fn-params (mapv params (map (comp keyword name) (first (:arglists (meta handler)))))]
       (try
         {:status 200


Block on a latch instead of sleeping to tie up concurrent listeners.

--- modules/messaging/src/test/clojure/wunderboss/messaging_tests.clj
+++ modules/messaging/src/test/clojure/wunderboss/messaging_tests.clj
@@ -143,20 +143,17 @@
 (deftest listen-with-concurrency
   (with-open [connection (.createConnection default nil)
               queue (create-endpoint "listen-queue")]
-    (let [thread-ids (atom #{})
-          latch (java.util.concurrent.CountDownLatch. 10)
+    (let [latch (java.util.concurrent.CountDownLatch. 5)
           listener (.listen connection queue
                      (reify MessageHandler
                        (onMessage [_ msg]
                          (let [msg (read-string (.body msg String))]
-                           (Thread/sleep 50)
-                           (swap! thread-ids conj (.getId (Thread/currentThread)))
-                           (.countDown latch))))
+                           (.countDown latch)
+                           (.await latch))))
                      (coerce-listen-options {:concurrency 5}))]
-      (dotimes [n 10]
+      (dotimes [n 5]
         (.send connection queue (str n) nil nil))
-      (.await latch)
-      (is (= 5 (count @thread-ids)))
+      (is (.await latch 10 TimeUnit/SECONDS))
       (.close listener))))

 (deftest request-response


Toggle controls-visibility by clicking the bg

--- src/app/core.cljs
+++ src/app/core.cljs
@@ -35,6 +35,7 @@
 (defonce print-timer (atom 0))
 (defonce animation-timer (atom 0))

+
 (defonce words
 ;  "Data model"
   (atom ["ClojureScript" "In the browser" "Review your notes" "Generate random associations" "Preview text materials" "React" "Reagent"]))
@@ -50,13 +51,11 @@
 (defonce playmode (atom "drizzle"))
 (defonce randomize? (atom true))

-
 (defn get-player []
   (playmodes @playmode))

 (defn mount-root []
-
   (reagent/render [ctl/control-panel eventbus-in
                    playstate
                    playstates
@@ -108,4 +107,9 @@
             (= e :textarea-import) (importer/textarea-import words))
           (recur)))))

+
+(listen! (sel "#screen") :click
+         (fn [evt]
+           (.toggle (js/jQuery "nav"))))
+
 (restart)


CMR-2306 build test

CMR-2306 build test

--- metadata-db-app/project.clj
+++ metadata-db-app/project.clj
@@ -27,6 +27,7 @@
   {:dev {:dependencies [[org.clojure/tools.namespace "0.2.11"]
                         [org.clojars.gjahad/debug-repl "0.3.3"]
                         [proto-repl "0.3.1"]
+                        [environ "1.1.0"]
                         [pjstadig/humane-test-output "0.8.1"]
                         [clj-http "2.0.0"]
                         [nasa-cmr/cmr-mock-echo-app "0.1.0-SNAPSHOT"]]


Fix printing of wrapper objects in REPL.

--- src/guangyin/internal/types.clj
+++ src/guangyin/internal/types.clj
@@ -31,7 +31,12 @@
   (let [class (resolve type)]
     (cond
       ((supers class) Temporal)
-        `(deftype ~name [parent#]
+      `(do
+         (deftype ~name [parent#]
+           java.lang.Object
+           (equals [this# obj#] (.equals parent# obj#))
+           (hashCode [this#] (.hashCode parent#))
+           (toString [this#] (.toString parent#))
            clojure.lang.IDeref
            (deref [this#] parent#)
            clojure.lang.ILookup
@@ -45,15 +50,32 @@
              (get-entry parent# ~fields key#))
            (assoc [this# key# val#]
              (new ~name (assoc-field parent# ~fields key# val#))))
+         (defmethod print-method ~name [o# w#]
+           (.write w# (str "#<" (.getSimpleName (class o#)) " " (.toString o#) ">"))))
       ((supers class) TemporalAccessor)
-        `(deftype ~name [parent#]
+      `(do
+         (deftype ~name [parent#]
+           java.lang.Object
+           (equals [this# obj#] (.equals parent# obj#))
+           (hashCode [this#] (.hashCode parent#))
+           (toString [this#] (.toString parent#))
            clojure.lang.IDeref
            (deref [this#] parent#)
            clojure.lang.ILookup
            (valAt [this# key#] (get-field parent# ~fields key#))
            (valAt [this# key# notfound#]
              (get-field parent# ~fields key# notfound#)))
+         (defmethod print-method ~name [o# w#]
+           (.write w# (str "#<" (.getSimpleName (class o#)) " " (.toString o#) ">"))))
       :else
-        `(deftype ~name [parent#]
+      `(do
+         (deftype ~name [parent#]
+           java.lang.Object
+           (equals [this# obj#] (.equals parent# obj#))
+           (hashCode [this#] (.hashCode parent#))
+           (toString [this#] (.toString parent#))
            clojure.lang.IDeref
-           (deref [this#] parent#)))))
+           (deref [this#] parent#))
+         (defmethod print-method ~name [o# w#]
+           (.write w# (str "#<" (.getSimpleName (class o#)) " " (.toString o#) ">")))))))
+


Saving changes in entities

Saving changes in entities

--- src/helda/listeners/invoker.clj
+++ src/helda/listeners/invoker.clj
@@ -18,21 +18,24 @@
     }
   )

-(defn invoke-listener [listener action-event]
+(defn invoke-listener [db listener action-event]
   (println "Posting " action-event)
-  (:body
-    (client/post (:action-url listener) {
+  (let [
+    response (client/post (:action-url listener) {
       :form-params action-event
       :content-type :json
       :as :json-strict
       })
+    entities (-> response :body :action-ctx vals)
+    ]
+    (mapv #(save-entity db %) entities)
     )
   )

 (defn fire-action [db action-request]
   (let [action-event (populate-action-event db action-request)]
     (map
-      #(invoke-listener % action-event)
+      #(invoke-listener db % action-event)
       (find-listeners-by-entity-id db
         (:target-entity-id action-request)
         (:action action-request)


Trying to DRY up note selection - might be getting too clever though

--- src/aeolian/abc/notes.clj
+++ src/aeolian/abc/notes.clj
@@ -35,22 +35,23 @@
     (<= 40 method-length) (chord 6 composition-key)
     :else (chord 0 composition-key)))

-(defn- pick-note-from-octave [octave line-length]
-  (nth octave (mod line-length (count octave))))
+(defn- octave-idx-to-octave-name [octave-prefix octave-idx]
+  (intern 'aeolian.abc.notes (symbol (str octave-prefix octave-idx))))
+
+(defn- key-to-octave [octave-idx composition-key]
+  (if (= k/major composition-key)
+    (var-get (octave-idx-to-octave-name "major-octave-" octave-idx))
+    (var-get (octave-idx-to-octave-name "minor-octave-" octave-idx))))
+
+(defn- pick-note-from-octave [octave-idx line-length composition-key]
+  (let [octave (key-to-octave octave-idx composition-key)]
+    (nth octave (mod line-length (count octave)))))

 (defn pick-note-for-line-length [line-length composition-key]
-  (if (= 0 line-length)
-    rest-note
-    (if (= k/major composition-key)
-      (cond
-        (< line-length 10) (pick-note-from-octave major-octave-1 line-length)
-        (<= 10 line-length 39) (pick-note-from-octave major-octave-2 line-length)
-        (<= 40 line-length 79) (pick-note-from-octave major-octave-3 line-length)
-        (<= 80 line-length 99) (pick-note-from-octave major-octave-4 line-length)
-        (<= 100 line-length) (pick-note-from-octave major-octave-5 line-length))
-      (cond
-        (< line-length 10) (pick-note-from-octave minor-octave-1 line-length)
-        (<= 10 line-length 39) (pick-note-from-octave minor-octave-2 line-length)
-        (<= 40 line-length 79) (pick-note-from-octave minor-octave-3 line-length)
-        (<= 80 line-length 99) (pick-note-from-octave minor-octave-4 line-length)
-        (<= 100 line-length) (pick-note-from-octave minor-octave-5 line-length)))))+  (cond
+    (= 0 line-length) rest-note
+    (<= 1 line-length 9) (pick-note-from-octave 1 line-length composition-key)
+    (<= 10 line-length 39) (pick-note-from-octave 2 line-length composition-key)
+    (<= 40 line-length 79) (pick-note-from-octave 3 line-length composition-key)
+    (<= 80 line-length 99) (pick-note-from-octave 4 line-length composition-key)
+    (<= 100 line-length) (pick-note-from-octave 5 line-length composition-key)))


Chases containing only scenes would not run.

Chases were assuming the still-active? function returned an actual
boolean rather than a truthy value, and scenes returned just a truthy
value, so the chase would end instantly. Chases now explicitly convert
to the boolean they need. For consistency, scenes also now return a
boolean, but the real fix is in the chase code.

--- src/afterglow/effects.clj
+++ src/afterglow/effects.clj
@@ -152,7 +152,7 @@
     (Effect. scene-name
              (fn [show snapshot]
                (swap! active (fn [fx] (filterv #(still-active? % show snapshot) fx)))
-               (seq @active))
+               (boolean (seq @active)))
              (fn [show snapshot] (mapcat #(generate % show snapshot) @active))
              (fn [show snapshot]
                (swap! active (fn [fx] (filterv #(not (end % show snapshot)) fx)))
@@ -366,7 +366,7 @@
   ended."
   [active-vec effects show snapshot]
   (vec (map (fn [previously-active effect]
-              (and previously-active (still-active? effect show snapshot)))
+              (and previously-active (boolean (still-active? effect show snapshot))))
             active-vec effects)))

 (defn- end-still-active


FIX: Measurements post returns 202 again on win!

doseq returns nil, thus it needs the extra do wrapper.

--- src/kixi/hecuba/api/measurements.clj
+++ src/kixi/hecuba/api/measurements.clj
@@ -127,20 +127,22 @@
         type          (-> measurements first :type)]
     (db/with-session [session (:hecuba-session store)]
       (if (sensor-exists? session device_id type)
-        (doseq [measurement measurements]
-          (let [t  (util/db-timestamp (:timestamp measurement))
-                m  (stringify-values measurement)
-                m2 {:device_id device_id
-                    :type      type
-                    :timestamp t
-                    :value     (:value m)
-                    :error     (:error m)
-                    :month     (util/get-month-partition-key t)
-                    :reading_metadata  {}}]
-            (->> m2
-                 (v/validate store)
-                 (insert-measurement session))
-            (q/put-on-queue topic m2))
+        (do
+          (doseq [measurement measurements]
+            (let [t  (util/db-timestamp (:timestamp measurement))
+                  m  (stringify-values measurement)
+                  m2 {:device_id        device_id
+                      :type             type
+                      :timestamp        t
+                      :value            (:value m)
+                      :error            (:error m)
+                      :month            (util/get-month-partition-key t)
+                      :reading_metadata {}}]
+              (->> m2
+                   (v/validate store)
+                   (insert-measurement session))
+              (q/put-on-queue topic m2)))
+          ;; doseq returns nil, thus the extra (do ...) wrapper
           {:response {:status 202 :body "Accepted"}})
         {:response {:status 400 :body "Provide valid device_id and type."}}))))


use require :reload-all for tests

use require :reload-all for tests

--- bake/bake/test.clj
+++ bake/bake/test.clj
@@ -17,7 +17,7 @@
   (let [start (System/nanoTime)
         run?  (test-pred opts)]
     (doseq [ns namespaces]
-      (require ns)
+      (require :reload-all ns)
       (when-let [tests (seq (filter (partial run? ns) (ns-publics ns)))]
         (let [ns-meta (meta (find-ns ns))
               once-fixtures (join-fixtures (:clojure.test/once-fixtures ns-meta))


(maint) Coerce URI to str before passing to sl/maplog

The structured logging macro `maplog` will attempt to serialize a
URI, however we need its string representation for our logging. Coerce,
URIs to strings when closing connections due to CRL updates.

--- src/puppetlabs/pcp/broker/core.clj
+++ src/puppetlabs/pcp/broker/core.clj
@@ -703,7 +703,7 @@
     (doseq [[uri client-connection] inventory-snapshot]
       (when (:expired client-connection)
         (do
-          (sl/maplog :debug {:uri uri} #(i18n/trs "Closing expired connection for {0}." (:uri %)))
+          (sl/maplog :debug {:uri (str uri)} #(i18n/trs "Closing expired connection for {0}." (:uri %)))
           (Thread/sleep throttle-duration)
           (websockets-client/close!
             (:websocket client-connection)


rethrow errors after marking as unsent

rethrow errors after marking as unsent

--- src/pc/email.clj
+++ src/pc/email.clj
@@ -197,7 +197,8 @@
       (send-access-grant-email db eid)
       (catch Object e
         (.printStackTrace e)
-        (unmark-sent-email eid :email/access-grant-created)))
+        (unmark-sent-email eid :email/access-grant-created)
+        (throw+ e)))
     (log/infof "not re-sending access-grant email for %s" eid)))

 (defmethod send-entity-email :email/access-request-created
@@ -208,7 +209,8 @@
       (send-access-request-email db eid)
       (catch Exception e
         (.printStackTrace e)
-        (unmark-sent-email eid :email/access-request-created)))
+        (unmark-sent-email eid :email/access-request-created)
+        (throw+ e)))
     (log/infof "not re-sending access-request email for %s" eid)))


Add option data-argument to pepa.bus/notify!.

--- src/pepa/bus.clj
+++ src/pepa/bus.clj
@@ -14,27 +14,27 @@
     (async/sub (:output bus) topic chan)
     chan))

-;;; TODO: Add optional extra data. Replace `identity' in `async/pub'
-;;; below with ::topic or similar and make `notify!' put maps into the
-;;; channel.
-(defn notify! [bus topic]
-  (>!! (:input bus) topic ))
+(defn notify!
+  ([bus topic data]
+   (>!! (:input bus) (assoc data ::topic topic)))
+  ([bus topic]
+   (notify! bus topic {})))

 (defrecord Bus [input output]
   component/Lifecycle
   (start [component]
     (println ";; Starting bus")
     (let [input (async/chan)
-          output (async/pub input identity)]
+          output (async/pub input ::topic)]
       (assoc component
-        :input input
-        :output output)))
+             :input input
+             :output output)))

   (stop [component]
     (println ";; Stopping bus")
     (assoc component
-      :input nil
-      :output nil)))
+           :input nil
+           :output nil)))

 (defn make-component []
   (map->Bus {}))


Do not use naked-address when hashing messages prior to Keycard signing

Signed-off-by: Vitaliy Vlasov <e49d0217baed7632d034fb41cd352d74cf7c0ec8@gmail.com>

--- src/status_im/signing/keycard.cljs
+++ src/status_im/signing/keycard.cljs
@@ -39,7 +39,7 @@
   (if typed?
     {::hash-typed-data {:data         data
                         :on-completed #(re-frame/dispatch [:signing.keycard.callback/hash-message-completed %])}}
-    {::hash-message {:message      (ethereum/naked-address data)
+    {::hash-message {:message      data
                      :on-completed #(re-frame/dispatch [:signing.keycard.callback/hash-message-completed %])}}))

 (fx/defn hash-message-completed


make the pages created by mapv anonymous, don't allow opened sub steps at the same level

Signed-off-by: Chris Granger <5654cde260ae99bc4d30054171b8bcd902efd19a@gmail.com>

--- src/aurora/editor/ui.cljs
+++ src/aurora/editor/ui.cljs
@@ -347,6 +347,19 @@
 (defmethod item-ui :ref/js [step stack opts]
   (item-ui (conj step :js) stack))

+(defn open-sub-step [stack id]
+  (let [opened (from-cache [:open-paths])
+        stack-count (count stack)]
+    (if (get opened stack)
+      (assoc-cache! [:open-paths stack] nil)
+      ;;TODO: this will close things from other notebooks/pages - that's probably wrong.
+      (assoc-cache! [:open-paths] (reduce (fn [final [path v]]
+                                            (if (< (count path) stack-count)
+                                              (assoc final path v)
+                                              final))
+                                          {stack id}
+                                          opened)))))
+
 (defmethod item-ui :ref/id [step stack opts]
   (dom
    (let [page (cursor (:id @step))
@@ -362,7 +375,7 @@
            (item-ui (value-cursor res))]
       page? [:span {:className "ref"
                     :onClick (fn []
-                             (assoc-cache! [:open-paths stack] (:id @step)))
+                               (open-sub-step stack (:id @step)))
                :onContextMenu (ref-menu step stack)}
              [:span {:className "value"}
               (or (:desc @page) (:id @page))]]
@@ -451,7 +464,8 @@
   [:ul
    (each [[ref args] [[(ref-js "cljs.core._PLUS_") (fn [] [1 2])]
                       [(ref-js "cljs.core.mapv") (fn []
-                                                   (let [func (add-page! (current :notebook) "each thing" {:args ["current"]})]
+                                                   (let [func (add-page! (current :notebook) "each thing" {:anonymous true
+                                                                                :args ["current"]})]
                                                      [(ref-id (:id func)) [1 2 3]])
                                                    )]]]
          [:li [:button {:onClick (fn []