Remove comments.

Remove comments.

--- src/videotest/falling/fall_core.clj
+++ src/videotest/falling/fall_core.clj
@@ -98,13 +98,6 @@
                        [0 0 0 255])))
         [display-x display-y] (tri-points coords)
         c (color-fn display-x display-y)]
-    (when (and (= 63 col) (= 0 row))
-      (println "display-x: " display-x)
-      (println "display-y: " display-y)
-      (println "coords: " coords)
-      (println "points: " (tri-glyphs coords))
-      (println "color: " c))
-
     (cv-draw/draw-poly-with-pts drawn-mat c (tri-glyphs coords))))

 (defn overlay-triangles


don't complain when these Mac adapters with different names show missing links

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10903 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- buildscripts/buildcheck/src/buildcheck/core.clj
+++ buildscripts/buildcheck/src/buildcheck/core.clj
@@ -99,7 +99,7 @@
            (let [txt (slurp blacklist)]
              (map #(first (.split % ":")) (.split txt "\n")))))))

-(def non-windows-device-adapters #{"dc1394" "SimpleCam" "Video4Linux"})
+(def non-windows-device-adapters #{"dc1394" "SimpleCam" "Video4Linux" "Spot"})

 (defn device-adapter-dirs []
   (filter #(and (.isDirectory %)
@@ -180,7 +180,7 @@
   (let [index-txt (slurp device-list-page)]
     (remove empty? (map #(.trim %) (map second (re-seq #"\>(.*?)\<" index-txt))))))

-(def dont-link #{"HamamatsuMac NI100X" "NNLC" "Neos" "PriorLegacy" "SimpleCam"})
+(def dont-link #{"HamamatsuMac" "NI100X" "NNLC" "Neos" "PriorLegacy" "SimpleCam" "Spot"})

 (defn missing-device-links []
   (sort (clojure.set/difference


check for failure or error to find failed tests

--- frontend/components/build_head.cljs
+++ frontend/components/build_head.cljs
@@ -251,7 +251,7 @@
       (let [tests-data (:tests-data data)
             tests (:tests tests-data)
             sources (reduce (fn [s test] (conj s (:source test))) #{} tests)
-            failed-tests (filter #(not= "success" (:result %)) tests)]
+            failed-tests (filter #(contains? #{"failure" "error"} (:result %)) tests)]
         (html
          [:div.build-tests-container
           (if-not tests


Fix connection pool leaks on test initialization.

Befor it was leaking datasource connections that
on causes repl blocking after some test executions.

--- test/uxbox/tests/helpers.clj
+++ test/uxbox/tests/helpers.clj
@@ -16,20 +16,19 @@

 (def +base-url+ "http://localhost:5050")
 (def +config+ (ucfg/read-test-config))
-(def +ds+ (up/create-datasource (:database +config+)))

 (defn database-reset
   [next]
-  (with-open [conn (sc/context +ds+)]
-    (sc/execute conn "drop schema if exists public cascade;")
-    (sc/execute conn "create schema public;"))
   (-> (mount/only #{#'uxbox.config/config
                     #'uxbox.persistence/datasource
                     #'uxbox.migrations/migrations
                     #'uxbox.services.auth/secret})
-      (mount/swap {#'uxbox.config/config +config+
-                   #'uxbox.persistence/datasource +ds+})
+      (mount/swap {#'uxbox.config/config +config+})
       (mount/start))
+  (with-open [conn (up/get-conn)]
+    (sc/execute conn (str "truncate txlog, users, projects, pages, pages_history, "
+                          " color_collections, email_queue, image_collections, "
+                          " images CASCADE;")))
   (try
     (next)
     (finally


making sure its a set

making sure its a set

--- src/celestial/persistency/users.clj
+++ src/celestial/persistency/users.clj
@@ -83,4 +83,4 @@
 (defn op-allowed?
    "Checks if user can perform an operation"
    [op {:keys [operations] :as user}]
-    (operations (keyword op)))
+    ((into #{} operations) (keyword op)))


fixing empty yaml

fixing empty yaml

--- src/celestial/puppet_standalone.clj
+++ src/celestial/puppet_standalone.clj
@@ -33,8 +33,8 @@
   (if (and user (not= user "root"))
     (<< "sudo ~{cmd}") cmd))

-(defn args-of [type]
-   (or (some->> (get-in type [:puppet-std :args]) (join " ")) ""))
+(defn args-from [{:keys [args]}]
+   (or (some->> args (join " ")) ""))

 (ns- puppet
    (task copy-module
@@ -43,22 +43,24 @@

    (task extract-module
       (let [{:keys [module]} args]
-       (run (<< " cd /tmp && tar -xzf ~(:name module).tar.gz"))))
+       (run (<< " cd /tmp && tar -xzf ~(module :name).tar.gz"))))

    (task copy-yaml
-     (let [{:keys [type module]} args path (<< "/tmp/~(type :hostname).yml") f (file path) ]
-       (spit f (yaml/generate-string (module :classes)))
+     (let [{:keys [hostname module classes]} args path (<< "/tmp/~{hostname}.yml") f (file path) ]
+       (info args)
+       (spit f (yaml/generate-string classes))
        (debug "copy from " path remote)
        (copy path (<< "/tmp/~(module :name)/"))
        (.delete f)))

    (task run-puppet
-      (let [{:keys [module type]} args]
-        (run (str (<< "cd /tmp/~(:name module)") " && " (as-root remote (<< "./scripts/run.sh ~(args-of type) --detailed-exitcodes || [ $? -eq 2 ]"))))))
+      (let [{:keys [module]} args]
+        (run (str (<< "cd /tmp/~(module :name)") " && "
+          (as-root remote (<< "./scripts/run.sh ~(args-from args) --detailed-exitcodes || [ $? -eq 2 ]"))))))

    (task cleanup-tmp
       (let [{:keys [module]} args]
-        (run (<< "rm -rf /tmp/~(:name module)*")))))
+        (run (<< "rm -rf /tmp/~(module :name)*")))))

 (lifecycle cleanup {:doc "puppet standalone cleanup"}
    {puppet/cleanup-tmp #{}})
@@ -70,17 +72,17 @@
    puppet/run-puppet #{puppet/cleanup-tmp}
    })

-(defrecord Standalone [remote type env]
+(defrecord Standalone [remote m]
   Provision
   (apply- [this]
-    (let [puppet-std (get-in type [:puppet-std env]) module (puppet-std :module)
-          roles {:roles {:web #{remote}}}
-          res (execute puppet-provision {:module module :type type} :web :env roles)]
+    (let [roles {:roles {:web #{remote}}}
+          res (execute puppet-provision m :web :env roles)]
         (when-let [fail (-> res first :fail)]
           (throw fail))
       )))

 (defmethod pconstruct :puppet-std [type {:keys [machine env] :as spec}]
-  (let [remote {:host (machine :ip) :user (or (machine :user) "root")}]
-    (Standalone. remote (assoc type :hostname (machine :hostname)) env)))
+  (let [remote {:host (machine :ip) :user (or (machine :user) "root")}
+        by-env (get-in type [:puppet-std env])]
+    (Standalone. remote (assoc by-env :hostname (machine :hostname)))))


Tests: uncomment stuff (?)

Tests: uncomment stuff (?)

--- test/test_faraday/main.clj
+++ test/test_faraday/main.clj
@@ -32,7 +32,7 @@
 (deftest test-batch-simple
   (setup-table)

-  (let [;; result (batch-get-item creds table '("1" "2" "3" "4")) ; TODO PR
+  (let [result (batch-get-item cred table '("1" "2" "3" "4"))
         consis (batch-get-item creds {
                  table {
                    :consistent true
@@ -42,7 +42,7 @@
                    :consistent true
                    :attrs [attr]
                    :keys ["1" "2" "3" "4"]}})
-        ;; items  (get-in result [:responses table :items]) ; TODO PR
+        items  (get-in result [:responses table :items])
         item-1 (get-item creds table "1")
         item-2 (get-item creds table "2")
         item-3 (get-item creds table "3")
@@ -53,10 +53,10 @@
     (is (= "baz" (item-3 attr)) "batch-write-item :put failed")
     (is (= "foobar" (item-4 attr)) "batch-write-item :put failed")

-    ;; (is (= true (some #(= (% attr) "foo") items))) ; TODO PR
+    (is (= true (some #(= (% attr) "foo") items)))
     (is (= true (some #(= (% attr) "bar") (get-in consis [:responses table :items]))))
     (is (= true (some #(= (% attr) "baz") (get-in attrs [:responses table :items]))))
-    ;; (is (= true (some #(= (% attr) "foobar") items))) ; TODO PR
+    (is (= true (some #(= (% attr) "foobar") items)))

     (batch-write-item creds
       [:delete table {:hash-key "1"}]


Updates some data.

Updates some data.

--- src/tumblr_identity_manager/data.clj
+++ src/tumblr_identity_manager/data.clj
@@ -18,7 +18,7 @@
                         :third-singular-object "xir"
                         :reflexive "xirself"}
     :social-justice-causes ["manspreading"
-                            "class struggle"
+                            "microaggressions"
                             "white able-bodied heterosexual cisgender male privilege"]
     :trigger-words ["food"
                     "dessert"
@@ -42,7 +42,7 @@
                          :m-shift true
                          :p-shift false}
     :social-justice-causes ["HAES/FA"
-                            "sexual consent"
+                            "shirtgate"
                             "slut shaming"]
     :nounself-pronouns {:third-singular-subject "accipatheriposimuisea"
                         :third-singular-object "accipatheriposimoisiam"


Add morpheus to dev script includes

Add morpheus to dev script includes

--- src/clj/clojuredocs/site/common.clj
+++ src/clj/clojuredocs/site/common.clj
@@ -93,6 +93,8 @@
       [:script
        "!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');"]]]
     (when (env/bool :cljs-dev)
+      [:script {:src "/js/morpheus.min.js"}])
+    (when (env/bool :cljs-dev)
       [:script {:src "http://fb.me/react-0.9.0.js"}])
     (when (env/bool :cljs-dev)
       [:script {:type "text/javascript" :src "/cljs/goog/base.js"}])


more margin

more margin

--- src/clj/just_married/api/labels.clj
+++ src/clj/just_married/api/labels.clj
@@ -9,7 +9,7 @@
             [just-married.auth :refer [with-basic-auth]]
             [just-married.db :as db]))

-(def ^:private default-n-cols 2)
+(def ^:private default-n-cols 3)
 (def ^:private file-name "labels.pdf")
 (def ^:private default-font "Helvetica")

@@ -31,10 +31,10 @@

 (def pdf-options
   {:title                  "Address List"
-   :left-margin            2
-   :right-margin           2
-   :top-margin             2
-   :bottom-margin          2
+   :left-margin            10
+   :right-margin           10
+   :top-margin             8
+   :bottom-margin          8
    :size                   :a4
    :font                   {:size     12
                             :family   default-font


Removed `case`

Removed `case`

--- src/clj/kixi/hecuba/api/devices.clj
+++ src/clj/kixi/hecuba/api/devices.clj
@@ -132,15 +132,10 @@
   "Added to fix the absence of some synthetic sensors."
   [sensors]
   (let [cumulative-sensors (get-sensor sensors "CUMULATIVE")]
-    (case (count cumulative-sensors)
-      1 (let [cumulative-sensor (first cumulative-sensors)
-              pulse-sensor (ext-type cumulative-sensor "differenceSeries")
-              calc-sensor (calculated-sensor pulse-sensor)]
-          (vector cumulative-sensor pulse-sensor calc-sensor))
-      > 1 (let [pulse-sensors (map #(ext-type % "differenceSeries")
-                                   cumulative-sensors)
-                calc-sensors (map #(calculated-sensor %) pulse-sensors)]
-            (vector cumulative-sensors pulse-sensors calc-sensors)))))
+    (let [pulse-sensors (map #(ext-type % "differenceSeries")
+                             cumulative-sensors)
+          calc-sensors (map #(calculated-sensor %) pulse-sensors)]
+      (vector cumulative-sensors pulse-sensors calc-sensors))))

 (defn create-synth-sensors-default
   "The original way of creating synthetic sensors.


updates since MockTridentTuple is gone in latest storm

--- src/clj/marceline/storm/testing.clj
+++ src/clj/marceline/storm/testing.clj
@@ -6,10 +6,13 @@
            [marceline.storm.trident ClojureTridentTuple]
            [storm.trident.testing
             MemoryMapState$Factory
-            LRUMemoryMapState$Factory MockTridentTuple]
+            LRUMemoryMapState$Factory]
            [storm.trident.operation.impl CaptureCollector]
            [storm.trident.operation TridentOperationContext]
-           [storm.trident.tuple TridentTupleView$RootFactory TridentTuple$Factory]
+           [storm.trident.tuple
+            TridentTupleView
+            TridentTupleView$RootFactory
+            TridentTuple$Factory]
            [backtype.storm.tuple Fields]
            [backtype.storm.task TopologyContext]))

@@ -34,9 +37,9 @@
   "Create a new mock trident tuple. Field values should come in the format of field, value, field value. e.g:
    (new-mocj-tuple :a \"a-value\" :b \"b-value\" :c \"c what I did there?\")"
   [& args]
-  (let [fields (map name (take-nth 2 args))
+  (let [fields (apply trident/fields (map name (take-nth 2 args)))
         values (take-nth 2 (rest args))]
-    (MockTridentTuple. fields values)))
+    (TridentTupleView/createFreshTuple fields values)))

 (defn- new-nil-context
   "Creates a TridentOperationContext with nil topology and tuple factory for testing."
@@ -90,26 +93,3 @@
      :zero         (.zero aggregator)
      :combine      (.combine aggregator (.init aggregator mtuple1) (.init aggregator mtuple2))
      :combine-zero (.combine aggregator (.init aggregator mtuple1) (.zero aggregator))}))
-
-(extend-type MockTridentTuple
-  trident/ClojureTridentTuple
-  (first
-    [this]
-    (.getValue ^MockTridentTuple this 0))
-  (count
-    [this]
-    (.size ^MockTridentTuple this))
-  (get
-    ([this field]
-     (.getValueByField ^MockTridentTuple this (name field)))
-    ([this field not-found]
-     (or (.getValueByField ^MockTridentTuple this (name field))
-         not-found)))
-  (nth
-    ([this index]
-     (.getValue ^MockTridentTuple this index))
-    ([this index not-found]
-     (or (.getValue ^MockTridentTuple this index)
-         not-found)))
-  (vals [this]
-    (.getValues ^MockTridentTuple this)))


Extract functions for showing/hiding spinner

--- src/cljs/asciinema_player/core.cljs
+++ src/cljs/asciinema_player/core.cljs
@@ -37,6 +37,12 @@

 (defn dispatch [player event]
   (put! (:event-ch player) event))
+
+(defn show-spinner [player]
+  (assoc player :loading true))
+
+(defn hide-spinner [player]
+  (assoc player :loading false))

 (defn elapsed-time-since
   "Returns wall time (in seconds) elapsed since then."
@@ -204,7 +210,7 @@
          {:response-format :raw
           :handler #(dispatch player [:asciicast-response %])
           :error-handler #(dispatch player [:bad-response %])})
-    (assoc player :loading true)))
+    (show-spinner player)))

 (defn asciicast-loaded?
   "Returns truthy value indicating whether asciicast is loaded."
@@ -418,17 +424,17 @@
 (defn handle-bad-response [player resp]
   (print "error fetching asciicast file:")
   (prn resp)
-  (assoc player :loading false))
+  (hide-spinner player))

 (defn handle-stream-connected
   "Hides loading indicator. Called when stream connects."
   [player]
-  (assoc player :loading false))
+  (hide-spinner player))

 (defn handle-stream-disconnected
   "Shows loading indicator. Called when stream disconnects."
   [player]
-  (assoc player :loading true))
+  (show-spinner player))

 (defn handle-update-state
   "Applies given function (with args) to player."


figwheel-repl: print captured output to console if its called for

--- figwheel-repl/src/figwheel/repl.cljc
+++ figwheel-repl/src/figwheel/repl.cljc
@@ -242,7 +242,7 @@
        (map string/trim)
        (filter (complement string/blank?))
        (map keyword)
-       distinct))
+       set))

 (defmulti out-print (fn [k args] k))
 (defmethod out-print :console [_ args]
@@ -319,7 +319,8 @@
          product/SAFARI    :safari
          product/CHROME    :chrome
          product/FIREFOX   :firefox
-         product/IE        :ie)]
+         product/IE        :ie)
+      print-to-console? ((print-receivers print-output) :console)]
   (defn eval-javascript** [code]
     (let [ua-product (ua-product-fn)]
       (try
@@ -327,9 +328,12 @@
           ;; TODO capture err as well?
           (binding [cljs.core/*print-newline* true
                     cljs.core/*print-fn* (fn [x] (.append sb x))]
-            (let [result-value (*eval-js* code)]
+            (let [result-value (*eval-js* code)
+                  output-str (str sb)]
+              (when print-to-console?
+                (js/setTimeout #(out-print :console output-str) 0))
               {:status :success
-               :out (str sb)
+               :out output-str
                :ua-product ua-product
                :value result-value})))
         (catch js/Error e


Jumping to 0%, 10%, 20%, 30%... with keys "0", "1", "2", "3"...

--- src/cljs/asciinema_player/view.cljs
+++ src/cljs/asciinema_player/view.cljs
@@ -142,6 +142,16 @@
   (case (.-key dom-event)
     " " [:toggle-play]
     "f" [:toggle-fullscreen]
+    "0" [:seek 0.0]
+    "1" [:seek 0.1]
+    "2" [:seek 0.2]
+    "3" [:seek 0.3]
+    "4" [:seek 0.4]
+    "5" [:seek 0.5]
+    "6" [:seek 0.6]
+    "7" [:seek 0.7]
+    "8" [:seek 0.8]
+    "9" [:seek 0.9]
     nil))

 (defn map-key-down [dom-event]


sorted identities alphabetically in deckbuilder

--- src/cljs/netrunner/deckbuilder.cljs
+++ src/cljs/netrunner/deckbuilder.cljs
@@ -409,7 +409,7 @@
              [:h3 "Identity"]
              [:select.identity {:value (get-in state [:deck :identity :title])
                                 :on-change #(om/set-state! owner [:deck :identity] (get-card (.. % -target -value)))}
-              (for [card (side-identities (get-in state [:deck :identity :side]))]
+              (for [card (sort-by :title (side-identities (get-in state [:deck :identity :side])))]
                 [:option (:title card)])]]
             (om/build card-lookup cursor {:state state})
             [:h3 "Decklist"


Added find-by-path multi-method (wrapper around FileFolderService.resolveNamePath)

--- src/clojure/alfresco/filefolder.clj
+++ src/clojure/alfresco/filefolder.clj
@@ -14,8 +14,9 @@
 ; limitations under the License.

 (ns alfresco.filefolder
-  (:require [alfresco.core :as c]
-            [alfresco.auth :as a])
+  (:require [clojure.string :as s]
+            [alfresco.core  :as c]
+            [alfresco.nodes :as n])
   (:import [org.alfresco.service.cmr.model FileFolderService
                                            FileInfo]
            [org.alfresco.model ContentModel]))
@@ -55,3 +56,28 @@
   [source-node target-parent new-name]
   { :pre (exist? [source-node target-parent]) }
   (.getNodeRef (.copy (file-folder-service) source-node target-parent new-name)))
+
+; N00B WARNING: Don't yet know how to express this inline as an anonymous fn...
+(defn- first-sequential?
+  [& args]
+  (sequential? (first args)))
+
+(defmulti find-by-path
+  "Finds a node at the given path location, optionally providing a start-node (defaults to Company Home).
+  Returns nil if the path does not identify a node."
+  first-sequential?)
+
+(defmethod find-by-path true
+  ([path-elems] (find-by-path path-elems (n/company-home)))
+  ([path-elems start-node]
+    (let [file-info (.resolveNamePath (file-folder-service) start-node path-elems false)]
+      (if (nil? file-info)
+        nil
+        (.getNodeRef file-info)))))
+
+; This version of the multi-method converts the incoming path to a string, then splits it on "/". Naive, but useful...
+(defmethod find-by-path false
+  ([path] (find-by-path path (n/company-home)))
+  ([path start-node]
+    (find-by-path (filter #(< 0 (.length %)) (s/split (str path) #"/")) start-node)))
+


Fix relative indexing of appending autoconstruction instructions

--- src/clojush/instructions/genome.clj
+++ src/clojush/instructions/genome.clj
@@ -817,8 +817,8 @@
                      []
                      (stack-ref :genome 0 state))
             length (count genome)
-            start (stack-ref :integer 1 state)
-            end (stack-ref :integer 0 state)
+            start (+ length (stack-ref :integer 1 state))
+            end (+ length (stack-ref :integer 0 state))
             source (:parent1-genome state)
             max-length (int (/ @global-max-points 4))]
         (if (>= (+ length (Math/abs (float (- start end))))
@@ -853,8 +853,8 @@
                      []
                      (stack-ref :genome 0 state))
             length (count genome)
-            start (stack-ref :integer 1 state)
-            end (stack-ref :integer 0 state)
+            start (+ length (stack-ref :integer 1 state))
+            end (+ length (stack-ref :integer 0 state))
             source (:parent2-genome state)
             max-length (int (/ @global-max-points 4))]
         (if (>= (+ length (Math/abs (float (- start end))))
@@ -905,5 +905,3 @@
       (push-item (count (stack-ref :genome 0 state))
                  :integer
                state))))
-
-


Remove apply since signature is not variadic

Fixes #70

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -749,13 +749,20 @@
   (apply clojure.core/swap-vals! (:*clock at) f args))

 (defn compare-and-set! [at oldval newval]
-  (apply clojure.core/compare-and-set! (:*clock at) oldval newval))
+  (clojure.core/compare-and-set!
+   (:*clock at)
+   oldval
+   newval))

 (defn reset! [at newval]
-  (apply clojure.core/reset! (:*clock at) newval))
+  (clojure.core/reset!
+   (:*clock at)
+   newval))

 (defn reset-vals! [at newval]
-  (apply clojure.core/reset-vals! (:*clock at) newval))
+  (clojure.core/reset-vals!
+   (:*clock at)
+   newval))

 ;; Arithmetic

@@ -1152,4 +1159,3 @@
 (defn zone-offset?      [v] (cljc.java-time.extn.predicates/zone-offset? v))
 (defn zoned-date-time?  [v] (cljc.java-time.extn.predicates/zoned-date-time? v))
 (defn interval?         [v] (satisfies? ITimeSpan v))
-


add missing om instrumentation ex

add missing om instrumentation ex

--- lein/src/leiningen/new/mala/utils.cljs
+++ lein/src/leiningen/new/mala/utils.cljs
@@ -1,6 +1,8 @@
 (ns {{name}}.ui.utils
   (:require [cljs.reader :as reader]
-            [clojure.string :as str])
+            [clojure.string :as str]
+            [om.core :as om]
+            [om-i.core :as omi])
   (:import [goog.ui IdGenerator]))

 (enable-console-print!)
@@ -55,3 +57,11 @@
                        [(.toString  (bit-or 0x8 (bit-and 0x3 (rand-int 15))) 16)]
                        (take 3 (drop 15 r)) ["-"]
                        (take 12 (drop 18 r))))))
+
+;; Om Instrumentation
+(defn with-omi []
+  (fn [f cursor m]
+    (om/build* f cursor
+               (assoc m
+                      :descriptor omi/instrumentation-methods))))
+


Fix missing table-id

Fix missing table-id

--- src-cljs/kixi/hecuba/sensor.cljs
+++ src-cljs/kixi/hecuba/sensor.cljs
@@ -20,7 +20,8 @@
       (let [sensors (:sensors data)
             chart   (:chart data)
             cols    (get-in sensors [:header :cols])
-            history (om/get-shared owner :history)]
+            history (om/get-shared owner :history)
+            table-id "sensors-table"]

         (html
          [:table {:className "table table-hover"}


Avoid refreshing in Data Analyser

Avoid refreshing in Data Analyser

--- src-cljs/photon/ui/frontend.cljs
+++ src-cljs/photon/ui/frontend.cljs
@@ -1186,11 +1186,12 @@
             default (:stream def-schema)]
         {:analyse-stream default
          :analyse-version (first (keys (:schemas def-schema)))
-         :streams streams}))
+         :streams streams
+         :data data}))
     om/IRenderState
     (render-state [_ state]
       (let [schema (first (filter #(= (:analyse-stream state) (:stream %))
-                                  (:streams data)))
+                                  (:streams (:data state))))
             my-schema (get (:schemas schema) (:analyse-version state))
             with-name (merge my-schema (dissoc schema :schemas))]
         (dom/div


License text into jenkins-api module

License text into jenkins-api module

--- src/emender_service/jenkins_api.clj
+++ src/emender_service/jenkins_api.clj
@@ -1,3 +1,15 @@
+;
+;  (C) Copyright 2016  Pavel Tisnovsky
+;
+;  All rights reserved. This program and the accompanying materials
+;  are made available under the terms of the Eclipse Public License v1.0
+;  which accompanies this distribution, and is available at
+;  http://www.eclipse.org/legal/epl-v10.html
+;
+;  Contributors:
+;      Pavel Tisnovsky
+;
+
 (ns emender-service.jenkins-api)

 (require '[clojure.xml       :as xml])


[Issue #75] changing report wording to be match the style shown on the issue.

--- src/midje/internal_ideas/report.clj
+++ src/midje/internal_ideas/report.clj
@@ -109,14 +109,14 @@
   (defmethod report-strings :mock-incorrect-call-count [m]
     (letfn [(report-fail [fail]
               (list
-                (if (zero? (:actual-count fail))
-                  "You claimed the following was needed, but it was never used:"
-                  (cl-format nil
-                    "The following prerequisite was used ~R time~:P. That's not what you predicted."
-                    (:actual-count fail)))
-                (str "    " (:expected fail))))]
+                (str "    " (:expected fail)
+                  (if (zero? (:actual-count fail))
+                    " [expected at least once, actually never called]"
+                    (cl-format nil " [actually called ~R time~:P]" (:actual-count fail))))))]

-    (cons (fail-at (first (:failures m)))
+    (concat
+          (list (fail-at (first (:failures m))))
+          (list "These calls were not made the right number of times:")
           (mapcat report-fail (:failures m)))))

   (defmethod report-strings :validation-error [m]


Add the logging of who is disconnecting

Add the logging of who is disconnecting

--- src/puppetlabs/cthun/websockets.clj
+++ src/puppetlabs/cthun/websockets.clj
@@ -48,7 +48,6 @@
   (time! metrics/time-in-on-text
          (let [host (get-hostname ws)]
            (log/info "Received message from client" host)
-           (log/info "Validating Message...")
            (if-let [message-body (validation/validate-message message)]
              (cs/process-message host ws message-body)
              (log/warn "Received message does not match valid message schema. Dropping.")))))
@@ -67,11 +66,11 @@
 (defn- on-close!
   "OnClose websocket event handler"
   [ws status-code reason]
-  (log/info "Connection terminated with statuscode: " status-code ". Reason: " reason)
-  (log/debug "Removing connection from connection-map")
-  (dec! metrics/active-connections)
-  (time! metrics/time-in-on-close
-         (cs/remove-connection (get-hostname ws) ws)))
+  (let [hostname (get-hostname ws)]
+    (log/info "Connection from" hostname "terminated with statuscode:" status-code " Reason:" reason)
+    (dec! metrics/active-connections)
+    (time! metrics/time-in-on-close
+           (cs/remove-connection hostname ws))))

 ; Public Interface


Simplify reverse sort

Simplify reverse sort

--- frontend/src/cruncher/utils/lib.cljs
+++ frontend/src/cruncher/utils/lib.cljs
@@ -19,7 +19,7 @@
             :progress-running? false
             :player            {}
             :evolution-number  0
-            :sort-asc              true}))
+            :sort-asc          true}))

 (declare get-pokemon-by-id)
 (declare evolution-sum)
@@ -67,12 +67,10 @@

 (defmethod mutate 'sort/pokemon
   [{:keys [state]} _ {:keys [key]}]
-  {:action (fn [] (swap! state update-in [:pokemon] (fn [] (cond-> (sort-by (juxt key :individual_percentage :cp) (:pokemon @state))
-                                                                  (:sort-asc @state) reverse))))})
-
-(defmethod mutate 'sort/toggle-asc
-  [{:keys [state]} _ {:keys []}]
-  {:action (fn [] (swap! state update-in [:sort-asc] not))})
+  {:action (fn []
+             (swap! state update-in [:pokemon] (fn [] (cond-> (sort-by (juxt key :individual_percentage :cp) (:pokemon @state))
+                                                              (:sort-asc @state) reverse)))
+             (swap! state update-in [:sort-asc] not))})

 (defmethod mutate 'change/view
   [{:keys [state]} _ {:keys [view]}]
@@ -243,8 +241,7 @@
 (defn sort-pokemon!
   "Sort complete list of pokemon by given key."
   [key]
-  (om/transact! reconciler `[(sort/pokemon {:key ~key})])
-  (om/transact! reconciler `[(sort/toggle-asc)]))
+  (om/transact! reconciler `[(sort/pokemon {:key ~key})]))

 (defn update-player!
   "Update the playerdata."


Removed obsolete code.

Removed obsolete code.

--- umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
+++ umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
@@ -29,10 +29,6 @@
   [:dif :dif10 :echo10 :iso19115 :iso-smap])

 (def test-context (lkt/setup-context-for-test))
-
-(def tested-service-formats
-  "Seq of formats to use in round-trip conversion and XML validation tests."
-  [:serf])

 (def collection-destination-formats
   "Converting to these formats is tested in the roundrobin test."


auth refactoring

auth refactoring

--- server/src/gratefulplace/server.clj
+++ server/src/gratefulplace/server.clj
@@ -3,14 +3,11 @@
   (:require [compojure.core :as compojure]
             [rabble.ring-app :as ring-app]
             [rabble.middleware.routes :as routes]
+            [rabble.middleware.auth :refer (auth)]
             [ring.adapter.jetty :refer (run-jetty)]))

-(defn debug [f]
-  (fn [{:keys [uri request-method params session] :as request}]
-    (println params)
-    (f request)))
-
-(def app (ring-app/wrap (compojure/routes routes/auth-routes routes/rabble-routes)))
+(def app (ring-app/wrap
+          (auth (compojure/routes routes/auth-routes routes/rabble-routes))))

 (defn -main
   "Start the jetty server"


Add benchmarks to test transient navigators

--- scripts/benchmarks.clj
+++ scripts/benchmarks.clj
@@ -1,6 +1,7 @@
 (ns com.rpl.specter.benchmarks
   (:use [com.rpl.specter]
         [com.rpl.specter macros]
+        [com.rpl.specter.transient]
         [com.rpl.specter.impl :only [benchmark]])
   (:require [clojure.walk :as walk]))

@@ -141,3 +142,46 @@
     (tree-value-transform (fn [e] (if (even? e) (inc e) e)) data)
     ))

+(run-benchmark "transient comparison: building up vectors"
+  6
+  10000
+  (reduce (fn [v i] (conj v i)) [] (range 1000))
+  (reduce (fn [v i] (conj! v i)) (transient []) (range 1000))
+  ;; uncomment this when END is fast
+  #_(reduce (fn [v i] (setval [END] [i] v)) [] (range 1000))
+  (setval [END!] (range 1000) (transient []))
+  (reduce (fn [v i] (setval [END!] [i] v)) (transient []) (range 1000)))
+
+(let [data (vec (range 1000))
+      tdata (transient data)]
+  (run-benchmark "transient comparison: assoc'ing in vectors"
+    6
+    500000
+    (assoc data (rand-int 1000) 0)
+    (assoc! tdata (rand-int 1000) 0)
+    (setval [(keypath (rand-int 1000))] 0 data)
+    (setval [(keypath! (rand-int 1000))] 0 tdata)))
+
+(let [data (into {} (for [k (range 1000)]
+                      [k (rand)]))
+      tdata (transient data)]
+  (run-benchmark "transient comparison: assoc'ing in maps"
+    6
+    500000
+    (assoc data (rand-int 1000) 0)
+    (assoc! tdata (rand-int 1000) 0)
+    (setval [(keypath (rand-int 1000))] 0 data)
+    (setval [(keypath! (rand-int 1000))] 0 tdata)))
+
+(defn modify-submap
+  [m]
+  (assoc m 0 1 458 89))
+
+(let [data (into {} (for [k (range 1000)]
+                      [k (rand)]))
+      tdata (transient data)]
+  (run-benchmark "transient comparison: submap"
+    6
+    300000
+    (transform [(submap [(rand-int 1000)])] modify-submap data)
+    (transform [(submap! [(rand-int 1000)])] modify-submap tdata)))


An old test file removed

An old test file removed

--- test/clj/hellhound/system_tests.clj
+++ test/clj/hellhound/system_tests.clj
@@ -1,16 +0,0 @@
-(ns hellhound.system-tests
-  (:require [hellhound.system :as sut]
-            [clojure.test     :refer :all]))
-
-
-(defn test-component
-  [system]
-  (assoc-in system [:test-component] (fn [] nil)))
-
-(sut/defsystem test-system
-  (test-component))
-
-(deftest defsystem-test
-  (let [subject test-system]
-    (is (function? subject))
-    (is (function? (:test-component (subject))))))


Fix test daemon checks

Fix test daemon checks

--- test/com/climate/claypoole_test.clj
+++ test/com/climate/claypoole_test.clj
@@ -37,18 +37,18 @@
     (let [factory (.getThreadFactory pool)
           start (promise)
           thread (.newThread factory #(deref start))]
-      (is (false? (.isDaemon thread)))
+      (is (true? (.isDaemon thread)))
       (is (not (empty? (re-find #"claypoole-[0-9]*-4" (.getName thread)))))
       (is (= (.getPriority (Thread/currentThread)) (.getPriority thread)))))
   (cp/with-shutdown! [pool (pool-constructor 4
-                                             :daemon true
+                                             :daemon false
                                              :name "fiberpond"
                                              :thread-priority 4)]
     (dotimes [_ 8] (.submit pool #(inc 1)))
     (let [factory (.getThreadFactory pool)
           start (promise)
           thread (.newThread factory #(deref start))]
-      (is (true? (.isDaemon thread)))
+      (is (false? (.isDaemon thread)))
       (is (= "fiberpond-4" (.getName thread)))
       (is (= 4 (.getPriority thread))))))


Added more format tests

Added more format tests

--- src/test/clojure/gpio_core_test.clj
+++ src/test/clojure/gpio_core_test.clj
@@ -53,6 +53,28 @@
     (write-value! port :low)
     (is (= false (read-value port)))))

+(deftest test-read-integer
+  (spit "/sys/class/gpio/gpio2/value" \1)
+  (let [port (open-port 2 :digital-result-format :integer)]
+    (is (= 1 (read-value port)))
+    (write-value! port :low)
+    (is (= 0 (read-value port)))))
+
+(deftest test-read-char
+  (spit "/sys/class/gpio/gpio2/value" \1)
+  (let [port (open-port 2 :digital-result-format :char)]
+    (is (= \1 (read-value port)))
+    (write-value! port :low)
+
+(deftest test-read-custom
+  (spit "/sys/class/gpio/gpio2/value" \1)
+  (let [port (open-port 2 :from-raw-fn #(if (= \1 %) :foo :bar))]
+    (is (= :foo (read-value port)))
+    (write-value! port :low)
+    (is (= :bar (read-value port)))))
+
+   (is (= \0 (read-value port)))))
+
 (deftest test-set-direction
   (spit "/sys/class/gpio/gpio19/value" \0)
   (let [port (open-port 19)]


Reset conn atom when stopping slack connection.

--- src/yetibot/core/adapters/slack.clj
+++ src/yetibot/core/adapters/slack.clj
@@ -172,7 +172,8 @@

 (defn stop []
   (when @conn
-    (slack/send-event (:dispatcher @conn) :close)))
+    (slack/send-event (:dispatcher @conn) :close))
+  (reset! conn nil))

 (defn start []
   (stop)


don't clear highlight on modifier press

don't clear highlight on modifier press

--- src/chat/client/new-message.cljs
+++ src/chat/client/new-message.cljs
@@ -4,7 +4,8 @@
             [clojure.string :as string]
             [chat.client.views.helpers :as helpers]
             [chat.client.dispatcher :refer [dispatch!]]
-            [chat.client.store :as store]))
+            [chat.client.store :as store])
+  (:import [goog.events KeyCodes]))

 (defn new-message-view [config owner]
   (reify
@@ -87,7 +88,8 @@
                                      (.preventDefault e)
                                      (highlight-next!))
                                    :else
-                                   (do
+                                   (when (KeyCodes.isTextModifyingKeyEvent e)
+                                     ; Don't clear if a modifier key alone was pressed
                                      (highlight-clear!))))})

             (when autocomplete-open?


Minor refactor

Minor refactor

--- test/obb_rules/actions/move_test.clj
+++ test/obb_rules/actions/move_test.clj
@@ -1,5 +1,6 @@
 (ns obb-rules.actions.move-test
   (:use clojure.test
+        midje.sweet
         obb-rules.action
         obb-rules.actions.move
         obb-rules.board
@@ -24,9 +25,9 @@
     (is (not old-element))
     (is new-element)))

-(deftest all-movement
+(deftest movement-restrictions

-  (testing "all movement complete"
+  (testing "all-movement does not have restrictions"
     (test-complete-move board [2 2] [1 1])
     (test-complete-move board [2 2] [1 2])
     (test-complete-move board [2 2] [1 3])
@@ -104,3 +105,5 @@
             result (move-down board)]
         (is (failed? result))
         (is (= "EmptyCoordinate" (result-message result)))))))
+
+(run-tests)


lein-nubank

lein-nubank

--- stow/lein-nubank/.lein/profiles.clj
+++ stow/lein-nubank/.lein/profiles.clj
@@ -1,5 +1,5 @@
 {:user
- {:dependencies        [[cljdev "0.8.0"]]
+ {:dependencies        [[cljdev "0.9.0"]]

   :injections          [(require 'nu)]

@@ -14,7 +14,8 @@
   :plugins             [[s3-wagon-private "1.3.1" :upgrade false]
                         [venantius/ultra "0.6.0"]
                         [lein-ancient "0.6.15"]
-                        [lein-auto "0.1.3"]]}
+                        [lein-auto "0.1.3"]
+                        [com.jakemccrary/lein-test-refresh "0.24.1"]]}

  :repl {:plugins      [[cider/cider-nrepl "0.21.1"]
                        [refactor-nrepl "2.4.0"]
@@ -25,7 +26,7 @@
                        [olical/propel "1.3.0"]
                        [mvxcvi/puget "1.1.1"]]}

- :repl-options {:init (do (println "PASOU AQUI")
+ :repl-options {:init (do (println "Starting Propel...")
                           (require 'propel.core)
                           (let [prepl (propel.core/start-prepl! {:port-file? true})]
                             (println "pREPL server started on port"


Fix line-atom updates on update!

Fix line-atom updates on update!

--- src/org/knotation/editor/update.cljs
+++ src/org/knotation/editor/update.cljs
@@ -78,5 +78,14 @@

 (defn cross->>update!
   [line-map-atom & {:keys [env input   ttl nq rdfa]}]
-  (let [update! (fn [ed format] (when ed (cross->update! line-map-atom :env env :input input :output ed :format format)))]
-    (update! ttl :ttl) (update! nq :nq) (update! rdfa :rdfa)))
+  (let [out! (fn []
+               (doseq [[out format] [[ttl :ttl] [nq :nq] [rdfa :rdfa]]]
+                 (when out (compile-content-to line-map-atom :env env :input input :output out :format format))))]
+    (out!)
+    (doseq [in (conj env input)]
+      (.on in "changes"
+           (util/debounce
+            (fn [cs]
+              (ln/clear! line-map-atom)
+              (out!))
+            500)))))


Add new gathering

Add new gathering

--- src/clj/chili_dog_night/data.clj
+++ src/clj/chili_dog_night/data.clj
@@ -1,7 +1,54 @@
 (ns chili-dog-night.data
   (:require [hiccup.element :as el]))

-(def gatherings [{:date "2016/02/24"
+(def gatherings [{:date "2016/03/02"
+                  :address "3828 Meridian Ave N, Seattle, WA 98103, USA"
+                  :synopsis "March 2nd, 2016: Chili Dogs, Fuller House, The Intern, and Before We Go."
+                  :food ["Chili Dogs"
+                         "Red Velvet Oreo Sandwich Cookies"
+                         "Oreo Mega Stuf Chocolate Sandwich Cookies"
+                         "Chips Ahoy! Original Chocolate Chip"]
+                  :attendees ["Alex Sanchez"
+                              "Greg Ryan"
+                              "Jason Aumann"
+                              "Jacob Dobner"
+                              "Colin Teal"
+                              "Kaia"]
+                  :media [{:title "Fuller House" :uri "http://www.imdb.com/title/tt3986586/"}
+                          {:title "The Intern" :uri "http://www.imdb.com/title/tt2361509/"}
+                          {:title "Before We Go" :uri "http://www.imdb.com/title/tt0443465/"}]
+                  :notes [:p
+                          (el/link-to "http://www.imdb.com/title/tt3986586/" "Master of None")
+                          ", "
+                          (el/link-to "http://www.imdb.com/title/tt4061080/" "Love")
+                          ", and "
+                          (el/link-to "http://www.imdb.com/title/tt3398228/" "BoJack Horseman")
+                          ": Hollywood writing what it knows"
+                          [:br]
+                          (el/link-to "https://en.wikipedia.org/wiki/Emerging_adulthood_and_early_adulthood" "Emerging")
+                          " "
+                          (el/link-to "http://www.apa.org/monitor/jun06/emerging.aspx" "Adulthood")
+                          [:br]
+                          (el/link-to "https://en.wikipedia.org/wiki/Red_velvet_cake" "Red Velvet")
+                          [:br]
+                          (el/link-to "http://www.avclub.com/review/netflixs-fuller-house-porn-parody-without-porn-232696" "Fuller House is like a porn parody without the porn")
+                          [:br]
+                          (el/link-to "https://www.youtube.com/watch?v=fJWmbLS2_ec" "Kokomo")
+                          [:br]
+                          (el/link-to "http://www.imdb.com/name/nm1913734/" "The")
+                          " "
+                          (el/link-to "http://www.imdb.com/name/nm0544718/" "Mara")
+                          " "
+                          (el/link-to "https://en.wikipedia.org/wiki/Tim_Mara" "Family")
+                          [:br]
+                          (el/link-to "http://www.nytimes.com/2016/03/01/arts/sam-smith-the-only-openly-gay-oscar-winner-not-really.html?_r=0" "Sam Smith")
+                          " the "
+                          (el/link-to "https://www.youtube.com/watch?v=8jzDnsjYv9A" "Writing's on the Wall")
+                          [:br]
+                          (el/link-to "https://en.wikipedia.org/wiki/Neanderthal" "Neanderthals")
+                          [:br]
+                          (el/link-to "http://gawker.com/centennials-are-the-new-millennials-are-the-new-menaces-1705468073" "Centennials")]}
+                 {:date "2016/02/24"
                   :address "1808 SW Elmgrove St, Seattle, WA 98106, USA"
                   :synopsis "February 24th, 2016: Pizza plus Worms, Jem and the Holograms, and The Visit."
                   :food ["Pizza from Frelard Pizza Company"


Use zepto support domready syntax

Use zepto support domready syntax

--- src/clj/ji/service/templates.clj
+++ src/clj/ji/service/templates.clj
@@ -68,7 +68,7 @@
     [:div#game.row.collapse {:data-game-id (:id game-env)}])
   (defblock body-end
     (page/include-js "/js/main.js")
-    [:script "$(document).ready(ji.main.init);"]))
+    [:script "$(ji.main.init);"]))

 (defpage game-create [game-id]


extract process-chunk-record

extract process-chunk-record

--- src/clj_money/import/gnucash.clj
+++ src/clj_money/import/gnucash.clj
@@ -309,6 +309,9 @@
     :default 1000]])

 (defn- parse-chunk-file-opts
+  "Accepts the raw arguments passed into chunk-file
+  and returns a map containing the information needed
+  to service the request"
   [args]
   (let [opts (parse-opts args chunk-file-options)
         input-path (-> opts :arguments first)
@@ -320,6 +323,14 @@
      :file-name file-name
      :output-folder output-folder}))

+(defn- process-chunk-record
+  "Processes a single record for the file chunking process"
+  [{:keys [progress-chan] :as context} record]
+  (>!! progress-chan record)
+  (-> context
+      (update-in [:records] #(conj % record))
+      advance-context))
+
 (defn chunk-file
   "Accepts a path to a gnucash file and creates multiple, smaller files
   that container the same data, returning the paths to the new files"
@@ -328,28 +339,23 @@
                 output-folder
                 file-name]
          :as opts} (parse-chunk-file-opts args)
-        record-chan (chan)
+        progress-chan (chan)
         result (go
                  (with-open [input-stream (FileInputStream. input-file)]
-                   (reduce (fn [context record]
-                             (let [updated (-> context
-                                               (update-in [:records] (fn [records] (conj records record)))
-                                               advance-context)]
-                               (process-output updated)
-                               (>!! record-chan record)
-                               updated))
+                   (reduce process-chunk-record
                            {:output-paths []
                             :verbose (-> opts :options :verbose)
                             :records []
                             :max-record-count (-> opts :options :maximum)
                             :file-name (second (re-matches #"^(.+)(\..+)$" file-name))
-                            :output-folder output-folder}
+                            :output-folder output-folder
+                            :progress-chan progress-chan}
                            (read-source :gnucash input-stream))))]
-    (go-loop [record (<! record-chan)]
+    (go-loop [record (<! progress-chan)]
              (when (not (:verbose opts))
                (print (-> record meta :record-type name first))
                (flush))
-             (recur (<! record-chan)))
+             (recur (<! progress-chan)))
     (println "reading the source file...")
     (<!! result)
     (println "\nDone")))


Added operations chart

Added operations chart

--- src/cljs/asols/client/stats.cljs
+++ src/cljs/asols/client/stats.cljs
@@ -1,11 +1,12 @@
 (ns asols.client.stats
-  (:require [om.core :as om]
+  (:require [clojure.string :as str]
+            [om.core :as om]
             [om.dom :refer [render-to-str]]
             [om-tools.core :refer-macros [defcomponent]]
             [sablono.core :refer-macros [html]]
             [asols.client.solvings :refer [solving-block mutation-view]]
             [asols.client.widgets :as widgets]
-            [asols.client.utils :refer [debug format]]))
+            [asols.client.utils :refer [debug format log]]))

 (defn- iter-count-serie
   [solvings]
@@ -26,90 +27,112 @@
      [x y])))

 (defn- costs-chart-config
-  [solvings train-values test-values]
-  (let [train-serie (cons [1 (get train-values 1)]
-                          (solvings->serie solvings #(-> % :best-case :train-cost)))
-        test-serie (cons [1 (get test-values 1)]
-                         (solvings->serie solvings #(-> % :best-case :test-cost)))]
-    {:chart       {:type   "scatter"
-                   :height "400"}
-     :title       {:text "Cost"}
-     :xAxis       {:allowDecimals false}
-     :yAxis       {:title      {:text "Cost"}
-                   :maxPadding 0}
-     :plotOptions {:scatter {:lineWidth 1
-                             :marker    {:enabled false}}}
-     :tooltip     {:shared       true
-                   :useHTML      true
-                   :headerFormat "{point.key}
"
-                   :pointFormat  "\u25CF {series.name}: {point.y}
"}
-     :series      [{:name             "Static train cost"
-                    :data             (->> (sequence train-values)
-                                           (sort-by first))
-                    :color            "red"
-                    :allowPointSelect true}
-                   {:name             "Static test cost"
-                    :data             (->> (sequence test-values)
-                                           (sort-by first))
-                    :color            "red"
-                    :dashStyle        "Dash"
-                    :allowPointSelect true}
-                   {:name   "Train cost"
-                    :data   train-serie
-                    :color  "blue"
-                    :marker {:enabled true :symbol "square"}}
-                   {:name      "Test cost"
-                    :data      test-serie
-                    :color     "blue"
-                    :dashStyle "Dash"
-                    :marker    {:enabled true :symbol "square"}}]}))
+  [train-serie test-serie static-train-serie static-test-serie]
+  {:chart       {:type   "scatter"
+                 :height "400"}
+   :title       {:text "Cost"}
+   :xAxis       {:allowDecimals false}
+   :yAxis       {:title      {:text "Cost"}
+                 :maxPadding 0}
+   :plotOptions {:scatter {:lineWidth 1
+                           :marker    {:enabled false}}}
+   :tooltip     {:shared       true
+                 :useHTML      true
+                 :headerFormat "{point.key}
"
+                 :pointFormat  "\u25CF {series.name}: {point.y}
"}
+   :series      [{:name             "Static train cost"
+                  :data             static-train-serie
+                  :color            "red"
+                  :allowPointSelect true}
+                 {:name             "Static test cost"
+                  :data             static-test-serie
+                  :color            "red"
+                  :dashStyle        "Dash"
+                  :allowPointSelect true}
+                 {:name   "Train cost"
+                  :data   train-serie
+                  :color  "blue"
+                  :marker {:enabled true :symbol "square"}}
+                 {:name      "Test cost"
+                  :data      test-serie
+                  :color     "blue"
+                  :dashStyle "Dash"
+                  :marker    {:enabled true :symbol "square"}}]})

 (defn- ca-chart-config
-  [solvings train-values test-values]
-  (let [train-serie (cons [1 (get train-values 1)]
-                          (solvings->serie solvings #(-> % :best-case :train-ca)))
-        test-serie (cons [1 (get test-values 1)]
-                         (solvings->serie solvings #(-> % :best-case :test-ca)))]
-    {:chart       {:type   "scatter"
-                   :height "500"}
-     :title       {:text "CA"}
-     :xAxis       {:allowDecimals false}
-     :yAxis       {:title      {:text "CA"}
-                   :maxPadding 0}
-     :plotOptions {:scatter {:lineWidth 1
-                             :marker    {:enabled false}}}
-     :tooltip     {:shared       true
-                   :useHTML      true
-                   :headerFormat "{point.key}
"
-                   :pointFormat  "\u25CF {series.name}: {point.y}
"}
-     :series      [{:name  "Static train CA"
-                    :data  (sort-by first train-values)
-                    :color "red"}
-                   {:name      "Static test CA"
-                    :data      (sort-by first test-values)
-                    :color     "red"
-                    :dashStyle "Dash"}
-                   {:name   "Train CA"
-                    :data   train-serie
-                    :color  "blue"
-                    :marker {:enabled true :symbol "square"}}
-                   {:name      "Test CA"
-                    :data      test-serie
-                    :color     "blue"
-                    :dashStyle "Dash"
-                    :marker    {:enabled true :symbol "square"}}]}))
+  [train-serie test-serie static-train-serie static-test-serie]
+  {:chart       {:type   "scatter"
+                 :height "400"}
+   :title       {:text "CA"}
+   :xAxis       {:allowDecimals false}
+   :yAxis       {:title      {:text "CA"}
+                 :maxPadding 0}
+   :plotOptions {:scatter {:lineWidth 1
+                           :marker    {:enabled false}}}
+   :tooltip     {:shared       true
+                 :useHTML      true
+                 :headerFormat "{point.key}
"
+                 :pointFormat  "\u25CF {series.name}: {point.y}
"}
+   :series      [{:name  "Static train CA"
+                  :data  static-train-serie
+                  :color "red"}
+                 {:name      "Static test CA"
+                  :data      static-test-serie
+                  :color     "red"
+                  :dashStyle "Dash"}
+                 {:name   "Train CA"
+                  :data   train-serie
+                  :color  "blue"
+                  :marker {:enabled true :symbol "square"}}
+                 {:name      "Test CA"
+                  :data      test-serie
+                  :color     "blue"
+                  :dashStyle "Dash"
+                  :marker    {:enabled true :symbol "square"}}]})

-(defcomponent cost-chart [{:keys [solvings train-values test-values]}]
+(defn- operations-chart-config
+  [solvings]
+  (let [operations (mapcat
+                     (fn [solving]
+                       (let [m (:mutation (:best-case solving))
+                             o (:operation m)]
+                         (if (= :asols.mutations/combined o)
+                          (map :operation (:mutations m))
+                          [o])))
+                     solvings)
+        series (for [[operation ops] (group-by identity operations)]
+                 [(name operation) (count ops)])]
+    {:chart       {:plotBackgroundColor nil
+                   :plotBorderWidth     nil
+                   :plotShadow          false
+                   :height 300}
+     :title       {:text "Operations"}
+     :plotOptions {:pie {:allowPointSelect true
+                         :showInLegend     true}}
+     :series      [{:type "pie"
+                    :name "Operations used"
+                    :data series}]}))
+
+(defcomponent cost-chart [[s1 s2 s3 s4]]
   (render [_]
-    (om/build widgets/highchart (costs-chart-config solvings train-values test-values))))
+    (om/build widgets/highchart (costs-chart-config s1 s2 s3 s4))))

-(defcomponent ca-chart [{:keys [solvings train-values test-values]}]
+(defcomponent ca-chart [[s1 s2 s3 s4]]
   (render [_]
-    (om/build widgets/highchart (ca-chart-config solvings train-values test-values))))
+    (om/build widgets/highchart (ca-chart-config s1 s2 s3 s4))))
+
+(defcomponent operations-chart [{:keys [solvings]}]
+  (render [_]
+    (om/build widgets/highchart (operations-chart-config solvings))))
+
+(defn- series->csv
+  [series]
+  (str/join "\n\n" (for [serie series]
+                   (str (mapv first serie) "\n" (mapv second serie)))))

 (defcomponent stats-panel [{:keys [progress solvings metrics]}]
   (render [_]
-    (let [[train-cost-serie test-cost-serie train-ca-serie test-ca-serie] metrics]
+    (let [[train-cost-data test-cost-data train-ca-data test-ca-data] metrics]
       (html
        [:.panel.panel-success
         [:.panel-heading "Stats"]
@@ -121,12 +144,31 @@
              (widgets/progress-bar (:value progress))]])

          [:.row
-          [:.col-md-12
-           (om/build cost-chart {:solvings solvings
-                                 :train-values train-cost-serie
-                                 :test-values test-cost-serie})]]
+          (let [train-serie (cons [1 (get train-cost-data 1)]
+                                  (solvings->serie solvings #(-> % :best-case :train-cost)))
+                test-serie (cons [1 (get test-cost-data 1)]
+                                 (solvings->serie solvings #(-> % :best-case :test-cost)))
+                static-train-serie (sort-by first train-cost-data)
+                static-test-serie (sort-by first test-cost-data)
+                series [train-serie test-serie
+                        static-train-serie static-test-serie]]
+            [:.col-md-12
+             (om/build cost-chart series)
+             [:.btn.btn-success.btn-block {:on-click #(log (series->csv series))}
+              "Export"]])]
+         [:.row
+          (let [train-serie (cons [1 (get train-ca-data 1)]
+                                  (solvings->serie solvings #(-> % :best-case :train-ca)))
+                test-serie (cons [1 (get test-ca-data 1)]
+                                 (solvings->serie solvings #(-> % :best-case :test-ca)))
+                static-train-serie (sort-by first train-ca-data)
+                static-test-serie (sort-by first test-ca-data)
+                series [train-serie test-serie
+                        static-train-serie static-test-serie]]
+            [:.col-md-12
+             (om/build ca-chart series)
+             [:.btn.btn-success.btn-block {:on-click #(log (series->csv series))}
+              "Export"]])]
          [:.row
           [:.col-md-12
-           (om/build ca-chart {:solvings solvings
-                               :train-values train-ca-serie
-                               :test-values test-ca-serie})]]]]))))+           (om/build operations-chart {:solvings solvings})]]]]))))


fixed weird overflow problem

fixed weird overflow problem

--- src/cljs/material/component.cljs
+++ src/cljs/material/component.cljs
@@ -251,8 +251,7 @@
 (defn autocomplete [props]
   (auto-complete
     (merge props
-           {:listStyle {:overflow  "scroll"
-                        :maxHeight "230px"}})))
+           {:listStyle {:maxHeight "230px"}})))

 ;; Panel elements


Update how anonymous user is saved

Update how anonymous user is saved

--- src/cljs/whatishistory/core.cljs
+++ src/cljs/whatishistory/core.cljs
@@ -39,13 +39,25 @@
         token (-> rand-str js/CryptoJS.SHA1 .toString)]
     (str token)))

-; This returns a JS promise b/c that's what the signUp returns.
 (defn save-anonymous-user []
     (let [user (js/Parse.User.)
         token (generate-user-token)]
-    (.set user "username" token)
-    (.set user "password" token)
-    (.signUp user)))
+      (.set user "username" token)
+      (.set user "password" token)
+      (def usr-promise (.signUp user))
+      (.then usr-promise (fn [usr]
+                           (js/console.log "saving user")
+                           (.set usr "ip" (js/getIP))
+                           (.save usr)
+                           (swap! app-atom assoc :curr-user usr)))))
+
+(defn set-user [app-atom]
+  (let [curr-user (js/Parse.User.current)]
+    (if (nil? curr-user)
+      (save-anonymous-user)
+      (swap! app-atom assoc :curr-user curr-user))
+    (js/console.log (get @app-atom :curr-user))))
+

 ;(defn save-defn [app-atom]
 ;  (let [Definition (js/Parse.Object.extend "Definition")
@@ -151,10 +163,7 @@

 (defn defineit-page []
   (parse-init)
-  (def usr-promise (save-anonymous-user))
-  (.then usr-promise (fn [usr]
-                       (.set usr "ip" (js/getIP))
-                       (.save usr)))
+  (set-user app-atom)
   (fn []
     [:div {:class "container defineit"}
      [:header [:h2 {:class "title"} "What is History?"]]


[n.d.sqlite] added delete function

[n.d.sqlite] added delete function

--- src/clojure/neko/data/sqlite.clj
+++ src/clojure/neko/data/sqlite.clj
@@ -284,6 +284,14 @@
            (map-to-content tagged-db table-name data-map)))
 (def db-insert insert)

+(defn delete
+  "Executes DELETE query against the database on the given table with the given
+  where clauses."
+  [^TaggedDatabase tagged-db table-name where]
+  (.delete ^SQLiteDatabase (.db tagged-db) (name table-name)
+           (where-clause where) nil))
+
+
 (defn transact*
   "Executed nullary transact-fn in a transaction for batch query execution."
   [^TaggedDatabase tagged-db, transact-fn]


Don't bring in play-clj.repl by default

Don't bring in play-clj.repl by default

--- src/clojure/nightmod/sandbox.clj
+++ src/clojure/nightmod/sandbox.clj
@@ -89,7 +89,6 @@
                                 '[play-clj.math :refer :all]
                                 '[play-clj.net :refer :all]
                                 '[play-clj.physics :refer :all]
-                                '[play-clj.repl :refer :all]
                                 '[play-clj.ui :refer :all])))

 (defn safe-read
@@ -142,7 +141,6 @@
          'play-clj.math
          'play-clj.net
          'play-clj.physics
-         'play-clj.repl
          'play-clj.ui])

 ; set function that prevents blacklisted symbols from being in completions


Removing cmr.metadata-db.database namespace.

--- src/cmr/metadata_db/database.clj
+++ src/cmr/metadata_db/database.clj
@@ -1,9 +0,0 @@
-(ns cmr.metadata-db.database
-  "Defines a protocol for basic operations on a database.")
-
-(defprotocol Database
-  "Provides functions for basic database operations."
-
-  (reset
-    [db]
-    "Delete everything from the database.  USE WITH CAUTION."))


Added a function for getting the most-used bound from multiple variables.

--- src/cmr/opendap/ous/variable.clj
+++ src/cmr/opendap/ous/variable.clj
@@ -74,3 +74,20 @@
    :dimensions (parse-dimensions (get-in entry [:umm :Dimensions]))
    :bounds (extract-bounds entry)
    :size (get-in entry [:umm :Characteristics :Size])})
+
+(defn get-dominant-bound
+  "This function is intended to be used if spatial subsetting is not
+  proivded in the query: in that case, all the bounds of all the variables
+  will be counted, and the one most-used is what will be returned."
+  [bounding-info]
+  (->> bounding-info
+       (map :bounds)
+       frequencies
+       ;; the 'frequencies' function puts data first; let's swap the order
+       (map (fn [[k v]] [v k]))
+       ;; sort in reverse order to get the highest counts first
+       (sort (comp - compare))
+       ;; just get the highest
+       first
+       ;; the first element is the count, the second is the bounding data
+       second))


adds leadership gauge (#1006)

adds leadership gauge (#1006)

--- waiter/src/waiter/core.clj
+++ waiter/src/waiter/core.clj
@@ -668,6 +668,7 @@
                    (let [leader-latch-path (str base-path "/" leader-latch-relative-path)
                          latch (LeaderLatch. curator leader-latch-path router-id)]
                      (.start latch)
+                     (metrics/waiter-gauge #(if (.hasLeadership latch) 1 0) "core" "leader")
                      latch))
    :local-usage-agent (pc/fnk [] (agent {}))
    :offers-allowed-semaphore (pc/fnk [[:settings [:work-stealing max-in-flight-offers]]]


adding some logging

adding some logging

--- src/hivewing_core/hive_image.clj
+++ src/hivewing_core/hive_image.clj
@@ -230,6 +230,7 @@
   Public_keys are unique across the system by DB design"
   [bk-uuid public-keys]
     (let [beekeeper-keys-path (.getPath (io/file gitolite-key-root (uuid-split bk-uuid) bk-uuid))]
+      (logger/info "BK Keys Path: " beekeeper-keys-path)
       (logger/info "Setting " (count public-keys) " public keys on " bk-uuid)
       ; Delete the existing keys
       (file-utils/recursive-delete (io/file beekeeper-keys-path))


Fix link to devcard interface in the about component

--- src/kanban/components/about.cljs
+++ src/kanban/components/about.cljs
@@ -13,7 +13,7 @@
     (dom/h2 nil "How about user interface tests?")
     (dom/p nil
       "There aren't any for this demo. However, there is a "
-      (dom/a #js {:href "/cards.html"} "devcard interface") " exercising "
+      (dom/a #js {:href "cards.html"} "devcard interface") " exercising "
       "some of the user interface components in isolation from the demo "
       "app itself.")
     (dom/h2 nil "Where can I find the source code?")


Use webutil/routes-for

Use webutil/routes-for

--- src/kixi/hecuba/api/datasets.clj
+++ src/kixi/hecuba/api/datasets.clj
@@ -6,7 +6,7 @@
    [kixi.hecuba.queue :as q]
    [kixi.hecuba.security :as sec]
    [kixi.hecuba.webutil :as util]
-   [kixi.hecuba.webutil :refer (decode-body authorized? uuid)]
+   [kixi.hecuba.webutil :refer (decode-body authorized? uuid routes-from)]
    [liberator.core :refer (defresource)]
    [liberator.representation :refer (ring-response)]))

@@ -65,10 +65,9 @@

 (defn index-handle-created [handlers req]
   (let [route-params (:route-params req)
-        routes       (:modular.bidi/routes route-params)
         {:keys [name entity-id]} route-params
         name         (:name route-params)
-        location     (bidi/path-for routes
+        location     (bidi/path-for (routes-from ctx)
                                (:dataset @handlers)
                                :entity-id entity-id
                                :name name)]


Fix broken build.

Fix broken build.

--- src/kixi/hecuba/api/datasets.clj
+++ src/kixi/hecuba/api/datasets.clj
@@ -41,17 +41,23 @@
    :synthetic                 true
    })

-(defn index-post! [commander req]
-  (let [route-params           (:route-params req)
-        entity-id              (:entity-id route-params)
-        {:keys [members name]} (decode-body req)
+(defn- entity-id-from [ctx]
+  (get-in ctx [:request :route-params :entity-id]))
+
+(defn- name-from [ctx]
+  (get-in ctx [:request :route-params :namee]))
+
+(defn index-post! [commander ctx]
+  (let [request                (:request ctx)
+        {:keys [members name]} (decode-body request)
+        entity-id              (entity-id-from ctx)
         members-str            (string/join \, members)
         ds                     {:entity_id entity-id
                                 :name      name
                                 :members   members-str}
         device-id              (hecuba/upsert! commander
-                                        :device
-                                        (synthetic-device entity-id "Synthetic"))]
+                                               :device
+                                               (synthetic-device entity-id "Synthetic"))]
     (hecuba/upsert! commander :sensor (synthetic-sensor device-id))
     (hecuba/upsert! commander :dataset ds)
     (hash-map :name name
@@ -63,10 +69,9 @@
                              :dataset
                              (select-keys route-params [:entity-id])))))

-(defn index-handle-created [handlers req]
-  (let [route-params (:route-params req)
-        {:keys [name entity-id]} route-params
-        name         (:name route-params)
+(defn index-handle-created [handlers ctx]
+  (let [entity-id   (entity-id-from ctx)
+        name        (name-from ctx)
         location     (bidi/path-for (routes-from ctx)
                                (:dataset @handlers)
                                :entity-id entity-id
@@ -93,12 +98,11 @@
         {::item item}
         #_(throw (ex-info (format "Cannot find item of id %s"))))))

-(defn resource-post! [commander req]
-  (let [{route-params :route-params} req
-        {:keys [entity-id name]} route-params
-        {:keys [members name]} (decode-body req)
-        ds {:entity_id entity-id
-            :name      name
+(defn resource-post! [commander ctx]
+  (let [request (:request ctx)
+        {:keys [members name]} (decode-body request)
+        ds {:entity_id (entity-id-from ctx)
+            :name      (name-from ctx)
             :members   (string/join \, members)}]
     (hecuba/upsert! commander :dataset ds)))


Update Jetty dependency to 9.4.38

Update Jetty dependency to 9.4.38

Fixes #433.

See: https://snyk.io/vuln/SNYK-JAVA-ORGECLIPSEJETTY-1080611

--- ring-jetty-adapter/project.clj
+++ ring-jetty-adapter/project.clj
@@ -7,7 +7,7 @@
   :dependencies [[org.clojure/clojure "1.7.0"]
                  [ring/ring-core "1.9.1"]
                  [ring/ring-servlet "1.9.1"]
-                 [org.eclipse.jetty/jetty-server "9.4.36.v20210114"]]
+                 [org.eclipse.jetty/jetty-server "9.4.38.v20210224"]]
   :aliases {"test-all" ["with-profile" "default:+1.8:+1.9:+1.10" "test"]}
   :profiles
   {:dev  {:dependencies [[clj-http "3.10.0"]


Implemented expected-duration, a component that shows ' / xx:xx' or '', possibly showing the build time of the previous successful build.

--- frontend/components/build_head.cljs
+++ frontend/components/build_head.cljs
@@ -226,6 +226,49 @@
             [:i.fa.fa-caret-down {:class (when show-config "fa-rotate-180")}]]]
           (when show-config
             [:div.build-config-string [:pre config-string]])])))))
+
+(defn expected-duration
+  [{:keys [start stop build]} owner opts]
+  (reify
+    om/IDisplayName (display-name [_] "Expected Duration")
+    om/IInitState
+    (init-state [_]
+      {:watcher-uuid (utils/uuid)
+       :now (datetime/server-now)
+       :has-watcher? false})
+    om/IDidMount
+    (did-mount [_]
+      (when-not stop
+        (let [timer-atom (om/get-shared owner [:timer-atom])
+              uuid (om/get-state owner [:watcher-uuid])]
+          (add-watch timer-atom uuid (fn [_k _r _p t]
+                                       (om/set-state! owner [:now] t)))
+          (om/set-state! owner [:has-watcher?] true))))
+    om/IWillUnmount
+    (will-unmount [_]
+      (when (om/get-state owner [:has-watcher?])
+        (remove-watch (om/get-shared owner [:timer-atom])
+                      (om/get-state owner [:watcher-uuid]))))
+
+    om/IDidUpdate
+    (did-update [_ _ _]
+      (when (and stop (om/get-state owner [:has-watcher?]))
+        (remove-watch (om/get-shared owner [:timer-atom])
+                      (om/get-state owner [:watcher-uuid]))))
+    om/IRenderState
+    (render-state [_ {:keys [now]}]
+      (let [end-ms (if stop
+                     (.getTime (js/Date. stop))
+                     now)
+            formatter (get opts :formatter datetime/as-duration)
+            duration-ms (- end-ms (.getTime (js/Date. start)))
+            previous-build (:previous_successful_build build)
+            past-ms (:build_time_millis previous-build)]
+        (if (and past-ms
+                 (= (:status build) "running")
+                 (< duration-ms (* 1.5 past-ms)))
+          (dom/span nil " / " (formatter past-ms))
+          (dom/span nil ""))))))

 (defn build-head [data owner]
   (reify
@@ -266,11 +309,15 @@
               [:tr
                [:th "Trigger"]
                [:td (build-model/why-in-words build)]
+
                [:th "Duration"]
                [:td (if (build-model/running? build)
                       (om/build common/updating-duration {:start (:start_time build)
                                                           :stop (:stop_time build)})
-                      (build-model/duration build))]]
+                      (build-model/duration build))
+                    (om/build expected-duration {:start (:start_time build)
+                                                :stop (:stop_time build)
+                                                :build build})]]
               [:tr
                [:th "Previous"]
                (if-not (:previous build)


tests for route-params->image-type

tests for route-params->image-type

--- test/vignette/http/routes_test.clj
+++ test/vignette/http/routes_test.clj
@@ -133,4 +133,9 @@
         :middle-dir "7c"
         :original "1271044.png"
         :revision "latest"
-        :width "150"})+        :width "150"})
+
+(facts :route-params->image-type
+       (route-params->image-type {:image-type ""}) => "images"
+       (route-params->image-type {:image-type "/images"}) => "images"
+       (route-params->image-type {:image-type "/avatars"}) => "avatars")


Fix search value in tests

Fix search value in tests

--- test/warehouse/functional/test.clj
+++ test/warehouse/functional/test.clj
@@ -1,9 +1,6 @@
 (ns warehouse.functional.test
   (:use [clj-webdriver.taxi :exclude [clear]]
         [clojure.test]))
-
-;(System/setProperty "webdriver.chrome.driver" "/home/nenadalm/Downloads/selenium/chromedriver")
-;(def browser-spec {:browser :chrome})

 (def browser-spec {:browser :phantomjs})

@@ -206,6 +203,7 @@
   ;;;;;;;;;;;;;; Search new component ;;;;;;;;;;;;;

   ; guard
+  (clear "//input[@name='search']")
   (input-text "//input[@name='search']" "new-component")
   (wait-until (= 0 (count (elements "//li[@class='component']"))))
   (clear "//input[@name='search']")


Adjust copy: selector only accepts one file

--- src-cljs/frontend/components/pieces/form.cljs
+++ src-cljs/frontend/components/pieces/form.cljs
@@ -144,7 +144,7 @@
                                            (file-selected-fn (-> % .-dataTransfer .-files (aget 0))))}
                          [:.file-name
                           (or file-name
-                              (list "Drop your files here or click " [:b "Choose File"] " below to select them manually."))]
+                              (list "Drop your file here or click " [:b "Choose File"] " below to select them manually."))]
                          [:input {:id id
                                   :type "file"
                                   :ref "file-input"


Test chaining of pmaps.

Test chaining of pmaps.

--- test/com/climate/claypoole_test.clj
+++ test/com/climate/claypoole_test.clj
@@ -398,6 +398,27 @@
         (Thread/sleep 50)
         (is (= @started (set results) (set input)))))))

+(defn check-chaining
+  "Check that we can chain pmaps."
+  [pmap-like]
+  (cp/with-shutdown! [p1 (cp/threadpool 2)
+                      p2 (cp/threadpool 4)]
+    (is (= (range 1 11)
+           (->> (range 10)
+                (pmap-like p1 inc)
+                sort)))
+    (is (= (range 2 12)
+           (->> (range 10)
+                (pmap-like p1 inc)
+                (pmap-like p1 inc)
+                sort)))
+    (is (= (range 3 13)
+           (->> (range 10)
+                (pmap-like p1 inc)
+                (pmap-like p1 inc)
+                (pmap-like p2 inc)
+                sort)))))
+
 (defn check-shutdown-exceptions
   "Check that exceptions are thrown when tasks go to a shutdown pool."
   [pmap-like]
@@ -531,7 +552,9 @@
     (check-*parallel*-disables pmap-like))
   (testing (format "%s throws exceptions when tasks are sent to a shutdown pool"
                    fn-name)
-    (check-shutdown-exceptions pmap-like)))
+    (check-shutdown-exceptions pmap-like))
+  (testing (format "%s can be chained in various threadpools" fn-name)
+    (check-chaining pmap-like)))

 (deftest test-future
@@ -570,7 +593,9 @@
     (testing "Binding cp/*parallel* can disable parallelism in future"
       (check-*parallel*-disables pmap-like))
     (testing "Future throws exceptions when tasks are sent to a shutdown pool"
-      (check-shutdown-exceptions pmap-like))))
+      (check-shutdown-exceptions pmap-like))
+    (testing "Futures can be chained in various threadpools."
+      (check-chaining pmap-like))))

 (deftest test-pmap
   (testing "basic pmap test"


tests for multi-path and if-path with vals collection

--- test/com/rpl/specter/core_test.cljx
+++ test/com/rpl/specter/core_test.cljx
@@ -1268,3 +1268,30 @@
       (= (reduce + i (traverse [s/ALL p] v))
          (reduce + i (filter p v)))
       )))
+
+(declarepath KeyAccumWalker [k])
+(providepath KeyAccumWalker
+  (s/if-path
+    s/must s/STAY
+    [s/ALL (s/collect-one s/FIRST) s/LAST (s/params-reset KeyAccumWalker)]))
+
+
+(deftest recursive-if-path-select-vals-test
+  (let [data {"e1" {"e2" {"e1" {:template 1} "e2" {:template 2}}}}]
+    (is (= [["e1" "e2" "e1" {:template 1}] ["e1" "e2" "e2" {:template 2}]]
+           (select (KeyAccumWalker :template) data)))
+    (is (= {"e1" {"e2" {"e1" "e1e2e1" "e2" "e1e2e2"}}}
+           (transform (KeyAccumWalker :template)
+             (fn [& all] (apply str (butlast all)))
+             data)))
+    ))
+
+(deftest multi-path-vals-test
+  (is (= {:a 1 :b 6 :c 3}
+         (transform [(s/multi-path (s/collect-one :a) (s/collect-one :c)) :b]
+           +
+           {:a 1 :b 2 :c 3})))
+  (is (= [[1 2] [3 2]]
+         (select [(s/multi-path (s/collect-one :a) (s/collect-one :c)) :b]
+           {:a 1 :b 2 :c 3})))
+  )


Update basic MIDI example walkthrough with latest MIDI API

--- src/overtone/examples/midi/basic.clj
+++ src/overtone/examples/midi/basic.clj
@@ -1,18 +1,73 @@
-(ns ^:hw overtone.examples.midi.basic
-  (:use overtone.live))
+(ns overtone.examples.midi.basic
+  (:use [overtone.live]
+        [overtone.synth.sts :only [prophet]]))

-;; Use (midi-in) with no parameters in the repl to find out the details
-;; of your midi keyboard.
-;; Try using the contents of :name or :description or a substring of either.
+;; Now, we know we can trigger synths manually with code:

-(def kb (midi-in "nanokey"))
+(prophet :freq 110 :decay 5 :rq 0.6 :cutoff-freq 2000)
+(prophet :freq 130 :decay 5 :rq 0.6 :cutoff-freq 2000)

-;; Define an inst. If you want it to respond to note off messages
-;; then ensure it responds to (ctl <proc number> :gate 0)
-;; An adsr ugen will do this
+;; It's super easy to trigger synths with attached MIDI devices using
+;; Overtone's event system. By default all note-making MIDI devices will
+;; emit a [:midi :note-on] event. Make sure you attach a MIDI piano-like
+;; device *before* booting Overtone and the following will work:

-(definst pad2 [freq 440 vel 0.4 amt 0.3 gate 1.0]
-  (let [vel        (+ 0.5 (* 0.5 vel))
+(on-event [:midi :note-on]
+          (fn [m]
+            (let [note (:note m)]
+              (prophet :freq (midi->hz note)
+                       :decay 5
+                       :rq 0.6
+                       :cutoff-freq 1000)))
+          ::prophet-midi)
+
+;; You also have access to velocity information:
+
+(on-event [:midi :note-on]
+          (fn [m]
+            (let [note (:note m)]
+              (prophet :freq (midi->hz note)
+                       :decay 5
+                       :rq 0.6
+                       :cutoff-freq 1000
+                       :amp (:velocity-f m))))
+          ::prophet-midi)
+
+;; To see all the information passed to the event system:
+
+(on-event [:midi :note-on]
+          (fn [m]
+            (println (type (:velocity-f m))))
+          ::midi-debug)
+
+;; We can remove our event handlers with:
+
+(remove-event-handler ::prophet-midi)
+(remove-event-handler ::midi-debug)
+
+;; Useful keys are:
+;;
+;; * :note (MIDI note)
+;; * :timestamp
+;; * :velocity (MIDI value i.e. 0->127)
+;; * :velocity-f (float 0->1)
+
+;; We can also easily receive note off events with the event key [:midi
+;; :note-off]. So, if we have a gated synth that we want to sustain
+;; whilst we hold the MIDI key down, this is pretty easy to build.
+;; First, let's define a suitable synth:
+
+(defsynth pad1 [freq 110 amp 1 gate 1 out-bus 0]
+  (out out-bus
+       (* (saw [freq (* freq 1.01)])
+          (env-gen (adsr 0.01 0.1 0.7 0.5) :gate gate :action FREE))))
+
+
+;; Of course, we could also build a more sophisticated synth with the
+;; same properties:
+
+(defsynth pad2 [freq 440 amp 0.4 amt 0.3 gate 1.0 out-bus 0]
+  (let [vel        (+ 0.5 (* 0.5 amp))
         env        (env-gen (adsr 0.01 0.1 0.7 0.5) gate 1 0 1 FREE)
         f-env      (env-gen (perc 1 3))
         src        (saw [freq (* freq 1.01)])
@@ -25,19 +80,103 @@
         dampener   (+ 1 (* 0.5 (sin-osc:kr 0.5)))
         reverb     (free-verb compressor 0.5 0.5 dampener)
         echo       (comb-n reverb 0.4 0.3 0.5)]
-    (* vel env echo)))
+    (out out-bus
+         (* vel env echo))))
+
+;; We can trigger our synth like this:
+
+(def pad-s (pad2))
+
+;; and kill it by cutting off the gate (thus completing the envelope):
+
+(ctl pad-s :gate 0)
+
+;; We can easily trigger this with our Keyboard

 ;; Create a map to store the note/proc-number tuples so we can
 ;; switch off the correct note when a note-off is recieved

-(def mem (atom {}))
+(defonce memory (agent {}))

-(defn midi-responder [e t]
-  (case (:cmd e)
-        :note-on (let [id (pad2 (midi->hz (:note e)))]
-                     (swap! mem assoc (:note e) id))
+(on-event [:midi :note-on]
+          (fn [m]
+            (send memory
+                  (fn [mem]
+                    (let [n (:note m)
+                          s (pad2 :freq (midi->hz n))]
+                      (assoc mem n s)))))
+          ::play-note)

-        :note-off (let [id (get @mem (:note e))]
-                    (ctl id :gate 0))))
+(on-event [:midi :note-off]
+          (fn [m]
+            (send memory
+                  (fn [mem]
+                    (let [n (:note m)]
+                      (when-let [s (get mem n)]
+                        (ctl s :gate 0))
+                      (dissoc mem n))))
+)
+          ::release-note)

-(midi-handle-events kb #'midi-responder)
+
+;; And again for tidiness:
+
+(remove-event-handler ::play-note)
+(remove-event-handler ::release-note)
+
+;; See overtone.examples.midi.keyboard for a built-in way of achieving
+;; exactly this behaviour.
+
+
+;; So, what if you have multiple MIDI devices capable of generating note
+;; on and off events? Clearly the approach above won't work. Luckily,
+;; we've got you covered.
+
+;; All attached MIDI devices are registered when Overtone booted.
+;; You can look at the list of attached devices with:
+
+(connected-midi-devices)
+
+;; The MIDI devices are not guaranteed to be registered in the same
+;; order every time you boot Overtone, so you can't rely on the index of
+;; the device you want to be consistent. However, you can search for
+;; your device usign a string or regexp. For example, the following
+;; finds my Korg nanoKEY2 keyboard:
+
+(def nk (midi-find-connected-device "nanoKEY2"))
+
+;; If I happen to have more than one Kort nanoKEY2 keyboard, I can
+;; search for them all with:
+
+(def nks (midi-find-connected-devices "nanoKEY2"))
+
+;; Once I have my device, I can find the unique key that Overtone's
+;; event system uses to manage events from the MIDI device:
+
+(midi-mk-full-device-key nk)
+;;=> [:midi-device "KORG INC." "KEYBOARD" "nanoKEY2 KEYBOARD" 0]
+
+;; our note on and off events are also sent with this unique device
+;; id. All you need to do is append either :note-on or :note-off. The
+;; following code will only work with a connected nanoKEY2 device:
+
+(on-event (conj (midi-mk-full-device-key nk) :note-on)
+          (fn [m]
+            (let [note (:note m)]
+              (prophet :freq (midi->hz note)
+                       :decay 5
+                       :rq 0.6
+                       :cutoff-freq 1000)))
+          ::prophet-midi)
+
+(remove-event-handler ::prophet-midi)
+
+;; In addition to :note-on and :note-off, other available midi events
+;; are:
+;; * :channel-pressure
+;; * :control-change
+;; * :pitch-bend
+;; * :poly-pressure
+;; * :program-change
+
+;; Enjoy playing notes with your MIDI devices!


Fixed require.

Fixed require.

--- test/hxgm30/language/tests/core.clj
+++ test/hxgm30/language/tests/core.clj
@@ -1,4 +1,4 @@
 (ns hxgm30.language.tests.core
   (:require
     [clojure.test :refer :all]
-    [hxgm30.language.tests.core :refer :all]))
+    [hxgm30.language.core :refer :all]))


Show that read-log is inclusive of end-tx

--- test/onyx/plugin/input_log_test.clj
+++ test/onyx/plugin/input_log_test.clj
@@ -91,7 +91,7 @@
     (try
       (with-test-env [test-env [4 env-config peer-config]]
         (testing "That we can read the initial transaction log"
-          (let [job (build-job db-uri 1002 10 1000)
+          (let [job (build-job db-uri 1001 10 1000)
                 {:keys [persist]} (get-core-async-channels job)
                 _ (mapv (partial ensure-datomic! db-uri) [schema people])
                 job-id (:job-id (onyx.api/submit-job peer-config job))]


test the movement system

test the movement system

--- test/voke/system/movement_test.cljs
+++ test/voke/system/movement_test.cljs
@@ -1,5 +1,7 @@
 (ns voke.system.movement-test
   (:require [cljs.test :refer [deftest is testing]]
+            [voke.system.core :refer [system-to-tick-fn]]
+            [voke.system.collision.system :as collision]
             [voke.system.movement :as movement]
             [voke.test-utils :refer [blank-game-state game-state-with-an-entity]]))

@@ -14,9 +16,36 @@
 (deftest should-update-velocity
   (is (movement/should-update-velocity? {:motion {:direction 1}}))
   (is (movement/should-update-velocity? {:motion {:affected-by-friction true
-                                                          :velocity             {:x 0.5 :y 0}}}))
+                                                  :velocity             {:x 0.5 :y 0}}}))

   (is (not (movement/should-update-velocity? {:motion {:direction nil}})))
   (is (not (movement/should-update-velocity? {:motion {:affected-by-friction true
-                                                   :velocity             {:x 0 :y 0}}})))
+                                                       :velocity             {:x 0 :y 0}}})))
   (is (not (movement/should-update-velocity? {:foo :bar}))))
+
+(deftest move-system-tick
+  (testing "the movement system should call attempt-to-move! once per each relevant moving entity"
+    (let [tick-fn (system-to-tick-fn movement/move-system)]
+      (let [initial-state (-> blank-game-state
+                              (assoc-in [:entities 0]
+                                        {:id     0
+                                         :shape  {:center {:x 10 :y 10}}
+                                         :motion {:direction        0
+                                                  :velocity         {:x 0 :y 0}
+                                                  :max-acceleration 1
+                                                  :max-speed        10}})
+                              (assoc-in [:entities 1]
+                                        {:id 1 :motion {:direction nil}})
+                              (assoc-in [:entities 2]
+                                        {:id 2 :foo :bar}))
+            attempt-to-move-args (atom [])]
+
+        (with-redefs [collision/attempt-to-move! (fn [& args]
+                                                   (swap! attempt-to-move-args conj args))]
+          (tick-fn initial-state)
+
+          (is (= (count @attempt-to-move-args) 1))
+
+          (let [[_ new-center new-velocity _] (first @attempt-to-move-args)]
+            (is (= new-center {:x 11 :y 10}))
+            (is (= new-velocity {:x 1 :y 0}))))))))


fix(examples): suzanne asset path

fix(examples): suzanne asset path

--- examples/jogl/ex02.clj
+++ examples/jogl/ex02.clj
@@ -39,7 +39,7 @@
   (let [^GL3 gl   (.. drawable getGL getGL3)
         view-rect (gl/get-viewport-rect gl)
         shader    (sh/make-shader-from-spec gl (assoc phong/shader-spec :version 330))
-        model     (-> (load-mesh "../assets/suzanne.stl" (a/aabb 2))
+        model     (-> (load-mesh "assets/suzanne.stl" (a/aabb 2))
                       (gl/as-gl-buffer-spec {})
                       (update :uniforms merge
                               {:lightPos [0 2 2]


[#40] Support date formats of the form '29-08-2013 02:00:00 CEST' (#41)

* [#40] Support date formats of the form '29-08-2013 02:00:00 CEST'

* [#40] SimpleDateFormat is not thread safe so we create a new one for each parse

--- api/src/clojure/org/akvo/flow_api/datastore/form_instance.clj
+++ api/src/clojure/org/akvo/flow_api/datastore/form_instance.clj
@@ -7,7 +7,8 @@
             [org.akvo.flow-api.datastore :as ds])
   (:refer-clojure :exclude [list])
   (:import [com.fasterxml.jackson.core JsonParseException]
-           [com.google.appengine.api.datastore Entity Text QueryResultIterator QueryResultIterable]))
+           [com.google.appengine.api.datastore Entity Text QueryResultIterator QueryResultIterable]
+           [java.text SimpleDateFormat]))

 (set! *warn-on-reflection* true)

@@ -105,7 +106,13 @@

 (defmethod parse-response "DATE"
   [_ response-str]
-  (ds/to-iso-8601 (java.util.Date. (Long/parseLong response-str))))
+  (let [date (try (java.util.Date. (Long/parseLong response-str))
+                  (catch NumberFormatException e
+                    (let [;; SimpleDateFormat is not thread safe so we create a
+                          ;; new one every time.
+                          date-format (SimpleDateFormat. "dd-MM-yyyy HH:mm:ss z")]
+                      (.parse date-format response-str))))]
+    (ds/to-iso-8601 date)))

 (defmethod parse-response "CASCADE"
   [_ response-str]


Shift setting of the instrument into part.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -52,8 +52,11 @@

 (defn part
   "Generate version of the model using the variations fns."
-  [model & variations]
-  ((apply juxt identity variations) model))
+  [instrument model & variations]
+  (->>
+    model
+    ((apply juxt identity variations))
+    (map (partial all :part instrument))))

 (defn introduce-after
   "Gradually introduce each part after t beats."
@@ -74,18 +77,18 @@
         b (split 5/5 1/10)
         c (comp (split 17/15 2/15) (split 5/5 2/15) (skip 6/5))
         d (comp (skip 7/5) (skip 6/5))]
-    (part model a b c d)))
+    (part :child model a b c d)))

 (def mother
-  (let [model (->> (rhythm [2/5 2/5 4/5 1/5 1/5]) (all :part :mother))
+  (let [model (->> (rhythm [2/5 2/5 4/5 1/5 1/5]))
         a (skip 9/5)
         b (skip 0)
         c (comp a b)
-        d #(then % (->> (rhythm (repeat 5 2/5)) (all :part :mother)))]
-    (part model a b c d)))
+        d #(then % (->> (rhythm (repeat 5 2/5))))]
+    (part :mother model a b c d)))

 (def father
-  (let [model (->> (rhythm [2/5 1/5 2/5]) (all :part :father))
+  (let [model (->> (rhythm [2/5 1/5 2/5]))
         a (skip 2/5)
         b (skip 3/5)
         c (comp (split 0 1/5) a)
@@ -93,7 +96,7 @@
         e (comp (split 3/5 1/10) d)
         f (split 0 1/5)
         g (comp (split 0 1/10) f)]
-    (part model a b c d e f g)))
+    (part :father model a b c d e f g)))

 (def aga-terumo ; p299
   (let [drums [child mother father]]
@@ -205,7 +208,7 @@
         b (comp (split 1/4 1/4) a)
         c (comp (accent 2/4) (split 2/4 1/4) b)
         d (comp (skip 0/4) c)]
-    (part model a b c d)))
+    (part :horn model a b c d)))

 (def ta
   (let [model (->> (phrase [5/4 3/4 4/4] (repeat 1)) (after 4/4))
@@ -214,7 +217,7 @@
         c (comp (accent 11/4) (split 11/4 1/8) b) ; 17
         d (split 4/4 1/4)
         e (comp (skip 10/4) c)] ; 8
-    (part model a b c d e)))
+    (part :horn model a b c d e)))

 (def ha
   (let [model (->> (phrase [12/4 2/4] (repeat 2)) (after 2/4))
@@ -222,14 +225,14 @@
         b (comp (split 6/4 1/4))
         c (comp (split 0 1/4) b)
         d (comp a b)]
-    (part model a b c d)))
+    (part :horn model a b c d)))

 (def tulule
   (let [model (phrase [8/4 8/4] (repeat 3))
         a (comp (split 8/4 2/4) (split 0 2/4)) ; 28
         b (comp (split 0 1/4) (split 2/4 1/4) a) ; 6
         c (comp (accent 7/8) (split 3/4 1/8) b)] ; 5
-    (part model a b c)))
+    (part :horn model a b c)))

 (def bongo
   (let [model (->> (phrase [3/4 7/4] (repeat 4)) (after 6/4)) ; 5
@@ -237,7 +240,7 @@
         b (comp (split 6/4 1/4) a) ; 9
         c (comp (split 14/4 1/4) b) ; 8
         d (comp (accent 10/4) (split 9/4 1/4) b)] ; 19
-    (part model a b c d)))
+    (part :horn model a b c d)))

 (defn big [notes]
   (->> notes (map #(where :pitch (from 5) %))))
@@ -262,7 +265,7 @@
     (map pan)
     (where :pitch (comp midi->hz A central-african-scale))
     (tempo (bpm 120))
-    (live/play)))
+    live/play))

@@ -301,5 +304,5 @@
       (pan2 pan)
       (* vol)))

-(defmethod live/play-note :default [{:keys [pitch pan]}]
-  (when pitch (horn :freq pitch :pan (or pan 0))))
+(defmethod live/play-note :horn [{:keys [pitch pan]}]
+  (horn :freq pitch :pan (or pan 0)))


use v^ for fn boundaries in str output. little fix too

--- src/com/billpiel/mem_tracer/string_output.clj
+++ src/com/billpiel/mem_tracer/string_output.clj
@@ -19,15 +19,33 @@
                                                            :class-delimiter [:cyan]
                                                            :class-name      [:cyan]}}))

-(defn arg-indent
+(defn base-indent-slinky
+  [& {:keys [override underride]
+      :or {override [] underride []}}]
+  (concat override
+          [:start " "
+           :end " "
+           :default (fn [i]
+                      {:fg* i :text "|"})]
+          underride))
+
+(defn arg-indent-slinky
   [& {:keys [start end]
       :or {start " "
            end " "}}]
-  [:start start
-   -1 "-"
-   :default (fn [i]
-              {:fg* i :text "|"})
-   :end end])
+  (base-indent-slinky :override [:start start
+                                 -1 "-"
+                                 :end end]))
+
+(defn fn-header-indent-slinky
+  []
+  (base-indent-slinky :override [-1 (fn [i]
+                                      {:fg* i :text "v"})]))
+
+(defn fn-footer-indent-slinky
+  []
+  (base-indent-slinky :override [-1 (fn [i]
+                                      {:fg* i :text "^"})]))

 (defn apply-color-palette
   [n]
@@ -54,7 +72,7 @@
                         (= :default fi) [java.lang.Integer/MIN_VALUE java.lang.Integer/MAX_VALUE]
                         (number? fi) [fi fi])]
       (when (or (<= lo i hi)
-                (<= lo (- len i) hi))
+                (<= lo (- i len) hi))
         se))))

 (defn slinky-first-match
@@ -94,7 +112,7 @@

 (defn indent
   [depth & rest]
-  (slinky->str (apply arg-indent rest)
+  (slinky->str (apply base-indent-slinky rest)
                depth))

 (defn indent-line-breaks
@@ -110,9 +128,7 @@
   [entry]
   (let [{:keys [depth name]} entry]
     (if name
-      (clojure.string/join "" [(indent depth :end {:fg 7
-                                                   :bold true
-                                                   :text "> "})
+      (clojure.string/join "" [(slinky->str #spy/d (fn-header-indent-slinky) depth)
                                (color-code :fg* (dec depth) :bg 0 :bold false)
                                (:name entry)
                                "  "
@@ -192,7 +208,10 @@
              (when post-ret
                (return-str entry))
              (when post-ex
-               (throw-str entry))])]
+               (throw-str entry))])
+          (slinky->str (fn-footer-indent-slinky)
+                       (:depth entry))
+          "\n"]
          flatten
          (remove nil?)
          (clojure.string/join ""))))


take some suggestions from kibit and refactor

--- src/refactor_nrepl/artifacts.clj
+++ src/refactor_nrepl/artifacts.clj
@@ -5,6 +5,7 @@
              [string :as str]]
             [clojure.data.json :as json]
             [clojure.java.io :as io]
+            [clojure.string :as str]
             [clojure.tools.nrepl
              [middleware :refer [set-descriptor!]]
              [misc :refer [response-for]]
@@ -33,7 +34,7 @@
   (or (empty? @artifacts)
       (neg? (- millis-per-day
                (- (-> artifacts meta :last-modified .getTime)
-                  (-> (java.util.Date.) .getTime))))))
+                  (.getTime (java.util.Date.)))))))

 (defn- get-all-clj-artifacts!
   "All the artifacts under org.clojure in mvn central"
@@ -74,13 +75,12 @@
                           dorun)))))

 (defn- get-artifacts-from-mvn-central! []
-  (-> (get-all-clj-artifacts!)
-      (add-artifacts)))
+  (add-artifacts (get-all-clj-artifacts!)))

 (defn- update-artifact-cache! []
   (let [mvn-central-futures (get-artifacts-from-mvn-central!)
         clojars-future (future (add-artifacts-from-clojars!))]
-    (-> (map deref mvn-central-futures) dorun)
+    (dorun (map deref mvn-central-futures))
     @clojars-future)
   (alter-meta! artifacts update-in [:last-modified]
                (constantly (java.util.Date.))))
@@ -111,8 +111,7 @@
       (add-dependencies :coordinates coords :repositories repos)
       (transport/send transport
                       (response-for msg :status :done
-                                    :dependency
-                                    (apply str (interpose " " (first coords))))))
+                                    :dependency (str/join " " dependency-vector))))
     (catch Exception e
       (transport/send transport (response-for msg :error (.getMessage e)
                                               :status :done)))))


removed unnecessary print

removed unnecessary print

--- src/server/client-interface.cljs
+++ src/server/client-interface.cljs
@@ -458,8 +458,6 @@

                       (.on stream "data"
                         (fn [data-chunk]
-                          (println "Received data chunk of" original-filename
-                                   "from" (.-id socket))
                           (rooms/get-username room user-id
                             (fn [username]
                               (let [bytes-received (aget (.statSync fs temp-absolute-file-path) "size")]