changes to entity coercion: can create entities with complete or incomplete keys

--- datastore/src/clojure/gclouj/datastore.clj
+++ datastore/src/clojure/gclouj/datastore.clj
@@ -4,7 +4,7 @@
   (:import [gclouj DatastoreOptionsFactory]
            [java.io InputStream]
            [java.nio ByteBuffer]
-           [com.google.cloud.datastore DatastoreOptions Entity FullEntity DatastoreOptions$DefaultDatastoreFactory Transaction Key IncompleteKey DatastoreBatchWriter EntityValue ValueType StringValue LongValue DoubleValue DateTime DateTimeValue BooleanValue BlobValue Blob ListValue NullValue Value KeyValue FullEntity$Builder Query StructuredQuery$PropertyFilter StructuredQuery$CompositeFilter StructuredQuery$Filter StructuredQuery$OrderBy]
+           [com.google.cloud.datastore DatastoreOptions FullEntity Entity FullEntity DatastoreOptions$DefaultDatastoreFactory Transaction Key IncompleteKey DatastoreBatchWriter EntityValue ValueType StringValue LongValue DoubleValue DateTime DateTimeValue BooleanValue BlobValue Blob ListValue NullValue Value KeyValue FullEntity$Builder Query StructuredQuery$PropertyFilter StructuredQuery$CompositeFilter StructuredQuery$Filter StructuredQuery$OrderBy]
            [com.google.cloud AuthCredentials]))

 (defn credential-options [project-id namespace json-key]
@@ -45,7 +45,12 @@
 (defn byte-array? [x]
   (= (Class/forName "[B") (class x)))

-(defn property-value [x]
+
+
+
+(declare entity)
+
+(defn to-value [x]
   (cond (nil? x)                      (NullValue. )
         (float? x)                    (DoubleValue/of x)
         (number? x)                   (LongValue/of x)
@@ -56,23 +61,29 @@
         (or (byte-array? x)
             (instance? InputStream x)
             (instance? ByteBuffer x)) (BlobValue/of (Blob/copyFrom x))
-        (sequential? x)               (ListValue/of (map property-value x))
+        (sequential? x)               (ListValue/of (map to-value x))
+        (instance? FullEntity x)      (EntityValue/of x)
+        (map? x)                      (EntityValue/of (entity x))
         :else      x))
+
+(defn- map->entity
+  [builder m]
+  (doseq [[k v] m]
+    (if (map? v)
+      (.set builder k ^FullEntity (entity v))
+      (.set builder k ^Value (to-value v))))
+  builder)

 (defn entity
   "Converts a Clojure map into a Datastore Entity. Recursively converts
   all values into an entity or value using property-value. Keys must all
   be strings."
-  [key m & {:keys [index]}]
-  (let [builder    (Entity/builder key)]
-    (doseq [[k v] m]
-      (try
-        (cond (map? v) (let [attrkey (incomplete-key (.projectId key) (format "%s.%s" (.kind key) k))]
-                         (.set builder k (entity attrkey v)))
-              :else    (.set builder k (property-value v)))
-        (catch IllegalArgumentException e
-          (throw (ex-info (str "error mapping " k " with value " v) {})))))
-    (.build builder)))
+  ([m] (let [b (FullEntity/builder)]
+         (.build (map->entity b m))))
+  ([k m] (let [b (cond
+                   (instance? Key k)           (Entity/builder k)
+                   (instance? IncompleteKey k) (FullEntity/builder k))]
+           (.build (map->entity b m)))))

 (defprotocol ToClojure
   (to-clojure [x]))


Require goog.dom in sablono.test.

Require goog.dom in sablono.test.

--- test/sablono/test.cljx
+++ test/sablono/test.cljx
@@ -1,7 +1,8 @@
 (ns sablono.test
   (:refer-clojure :exclude [replace])
   (:require [clojure.string :refer [replace]]
-            [sablono.core :as core]))
+            [sablono.core :as core]
+            #+cljs [goog.dom :as dom]))

 (defmacro are-html-rendered [& body]
   `(cemerick.cljs.test/are [form# expected#]


Update figwheel to 0.5.11

Update figwheel to 0.5.11

This prevents an exception with a plain new project:
Caused by: java.io.FileNotFoundException: Could not locate
ring/core/protocols__init.class or ring/core/protocols.clj on classpath.,
compiling:(ring/util/servlet.clj:1:1)

--- src/leiningen/new/chestnut/project.clj
+++ src/leiningen/new/chestnut/project.clj
@@ -109,14 +109,14 @@
   {{/sass?}}

   :profiles {:dev
-             {:dependencies [[figwheel "0.5.10"]
-                             [figwheel-sidecar "0.5.10"]
+             {:dependencies [[figwheel "0.5.11"]
+                             [figwheel-sidecar "0.5.11"]
                              [com.cemerick/piggieback "0.2.1"]
                              [org.clojure/tools.nrepl "0.2.13"]
                              [lein-doo "0.1.7"]
                              [reloaded.repl "0.2.3"]]

-              :plugins [[lein-figwheel "0.5.10"]
+              :plugins [[lein-figwheel "0.5.11"]
                         [lein-doo "0.1.7"]]

               :source-paths ["dev"]


Corrected whitespace nonesense

Corrected whitespace nonesense

--- src/leiningen/new/figwheel/project.clj
+++ src/leiningen/new/figwheel/project.clj
@@ -17,19 +17,19 @@
   :source-paths ["src"]

   :cljsbuild {
-   :builds [{:id "dev"
-             :source-paths ["src"]
-             :compiler {:output-to "resources/public/js/compiled/{{sanitized}}.js"
-                        :output-dir "resources/public/js/compiled/out"
-                        :optimizations :none
-                        :source-map true
-                        :source-map-timestamp true
-                        :cache-analysis true }}
-            {:id "min"
-             :source-paths ["src"]
-             :compiler {:output-to "resources/public/{{sanitized}}.min.js"
-                        :optimizations :advanced
-                        :pretty-print false}}]}
+    :builds [{:id "dev"
+              :source-paths ["src"]
+              :compiler {:output-to "resources/public/js/compiled/{{sanitized}}.js"
+                         :output-dir "resources/public/js/compiled/out"
+                         :optimizations :none
+                         :source-map true
+                         :source-map-timestamp true
+                         :cache-analysis true }}
+             {:id "min"
+              :source-paths ["src"]
+              :compiler {:output-to "resources/public/{{sanitized}}.min.js"
+                         :optimizations :advanced
+                         :pretty-print false}}]}

   :figwheel {
              :http-server-root "public" ;; default and assumes "resources"


Clicking records can be cancelled now

Clicking records can be cancelled now

--- src/webapp/client/ui_tree.cljs
+++ src/webapp/client/ui_tree.cljs
@@ -230,9 +230,9 @@
   (fn [app records]
     (let [r (first records)]
     (js/alert (str "record:" r))
-      (comment update-app  app
+      (update-app  app
                    [:ui :companies :values]
-                   (amend-record (into [] (get-in-app app [:ui :request :endorsement :value]))
+                   (amend-record (into [] (get-in-app app [:ui :companies :values]))
                                  "company"
                                  (get r "company")
                                  (fn[z] (merge z {:clicked false}))


Redis wishlist, added update merge, takes partial changes for wishlist

--- src/wishlistd/models/redis.clj
+++ src/wishlistd/models/redis.clj
@@ -38,3 +38,10 @@
   "Deletes a single wishlist in the datastore."
   (r/with-server db
     (r/del code)))
+
+;; Advanced
+
+(defn update-merge [{:keys [code] :as wishlist}]
+  (r/with-server db
+    (when-let [old (read-wishlist code)]
+      (update-wishlist (merge old wishlist)))))


Fix typos.

Fix typos.

--- src/workshop/challenge_6_0.clj
+++ src/workshop/challenge_6_0.clj
@@ -93,7 +93,7 @@
 ;; we can get onto the meat of this challenge - the window
 ;; and trigger constructs. Windows indicate *how* to accrete
 ;; state over time. Triggers indicate *what* to do with the data
-;; in reaction to a specific stimulous.
+;; in reaction to a specific stimulus.

 (def windows
   ;; :window/id is a unique name for this window. We need it
@@ -120,7 +120,7 @@
     ;; Here, we indicate a "window key". This lets us peek into the segment
     ;; itself and pull out the :event-time key. We use *this* value to bucket
     ;; the segment. Onyx is also capable of bucketing by wall clock (normally
-    ;; called "Processing Time") by using a Timer Trigger. See the User User for
+    ;; called "Processing Time") by using a Timer Trigger. See the User Guide for
     ;; more information on this.
     :window/window-key :event-time


update santize player test

update santize player test

--- tests/battlebots/game_spec.clj
+++ tests/battlebots/game_spec.clj
@@ -59,7 +59,11 @@

 (deftest sanitize-player-spec
   (is (= {:_id "1"
-          :login "oconn"} (#'game/sanitize-player (first test-players)))))
+          :login "oconn"
+          :energy 100} (#'game/sanitize-player {:_id "1"
+                                                :login "oconn"
+                                                :energy 100
+                                                :super-secret-value "shhhh...."}))))

 (comment (deftest save-segment-spec))

@@ -98,3 +102,6 @@
       "When false is passed as the last argument, the item is not replaced with an open space")
   (is (= (assoc b :energy (dec (:energy b))) (#'game/apply-damage b 1))
       "An item's energy is updated when damage is applied"))
+
+;; TODO
+(comment (deftest player-occupy-space-spec))


Updated navigation bar: new item Glossary

--- src/zg/html_renderer.clj
+++ src/zg/html_renderer.clj
@@ -119,6 +119,7 @@
                             [:li (tab-class :whitelist mode) [:a {:href (str url-prefix "whitelist")} "Whitelist"]]
                             [:li (tab-class :blacklist mode) [:a {:href (str url-prefix "blacklist")} "Blacklist"]]
                             [:li (tab-class :atomic-typos mode) [:a {:href (str url-prefix "atomic-typos")} "Atomic typos"]]
+                            [:li (tab-class :glossary mode) [:a {:href (str url-prefix "glossary")} "Glossary"]]
                         ]
                     ]
                 ] ; col-md-7 ends


Cleanup file

Cleanup file

--- src/zoo_live/handler.clj
+++ src/zoo_live/handler.clj
@@ -1,12 +0,0 @@
-(ns zoo-live.handler
-  (:use compojure.core)
-  (:require [compojure.handler :as handler]
-            [compojure.route :as route]))
-
-(defroutes app-routes
-  (GET "/" [] "Hello World")
-  (route/resources "/")
-  (route/not-found "Not Found"))
-
-(def app
-  (handler/site app-routes))


DJSON-38 Type hint return type of write-str

Signed-off-by: Alex Miller <99328387f8334f68433c424d2dfd83062f62754b@cognitect.com>

--- src/main/clojure/clojure/data/json.clj
+++ src/main/clojure/clojure/data/json.clj
@@ -521,7 +521,7 @@
 (defn write-str
   "Converts x to a JSON-formatted string. Options are the same as
   write."
-  [x & options]
+  ^String [x & options]
   (let [sw (StringWriter.)]
     (-write x sw (merge default-write-options (apply array-map options)))
     (.toString sw)))


Correct project template

Correct project template

--- resources/leiningen/new/onyx_plugin/project.clj
+++ resources/leiningen/new/onyx_plugin/project.clj
@@ -1,4 +1,4 @@
-(defproject onyx-medium-name "0.7.0-SNAPSHOT"
+(defproject onyx-{{medium}} "0.7.0-SNAPSHOT"
   :description "Onyx plugin for {{medium}}"
   :url "FIX ME"
   :license {:name "Eclipse Public License"


Bugfix: don't relocalize notebooks to the same cluster after they have already been localized (#1406)

--- src/cljs/main/broadfcui/page/workspace/notebooks/notebooks_table.cljs
+++ src/cljs/main/broadfcui/page/workspace/notebooks/notebooks_table.cljs
@@ -330,11 +330,19 @@
      (let [{:keys [workspsaceName]} props
            {:keys [server-response]} @state
            {:keys [notebooks]} server-response
-           filtered-notebooks (filter (comp (partial = (:clusterName cluster)) :cluster-name) notebooks)]
+           notebooks-to-localize (filter (every-pred (comp (partial = (:clusterName cluster)) :cluster-name)
+                                                     (comp false? :localized?))
+                                         notebooks)]
        (endpoints/localize-notebook (:googleProject cluster) (:clusterName cluster)
-                                    (reduce merge (conj (map (partial this :-localize-entry) filtered-notebooks) (this :-delocalize-json)))
+                                    (reduce merge (conj (map (partial this :-localize-entry) notebooks-to-localize) (this :-delocalize-json)))
                                     (fn [{:keys [success? get-parsed-response]}]
-                                      (when-not success?
+                                      (if success?
+                                        ; flip :localized? to true so we don't re-localize notebooks to this cluster
+                                        (swap! state assoc :server-response {:notebooks (map (fn [n]
+                                                                                (if (= (:cluster-name n) (:clusterName cluster))
+                                                                                (merge n {:localized? true})
+                                                                                n))
+                                                                                notebooks)})
                                         (js/setTimeout #(this :-localize-notebooks cluster) 10000))))))

    :-delocalize-json
@@ -449,7 +457,7 @@
            {:keys [notebooks]} server-response
            updated-notebooks (map (fn [n]
                                     (if (= (:name n) (:name notebook))
-                                      (merge n {:cluster-name cluster-name})
+                                      (merge n {:cluster-name cluster-name :localized? false})
                                       n))
                                   notebooks)]
        (this :-get-clusters-list)


Update to released version of Clojure

Update to released version of Clojure

--- ClojureScript/replete/project.clj
+++ ClojureScript/replete/project.clj
@@ -1,4 +1,4 @@
 (defproject replete "0.1.0"
-  :dependencies [[org.clojure/clojure "1.7.0-RC2"]
+  :dependencies [[org.clojure/clojure "1.7.0"]
                  [org.clojure/clojurescript "0.0-3422"]
                  [org.clojure/tools.reader "0.10.0-SNAPSHOT" :exclusions [org.clojure/clojure]]])


don't assume ordering

don't assume ordering

--- test/flambo/api_test.clj
+++ test/flambo/api_test.clj
@@ -25,9 +25,10 @@
       "union concats two RDDs"
       (let [rdd1 (f/parallelize c [1 2 3 4])
             rdd2 (f/parallelize c [11 12 13])
-            rdd3 (f/parallelize c [21 22 23])
-            union-rdd (f/union c rdd1 rdd2 rdd3)]
-        (vec (f/collect union-rdd))) => (just [1 2 3 4 11 12 13 21 22 23])))))
+            rdd3 (f/parallelize c [21 22 23])]
+        (-> (f/union c rdd1 rdd2 rdd3)
+            f/collect
+            vec) => (just [1 2 3 4 11 12 13 21 22 23] :in-any-order))))))

 (facts
  "about serializable functions"


fix test fixture

fix test fixture

--- test/lumo/test_util.cljs
+++ test/lumo/test_util.cljs
@@ -5,7 +5,7 @@
   (:require-macros [cljs.env.macros :as env]))

 (defn with-parinfer [f]
-  (set! (. js/global -$$LUMO_GLOBALS) #js {:getParinfer #(node/require "parinfer")})
+  (set! (. js/global -$$LUMO_GLOBALS) #js {:parinfer (node/require "parinfer")})
   (f)
   (set! (. js/global -$$LUMO_GLOBALS) nil))


Add tests for a bunch more map functions

--- test/useful/map_test.clj
+++ test/useful/map_test.clj
@@ -51,3 +51,12 @@
 (deftest test-position
   (is (= (position [1 3 5 3])
          {1 0 3 1 5 2})))
+
+(deftest map-filtering-tests
+  (let [m '{a 0, b 1, c 11, d 92}]
+    (is (= '#{a d} (filter-keys-by-val even? m)))
+    (is (= '#{b c} (remove-keys-by-val even? m)))
+    (is (= '{a 0} (filter-vals zero? m)))
+    (is (= '{b 1, c 11, d 92} (remove-vals zero? m)))
+    (is (= '{a 0} (filter-keys '#{a} m)))
+    (is (= '{b 1, c 11, d 92} (remove-keys '#{a} m)))))


Fix core test.

Fix core test.

- Rename alerts.
- We're expecting 5 events, not 4.

--- test/wonko/core_test.clj
+++ test/wonko/core_test.clj
@@ -108,16 +108,16 @@
       (client/stream :validation-metric {:first 5} 5)
       (is (thrown? IllegalArgumentException (client/stream :validation-metric {:first 6 :second 7} 6)))

-      (client/alert :validation-metric {:first 5})
-      (is (client/alert :validation-metric {:first 6 :second 7}))
+      (client/alert :some-alert {:first 5})
+      (is (client/alert :some-alert {:first 6 :second 7}))

       (let [consumed-events (atom [])
             thread-pool (consume/start {events-topic 1 alerts-topic 1}
                                        (fn [event]
                                          (process event)
                                          (swap! consumed-events conj event)))]
-        (tu/wait-for #(= 4 (count @consumed-events)) :interval 1 :timeout 3)
-        (is (= (count @consumed-events) 4))
+        (tu/wait-for #(= 5 (count @consumed-events)) :interval 1 :timeout 3)
+        (is (= (count @consumed-events) 5))

         (consume/stop thread-pool)
         (tu/delete-topics events-topic alerts-topic)))))


Refactor code

Refactor code

--- solutions/uri/1011/1011.clj
+++ solutions/uri/1011/1011.clj
@@ -1,15 +1,12 @@
 (ns main)

 (def pi 3.14159)
-
-(defn pow [x n]
-  (reduce * (repeat n x)))

 (defn main []
   (loop [line (read-line)]
     (when line
        (let [radius (Double/parseDouble line)]
-         (printf "VOLUME = %.3f%n" (*(*(/ 4.0 3.0) pi) (pow radius 3))))
+         (printf "VOLUME = %.3f%n" (*(*(/ 4.0 3.0) pi) (Math/pow radius 3))))
        (recur (read-line)))))

 (main)


Use arrows instead of pluses

Use arrows instead of pluses

--- src-cljs/frontend/components/pieces/topbar.cljs
+++ src-cljs/frontend/components/pieces/topbar.cljs
@@ -53,7 +53,7 @@
                 {:data-toggle "dropdown"
                  :aria-haspopup "true"
                  :aria-expanded "false"}
-                [:i.material-icons "add"] "What's New"]
+                 "What's New" [:i.material-icons "keyboard_arrow_down"]]
                [:ul.dropdown-menu.pull-right.animated.slideInDown
                 (when-not (config/enterprise?)
                   [:li [:a (html/open-ext {:href "https://circleci.com/changelog/"}) "Changelog"]])
@@ -63,7 +63,7 @@
                 {:data-toggle "dropdown"
                  :aria-haspopup "true"
                  :aria-expanded "false"}
-                [:i.material-icons "add"] "Get Help"]
+                "Get Help" [:i.material-icons "keyboard_arrow_down"] ]
                [:ul.dropdown-menu.pull-right.animated.slideInDown
                 [:li
                  ;; FIXME: NEED TO ADD QUICK START PAGE


Mainly rename AST keys to :cljs.analyzer/namespaces

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -51,10 +51,15 @@
   ([state ns]
    {:pre [(symbol? ns)]}
    (->> (merge
-          (get-in @state [::ana/namespaces ns :macros])
-          (get-in @state [::ana/namespaces ns :defs]))
+         (get-in @state [:cljs.analyzer/namespaces ns :macros])
+         (get-in @state [:cljs.analyzer/namespaces ns :defs]))
         (remove (fn [[k v]] (:private v)))
         (into {}))))
+
+(defn get-namespace-defs
+  "Given a namespace symbol, returns its AST :defs content"
+  [sym]
+  (get-in @st [:cljs.analyzer/namespaces sym :defs]))

 (defn get-namespace
   [sym]
@@ -94,7 +99,7 @@
       (second first-form))))

 (defn resolve
-  "From cljs.analizer.api.clj. Given an analysis environment resolve a
+  "From cljs.analyzer.api.clj. Given an analysis environment resolve a
   var. Analogous to clojure.core/resolve"
   [opts env sym]
   {:pre [(map? env) (symbol? sym)]}
@@ -172,7 +177,7 @@
 ;; from https://github.com/mfikes/planck/commit/fe9e7b3ee055930523af1ea3ec9b53407ed2b8c8
 (defn purge-ns-analysis-cache!
   [st ns]
-  (swap! st update-in [::ana/namespaces] dissoc ns))
+  (swap! st update-in [:cljs.analyzer/namespaces] dissoc ns))

 (defn purge-ns!
   [st ns]


cljs/skyport.core: Fix shooting laser

cljs/skyport.core: Fix shooting laser

The laser didn't shoot properly. It turned out that the coordinates
wern't parsed properly and that there was a bug with the way we
calculated the hight of the shot. Instead of passing the action-map to
the laser-shot function there were also too many arguments.

--- src/cljs/skyport/core.cljs
+++ src/cljs/skyport/core.cljs
@@ -43,14 +43,9 @@
                     :position [12 0]}]
          :message "gamestate"}))

-(defn coords-to-pixel [[j k]]
-  [(+ X-OFFSET (* TILE-SIZE
-                  (/ 3 2)
-                  (+ 2 (- k j))))
-   (+ Y-OFFSET (* (/ TILE-SIZE 2)
-                  (js/Math.sqrt 3)
-                  (+ k (- j 2))))])
-
+(defn parse-coords [coords]
+  (mapv (comp js/parseInt str/trim)
+        (str/split coords ",")))

 (defmulti handle-action :type)

@@ -63,9 +58,7 @@
                   first
                   :position)]
     (swap! state assoc :action
-           (assoc action
-             :start (coords-to-pixel start)
-             :stop (coords-to-pixel stop)))))
+           (assoc action :start start :stop (parse-coords stop)))))

 (defmethod handle-action "droid"
   [action]
@@ -96,8 +89,8 @@

 (defn parse-position [player]
   (assoc player
-    :position (mapv (comp js/parseInt str/trim)
-                    (str/split (:position player) ","))))
+    :position (parse-coords
+               (:position player))))

 (defmulti handle-message! :message)

@@ -185,6 +178,14 @@
         [:text {:class "damage" :x x :y y}
          text]]))))

+(defn coords-to-pixel [[j k]]
+  [(+ X-OFFSET (* TILE-SIZE
+                  (/ 3 2)
+                  (+ 2 (- k j))))
+   (+ Y-OFFSET (* (/ TILE-SIZE 2)
+                  (js/Math.sqrt 3)
+                  (+ k (- j 2))))])
+
 (defn laser-shot [{:keys [start stop]}]
   (html
    (let [[x_1 y_1] (coords-to-pixel start)
@@ -192,8 +193,8 @@
          x_d (- x_1 x_2)
          y_d (- y_1 y_2)
          height (+ TILE-SIZE
-                   (js/Math.sqrt (js/Math.pow x_d 2)
-                                 (js/Math.pow y_d 2)))
+                   (js/Math.sqrt (+ (js/Math.pow x_d 2)
+                                    (js/Math.pow y_d 2))))
          width 20
          angle (* (js/Math.atan2 x_d y_d)
                   (/ -180 js/Math.PI))]
@@ -221,8 +222,8 @@

 (defmulti action-view :type)
 (defmethod action-view "laser"
-  [{:keys [start stop]}]
-  (laser-shot start stop))
+  [shot]
+  (laser-shot shot))
 (defmethod action-view "droid"
   [action]
   (html [:g]))
@@ -267,7 +268,13 @@
              [:div {:class "level"}
               level]]))))

-(defn player-interface-view [{:keys [name position health score primary-weapon secondary-weapon]} owner]
+(defn player-interface-view [{:keys [name
+                                     position
+                                     health
+                                     score
+                                     primary-weapon
+                                     secondary-weapon]}
+                             owner]
   (reify
     om/IRender
     (render [_]
@@ -277,7 +284,7 @@
              [:div {:class "attr"}
               "Position: "
               [:div {:class "value"}
-                (str/join " " position)]]
+               (str/join " " position)]]
              [:div {:class "attr"}
               (str "HP: ")
               [:div {:class "value"}


Aesthetical improvements.

Aesthetical improvements.


construct sentences, rm repeated newlines etc.

--- clojure/beer-song/beer.clj
+++ clojure/beer-song/beer.clj
@@ -1,31 +1,37 @@
 (ns beer
-  (:use [clojure.string :only [join]]))
+  (:use [clojure.string :only [join upper-case]]))

-(defn- first-stanza [n]
+(defn- current-count-phrase [n]
   (cond
-   (= n 0) "No more bottles of beer on the wall, no more bottles of beer.\n"
-   (= n 1) (str n " bottle of beer on the wall, " n " bottle of beer.\n")
-   :else (str n " bottles of beer on the wall, " n " bottles of beer.\n")))
+   (= n 0) "no more bottles of beer on the wall, no more bottles of beer"
+   (= n 1) (str n " bottle of beer on the wall, " n " bottle of beer")
+   :else (str n " bottles of beer on the wall, " n " bottles of beer")))

-(defn- second-stanza [n]
+(defn- action-phrase [n]
   (cond
-   (= n 0) "Go to the store and buy some more, "
-   (= n 1) "Take it down and pass it around, "
-   :else "Take one down and pass it around, "))
+   (= n 0) "go to the store and buy some more, "
+   (= n 1) "take it down and pass it around, "
+   :else "take one down and pass it around, "))

-(defn- last-stanza [n]
+(defn- next-count-phrase [n]
   (cond
-   (= n -1) "99 bottles of beer on the wall.\n"
-   (= n 0) "no more bottles of beer on the wall.\n"
-   (= n 1) (str n " bottle of beer on the wall.\n")
-   :else (str n " bottles of beer on the wall.\n")))
+   (= n -1) "99 bottles of beer on the wall"
+   (= n 0) "no more bottles of beer on the wall"
+   (= n 1) (str n " bottle of beer on the wall")
+   :else (str n " bottles of beer on the wall")))
+
+(defn- make-sentense [[fst & rst]]
+  (str (apply str (upper-case fst) rst) ".\n"))

 (defn verse [n]
-  (str
-   (first-stanza n) (second-stanza n) (last-stanza (dec n))))
+  (join "" [
+            (make-sentense (current-count-phrase n))
+            (make-sentense (str
+                            (action-phrase n)
+                            (next-count-phrase (dec n))))]))

 (defn sing
   ([from] (sing from 0))
   ([from to]
      (join "\n"
-           (map verse (range from (- to 1) -1)))))
+           (map verse (range from (dec to) -1)))))


Loading project name, version, and dependencies into hash-map


Escape address so newlines and spaces don't interfere

Signed-off-by: shivekkhurana <ae036b02ef2f3d9f073f7930137ecb248a31c067@status.im>

--- src/status_im/ui/screens/wallet/recipient/views.cljs
+++ src/status_im/ui/screens/wallet/recipient/views.cljs
@@ -272,7 +272,7 @@
              :text-align-vertical :top
              :on-change-text      #(do
                                      (re-frame/dispatch [:set-in [:wallet/recipient :searching] :searching])
-                                     (debounce/debounce-and-dispatch [:wallet.recipient/address-changed %] 600))
+                                     (debounce/debounce-and-dispatch [:wallet.recipient/address-changed (utils/safe-trim %)] 600))
              :accessibility-label :recipient-address-input}]]
           [react/view {:align-items :center :height 30 :padding-bottom 8}
            (if searching
@@ -305,4 +305,4 @@
             :after               :main-icons/next
             :disabled            disabled?
             :on-press            #(re-frame/dispatch [:wallet.send/set-recipient resolved-address])}
-           (i18n/label :t/done)]}]]])))+           (i18n/label :t/done)]}]]])))


Adding logs to the message service

Adding logs to the message service


Added wait-until-indexed to test to catch ingest errors when changing collection formats.

--- system-int-test/test/cmr/system_int_test/ingest/granule_parent_dependency_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/granule_parent_dependency_test.clj
@@ -125,7 +125,7 @@
          gran-for-iso-smap-coll)))

 ;; This tests for limitations when changing the format for a collection with granules.
-;; TODO - Based on the test above, we would expect to see errors when saving when saving
+;; TODO - Based on the test above, we would expect to see the same errors seen when saving
 ;; collections in formats that don't support some things referenced by child granules, but we
 ;; do not. This needs to be investigated in CMR-2326.
 (deftest collection-format-change-test
@@ -174,13 +174,22 @@
         _ (d/ingest "PROV1" coll {:format :echo10})
         gran (dg/granule coll gran-data)
         _ (d/ingest "PROV1" gran {:format :echo10 :allow-failure? true})]
+    (index/wait-until-indexed)

-    (are [metadata-format]
-         (= []
-            (flatten (map (fn [error] (:errors error))
-                          (:errors (d/ingest "PROV1" coll {:format metadata-format
-                                                           :allow-failure? true})))))
+    (are [exp-errors metadata-format]
+         (= exp-errors
+            (flatten (:errors (d/ingest "PROV1" coll {:format metadata-format
+                                                           :allow-failure? true}))))
+         []
          :dif
+
+         []
          :dif10
+
+         ["Collection additional attribute [a-float] is referenced by existing granules, cannot be removed. Found 1 granules."
+           "Collection changing from GEODETIC granule spatial representation to NO_SPATIAL is not allowed when the collection has granules. Found 1 granules."]
          :iso19115
+
+         ["Collection additional attribute [a-float] is referenced by existing granules, cannot be removed. Found 1 granules."
+           "Collection changing from GEODETIC granule spatial representation to NO_SPATIAL is not allowed when the collection has granules. Found 1 granules."]
          :iso-smap)))


CMR-2390: Renamed function.

CMR-2390: Renamed function.

--- search-app/src/cmr/search/services/parameters/parameter_validation.clj
+++ search-app/src/cmr/search/services/parameters/parameter_validation.clj
@@ -610,7 +610,7 @@
               (csk/->snake_case_string param) value)))))
     [:snippet-length :num-snippets]))

-(defn- result-format-parameters-validation
+(defn- include-tags-parameter-validation
   "Validates parameters against result format."
   [concept-type params]
   (concat
@@ -709,7 +709,7 @@
    line-validation
    no-highlight-options-without-highlights-validation
    highlights-numeric-options-validation
-   result-format-parameters-validation])
+   include-tags-parameter-validation])

 (def standard-query-parameter-validations
   "A list of functions that can validate the query parameters passed in with an AQL or JSON search.


Bug fix for DOM refactoring.

Bug fix for DOM refactoring.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -870,7 +870,7 @@
         (append-children! elem ch))
       (append-child! elem ch))))

-(defn- build-dom-element [xmlns tag-name tail]
+(defn- build-dom-element [tag elem-spec xmlns tag-name tail]
   (let [node (create-dom-node xmlns tag-name)
         attrs? (first tail)
         attrs (when (map? attrs?) attrs?)
@@ -899,7 +899,7 @@
           (if-let [tag-handler (aget node-ns-lookup tag-ns)]
             (cond
              (string? tag-handler)
-             (build-dom-element tag-handler tag-name tail)
+             (build-dom-element tag elem-spec tag-handler tag-name tail)

              (fn? attr-handler)
              (tag-handler tag-name tail)
@@ -907,7 +907,7 @@
              :default
              (throw (js/Error. (str "Invalid ns node handler " tag-handler))))
             (throw (js/Error. (str "Undefined ns node prefix " tag-ns))))
-          (build-dom-element nil tag-name tail))))))
+          (build-dom-element tag elem-spec nil tag-name tail))))))

 (defn mount! [element child]
   (when-let [last-child (.-lastChild element)]


WIP on new DOM implementation.

WIP on new DOM implementation.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -52,8 +52,7 @@
 (defn- init-element-state! [dom-node tag]
   (let [node-id (str auto-node-id)
         state ;;(ElementState. node-id false element-spec nil)
-        #js
-        {:id node-id :disposed false :tag tag}]
+        #js {:id node-id :disposed false :tag tag}]
     (set! auto-node-id (inc auto-node-id))
     (set! (.-freactive-state dom-node) state)
     state))
@@ -186,6 +185,21 @@
     (aset (.-style elem) prop-name (normalize-attr-value prop-value))
     (js-delete (.-style elem) prop-name))
   prop-value)
+
+(deftype ReactiveAttribute [id the-ref binding-info set-fn ^:mutable disposed]
+  Object
+  (dispose [this]
+    ((.-remove-watch binding-info) ref id)
+    (when-let [clean (.-clean binding-info)] (clean the-ref))
+    (when-let [binding-disposed (get (meta the-ref) :binding-disposed)]
+      (binding-disposed)))
+  (invalidate [this]
+    ((.-remove-watch binding-info) ref id)
+    (queue-animation
+     (fn [_]
+       (when-not disposed
+         ((.-add-watch binding-info) ref id #(.invalidate this))
+         (set-fn ((.-raw-deref binding-info) ref)))))))

 (defn- bind-attr* [set-fn element state-key ref node-state]
   (let [binding-fns (r/get-binding-fns ref)
@@ -883,3 +897,258 @@

 ;; (defn bind-keys [keyset-cursor element-fn]
 ;;   )
+
+
+(defprotocol IVirtualDOM
+  (-vdom-insert [this dom-parent dom-before])
+  (-vdom-remove [this])
+  (-vdom-head [this])
+  (-vdom-tail [this])
+  (-vdom-replace [this new-vdom])
+  (-vdom-node [this])
+  (-vdom-element [this]))
+
+(defn vdom-node [this]
+  (if (dom-node? this)
+    this
+    (-vdom-node this)))
+
+(defn vdom-element [this]
+  (if (dom-node? this)
+    this
+    (-vdom-element this)))
+
+(defn dom-insert [dom-node dom-parent dom-before]
+  (if dom-before
+    (.insertBefore dom-parent dom-node dom-before)
+    (.appendChild dom-parent dom-node)))
+
+(defn dom-remove [dom-node]
+  (when-let [parent (.-parentNode dom-node)]
+    (.removeChild parent dom-node)))
+
+(defn vdom-head [this]
+  (if (dom-node? this)
+    this
+    (-vdom-head this)))
+
+(defn vdom-tail [this]
+  (if (dom-node? this)
+    this
+    (-vdom-tail this)))
+
+(defn vdom-remove [this]
+  (if (dom-node? this)
+    (dom-remove this)
+    (-vdom-remove this)))
+
+(defn vdom-insert [this dom-parent dom-before]
+  (if (dom-node? this)
+    (dom-insert this dom-parent dom-before)
+    (-vdom-insert this dom-parent dom-before)))
+
+(defn dom-replace [dom-node new-vdom]
+  (when-let [parent (.-parentNode dom-node)]
+    (if-let [node (vdom-node new-vdom)]
+      (do
+        (.replaceChild parent node dom-node)
+        new-vdom)
+      (let [next-sib (.-nextSibling dom-node)]
+        (.removeChild parent dom-node)
+        (vdom-insert new-vdom parent next-sib)))))
+
+(defn vdom-replace [this new-vdom]
+  (if (dom-node? this)
+    (dom-replace this new-vdom)
+    (-vdom-replace this new-vdom)))
+
+;; replace scenarios
+;; DOMElement DOMElement -> diff or replace
+;; DOMTextNode DOMTextNode -> simple update
+;; DOMElement DOMTextNode -> replace
+;; DOMElement ReactiveElement -> defer to ReactiveElement
+;; DOMElement ReactiveElementCollection -> remove, insert
+;; ReactiveElement ReactiveElement -> defer to replacing elem
+;; ReactiveElement DOMTextNode -> defer to replacing elem
+;; ReactiveElement ReactiveElementCollection
+;; ReactiveElementCollection DOMTextNode
+;; ReactiveElementCollection ReactiveElementCollection
+
+(defn- vdom-full-replace [this node new-vdom]
+  (let [next-sib (.-nextSibling node)
+        parent (.-parentNode node)]
+    (vdom-remove this)
+    (-vdom-insert new-vdom parent next-sub)))
+
+(defn dom-simple-replace [dom-node new-elem]
+  (when-let [parent (.-parentNode dom-node)]
+    (.replaceChild parent node (vdom-node new-elem))))
+
+(defn dom-remove-replace [dom-node new-vdom]
+  (when-let [parent (.-parentNode dom-node)]
+    (let [next-sib (.-nextSibling dom-node)]
+      (.removeChild parent dom-node)
+      (vdom-insert new-vdom parent next-sib))))
+
+(deftype DOMElement [ns-uri tag attrs events bindings children ^:mutable node]
+  Object
+  (ensureNode [this]
+    (when-not node
+      (set! node
+            (if xmlns
+              (.createElementNS js/document ns-uri tag)
+              (.createElement js/document tag)))
+      (doseq [child children]
+        (-vdom-insert child node nil))))
+
+  IVirtualDOM
+  (-vdom-head [this] node)
+  (-vdom-tail [this] node)
+  (-vdom-node [this]
+    (.ensureNode this)
+    node)
+  (-vdom-element [this] this)
+  (-vdom-insert [this dom-parent dom-before]
+    (.ensureNode this)
+    (dom-insert dom-parent node dom-before))
+
+  (vdom-remove [this]
+    (dom-remove node))
+  (-vdom-replace [this new-vdom]
+    (if-let [new-elem (vdom-element new-vdom)]
+      (if (and (instance? DOMElement new-elem)
+               (identical? (.-ns-uri new-elem) ns-uri)
+               (identical? (.-tag new-elem) tag))
+        (do
+          ;; TODO do diff replace
+          this)
+        (do
+          (dom-simple-replace node new-elem)
+          new-vdom))
+      (dom-remove-replace node new-vdom))))
+
+(deftype DOMTextNode [^:mutable text ^:mutable node]
+  Object
+  (ensureNode [this]
+    (when-not node
+      (set! node (.createTextNode js/document text))))
+  IVirtualDOM
+  (-vdom-head [this] node)
+  (-vdom-tail [this] node)
+  (-vdom-node [this]
+    (.ensureNode this)
+    node)
+  (-vdom-element [this] this)
+  (-vdom-insert [this dom-parent dom-before]
+    (.ensureNode this)
+    (dom-insert dom-parent node dom-before))
+  (-vdom-remove [this]
+    (dom-remove node))
+  (-vdom-replace [this new-vdom]
+    (if-let [new-elem (vdom-element new-vdom)]
+      (if (instance? DOMTextNode new-vdom)
+        (do
+          (.ensureNode this)
+          (set! text (.-text new-vdom))
+          (set! (.-textContent node) text)
+          this)
+        (do
+          (dom-simple-replace node new-elem)
+          new-vdom))
+      (dom-remove-replace node new-vdom))))
+
+(deftype ReactiveElement [id ^:mutable parent the-ref binding-info ^:mutable cur-vdom ^:mutable dirty
+                          ^:mutable updating ^:mutable disposed]
+  Object
+  (dispose [this]
+    #_(remove-watch* the-ref id)
+    #_(when clean* (clean* child-ref))
+    #_(when-let [binding-disposed (get ref-meta :binding-disposed)]
+      (binding-disposed)))
+  (get-new-elem [this]
+    (set! dirty false)
+    ((.-add-watch binding-info) the-ref id #(.invalidate this))
+    (or ((.-raw-deref binding-info) the-ref) ""))
+
+  (show-new-elem [this new-vdom dom-before]
+    (if cur-elem
+      (set! cur-vdom (-vdom-replace cur-vdom new-vdom))
+      (-vdom-insert new-elem parent before))
+    (set! updating false)
+    (when dirty
+      (queue-animation #(.animate this))))
+
+  (animate [this]
+    (when-not disposed
+      (let [new-vdom (get-new-elem)]
+        (when-not (= new-vdom cur-vdom)
+          (-vdom-replace cur-vdom
+           (fn []
+             (if disposed
+               (set! updating false)
+               (.show-new-elem this (if dirty
+                                      (get-new-elem)
+                                      new-vdom) nil))))))))
+  (invalidate [this]
+    ((.-remove-watch binding-info) the-ref id)
+    (when-not disposed
+      (set! dirty true)
+      (when-not updating
+        (set! updating true)
+        (queue-animation #(.animate this)))))
+
+  IEquiv
+  (-equiv [this other]
+    (and
+     (instance? ReactiveElement other)
+     (= the-ref (.-the-ref other))))
+
+  IVirtualDOM
+  (-vdom-head [this] (vdom-head cur-elem))
+  (-vdom-tail [this] (vdom-tail cur-elem))
+  (-vdom-node [this] (vdom-node cur-elem))
+  (-vdom-element [this] (vdom-element cur-elem))
+  (-vdom-insert [this dom-parent dom-before]
+    (set! (.-parent this) dom-parent)
+    (.show-new-elem this (.get-new-elem this) dom-before)
+    this)
+  (-vdom-remove [this]
+    (set! (.-disposed this) true)
+    (vdom-remove cur-elem))
+  (-vdom-replace [this new-vdom]
+    (if (= this new-vdom)
+      this
+      (do
+        (.dispose this)
+        (vdom-replace cur-elem new-vdom)))))
+
+(deftype ReactiveElementCollection [dom-parent elements]
+  Object
+  (move [this idx before-idx]
+    (.insert this (aget (.splice elements idx 1) 0) before-idx))
+  (remove [this idx]
+    (vdom-remove (aget (.splice elements idx 1) 0)))
+  (insert [this elem before-idx]
+    (let [before-elem (when before-idx (aget elements before-idx))]
+      (.splice elements (or before-idx (alength elements)) 0 to-move)
+      ;; TODO handle append case
+      (-vdom-insert to-move dom-parent (vdom-head before-elem))))
+
+  IVirtualDOM
+  (-vdom-node [this])
+  (-vdom-element [this])
+  (-vdom-head [this]
+    (when (> (.-length elements) 0)
+      (vdom-head (aget elements 0))))
+  (-vdom-tail [this]
+    (when (> (.-length elements) 0)
+      (vdom-tail (aget elements (dec (.-length elements))))))
+  (-vdom-insert [this dom-parent dom-before]
+    (loop [dom-before dom-before
+           [elem & more] elements]
+      (when elem
+        (recur (dom-insert dom-parent elem dom-before) more))))
+  (-vdom-remove [this]
+    (set! (.-disposed this) true)
+    (doseq [elem elements]
+      (vdom-remove elem))))


populate project-crumb data correctly in send

--- src-cljs/frontend/send.cljs
+++ src-cljs/frontend/send.cljs
@@ -383,9 +383,13 @@
                (= 1 (count children))
                (= :organization/project (:key (first children)))
                (= '[:project/name] (:query (first children)))))
-        (let [{:keys [organization/vcs-type organization/name]} (:params ast)]
-          (cb {:circleci/organization {:organization/vcs-type vcs-type
-                                       :organization/name name}}
+        (let [project-name (-> ast
+                               (expr-ast/get :organization/project)
+                               :params
+                               :project/name)]
+          (cb {:circleci/organization
+               {:organization/project
+                {:project/name project-name}}}
               query))


Fix default value of action type selector.

--- src/cljs/hatnik/web/client/form/add_action.cljs
+++ src/cljs/hatnik/web/client/form/add_action.cljs
@@ -61,9 +61,10 @@
     om/IRender
     (render [this]
       (let [callback (:handler data)]
-        (dom/div #js {:className "form-group"}
+        (dom/div #js {:className "form-group action-type-component"}
                  (dom/label nil "Action type")
                  (dom/select #js {:className "form-control"
+                                  :defaultValue (name (:type data))
                                   :onChange #(callback (keyword (.. % -target -value)))}
                              (dom/option (option-element-map "email" (= :email (:type data)))  "Email")
                              (dom/option (option-element-map "noop" (= :noop (:type data))) "Noop")))))))


Update urls.cljs

Update urls.cljs

--- src/cljs/wombats_web_client/constants/urls.cljs
+++ src/cljs/wombats_web_client/constants/urls.cljs
@@ -10,7 +10,7 @@
 (def github-signout-url (str base-api-url "/api/v1/auth/github/signout"))
 (def github-signin-url (str base-api-url "/api/v1/auth/github/signin"))

-(def ws-url (str "wss:" base-api-url "/ws/game"))
+(def ws-url (str "ws:" base-api-url "/ws/game"))

 (defn my-wombats-url
   [id]


Comment experimental tests.

Comment experimental tests.

--- test/suricatta/extend_test.clj
+++ test/suricatta/extend_test.clj
@@ -6,70 +6,70 @@
             [cheshire.core :refer :all])
   (:import org.postgresql.util.PGobject))

-(def dbspec {:subprotocol "postgresql"
-             :subname "//localhost/test"})
+;; (def dbspec {:subprotocol "postgresql"
+;;              :subname "//localhost/test"})

-(def ^:dynamic *ctx*)
+;; (def ^:dynamic *ctx*)

-(defn my-fixture
-  [end]
-  (with-open [ctx (sc/context dbspec)]
-    (sc/atomic ctx
-      (binding [*ctx* ctx]
-        (end)
-        (sc/set-rollback! ctx)))))
+;; (defn my-fixture
+;;   [end]
+;;   (with-open [ctx (sc/context dbspec)]
+;;     (sc/atomic ctx
+;;       (binding [*ctx* ctx]
+;;         (end)
+;;         (sc/set-rollback! ctx)))))

-(use-fixtures :each my-fixture)
+;; (use-fixtures :each my-fixture)

-(defn json
-  [data]
-  (proxy [org.jooq.impl.CustomField] [nil, org.jooq.util.postgres.PostgresDataType/JSON]
-    (accept [ctx]
-      (cond
-       (instance? org.jooq.RenderContext ctx)
-       (doto ctx
-         (.sql "'")
-         (.sql (generate-string data))
-         (.sql "'::json"))
+;; (defn json
+;;   [data]
+;;   (proxy [org.jooq.impl.CustomField] [nil, org.jooq.util.postgres.PostgresDataType/JSON]
+;;     (accept [ctx]
+;;       (cond
+;;        (instance? org.jooq.RenderContext ctx)
+;;        (doto ctx
+;;          (.sql "'")
+;;          (.sql (generate-string data))
+;;          (.sql "'::json"))

-       (instance? org.jooq.BindContext ctx)
-       (let [obj        (doto (PGobject.)
-                          (.setType "json")
-                          (.setValue (generate-string data)))
-             statement  (.statement ctx)
-             _          (println 454545 (class (.getDelegate statement)))
-             paramcount (.getParameterCount (.getParameterMetaData statement))]
-        (when (<= (.peekIndex ctx) paramcount)
-          (.setObject statement
-                      (.nextIndex ctx)
-                      obj)))))))
+;;        (instance? org.jooq.BindContext ctx)
+;;        (let [obj        (doto (PGobject.)
+;;                           (.setType "json")
+;;                           (.setValue (generate-string data)))
+;;              statement  (.statement ctx)
+;;              _          (println 454545 (class (.getDelegate statement)))
+;;              paramcount (.getParameterCount (.getParameterMetaData statement))]
+;;         (when (<= (.peekIndex ctx) paramcount)
+;;           (.setObject statement
+;;                       (.nextIndex ctx)
+;;                       obj)))))))

-(deftest inserting-json
-  (sc/execute *ctx* "create table t1 (data json, k int)")
-  (sc/execute *ctx* ["insert into t1 (data, k) values (?, ?)" (json {:foo "bar"}) 2])
-  (-> (sc/fetch *ctx* "select * from t1")
-      (println)))
+;; (deftest inserting-json
+;;   (sc/execute *ctx* "create table t1 (data json, k int)")
+;;   (sc/execute *ctx* ["insert into t1 (data, k) values (?, ?)" (json {:foo "bar"}) 2])
+;;   (-> (sc/fetch *ctx* "select * from t1")
+;;       (println)))

-(deftest inserting-json-dsl
-  (sc/execute *ctx* "create table t1 (data json)")
-  (let [q (-> (dsl/insert-into :t1)
-              (dsl/insert-values {:data (json {:foo 1})})
-              (dsl/insert-values {:data (json {:bar 2})}))]
-    (sc/execute *ctx* q))
-  (-> (sc/fetch *ctx* "select * from t1")
-      (println)))
+;; (deftest inserting-json-dsl
+;;   (sc/execute *ctx* "create table t1 (data json)")
+;;   (let [q (-> (dsl/insert-into :t1)
+;;               (dsl/insert-values {:data (json {:foo 1})})
+;;               (dsl/insert-values {:data (json {:bar 2})}))]
+;;     (sc/execute *ctx* q))
+;;   (-> (sc/fetch *ctx* "select * from t1")
+;;       (println)))

-(deftest inserting-arrays
-  (sc/execute *ctx* "create table t1 (data int[])")
-  (let [data [1 2 3]]
-    (sc/execute *ctx* ["insert into t1 (data) values (?)" data])
-    (-> (sc/fetch *ctx* "select * from t1")
-        (println))))
+;; (deftest inserting-arrays
+;;   (sc/execute *ctx* "create table t1 (data int[])")
+;;   (let [data [1 2 3]]
+;;     (sc/execute *ctx* ["insert into t1 (data) values (?)" data])
+;;     (-> (sc/fetch *ctx* "select * from t1")
+;;         (println))))

-(deftest json-select
-  (let [q (dsl/select (.as (json {:a 1}) "dd"))]
-    (-> (sc/fetch *ctx* q)
-        (println))))
+;; (deftest json-select
+;;   (let [q (dsl/select (.as (json {:a 1}) "dd"))]
+;;     (-> (sc/fetch *ctx* q)
+;;         (println))))


Add with-pass-thru macro

Add with-pass-thru macro

--- boot/core/src/boot/core.clj
+++ boot/core/src/boot/core.clj
@@ -745,6 +745,16 @@

 ;; Low-Level Tasks, Helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+(defmacro with-pass-thru
+  "Given a binding and body expressions, constructs a task handler. The body
+  expressions are evaluated for side effects with the current fileset bound
+  to binding. The current fileset is then passed to the next handler and the
+  result is then returned up the handler stack."
+  [bind & body]
+  (let [bind (if (vector? bind) (first bind) bind)]
+    `(boot.core/with-pre-wrap [fs#]
+       (boot.util/with-let [~bind fs#] ~@body))))
+
 (defmacro with-pre-wrap
   "Given a binding and body expressions, constructs a task handler. The body
   expressions are evaluated with the current fileset bound to binding, and the


Fix namespace name on some test file.

Fix namespace name on some test file.

--- test/buddy/test_buddy_core_hashers.clj
+++ test/buddy/test_buddy_core_hashers.clj
@@ -12,16 +12,14 @@
 ;; See the License for the specific language governing permissions and
 ;; limitations under the License.

-(ns buddy.test-buddy-core
+(ns buddy.test-buddy-core-hashers
   (:require [clojure.test :refer :all]
             [buddy.core.codecs :refer :all]
-            ;; [buddy.core.keys :refer :all]
             [buddy.hashers.pbkdf2 :as pbkdf2]
             [buddy.hashers.bcrypt :as bcrypt]
             [buddy.hashers.sha256 :as sha256]
             [buddy.hashers.md5 :as md5]
             [buddy.hashers.scrypt :as scrypt]))
-            ;; [clojure.java.io :as io])o

 (deftest buddy-hashers
   (testing "Test low level api for encrypt/verify pbkdf2"


Add a couple of more tests for with-let

Add a couple of more tests for with-let

--- test/reagenttest/testreagent.cljs
+++ test/reagenttest/testreagent.cljs
@@ -585,3 +585,30 @@
         (r/flush)
         (is (= [1 2 0] [@n1 @n2 @n3]))))
     (is (= [1 2 1] [@n1 @n2 @n3]))))
+
+(deftest with-let-destroy-only
+  (let [n1 (atom 0)
+        n2 (atom 0)
+        c (fn []
+            (with-let []
+              (swap! n1 inc)
+              [:div]
+              (finally
+                (swap! n2 inc))))]
+    (with-mounted-component [c]
+      (fn [_ div]
+        (is (= [1 0] [@n1 @n2]))))
+    (is (= [1 1] [@n1 @n2]))))
+
+(deftest with-let-non-reactive
+  (let [n1 (atom 0)
+        n2 (atom 0)
+        n3 (atom 0)
+        c (fn []
+            (with-let [a (swap! n1 inc)]
+              (swap! n2 inc)
+              [:div a]
+              (finally
+                (swap! n3 inc))))]
+    (is (= (rstr [c]) (rstr [:div 1])))
+    (is (= [1 1 1] [@n1 @n2 @n3]))))


Updating version to 1.62.6-SNAPSHOT

Updating version to 1.62.6-SNAPSHOT

--- scheduler/project.clj
+++ scheduler/project.clj
@@ -13,7 +13,7 @@
 ;; See the License for the specific language governing permissions and
 ;; limitations under the License.
 ;;
-(defproject cook "1.62.5"
+(defproject cook "1.62.6-SNAPSHOT"
   :description "This launches jobs on a Mesos cluster with fair sharing and preemption"
   :license {:name "Apache License, Version 2.0"}
   :dependencies [[org.clojure/clojure "1.10.3"]


prevent logging statement from expanding lazy evaluation of return value

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -277,10 +277,7 @@
 ;                (throw (exception message)))
 )
               (do (log/debug (str "add-complement after adding complement: "
-                                  (string/join ","
-                                               (map (fn [each]
-                                                      (morph each))
-                                                    return-val))))
+                                  (morph (first return-val)) ",.."))
                   return-val)))))

       ;; path doesn't exist in bolt: simply return the bolt unmodified.


Removed :print-behavioral-diversity from RSWN

--- src/clojush/problems/software/replace_space_with_newline.clj
+++ src/clojush/problems/software/replace_space_with_newline.clj
@@ -203,7 +203,6 @@
    :uniform-mutation-rate 0.01
    :problem-specific-report replace-space-with-newline-report
    :problem-specific-initial-report replace-space-with-newline-initial-report
-   :print-behavioral-diversity true
    :report-simplifications 0
    :final-report-simplifications 5000
    :max-error 5000


recovered css

recovered css

--- cljs/tag/src/todo/core.cljs
+++ cljs/tag/src/todo/core.cljs
@@ -21,7 +21,6 @@
              	todo-to-map title completed todo-to-json todo-load todo-upsert
             	todo-dump todo-delete  load-all-todos gTodo-items]]))

-
 (declare todoDelete mk-todo-item mk-main mk-info
 	mk-dashboard mk-todo-entry)

@@ -30,7 +29,7 @@
 	;; (todo-dump "landing entry")

 	(comment
-		(pln :truncating!!!!! TODO_LS_PREFIX)
+		(pln :truncating!!! TODO_LS_PREFIX)
 		(io-truncate TODO_LS_PREFIX)

 		(make-todo {:title "move North"})
@@ -47,15 +46,11 @@
 	(pln :loadedtodos-raw (count (md-get @gTodo :items-raw)))
 	(pln :loadedtodos (count (md-get @gTodo :items)))

-	;; todo functionalize
-	(let [bits [(section (:class "todoapp")
+	(to-html [(section (:class "todoapp")
             		(mk-todo-entry)
             		(mk-main)
 					(mk-dashboard))
-          		(mk-info)]
-		b$ (to-html bits)]
-		(pln (count bits) :b$ b$)
-    	b$))
+          		(mk-info)]))

 ;;; --- new todo entry, validation, and storage ------------------------------------


Revised combined-pairs function to constrain the skos:exactMatch relation between ids

--- kabob-build/src/main/clojure/edu/ucdenver/ccp/kabob/build/id_sets/kabob_id_sets.clj
+++ kabob-build/src/main/clojure/edu/ucdenver/ccp/kabob/build/id_sets/kabob_id_sets.clj
@@ -213,9 +213,14 @@
         ;; [(hash-of khash)
         ;;  (clean-union-find union-find)]))))

-
+
 (defn combined-pairs-fn [kb]
-  (let [query-pat `((?/ice1 skos/exactMatch ?/ice2))]
+  (let [query-pat `((?/id skos/exactMatch ?/id2)
+                     (?/id rdf/type ?/id_type)
+                     (?/id_type [rdfs/subClassOf *] obo/IAO_0000578 ) ;centrally registered identifier
+                     (?/id2 rdf/type ?id_type2)
+                     (?/id_type2 [rdfs/subClassOf *] obo/IAO_0000578) ;centrally registered identifier
+                     (!= ?/id  ?/id2))]
     (binding [*use-inference* false
               *work-queue-single-threaded* true]
       (println "running pairs query.")
@@ -231,11 +236,11 @@
           (query-reduce-with-logging kb query-pat union-find
             (fn [_ bindings]
               ;(work (fn []
-                      (let [ice1 (get bindings '?/ice1 nil)
-                            ice2 (get bindings '?/ice2 nil)]
-                        (and ice1
-                             ice2
-                             (uf-union union-find ice1 ice2)))
+                      (let [id (get bindings '?/id nil)
+                            id2 (get bindings '?/id2 nil)]
+                        (and id
+                             id2
+                             (uf-union union-find id id2)))
                       nil));)))
         union-find))))


name change

name change

--- examples/basic/src/basic/core.cljs
+++ examples/basic/src/basic/core.cljs
@@ -15,7 +15,7 @@
   (go
     (<! (r/load-resources canvas :bg ["img/bunny.png"]))

-    (t/set-texture! :rabbit (r/get-texture :bunny :nearest))
+    (t/add! :rabbit (r/get-texture :bunny :nearest))

     (m/with-sprite canvas :bg
       [rabbit (s/make-sprite :rabbit)]


whitespace

whitespace

--- src/babel/italiano/morphology/nouns.cljc
+++ src/babel/italiano/morphology/nouns.cljc
@@ -21,6 +21,7 @@
                  :case :acc
                  :agr {:number :sing
                        :gender :fem}}}}
+
    {:p [#"^l$" "lo"] ;; "l'" -> "lo"
     :u {:synsem {:cat :noun
                  :pronoun true
@@ -33,14 +34,14 @@
                  :agr {:gender :fem
                        :number :plur}}}}

-   { :g [#"(.*)ca"   "$1che" ] ;; "mucca" -> "mucche"
-     :p [#"(.*)che$" "$1ca"] ;; "mucche" -> "mucca"
-     :u {:synsem {:cat :noun
+   {:g [#"(.*)ca"   "$1che" ] ;; "mucca" -> "mucche"
+    :p [#"(.*)che$" "$1ca"] ;; "mucche" -> "mucca"
+    :u {:synsem {:cat :noun
                  :agr {:gender :fem
                        :number :plur}}}}

    {:g [#"(.*)à"   "$1à" ]
-     :p [#"(.*)à$" "$1à"] ;; "città" -> "città"
+    :p [#"(.*)à$" "$1à"] ;; "città" -> "città"
     :u {:synsem {:cat :noun
                  :agr {:gender :fem
                        :number :plur}}}}
@@ -51,13 +52,13 @@
                  :agr {:number :plur}}}}

    {:g [#"(.*)e"   "$1i" ] ;; cane --> cani
-     :p [#"(.*)i$" "$1e"] ;; "cani" -> "cane"; "madri" -> "madre"
+    :p [#"(.*)i$" "$1e"] ;; "cani" -> "cane"; "madri" -> "madre"
     ;; (note that no gender is specified in :u because it could be either.
     :u {:synsem {:cat :noun
                  :agr {:number :plur}}}}

    {:g [#"(.*)o"   "$1i" ]
-     :p [#"(.*)i$" "$1o"] ;; "compiti" -> "compito"
+    :p [#"(.*)i$" "$1o"] ;; "compiti" -> "compito"
     :u {:synsem {:cat :noun
                  :agr {:number :plur}}}}
    ])


remove exceptional lexical entries which use :boot-stem1 : treat as regular instead

--- src/babel/italiano/morphology/verbs.cljc
+++ src/babel/italiano/morphology/verbs.cljc
@@ -282,51 +282,6 @@
                   :italiano (get-in val [:italiano :present :3plur] :nothing)
                   :agr {:number :plur
                         :person :3rd}}})}
-
-   ;; 2.1. present tense boot-stem
-   (let [surface-form (fn [val] (str (get-in val [:italiano :boot-stem1]) "o"))]
-     {:path [:italiano :boot-stem1]
-      :label "present boot-stem1: o"
-      :surface-form surface-form
-      :merge-fn
-      (fn [val]
-        {:italiano {:infl :present
-                    :italiano (surface-form val)
-                    :agr {:number :sing
-                          :person :1st}}})})
-
-   (let [surface-form (fn [val] (str (get-in val [:italiano :boot-stem1]) "i"))]
-     {:path [:italiano :boot-stem1]
-      :label "present boot-stem1: i"
-      :surface-form surface-form
-      :merge-fn
-      (fn [val]
-        {:italiano {:infl :present
-                    :italiano (surface-form val)
-                    :agr {:number :sing
-                          :person :2nd}}})})
-
-   (let [surface-form (fn [val] (str (get-in val [:italiano :boot-stem1]) "e"))]
-     {:path [:italiano :boot-stem1]
-      :label "present boot-stem1: e"
-      :surface-form surface-form
-      :merge-fn
-      (fn [val]
-        {:italiano {:infl :present
-                    :italiano (surface-form val)
-                    :agr {:number :sing
-                          :person :3rd}}})})
-
-   (let [surface-form (fn [val] (str (get-in val [:italiano :boot-stem1]) "ono"))]
-     {:path [:italiano :boot-stem1]
-      :label "present boot-stem1: ono"
-      :surface-form surface-form
-      :merge-fn
-      (fn [val]
-        {:italiano {:infl :present
-                    :italiano (surface-form val)
-                    :agr {:number :plur
-                          :person :3rd}}})})

    ;; 3. future-tense exceptions
    {:path [:italiano :future :1sing]


renaming variables to shorter names

renaming variables to shorter names

--- src/babel/italiano/morphology/verbs.cljc
+++ src/babel/italiano/morphology/verbs.cljc
@@ -34,14 +34,14 @@
 ;; </conditional>

 ;; <future>
-(let [regular-future-source
+(let [source
       (-> (clojure.java.io/resource "babel/italiano/morphology/verbs/future.edn")
           slurp
           read-string)]
   (defonce patterns-future
     (compile-patterns
      {:synsem {:infl :future}}
-     regular-future-source)))
+     source)))

 (defn regular-future? [word]
   (and (= (get-in word [:infl]) :future)
@@ -57,14 +57,14 @@
 ;; </future>

 ;; <imperfect>
-(let [regular-imperfect-source
+(let [source
       (-> (clojure.java.io/resource "babel/italiano/morphology/verbs/imperfetto.edn")
           slurp
           read-string)]
   (defonce patterns-imperfect
     (compile-patterns
      {:synsem {:infl :imperfect}}
-     regular-imperfect-source)))
+     source)))

 (defn regular-imperfect? [word]
   ;; regular imperfect sense
@@ -81,32 +81,25 @@
 ;; </imperfect>

 ;; <present>
-(let [regular-present-source
+(let [source
       (-> (clojure.java.io/resource "babel/italiano/morphology/verbs/present.edn")
           slurp
           read-string)]
   (defonce patterns-present
     (compile-patterns
      {:synsem {:infl :present}}
-     regular-present-source)))
-
+     source)))
 ;; </present>

 ;; <passato>
-(let [regular-past-source
+(let [source
       (-> (clojure.java.io/resource "babel/italiano/morphology/verbs/past.edn")
           slurp
           read-string)]
-  (defonce regular-past-generate-patterns
-    (compile-patterns
-     {:synsem {:infl :past}}
-     regular-past-source))
-
   (def patterns-past
     (compile-patterns
      {:synsem {:infl :past}}
-     regular-past-source)))
-
+     source)))
 ;; </passato>

 ;; <subjunctive>


fileDownload is now using BufferInputStream

--- src/clj/backtype/storm/daemon/nimbus.clj
+++ src/clj/backtype/storm/daemon/nimbus.clj
@@ -986,7 +986,7 @@
           ))

       (^String beginFileDownload [this ^String file]
-        (let [is (.open storage file)
+        (let [is (BufferInputStream. (.open storage file))
               id (uuid)]
           (.put (:downloaders nimbus) id is)
           id
@@ -994,7 +994,7 @@

       (^ByteBuffer downloadChunk [this ^String id]
         (let [downloaders (:downloaders nimbus)
-              ^InputStream is (.get downloaders id)]
+              ^BufferInputStream is (.get downloaders id)]
           (when-not is
             (throw (RuntimeException.
                     "Could not find input stream for that id")))


msg fixed

msg fixed

--- src/clj/backtype/storm/daemon/nimbus.clj
+++ src/clj/backtype/storm/daemon/nimbus.clj
@@ -822,7 +822,7 @@
         active-topologies (set (.active-storms storm-cluster-state))
         corrupt-topologies (set/difference active-topologies code-ids)]
     (doseq [corrupt corrupt-topologies]
-      (log-message "Corrupt topology " corrupt " has state on zookeeper but doesn't have a local dir on Nimbus. Cleaning up...")
+      (log-message "Corrupt topology " corrupt " has state on zookeeper but doesn't have a dir in Nimbus storage. Cleaning up...")
       (.remove-storm! storm-cluster-state corrupt)
       )))


Tweaking defmain to not use multiple arity

--- src/clj/forma/hadoop/jobs/preprocess.clj
+++ src/clj/forma/hadoop/jobs/preprocess.clj
@@ -95,12 +95,10 @@
   "Path for running FORMA fires processing. See the forma-clj wiki for
 more details. m-res is the resolution of the other MODIS data we are
 using, likely \"500\""
-  ([type path pail-path m-res]
+  ([path pail-path m-res & [type]]
      (->> (case type
             nil (f/fire-source               (hfs-textline path))
             "daily" (f/fire-source-daily     (hfs-textline path))
             "monthly" (f/fire-source-monthly (hfs-textline path)))
           (f/reproject-fires m-res)
-          (to-pail pail-path)))
-  ([path pail-path m-res]
-     (PreprocessFire nil path pail-path m-res)))
+          (to-pail pail-path))))


(TK-179) Refactor clojure client init to use JavaClient/createClient

Previously, there were two completely separate code paths for java and clojure
http client initialization. This meant that there was a lot of duplicated
logic between them for handling a number of client options, such as redirect
strategy, ssl protocols and ciphers, and ssl setup.

This refactors clojure client initialization to use JavaClient/createClient,
thereby removing a lot of this duplication.

--- src/clj/puppetlabs/http/client/async.clj
+++ src/clj/puppetlabs/http/client/async.clj
@@ -13,14 +13,8 @@

 (ns puppetlabs.http.client.async
   (:import (com.puppetlabs.http.client ClientOptions RequestOptions ResponseBodyType HttpMethod)
-           (org.apache.http.impl.nio.client HttpAsyncClients)
            (org.apache.http.client.utils URIBuilder)
-           (com.puppetlabs.http.client.impl JavaClient ResponseDeliveryDelegate)
-           (org.apache.http.client RedirectStrategy)
-           (org.apache.http.impl.client LaxRedirectStrategy DefaultRedirectStrategy)
-           (org.apache.http.nio.conn.ssl SSLIOSessionStrategy)
-           (org.apache.http.client.config RequestConfig)
-           (org.apache.http.nio.client HttpAsyncClient))
+           (com.puppetlabs.http.client.impl JavaClient ResponseDeliveryDelegate SslUtils)))
   (:require [puppetlabs.ssl-utils.core :as ssl]
             [puppetlabs.http.client.common :as common]
             [schema.core :as schema])
@@ -70,71 +64,29 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Private utility functions

-(schema/defn extract-ssl-opts :- common/SslOptions
-  [opts :- common/ClientOptions]
-  (select-keys opts [:ssl-context :ssl-ca-cert :ssl-cert :ssl-key]))
-
-(schema/defn ^:always-validate ssl-strategy :- SSLIOSessionStrategy
-  [ssl-ctxt-opts :- common/SslContextOptions
-   ssl-prot-opts :- common/SslProtocolOptions]
-  (SSLIOSessionStrategy.
-    (:ssl-context ssl-ctxt-opts)
-    (if (contains? ssl-prot-opts :ssl-protocols)
-      (into-array String (:ssl-protocols ssl-prot-opts))
-      ClientOptions/DEFAULT_SSL_PROTOCOLS)
-    (if (contains? ssl-prot-opts :cipher-suites)
-      (into-array String (:cipher-suites ssl-prot-opts)))
-    SSLIOSessionStrategy/BROWSER_COMPATIBLE_HOSTNAME_VERIFIER))
-
-(schema/defn ^:always-validate redirect-strategy :- RedirectStrategy
-  [opts :- common/ClientOptions]
-  (let [follow-redirects (:follow-redirects opts)
-        force-redirects (:force-redirects opts)]
-    (cond
-      (and (not (nil? follow-redirects)) (not follow-redirects))
-        (proxy [RedirectStrategy] []
-          (isRedirected [req resp context]
-            false)
-          (getRedirect [req resp context]
-            nil))
-        force-redirects
-          (LaxRedirectStrategy.)
-        :else
-          (DefaultRedirectStrategy.))))
-
-(schema/defn request-config :- RequestConfig
-  [connect-timeout-milliseconds :- (schema/maybe schema/Int)
-   socket-timeout-milliseconds :- (schema/maybe schema/Int)]
-  (let [request-config-builder (RequestConfig/custom)]
-    (if connect-timeout-milliseconds
-      (.setConnectTimeout request-config-builder
-                          connect-timeout-milliseconds))
-    (if socket-timeout-milliseconds
-      (.setSocketTimeout request-config-builder
-                         socket-timeout-milliseconds))
-    (.build request-config-builder)))
-
 (schema/defn ^:always-validate create-default-client :- common/Client
-  [opts :- common/ClientOptions]
-  (let [ssl-ctxt-opts   (configure-ssl-ctxt (extract-ssl-opts opts))
-        ssl-prot-opts   (select-keys opts [:ssl-protocols :cipher-suites])
-        client-builder  (HttpAsyncClients/custom)
-        connect-timeout (:connect-timeout-milliseconds opts)
-        socket-timeout  (:socket-timeout-milliseconds opts)
-        client          (do (when (:ssl-context ssl-ctxt-opts)
-                              (.setSSLStrategy client-builder
-                                               (ssl-strategy
-                                                 ssl-ctxt-opts ssl-prot-opts)))
-                            (.setRedirectStrategy client-builder
-                                                  (redirect-strategy opts))
-                            (if (or connect-timeout socket-timeout)
-                              (.setDefaultRequestConfig client-builder
-                                                        (request-config
-                                                          connect-timeout
-                                                          socket-timeout)))
-                            (.build client-builder))]
-    (.start client)
-    client))
+  [{:keys [ssl-context ssl-ca-cert ssl-cert ssl-key ssl-protocols cipher-suites
+           follow-redirects force-redirects connect-timeout-milliseconds
+           socket-timeout-milliseconds]}:- common/ClientOptions]
+  (let [client-options (ClientOptions.)]
+    (cond-> client-options
+            (some? ssl-context) (.setSslContext ssl-context)
+            (some? ssl-cert) (.setSslCert ssl-cert)
+            (some? ssl-ca-cert) (.setSslCaCert ssl-ca-cert)
+            (some? ssl-key) (.setSslKey ssl-key)
+            (some? ssl-context) (.setSslContext ssl-context)
+            (some? ssl-protocols) (.setSslProtocols (into-array String ssl-protocols))
+            (some? cipher-suites) (.setSslCipherSuites (into-array String cipher-suites))
+            (some? force-redirects) (.setForceRedirects force-redirects)
+            (some? follow-redirects) (.setFollowRedirects follow-redirects)
+            (some? connect-timeout-milliseconds)
+            (.setConnectTimeoutMilliseconds connect-timeout-milliseconds)
+            (some? socket-timeout-milliseconds)
+            (.setSocketTimeoutMilliseconds socket-timeout-milliseconds))
+    (let [coerced-options (JavaClient/coerceClientOptions (SslUtils/configureSsl client-options))
+          client (JavaClient/createClient coerced-options)]
+      (.start client)
+      client)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Map the Ring request onto the Java API
@@ -242,7 +194,7 @@
    * :query-params - used to set the query parameters of an http request"
   [opts :- common/RawUserRequestOptions
    callback :- common/ResponseCallbackFn
-   client :- HttpAsyncClient]
+   client :- common/Client]
   (let [result (promise)
         defaults {:headers         {}
                   :body            nil


Edit event page

Edit event page

--- src/cljs/event_planner/pages/events.cljs
+++ src/cljs/event_planner/pages/events.cljs
@@ -1,9 +1,8 @@
 (ns event-planner.pages.events)

 (defn events-page [id]
-  [:div "Wow my id is: " id]
   [:div.container
-    [:div.row.col-md-4
+    [:div.row.col-xs-4
       [:form.form-signin
         [:h2.form-signin-heading "Sign In"]
         [:label {:for "inputusername"
@@ -19,8 +18,9 @@
                  :id "inputpassword"
                  :placeholder "Password"}]
         [:button.btn.btn-sm.btn-primary {:type "Submit"} "Sign In"]]
-    [:p ]
-    [:p "Please note that all sign in usernames and passwords are temporary."]
-    [:p "To sign in using your account please go to the "
-        [:a {:href "#"} "Login"] " page."]
-   ]])
+      [:p ]
+      [:p "Please note that all sign in usernames and passwords are temporary."]
+      [:p "To sign in using your account please go to the "
+        [:a {:href "#"} "Login"] " page."]]
+    [:div.row.col-xs-8
+     [:h1 "HELL YEAH"]]])


added sorting

added sorting

--- src/cljs_bjj_tournament/competitors.cljs
+++ src/cljs_bjj_tournament/competitors.cljs
@@ -48,7 +48,31 @@
 (defn data-table
   []
   (let [mouse-over (reagent/atom nil)
-        click-msg  (reagent/atom "")]
+        click-msg  (reagent/atom "")
+        sort-key   (reagent/atom :fname)
+        label-fn   (fn [label-str label-key col-widths]
+                     [h-box
+                      :gap "2px"
+                      :width (label-key col-widths)
+                      :children
+                      [[label
+                        :label label-str]
+                       [row-button
+                        :md-icon-name "md-sort"
+                        :tooltip (str "sort on " label-str)
+                        :on-click #(reset! sort-key label-key)]]])
+        sort-fn    (fn [key]
+                     (case key
+                       :name #(.full-name %)
+                       :belt #(case (:belt %)
+                                "White"  1
+                                "Blue"   2
+                                "Purple" 3
+                                "Brown"  4
+                                "Black"  5
+                                6)
+                       :club #(:name (:club %))
+                       key))]
     (fn [rows col-widths]
       [v-box
        :align    :start
@@ -58,13 +82,16 @@
                    :children [^{:key "0"}
                               [h-box
                                :class    "rc-div-table-header"
-                               :children [[label :label "Name" :width (:name col-widths)]
-                                          [label :label "Gender" :width (:gender col-widths)]
-                                          [label :label "Club" :width (:club col-widths)]
-                                          [label :label "YOB" :width (:yob col-widths)]
-                                          [label :label "Belt" :width (:belt col-widths)]
-                                          [label :label "Actions" :width (:actions col-widths)]]]
-                              (for [[id row first? last?] (enumerate rows)]
+                               :children [[label-fn "Name" :name col-widths]
+                                          [label-fn "Gender" :gender col-widths]
+                                          [label-fn "Club" :club col-widths]
+                                          [label-fn "YOB" :yob col-widths]
+                                          [label-fn "Belt" :belt col-widths]
+                                          [label-fn "Actions" :actions col-widths]]]
+                              (for [[id row first? last?] (enumerate
+                                                            (sort-by
+                                                              (sort-fn @sort-key)
+                                                              rows))]
                                 ^{:key id} [data-row (:guid row) row first? last? col-widths mouse-over click-msg])]]]])))

 (defn field-label
@@ -137,10 +164,10 @@
         data (rest data)]
     (into []
           (for [line data]
-              (into {}
-                    (for [[k v]
-                          (map list headers line)]
-                      [k (clojure.string/trim v)]))))))
+            (into {}
+                  (for [[k v]
+                        (map list headers line)]
+                    [k (clojure.string/trim v)]))))))

 (defn- load-file-handler
   []
@@ -161,7 +188,7 @@
 (defn competitor-panel
   []
   (let [competitors (subscribe [:competitors])
-        col-widths {:name "15em" :gender "4em" :club "15em" :yob "4em" :belt "4.5em" :actions "4.5em"}]
+        col-widths {:name "15em" :gender "6em" :club "15em" :yob "4em" :belt "4.5em" :actions "4.5em"}]
     (fn []
       [v-box
        :gap "10px"


Rename crypto ns logging alias

Rename crypto ns logging alias

--- src/clojure/frereth/cp/shared/crypto.clj
+++ src/clojure/frereth/cp/shared/crypto.clj
@@ -11,7 +11,7 @@
              [specs :as specs]
              [util :as util]]
             [frereth.weald
-             [logging :as log2]
+             [logging :as log]
              [specs :as weald]])
   (:import clojure.lang.ExceptionInfo
            [com.iwebpp.crypto TweetNaclFast
@@ -103,9 +103,7 @@
         :ret ::nonce-state)
 (defn initial-nonce-agent-state
   []
-  {::weald/state (log2/init ::nonce-agent)
-   ;; FIXME: Needs a logger for flushing
-   ;; the log-state (soon)
+  {::weald/state (log/init ::nonce-agent)
    ::counter-low 0
    ::counter-high 0
    ::data (byte-array 16)
@@ -124,7 +122,7 @@
     :as this}
    logger
    key-dir]
-  (let [log-state-atom (atom (log2/debug log-state
+  (let [log-state-atom (atom (log/debug log-state
                                          ::load-nonce-key
                                          ""
                                          {::key-dir key-dir}))]
@@ -135,7 +133,7 @@
           (let [raw-nonce-key (byte-array nonce-key-length)
                 bytes-read (.read key-file raw-nonce-key)]
             (when (not= bytes-read nonce-key-length)
-              (log2/flush-logs! logger @log-state-atom)
+              (log/flush-logs! logger @log-state-atom)
               (throw (ex-info "Key too short"
                               {::expected K/key-length
                                ::actual bytes-read
@@ -144,12 +142,12 @@
               (deliver key-loaded? true)
               (assoc this
                      ::nonce-key nonce-key
-                     ::weald/state (log2/flush-logs! logger log-state)))))
+                     ::weald/state (log/flush-logs! logger log-state)))))
         (do
-          (log2/flush-logs! logger @log-state-atom)
+          (log/flush-logs! logger @log-state-atom)
           (throw (ex-info "Missing noncekey file"
                           {::searching-in key-dir
-                           ::log2/state log-state})))))))
+                           ::log/state log-state})))))))

 (declare encrypt-block)
 (defn obscure-nonce
@@ -207,9 +205,9 @@
    logger
    key-dir
    long-term?]
-  (let [log-state (log2/debug log-state
-                              ::reload-nonce
-                              "Top")
+  (let [log-state (log/debug log-state
+                             ::reload-nonce
+                             "Top")
         raw-path (str key-dir "/.expertsonly/")
         path (io/resource raw-path)]
     (let [f (io/file path "lock")]
@@ -219,9 +217,9 @@
           (let [channel (.getChannel (RandomAccessFile. f "rw"))]
             (try
               (let [lock (.lock channel 0 Long/MAX_VALUE false)
-                    log-state (log2/info log-state
-                                         ::reload-nonce
-                                         "Lock acquired")]
+                    log-state (log/info log-state
+                                        ::reload-nonce
+                                        "Lock acquired")]
                 (try
                   (let [nonce-counter (io/file path "noncecounter")]
                     (when-not (.exists nonce-counter)
@@ -229,22 +227,22 @@
                       (with-open [counter (io/output-stream nonce-counter)]
                         ;; FIXME: What's a good initial value?
                         (.write counter (byte-array 8))))
-                    (let [log-state (log2/debug log-state
-                                                ::reload-nonce
-                                                "Opening"
-                                                {::nonce-file-name nonce-counter})]
+                    (let [log-state (log/debug log-state
+                                               ::reload-nonce
+                                               "Opening"
+                                               {::nonce-file-name nonce-counter})]
                       (with-open [counter (io/input-stream nonce-counter)]
-                        (let [log-state (log2/debug log-state
-                                                    ::reload-nonce
-                                                    "Nonce counter file opened for reading")
+                        (let [log-state (log/debug log-state
+                                                   ::reload-nonce
+                                                   "Nonce counter file opened for reading")
                               data (bytes data)
                               bytes-read (.read counter data 0 8)
-                              log-state (log2/debug log-state
-                                                    ::reload-nonce
-                                                    "Read bytes"
-                                                    {::byte-count bytes-read})]
+                              log-state (log/debug log-state
+                                                   ::reload-nonce
+                                                   "Read bytes"
+                                                   {::byte-count bytes-read})]
                           (when (not= bytes-read 8)
-                            (log2/flush-logs! logger log-state)
+                            (log/flush-logs! logger log-state)
                             (throw (ex-info "Nonce counter file too small"
                                             {::contents (b-t/->string data)
                                              ::length bytes-read})))
@@ -258,7 +256,7 @@
                             (assoc this
                                    ::counter-low counter-low
                                    ::counter-high counter-high
-                                   ::weald/state (log2/flush-logs! logger log-state)))))))
+                                   ::weald/state (log/flush-logs! logger log-state)))))))
                   (finally
                     ;; Closing the channel should release the lock,
                     ;; but being explicit about this doesn't hurt
@@ -324,9 +322,9 @@
      ;; Read the last saved version from keydir
      (let [log-state
            (if-not (-> nonce-writer deref ::key-loaded? realized?)
-             (let [log-state (log2/debug log-state
-                                         ::do-safe-nonce
-                                         "Triggering nonce-key initial load")]
+             (let [log-state (log/debug log-state
+                                        ::do-safe-nonce
+                                        "Triggering nonce-key initial load")]
                (send nonce-writer load-nonce-key logger key-dir)
                log-state)
              log-state)]
@@ -342,18 +340,18 @@
          ;; nonce-writer?

        (if-let [ex (agent-error nonce-writer)]
-         (log2/exception log-state
-                         ex
-                         ::do-safe-nonce
-                         "System is down")
+         (log/exception log-state
+                        ex
+                        ::do-safe-nonce
+                        "System is down")
          log-state)))
     ([log-state dst offset]
      (let [length-to-fill (- (count dst) offset)
            tmp (get-random-bytes length-to-fill)]
        (b-t/byte-copy! dst offset length-to-fill tmp)
-       (log2/debug log-state
-                   ::safe-nonce!
-                   "Picked a random nonce")))))
+       (log/debug log-state
+                  ::safe-nonce!
+                  "Picked a random nonce")))))
 (comment
   (get-nonce-agent-state)
   (reset-safe-nonce-state!))
@@ -578,14 +576,14 @@
   (if keydir
     (let [secret (util/slurp-bytes (io/resource (str keydir "/.expertsonly/secretkey")))
           pair (TweetNaclFast$Box/keyPair_fromSecretKey secret)
-          log-state (log2/info log-state
-                               ::do-load-keypair
-                               (str "FIXME: Don't record these\n"
-                                    "Loaded secret key from file")
-                               {::secret-key-contents (b-t/->string secret)
-                                ::specs/secret-long (b-t/->string (.getSecretKey pair))
-                                ::specs/public-long
-                                (b-t/->string (.getPublicKey pair))})]
+          log-state (log/info log-state
+                              ::do-load-keypair
+                              (str "FIXME: Don't record these\n"
+                                   "Loaded secret key from file")
+                              {::secret-key-contents (b-t/->string secret)
+                               ::specs/secret-long (b-t/->string (.getSecretKey pair))
+                               ::specs/public-long
+                               (b-t/->string (.getPublicKey pair))})]
       {::java-key-pair pair
        ::weald/state log-state})
     ;; FIXME: This really should call random-keys instead.
@@ -687,9 +685,9 @@
     (if (and box
              (>= (count box) (+ box-offset box-length))
              (>= box-length K/box-zero-bytes))
-      (let [log-state (log2/debug log-state
-                                  ::open-after
-                                  "Box is large enough")]
+      (let [log-state (log/debug log-state
+                                 ::open-after
+                                 "Box is large enough")]
         (let [n (+ box-length K/box-zero-bytes)
               cipher-text (byte-array n)
               plain-text (byte-array n)]
@@ -717,9 +715,9 @@
             (comment (-> plain-text
                          vec
                          (subvec K/decrypt-box-zero-bytes)))
-            {::weald/state (log2/debug log-state
-                                       ::open-after
-                                       "Box Opened")
+            {::weald/state (log/debug log-state
+                                      ::open-after
+                                      "Box Opened")
              ;; Q: Why am I wrapping this in a ByteBuf?
              ;; That seems like I'm probably jumping through extra hoops
              ;; for the sake of hoop-jumping.
@@ -774,26 +772,11 @@
     (try
       (open-after log-state crypto-box 0 crypto-length nonce shared-key)
       (catch Exception ex
-        {::weald/state (log2/exception log-state
+        {::weald/state (log/exception log-state
                                       ex
                                       ::open-box
                                       "Failed to open box")}))))

-(defn decompose-box
-  "Open a crypto box and decompose its bytes"
-  [log-state tmplt nonce-prefix nonce-suffix crypto-box shared-key]
-  (let [{log-state ::weald/state
-         :keys [::unboxed]
-         :as opened} (open-box log-state
-                               nonce-prefix
-                               nonce-suffix
-                               crypto-box
-                               shared-key)]
-    (if unboxed
-      (let [result (serial/decompose-array tmplt unboxed)]
-        {::weald/state log-state
-         ::serial/decomposed result})
-      opened)))

 (s/fdef random-array
   :args (s/cat :n integer?)


yet more doc

yet more doc

--- src/clojure/zensols/nlparse/stopword.clj
+++ src/clojure/zensols/nlparse/stopword.clj
@@ -2,14 +2,13 @@

 To avoid the double negative in function names, *go words* are defined to be
 the compliment of a vocabulary with a stop word list.  Functions
-like [[meaningful-word?]] tell whether or not a token is a stop word, which are
+like [[go-word?]] tell whether or not a token is a stop word, which are
 defined to be:

   * stopwords (predefined list)
   * punctuation
   * numbers
-  * non-alphabetic characters
-  * URLs"
+  * non-alphabetic characters"
       :author "Paul Landes"}
     zensols.nlparse.stopword
   (:require [clojure.string :as s]))
@@ -21,8 +20,8 @@
 ---
 * **:post-tags** POS tags for *go words* (see namespace docs)
 * **:word-form-fn** function run on the token in [[go-word-form]]; for example
-  if `#(-> % :lemma s/lower-case)` then lemmatization is used (i.e. Running ->
-  run)"
+  if `#(-> % :lemma s/lower-case)` is given then lemmatization is
+  used (i.e. Running -> run)"
   {:pos-tags #{"RB", "JJ", "JJR", "JJS", "MD",
                "NN", "NNS", "NNP", "NNPS",
                "VB", "VBD", "VBG", "VBN", "VBP", "VBZ",
@@ -37,7 +36,7 @@
          (contains? tags (:pos-tag token)))))

 (defn go-word-form
-  "Conical string word count form of a token.  ."
+  "Conical string word count form of a token."
   [token]
   ((:word-form-fn *stopword-config*) token))


Optimized the alternate function of ULTRA.

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -314,19 +314,21 @@

 (defn alternate
   [s1 s2 alternation-rate alignment-deviation]
-  (loop [i 0
-         use-s1 (lrand-nth [true false])
-         result ()]
-    (if (or (>= i (count (if use-s1 s1 s2)))
-            (> (count result) 10000)) ;; runaway growth
-      result
-      (if (< (lrand) alternation-rate)
-        (recur (max 0 (+' i (Math/round (*' alignment-deviation (gaussian-noise-factor)))))
-               (not use-s1)
-               result)
-        (recur (inc i)
-               use-s1
-               (concat result (list (nth (if use-s1 s1 s2) i))))))))
+  (let [s1 (vec s1)
+        s2 (vec s2)]
+    (loop [i 0
+           use-s1 (lrand-nth [true false])
+           result []]
+      (if (or (>= i (count (if use-s1 s1 s2)))
+              (> (count result) 10000)) ;; runaway growth
+        (apply list result)
+        (if (< (lrand) alternation-rate)
+          (recur (max 0 (+' i (Math/round (*' alignment-deviation (gaussian-noise-factor)))))
+                 (not use-s1)
+                 result)
+          (recur (inc i)
+                 use-s1
+                 (conj result (nth (if use-s1 s1 s2) i))))))))

 ; (alternate '(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16) '(a b c d e f g h i j k) 0.2 1)


Actually test music evaluation.

Actually test music evaluation.

--- test/klangmeister/test/processing.cljs
+++ test/klangmeister/test/processing.cljs
@@ -22,5 +22,5 @@
   (testing
     (is
       (=
-       (framework/process (action/->Refresh "[{:time 0 :duration 1}]" :foo) ignore! {})
-       {:foo {:value [{:time 0 :duration 1}] :text "[{:time 0 :duration 1}]" :error nil}}))))
+       (framework/process (action/->Refresh "(phrase [1] [69])" :foo) ignore! {})
+       {:foo {:value [{:time 0 :pitch 69 :duration 1}] :text "(phrase [1] [69])" :error nil}}))))


Fix pdf sizing

Fix pdf sizing

--- src/export_server/utils/rasterizator.clj
+++ src/export_server/utils/rasterizator.clj
@@ -56,8 +56,10 @@
     ;(with-open [out (output-stream (clojure.java.io/file "/media/ssd/sibental/export-server-data/1.png"))]
     ;  (.write out img))
     (with-open [out (new ByteArrayOutputStream)]
-      (pdf [{:size          [(* 0.75 (first pdf-size)) (* 0.75 (second pdf-size))]
-             ;:orientation   (if landscape :landscape nil)
+      (pdf [{:size          (if (coll? pdf-size)
+                              [(* 0.75 (first pdf-size)) (* 0.75 (second pdf-size))]
+                              pdf-size)
+             :orientation   (if landscape :landscape nil)
              :footer        {:page-numbers false}
              :left-margin   0
              :right-margin  0
@@ -65,7 +67,7 @@
              :bottom-margin 0}
             ;[:svg {:translate [x y]} (clear-svg (trim-svg-string svg))]
             [:image {:translate [x y]
-                     :scale     75
+                     :scale     (when (coll? pdf-size) 75)
                      :width     width
                      ;:height    height
                      } img]]


fix bug in autofocus logic

fix bug in autofocus logic

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

--- acqEngine/src/org/micromanager/sequence_generator.clj
+++ acqEngine/src/org/micromanager/sequence_generator.clj
@@ -97,12 +97,12 @@
     events))

 (defn process-use-autofocus [events use-autofocus autofocus-skip]
-  (for [event events]
-    (assoc event :autofocus
+  (for [[e1 e2] (pairs-back events)]
+    (assoc e2 :autofocus
       (and use-autofocus
-        (or
-          (nil? (event :frame))
-          (zero? (mod (event :frame) (inc autofocus-skip))))))))
+        (and (zero? (mod (e2 :frame) (inc autofocus-skip)))
+             (or (not= (:position e1) (:position e2))
+                 (not= (:frame e1) (:frame e2))))))))

 (defn process-wait-time [events interval-ms]
   (cons


Remove unused property

Remove unused property

--- src/javascript_externs_generator/ui.cljs
+++ src/javascript_externs_generator/ui.cljs
@@ -11,7 +11,6 @@
 (def default-state {:loaded-urls #{}
                     :externed-namespaces {}
                     :current-namespace nil
-                    :current-url nil
                     :url-text ""
                     :namespace-text ""
                     :loading-js false})
@@ -39,7 +38,7 @@
           (load-script url
                        #(rf/dispatch [:load-succeeded url])
                        #(rf/dispatch [:load-failed url]))
-          (assoc db :loading-js true :current-url url))))))
+          (assoc db :loading-js true))))))

 (rf/register-handler
   :generate-extern


Fix publish command brocken in leinout refactoring

--- src/leiningen/pallet_release/release.clj
+++ src/leiningen/pallet_release/release.clj
@@ -161,4 +161,4 @@
   (git/checkout "master")
   (git/pull)
   (lein/clean project)
-  (lein/deploy project))
+  (lein/deploy project "clojars"))


price-on-request? should only be true if it is originally not nil

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -283,7 +283,7 @@
                   :source-date (get-year source-date)
                   :library-signature library-signature
                   :product-number product-number
-                  :price-on-request? (when price-on-request? true)
+                  :price-on-request? (when (some? price-on-request?) true)
                   :price (if price-on-request? (layout/translations :price-on-request) price)))]
     (case fmt
       :hörbuch (-> item


Cosmetic improvements on monoid types.

Cosmetic improvements on monoid types.

--- src/cats/builtin.cljc
+++ src/cats/builtin.cljc
@@ -272,6 +272,7 @@
     p/Semigroup
     (-mappend [_ sv sv']
       (or sv sv'))
+
     p/Monoid
     (-mempty [_]
       false)))
@@ -284,6 +285,7 @@
     p/Semigroup
     (-mappend [_ sv sv']
       (and sv sv'))
+
     p/Monoid
     (-mempty [_]
       true)))
@@ -296,6 +298,7 @@
     p/Semigroup
     (-mappend [_ sv sv']
       (+ sv sv'))
+
     p/Monoid
     (-mempty [_]
       0)))
@@ -308,6 +311,7 @@
     p/Semigroup
     (-mappend [_ sv sv']
       (* sv sv'))
+
     p/Monoid
     (-mempty [_]
       1)))
@@ -320,6 +324,7 @@
     p/Semigroup
     (-mappend [_ sv sv']
       (str sv sv'))
+
     p/Monoid
     (-mempty [_]
       "")))


Minor

Minor

--- web/src/immutant/web.clj
+++ web/src/immutant/web.clj
@@ -23,10 +23,12 @@

 (defn run
   "Runs a handler with the given options.
-   The handler can be a ring handler function, a servlet, or an Undertow
-   HttpHandler. Can be called multiple times - if given the same env,
-   any prior handler with that env will be replaced. Returns the given
-   env with any missing defaults filled in.
+
+   The handler can be a Ring handler function, a Servlet, or an
+   Undertow HttpHandler. Can be called multiple times - if given the
+   same env, any prior handler with that env will be replaced. Returns
+   the given env with any missing defaults filled in.
+
    Needs: options, examples"
   ([handler] (run nil handler))
   ([env handler]
@@ -41,12 +43,14 @@

 (defn stop
   "Stops a running handler.
-   handler-env should be the return value of a run call. If that return
-   value is not available, you can pass the same env map passed to run for
-   the handler you want to stop. If handler-env isn't provided, the handler
-   at the root context (\"/\") of the default server will be stopped. If
-   there are no handlers remaning on the server, the server itself is stopped.
-   Returns true if a handler was actually removed."
+
+   The handler-env argument is a map, typically the return value of a
+   run call. If that return value is not available, you can pass the
+   same env map passed to run for the handler you want to stop. If
+   handler-env isn't provided, the handler at the root context (\"/\")
+   of the default server will be stopped. If there are no handlers
+   remaining on the server, the server itself is stopped. Returns true
+   if a handler was actually removed."
   ([]
      (stop nil))
   ([handler-env]
@@ -62,6 +66,7 @@

 (defmacro run-dmc
   "Run in Development Mode (the 'C' is silent).
+
    This macro invokes run after ensuring the passed handler is
    var-quoted, with reload and stacktrace middleware applied, and then
    opens the app in a browser. Supports the same options as run."


CLJS-495: add exists? macro

CLJS-495: add exists? macro

`exists?` can be used to determined whether some value exists. In
JavaScript this is traditionally accomplished with `typeof foo ==
'undefined'`. This allows for feature detection across heterogenous JS
clients.

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -212,6 +212,9 @@

 (defmacro false? [x]
   (bool-expr (list 'js* "~{} === false" x)))
+
+(defmacro exists? [x]
+  (bool-expr (list 'js* "typeof ~{} !== 'undefined'" x)))

 (defmacro undefined? [x]
   (bool-expr (list 'js* "(void 0 === ~{})" x)))


Defer to get-redirect-strategy to determine redirect behaviour

Do not use the same `follow-redirects` option like `wrap-redirects` because both
redirect strategies are enabled.

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -109,7 +109,6 @@
 (defn request-config [{:keys [conn-timeout
                               socket-timeout
                               conn-request-timeout
-                              follow-redirects
                               max-redirects
                               allow-circular-redirects
                               allow-relative-redirects
@@ -119,8 +118,7 @@
                    (.setSocketTimeout (or socket-timeout -1))
                    (.setConnectionRequestTimeout
                     (or conn-request-timeout -1))
-                   (.setRedirectsEnabled ((complement false?)
-                                          follow-redirects))
+                   (.setRedirectsEnabled true)
                    (.setCircularRedirectsAllowed
                     (boolean allow-circular-redirects))
                    (.setRelativeRedirectsAllowed
@@ -349,7 +347,7 @@
   ([req] (request req nil nil))
   ([{:keys [body conn-timeout conn-request-timeout connection-manager
             cookie-store cookie-policy headers multipart query-string
-            redirect-strategy follow-redirects max-redirects retry-handler
+            redirect-strategy max-redirects retry-handler
             request-method scheme server-name server-port socket-timeout
             uri response-interceptor proxy-host proxy-port async?
             proxy-ignore-hosts proxy-user proxy-pass digest-auth ntlm-auth]


Proxy to clj->js in singult (it's slightly faster; no point in having the same fn twice).

--- src/cljs/c2/util.cljs
+++ src/cljs/c2/util.cljs
@@ -1,26 +1,7 @@
-(ns c2.util)
+(ns c2.util
+  (:require [singult.core :as singult]))

-;;Taken from Mark McGranaghan
-;;http://mmcgrana.github.com/2011/09/clojurescript-nodejs.html
-(defn clj->js
-  "Recursively transforms ClojureScript maps into Javascript objects,
-   other ClojureScript colls into JavaScript arrays, and ClojureScript
-   keywords into JavaScript strings."
-  [x]
-  (cond
-   (string? x)  x
-   (keyword? x) (name x)
-   (map? x)     (reduce (fn [o [k v]]
-                          (let [key (clj->js k)]
-                            (when-not (string? key)
-                              (throw "Cannot convert; JavaScript map keys must be strings"))
-                            (aset o key (clj->js v))
-                            o))
-                        (js-obj) x)
-   (coll? x)    (apply array (map clj->js x))
-   :else x))
-
-
+(def clj->js singult/clj->js)

 (defn ->coll
   "Convert something into a collection, if it's not already."