completely re-implement nav, collector, fixed-pathed-nav, and pathed-collector in cleaner and more flexible way

--- src/clj/com/rpl/specter/macros.clj
+++ src/clj/com/rpl/specter/macros.clj
@@ -2,7 +2,8 @@
   (:use [com.rpl.specter.protocols :only [Navigator]]
         [com.rpl.specter.impl :only [RichNavigator]])
   (:require [com.rpl.specter.impl :as i]
-            [clojure.walk :as cljwalk])
+            [clojure.walk :as cljwalk]
+            [com.rpl.specter.defnavhelpers :as dnh])
   )

 (defn ^:no-doc gensyms [amt]
@@ -11,134 +12,18 @@
 (defn ^:no-doc determine-params-impls [[name1 & impl1] [name2 & impl2]]
   (if-not (= #{name1 name2} #{'select* 'transform*})
     (i/throw-illegal "defnav must implement select* and transform*, instead got "
-      name1 " and " name2))
+                     name1 " and " name2))
   (if (= name1 'select*)
     [impl1 impl2]
     [impl2 impl1]))

-
-(def ^:no-doc PARAMS-SYM (gensym "params"))
-(def ^:no-doc PARAMS-IDX-SYM (gensym "params-idx"))
-
-(defn ^:no-doc paramsnav* [bindings num-params [impl1 impl2]]
-  (let [[[[_ s-structure-sym s-next-fn-sym] & select-body]
-         [[_ t-structure-sym t-next-fn-sym] & transform-body]]
-         (determine-params-impls impl1 impl2)]
-    (if (= 0 num-params)
-      `(i/lean-compiled-path
-         (reify Navigator
-           (~'select* [this# ~s-structure-sym ~s-next-fn-sym]
-             ~@select-body)
-           (~'transform* [this# ~t-structure-sym ~t-next-fn-sym]
-             ~@transform-body)
-           ))
-      `(i/->ParamsNeededPath
-         (reify RichNavigator
-           (~'rich-select* [this# ~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~s-structure-sym next-fn#]
-             (let [~s-next-fn-sym (fn [structure#]
-                                    (next-fn#
-                                      ~PARAMS-SYM
-                                      (+ ~PARAMS-IDX-SYM ~num-params)
-                                      vals#
-                                      structure#))
-                   ~@bindings]
-               ~@select-body
-               ))
-           (~'rich-transform* [this# ~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~t-structure-sym next-fn#]
-             (let [~t-next-fn-sym (fn [structure#]
-                                    (next-fn#
-                                      ~PARAMS-SYM
-                                      (+ ~PARAMS-IDX-SYM ~num-params)
-                                      vals#
-                                      structure#))
-                   ~@bindings]
-               ~@transform-body
-               ))
-           )
-         ~num-params
-         ))))
-
-(defn ^:no-doc paramscollector* [post-bindings num-params [_ [_ structure-sym] & body]]
-  `(let [collector# (fn [~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#]
-                      (let [~@post-bindings ~@[] ; to avoid syntax highlighting issues
-                            c# (do ~@body)]
-                        (next-fn#
-                          ~PARAMS-SYM
-                          (+ ~PARAMS-IDX-SYM ~num-params)
-                          (conj vals# c#)
-                          ~structure-sym)
-                        ))
-         nav# (reify RichNavigator
-                (~'rich-select* [this# ~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#]
-                  (collector# ~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#))
-                (~'rich-transform* [this# ~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#]
-                  (collector# ~PARAMS-SYM ~PARAMS-IDX-SYM vals# ~structure-sym next-fn#))
-                )]
-     (if (= ~num-params 0)
-       (i/no-params-rich-compiled-path nav#)
-       (i/->ParamsNeededPath
-         nav#
-         ~num-params
-         ))))
-
-(defn ^:no-doc pathed-nav* [builder paths-seq latefns-sym pre-bindings post-bindings impls]
-  (let [num-params-sym (gensym "num-params")]
-    `(let [paths# (map i/comp-paths* ~paths-seq)
-           needed-params# (map i/num-needed-params paths#)
-           offsets# (cons 0 (reductions + needed-params#))
-           any-params-needed?# (->> paths#
-                                    (filter i/params-needed-path?)
-                                    empty?
-                                    not)
-           ~num-params-sym (last offsets#)
-           ~latefns-sym (map
-                          (fn [o# p#]
-                            (if (i/compiled-path? p#)
-                              (fn [params# params-idx#]
-                                p# )
-                              (fn [params# params-idx#]
-                                (i/bind-params* p# params# (+ params-idx# o#))
-                                )))
-                          offsets#
-                          paths#)
-           ~@pre-bindings
-           ret# ~(builder post-bindings num-params-sym impls)
-           ]
-    (if (not any-params-needed?#)
-      (if (i/params-needed-path? ret#)
-        (i/bind-params* ret# nil 0)
-        ret#)
-      ret#
-      ))))
-
-(defn ^:no-doc make-param-retrievers [params]
-  (->> params
-       (map-indexed
-         (fn [i p]
-           [p `(i/object-aget ~PARAMS-SYM
-                              (+ ~PARAMS-IDX-SYM ~i))]
-           ))
-       (apply concat)))
-
-
-(defmacro nav
-  "Defines a navigator with late bound parameters. This navigator can be precompiled
-  with other navigators without knowing the parameters. When precompiled with other
-  navigators, the resulting path takes in parameters for all navigators in the path
-  that needed parameters (in the order in which they were declared)."
-  [params impl1 impl2]
-  (let [num-params (count params)
-        retrieve-params (make-param-retrievers params)]
-    (paramsnav* retrieve-params num-params [impl1 impl2])
-    ))
-
 (defmacro richnav
-  "Defines a navigator with full access to collected vals, the parameters array,
-   and the parameters array index. `next-fn` expects to receive the params array,
-   a params index, the collected vals, and finally the next structure.
-   `next-fn` will automatically skip ahead in params array by `num-params`, so the
-   index passed to it is ignored.
-   This is the lowest level way of making navigators."
+  "Defines a navigator with full access to collected vals, the parameters array,
+  and the parameters array index. `next-fn` expects to receive the params array,
+  a params index, the collected vals, and finally the next structure.
+  `next-fn` will automatically skip ahead in params array by `num-params`, so the
+  index passed to it is ignored.
+  This is the lowest level way of making navigators."
   [num-params impl1 impl2]
   (let [[[s-params & s-body] [t-params & t-body]] (determine-params-impls impl1 impl2)
         s-next-fn-sym (last s-params)
@@ -148,100 +33,215 @@
         ]
     `(let [num-params# ~num-params
            nav# (reify RichNavigator
-                  (~'rich-select* ~s-params
+                  (~'rich-select* ~s-params
                     (let [~s-next-fn-sym (i/mk-jump-next-fn ~s-next-fn-sym ~s-pidx-sym num-params#)]
                       ~@s-body))
                   (~'rich-transform* ~t-params
                     (let [~t-next-fn-sym (i/mk-jump-next-fn ~t-next-fn-sym ~t-pidx-sym num-params#)]
                       ~@t-body))
                   )]
-      (if (zero? num-params#)
-        (i/no-params-rich-compiled-path nav#)
-        (i/->ParamsNeededPath nav# num-params#)
-        ))))
-
-(defmacro paramsfn [params [structure-sym] & impl]
-  `(nav ~params
-     (~'select* [this# structure# next-fn#]
-       (let [afn# (fn [~structure-sym] ~@impl)]
-         (i/filter-select afn# structure# next-fn#)
-         ))
-     (~'transform* [this# structure# next-fn#]
-       (let [afn# (fn [~structure-sym] ~@impl)]
-         (i/filter-transform afn# structure# next-fn#)
+       (if (zero? num-params#)
+         (i/no-params-rich-compiled-path nav#)
+         (i/->ParamsNeededPath nav# num-params#)
          ))))

-(defmacro paramscollector
+(defmacro lean-nav* [& impls]
+  `(reify Navigator ~@impls))
+
+(defn operation-with-bindings [bindings params-sym params-idx-sym op-maker]
+  (let [bindings (partition 2 bindings)
+        binding-fn-syms (gensyms (count bindings))
+        binding-syms (map first bindings)
+        fn-exprs (map second bindings)
+        binding-fn-declarations (map vector binding-fn-syms fn-exprs)
+        binding-declarations (map (fn [s f] `[s (f ~params-sym ~params-idx-sym)])
+                                  binding-syms
+                                  binding-fn-syms)
+        body (op-maker binding-declarations)]
+    `(let [~@binding-fn-declarations]
+       ~body
+       )))
+
+(defmacro rich-nav-with-bindings [num-params-code bindings & impls]
+  (let [[[[_ s-structure-sym s-next-fn-sym] & s-body]
+         [[_ t-structure-sym t-next-fn-sym] & t-body]]
+        (determine-params-impls impl1 impl2)
+        params-sym (gensym "params")
+        params-idx-sym (gensym "params-idx")
+        ]
+    (operation-with-bindings
+      bindings
+      params-sym
+      params-idx-sym
+      (fn [binding-declarations]
+        `(reify RichNavigator
+          (~'rich-select* [this# ~params-sym ~params-idx-sym vals# ~s-structure-sym next-fn#]
+            (let [~@binding-declarations
+                  next-params-idx# (+ ~params-idx-sym ~num-params-code)
+                  ~s-next-fn-sym (fn [structure#]
+                                   (next-fn# ~params-sym
+                                             next-params-idx#
+                                             vals#
+                                             structure#))]
+              ~@s-body
+              ))
+          (~'rich-transform* [this# ~params-sym ~params-idx-sym vals# ~t-structure-sym next-fn#]
+            (let [~@binding-declarations
+                  next-params-idx# (+ ~params-idx-sym ~num-params-code)
+                  ~t-next-fn-sym (fn [structure#]
+                                   (next-fn# ~params-sym
+                                             next-params-idx#
+                                             vals#
+                                             structure#))]
+              ~@t-body
+              ))
+          )))))
+
+(defmacro collector-with-bindings [bindings impl]
+  (let [[_ [_ structure-sym] & body] impl
+        params-sym (gensym "params")
+        params-idx-sym (gensym "params")]
+    (operation-with-bindings
+      bindings
+      params-sym
+      params-idx-sym
+      (fn [binding-declarations]
+        `(let [cfn# (fn [params# params-idx# vals# ~structure-sym next-fn#]
+                     (next-fn# params# params-idx# (conj vals# (do ~@body) ~structure-sym))
+                     )]
+          (reify RichNavigator
+            (~'rich-select* [this# params# params-idx# vals# structure# next-fn#]
+              (cfn# params# params-idx# vals# structure# next-fn#))
+            (~'rich-transform* [this# params# params-idx# vals# structure# next-fn#]
+              (cfn# params# params-idx# vals# structure# next-fn#))
+            ))))))
+
+(defn- delta-param-bindings [params]
+  (->> params
+       (map (fn [i p] [p `(dnh/param-delta ~i)]))
+       (apply concat)
+       vec
+       ))
+
+(defmacro nav
+  "Defines a navigator with late bound parameters. This navigator can be precompiled
+  with other navigators without knowing the parameters. When precompiled with other
+  navigators, the resulting path takes in parameters for all navigators in the path
+  that needed parameters (in the order in which they were declared)."
+  [params & impls]
+  (if (empty? params)
+    `(i/lean-compiled-path (lean-nav* ~@impls))
+    `(i/->ParamsNeededPath
+      ;(fn ~params (lean-nav* ~@body))
+      (rich-nav-with-bindings ~(count params)
+          ~(delta-param-bindings params)
+          ~@impls
+          )
+      ~(count params)
+      )))
+
+(defmacro collector
   "Defines a Collector with late bound parameters. This collector can be precompiled
   with other selectors without knowing the parameters. When precompiled with other
   selectors, the resulting selector takes in parameters for all selectors in the path
   that needed parameters (in the order in which they were declared).
-   "
-  [params impl]
-  (let [num-params (count params)
-        retrieve-params (make-param-retrievers params)]
-    (paramscollector* retrieve-params num-params impl)
-    ))
+  "
+  [params body]
+  `(let [rich-nav (collector-with-bindings ~(count params)
+                                           ~(delta-param-bindings params)
+                                           ~impl-body
+                                           )]
+     (if ~(empty? params)
+       (i/no-params-rich-compiled-path rich-nav)
+       (i/->ParamsNeededPath
+         ; (fn ~params
+         ;   (collector-with-bindings 0
+         ;     ~impl-body))
+         rich-nav
+         ~(count params))
+         )))
+
+(defn ^:no-doc fixed-pathed-operation [bindings op-maker]
+  (let [bindings (partition 2 bindings)
+        late-path-syms (map first bindings)
+        paths-code (vec (map second bindings))
+        delta-syms (vec (gensyms (count bindings)))
+        compiled-syms (vec (gensyms (count bindings)))
+        runtime-bindings (vec (mapcat
+                               (fn [l c d]
+                                 `[~l (dfn/bound-params ~c ~d)]
+                                 )
+                               late-path-syms
+                               compiled-syms
+                               delta-syms))
+        total-params-sym (gensym "total-params")
+        body (op-maker runtime-bindings compiled-syms total-params-sym)]
+    `(let [compiled# (doall (map i/comp-paths* ~paths-code))
+           ~compiled-syms compiled#
+           deltas# (cons 0 (reductions + (map i/num-needed-params compiled#)))
+           ~delta-syms deltas#
+           ~total-params-sym (last deltas#)
+           ]
+       ~body
+       )))
+
+(defmacro fixed-pathed-nav
+  "This helper is used to define navigators that take in a fixed number of other
+  paths as input. Those paths may require late-bound params, so this helper
+  will create a parameterized navigator if that is the case. If no late-bound params
+  are required, then the result is executable."
+  [bindings & impls]
+  (fixed-pathed-operation bindings
+    (fn [runtime-bindings compiled-syms total-params-sym]
+      (let [late-syms (map first (partition 2 bindings))
+            lean-bindings (mapcat vector late-syms compiled-syms)]
+        `(if (zero? ~total-params-sym)
+           (let [~@lean-bindings]
+             (i/lean-compiled-path (lean-nav* ~@body))
+             )
+           (->ParamsNeededPath
+            (rich-nav-with-bindings ~total-params-sym
+                                    ~runtime-bindings
+                                    ~@impls
+                                    )
+            ~total-params-sym
+            )))
+      )))
+
+
+(defmacro fixed-pathed-collector
+  "This helper is used to define collectors that take in a fixed number of
+  paths as input. That path may require late-bound params, so this helper
+  will create a parameterized navigator if that is the case. If no late-bound params
+  are required, then the result is executable."
+  [bindings & body]
+  (fixed-pathed-operation bindings
+    (fn [runtime-bindings _ total-params-sym]
+      `(->ParamsNeededPath
+        (collector-with-bindings ~total-params-sym
+                                 ~runtime-bindings
+                                 ~@body
+                                 )
+        ~total-params-sym
+        ))))
+
+(defmacro paramsfn [params [structure-sym] & impl]
+  `(nav ~params
+    (~'select* [this# structure# next-fn#]
+               (let [afn# (fn [~structure-sym] ~@impl)]
+                 (i/filter-select afn# structure# next-fn#)
+                 ))
+    (~'transform* [this# structure# next-fn#]
+                  (let [afn# (fn [~structure-sym] ~@impl)]
+                    (i/filter-transform afn# structure# next-fn#)
+                    ))))

 (defmacro defnav [name & body]
   `(def ~name (nav ~@body)))

 (defmacro defcollector [name & body]
-  `(def ~name (paramscollector ~@body)))
-
-(defmacro fixed-pathed-nav
-  "This helper is used to define navigators that take in a fixed number of other
-   paths as input. Those paths may require late-bound params, so this helper
-   will create a parameterized navigator if that is the case. If no late-bound params
-   are required, then the result is executable."
-  [bindings impl1 impl2]
-  (let [bindings (partition 2 bindings)
-        paths (mapv second bindings)
-        names (mapv first bindings)
-        latefns-sym (gensym "latefns")
-        latefn-syms (vec (gensyms (count paths)))]
-    (pathed-nav*
-      paramsnav*
-      paths
-      latefns-sym
-      [latefn-syms latefns-sym]
-      (mapcat (fn [n l] [n `(~l ~PARAMS-SYM ~PARAMS-IDX-SYM)]) names latefn-syms)
-      [impl1 impl2])))
-
-(defmacro variable-pathed-nav
-  "This helper is used to define navigators that take in a variable number of other
-   paths as input. Those paths may require late-bound params, so this helper
-   will create a parameterized navigator if that is the case. If no late-bound params
-   are required, then the result is executable."
-  [[latepaths-seq-sym paths-seq] impl1 impl2]
-  (let [latefns-sym (gensym "latefns")]
-    (pathed-nav*
-      paramsnav*
-      paths-seq
-      latefns-sym
-      []
-      [latepaths-seq-sym `(map (fn [l#] (l# ~PARAMS-SYM ~PARAMS-IDX-SYM))
-                               ~latefns-sym)]
-      [impl1 impl2]
-      )))
-
-(defmacro pathed-collector
-  "This helper is used to define collectors that take in a single selector
-   paths as input. That path may require late-bound params, so this helper
-   will create a parameterized selector if that is the case. If no late-bound params
-   are required, then the result is executable."
-  [[name path] impl]
-  (let [latefns-sym (gensym "latefns")
-        latefn (gensym "latefn")]
-    (pathed-nav*
-      paramscollector*
-      [path]
-      latefns-sym
-      [[latefn] latefns-sym]
-      [name `(~latefn ~PARAMS-SYM ~PARAMS-IDX-SYM)]
-      impl
-      )
-    ))
+  `(def ~name (collector ~@body)))
+

 (defn- protpath-sym [name]
   (-> name (str "-prot") symbol))
@@ -249,47 +249,47 @@

 (defmacro defprotocolpath
   "Defines a navigator that chooses the path to take based on the type
-   of the value at the current point. May be specified with parameters to
-   specify that all extensions must require that number of parameters.
-
-   Currently not available for ClojureScript.
-
-   Example of usage:
-   (defrecord SingleAccount [funds])
-   (defrecord FamilyAccount [single-accounts])
-
-   (defprotocolpath FundsPath)
-   (extend-protocolpath FundsPath
+  of the value at the current point. May be specified with parameters to
+  specify that all extensions must require that number of parameters.
+
+  Currently not available for ClojureScript.
+
+  Example of usage:
+  (defrecord SingleAccount [funds])
+  (defrecord FamilyAccount [single-accounts])
+
+  (defprotocolpath FundsPath)
+  (extend-protocolpath FundsPath
     SingleAccount :funds
     FamilyAccount [ALL FundsPath]
     )
-   "
+"
   ([name]
-    `(defprotocolpath ~name []))
+   `(defprotocolpath ~name []))
   ([name params]
-    (let [prot-name (protpath-sym name)
-          m (-> name (str "-retrieve") symbol)
-          num-params (count params)
-          ssym (gensym "structure")
-          rargs [(gensym "params") (gensym "pidx") (gensym "vals") ssym (gensym "next-fn")]
-          retrieve `(~m ~ssym)
-          ]
-      `(do
-          (defprotocol ~prot-name (~m [structure#]))
-          (let [nav# (reify RichNavigator
-                       (~'rich-select* [this# ~@rargs]
-                          (let [inav# ~retrieve]
-                            (i/exec-rich-select* inav# ~@rargs)
-                            ))
-                       (~'rich-transform* [this# ~@rargs]
-                          (let [inav# ~retrieve]
-                            (i/exec-rich-transform* inav# ~@rargs)
-                            )))]
-            (def ~name
-              (if (= ~num-params 0)
-                (i/no-params-rich-compiled-path nav#)
-                (i/->ParamsNeededPath nav# ~num-params)
-                )))))))
+   (let [prot-name (protpath-sym name)
+         m (-> name (str "-retrieve") symbol)
+         num-params (count params)
+         ssym (gensym "structure")
+         rargs [(gensym "params") (gensym "pidx") (gensym "vals") ssym (gensym "next-fn")]
+         retrieve `(~m ~ssym)
+         ]
+     `(do
+        (defprotocol ~prot-name (~m [structure#]))
+        (let [nav# (reify RichNavigator
+                     (~'rich-select* [this# ~@rargs]
+                       (let [inav# ~retrieve]
+                         (i/exec-rich-select* inav# ~@rargs)
+                         ))
+                     (~'rich-transform* [this# ~@rargs]
+                       (let [inav# ~retrieve]
+                         (i/exec-rich-transform* inav# ~@rargs)
+                         )))]
+          (def ~name
+            (if (= ~num-params 0)
+              (i/no-params-rich-compiled-path nav#)
+              (i/->ParamsNeededPath nav# ~num-params)
+              )))))))

@@ -301,32 +301,32 @@

 (defmacro declarepath
   ([name]
-    `(declarepath ~name []))
+   `(declarepath ~name []))
   ([name params]
-    (let [platform (if (contains? &env :locals) :cljs :clj)
-          select-exec (if (= platform :clj)
-                        `i/exec-rich-select*
-                        `i/rich-select*)
-          transform-exec (if (= platform :clj)
-                           `i/exec-rich-transform*
-                           `i/rich-transform*)
-          num-params (count params)
-          declared (declared-name name)
-          rargs [(gensym "params") (gensym "pidx") (gensym "vals")
-                 (gensym "structure") (gensym "next-fn")]]
-      `(do
-         (declare ~declared)
-         (def ~name
-           (let [nav# (reify RichNavigator
-                        (~'rich-select* [this# ~@rargs]
-                          (~select-exec ~declared ~@rargs))
-                        (~'rich-transform* [this# ~@rargs]
-                          (~transform-exec ~declared ~@rargs)
-                          ))]
-             (if (= ~num-params 0)
-               (i/no-params-rich-compiled-path nav#)
-               (i/->ParamsNeededPath nav# ~num-params)
-               )))))))
+   (let [platform (if (contains? &env :locals) :cljs :clj)
+         select-exec (if (= platform :clj)
+                       `i/exec-rich-select*
+                       `i/rich-select*)
+         transform-exec (if (= platform :clj)
+                          `i/exec-rich-transform*
+                          `i/rich-transform*)
+         num-params (count params)
+         declared (declared-name name)
+         rargs [(gensym "params") (gensym "pidx") (gensym "vals")
+                (gensym "structure") (gensym "next-fn")]]
+     `(do
+        (declare ~declared)
+        (def ~name
+          (let [nav# (reify RichNavigator
+                       (~'rich-select* [this# ~@rargs]
+                         (~select-exec ~declared ~@rargs))
+                       (~'rich-transform* [this# ~@rargs]
+                         (~transform-exec ~declared ~@rargs)
+                         ))]
+            (if (= ~num-params 0)
+              (i/no-params-rich-compiled-path nav#)
+              (i/->ParamsNeededPath nav# ~num-params)
+              )))))))

 (defmacro providepath [name apath]
   `(let [comped# (i/comp-paths-internalized ~apath)
@@ -334,10 +334,10 @@
          needed-params# (i/num-needed-params comped#)]
      (if-not (= needed-params# expected-params#)
        (i/throw-illegal "Invalid number of params in provided path, expected "
-           expected-params# " but got " needed-params#))
+                        expected-params# " but got " needed-params#))
      (def ~(declared-name name)
-      (i/extract-rich-nav (i/coerce-compiled->rich-nav comped#))
-      )))
+       (i/extract-rich-nav (i/coerce-compiled->rich-nav comped#))
+       )))

 (defmacro extend-protocolpath
   "Used in conjunction with `defprotocolpath`. See [[defprotocolpath]]."
@@ -347,14 +347,14 @@
 ;; copied from tools.macro to avoid the dependency
 (defn ^:no-doc name-with-attributes
   "To be used in macro definitions.
-   Handles optional docstrings and attribute maps for a name to be defined
-   in a list of macro arguments. If the first macro argument is a string,
-   it is added as a docstring to name and removed from the macro argument
-   list. If afterwards the first macro argument is a map, its entries are
-   added to the name's metadata map and the map is removed from the
-   macro argument list. The return value is a vector containing the name
-   with its extended metadata map and the list of unprocessed macro
-   arguments."
+  Handles optional docstrings and attribute maps for a name to be defined
+  in a list of macro arguments. If the first macro argument is a string,
+  it is added as a docstring to name and removed from the macro argument
+  list. If afterwards the first macro argument is a map, its entries are
+  added to the name's metadata map and the map is removed from the
+  macro argument list. The return value is a vector containing the name
+  with its extended metadata map and the list of unprocessed macro
+  arguments."
   [name macro-args]
   (let [[docstring macro-args] (if (string? (first macro-args))
                                  [(first macro-args) (next macro-args)]
@@ -372,14 +372,14 @@

 (defmacro defpathedfn
   "Defines a higher order navigator that itself takes in one or more paths
-   as input. This macro is generally used in conjunction with [[fixed-pathed-nav]]
-   or [[variable-pathed-nav]]. When inline factoring is applied to a path containing
-   one of these higher order navigators, it will automatically interepret all
-   arguments as paths, factor them accordingly, and set up the callsite to
-   provide the parameters dynamically. Use ^:notpath metadata on arguments
-   to indicate non-path arguments that should not be factored – note that in order
-   to be inline factorable, these arguments must be statically resolvable (e.g. a
-   top level var). See `transformed` for an example."
+  as input. This macro is generally used in conjunction with [[fixed-pathed-nav]]
+  or [[variable-pathed-nav]]. When inline factoring is applied to a path containing
+  one of these higher order navigators, it will automatically interepret all
+  arguments as paths, factor them accordingly, and set up the callsite to
+  provide the parameters dynamically. Use ^:notpath metadata on arguments
+  to indicate non-path arguments that should not be factored – note that in order
+  to be inline factorable, these arguments must be statically resolvable (e.g. a
+    top level var). See `transformed` for an example."
   [name & args]
   (let [[name args] (name-with-attributes name args)
         name (vary-meta name assoc :pathedfn true)]
@@ -388,26 +388,26 @@
 (defmacro defnavconstructor [name & args]
   (let [[name [[csym anav] & body-or-bodies]] (name-with-attributes name args)
         bodies (if (-> body-or-bodies first vector?) [body-or-bodies] body-or-bodies)
-
+
         checked-code
         (doall
-          (for [[args & body] bodies]
-            `(~args
-               (let [ret# (do ~@body)]
-                 (if (i/layered-nav? ret#)
-                    (i/layered-nav-underlying ret#)
-                    (i/throw-illegal "Expected result navigator '" (quote ~anav)
-                      "' from nav constructor '" (quote ~name) "'"
-                      " constructed with the provided constructor '" (quote ~csym)
-                      "'"))
-                 ))))]
+         (for [[args & body] bodies]
+           `(~args
+             (let [ret# (do ~@body)]
+               (if (i/layered-nav? ret#)
+                 (i/layered-nav-underlying ret#)
+                 (i/throw-illegal "Expected result navigator '" (quote ~anav)
+                                  "' from nav constructor '" (quote ~name) "'"
+                                  " constructed with the provided constructor '" (quote ~csym)
+                                  "'"))
+               ))))]
     `(def ~name
        (vary-meta
-         (let [~csym (i/layered-wrapper ~anav)]
-           (fn ~@checked-code))
-         assoc :layerednav true))
-     ))
-
+        (let [~csym (i/layered-wrapper ~anav)]
+          (fn ~@checked-code))
+        assoc :layerednav true))
+    ))
+

 (defn ^:no-doc ic-prepare-path [locals-set path]
   (cond
@@ -423,14 +423,14 @@

     (i/fn-invocation? path)
     (let [[op & params] path]
-      ;; need special case for 'fn since macroexpand does NOT
+      ;; need special case for 'fn since macroexpand does NOT
       ;; expand fn when run on cljs code, but it's also not considered a special symbol
       (if (or (= 'fn op) (special-symbol? op))
         `(com.rpl.specter.impl/->SpecialFormUse ~path (quote ~path))
         `(com.rpl.specter.impl/->FnInvocation
-           ~(ic-prepare-path locals-set op)
-           ~(mapv #(ic-prepare-path locals-set %) params)
-           (quote ~path)))
+          ~(ic-prepare-path locals-set op)
+          ~(mapv #(ic-prepare-path locals-set %) params)
+          (quote ~path)))
       )

     :else
@@ -440,21 +440,21 @@
 (defn ^:no-doc ic-possible-params [path]
   (do
     (mapcat
-      (fn [e]
-        (cond (or (set? e)
-                  (map? e) ; in case inline maps are ever extended
-                  (and (i/fn-invocation? e) (contains? #{'fn* 'fn} (first e))))
-              [e]
-
-              (i/fn-invocation? e)
-              ;; the [e] here handles nav constructors
-              (concat [e] (rest e) (ic-possible-params e))
-
-              (vector? e)
-              (ic-possible-params e)
-              ))
-      path
-      )))
+     (fn [e]
+       (cond (or (set? e)
+                 (map? e) ; in case inline maps are ever extended
+                 (and (i/fn-invocation? e) (contains? #{'fn* 'fn} (first e))))
+             [e]
+
+             (i/fn-invocation? e)
+             ;; the [e] here handles nav constructors
+             (concat [e] (rest e) (ic-possible-params e))
+
+             (vector? e)
+             (ic-possible-params e)
+             ))
+     path
+     )))

 (defn cljs-macroexpand [env form]
   (let [expand-fn (i/cljs-analyzer-macroexpand-1)
@@ -479,32 +479,32 @@
 ;; still possible to mess this up with alter-var-root
 (defmacro path
   "Same as calling comp-paths, except it caches the composition of the static part
-   of the path for later re-use (when possible). For almost all idiomatic uses
-   of Specter provides huge speedup. This macro is automatically used by the
-   select/transform/setval/replace-in/etc. macros."
+  of the path for later re-use (when possible). For almost all idiomatic uses
+  of Specter provides huge speedup. This macro is automatically used by the
+  select/transform/setval/replace-in/etc. macros."
   [& path]
   (let [;;this is a hack, but the composition of &env is considered stable for cljs
         platform (if (contains? &env :locals) :cljs :clj)
         local-syms (if (= platform :cljs)
-                    (-> &env :locals keys set) ;cljs
-                    (-> &env keys set) ;clj
-                    )
+                     (-> &env :locals keys set) ;cljs
+                     (-> &env keys set) ;clj
+                     )
         used-locals-cell (i/mutable-cell [])
         _ (cljwalk/postwalk
-            (fn [e]
-              (if (local-syms e)
-                (i/update-cell! used-locals-cell #(conj % e))
-                e
-                ))
-            path)
+           (fn [e]
+             (if (local-syms e)
+               (i/update-cell! used-locals-cell #(conj % e))
+               e
+               ))
+           path)
         used-locals (i/get-cell used-locals-cell)

         ;; note: very important to use riddley's macroexpand-all here, so that
         ;; &env is preserved in any potential nested calls to select (like via
         ;; a view function)
         expanded (if (= platform :clj)
-                  (i/clj-macroexpand-all (vec path))
-                  (cljs-macroexpand-all &env (vec path)))
+                   (i/clj-macroexpand-all (vec path))
+                   (cljs-macroexpand-all &env (vec path)))

         prepared-path (ic-prepare-path local-syms expanded)
         possible-params (vec (ic-possible-params expanded))
@@ -513,22 +513,22 @@
         ;; to invoke and/or parameterize the precompiled path without
         ;; a bunch of checks beforehand
         cache-sym (vary-meta
-                    (gensym "pathcache")
-                      assoc :cljs.analyzer/no-resolve true)
+                   (gensym "pathcache")
+                   assoc :cljs.analyzer/no-resolve true)

         info-sym (gensym "info")

         get-cache-code (if (= platform :clj)
                          `(try (i/get-cell ~cache-sym)
-                            (catch ClassCastException e#
-                              (if (bound? (var ~cache-sym))
-                                (throw e#)
-                                (do
-                                  (alter-var-root
-                                    (var ~cache-sym)
-                                    (fn [_#] (i/mutable-cell)))
-                                  nil
-                                  ))))
+                               (catch ClassCastException e#
+                                 (if (bound? (var ~cache-sym))
+                                   (throw e#)
+                                   (do
+                                     (alter-var-root
+                                      (var ~cache-sym)
+                                      (fn [_#] (i/mutable-cell)))
+                                     nil
+                                     ))))
                          cache-sym
                          )
         add-cache-code (if (= platform :clj)
@@ -543,28 +543,28 @@
         (if (= platform :clj)
           `(i/bind-params* ~precompiled-sym (~params-maker-sym ~@used-locals) 0)
           `(i/handle-params
-             ~precompiled-sym
-             ~params-maker-sym
-             ~(mapv (fn [p] `(fn [] ~p)) possible-params)
-             ))
+            ~precompiled-sym
+            ~params-maker-sym
+            ~(mapv (fn [p] `(fn [] ~p)) possible-params)
+            ))
         ]
     (if (= platform :clj)
       (i/intern* *ns* cache-sym (i/mutable-cell)))
     `(let [info# ~get-cache-code
-
+
            ^com.rpl.specter.impl.CachedPathInfo info#
-            (if (nil? info#)
-              (let [~info-sym (i/magic-precompilation
-                               ~prepared-path
-                               ~(str *ns*)
-                               (quote ~used-locals)
-                               (quote ~possible-params)
-                               )]
-                ~add-cache-code
-                ~info-sym
-                )
-              info#
-              )
+           (if (nil? info#)
+             (let [~info-sym (i/magic-precompilation
+                              ~prepared-path
+                              ~(str *ns*)
+                              (quote ~used-locals)
+                              (quote ~possible-params)
+                              )]
+               ~add-cache-code
+               ~info-sym
+               )
+             info#
+             )

            ~precompiled-sym (.-precompiled info#)
            ~params-maker-sym (.-params-maker info#)]
@@ -575,112 +575,112 @@
            ~handle-params-code
            )
          ))
-  ))
+    ))

 (defmacro select
   "Navigates to and returns a sequence of all the elements specified by the path.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-select* (path ~apath) ~structure))

 (defmacro select-one!
   "Returns exactly one element, throws exception if zero or multiple elements found.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-select-one!* (path ~apath) ~structure))

 (defmacro select-one
   "Like select, but returns either one element or nil. Throws exception if multiple elements found.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-select-one* (path ~apath) ~structure))

 (defmacro select-first
   "Returns first element found.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-select-first* (path ~apath) ~structure))

 (defmacro select-any
   "Returns any element found or [[NONE]] if nothing selected. This is the most
-   efficient of the various selection operations.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  efficient of the various selection operations.
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-select-any* (path ~apath) ~structure))

 (defmacro selected-any?
   "Returns true if any element was selected, false otherwise.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-selected-any?* (path ~apath) ~structure))

 (defmacro transform
   "Navigates to each value specified by the path and replaces it by the result of running
-   the transform-fn on it.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  the transform-fn on it.
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath transform-fn structure]
   `(i/compiled-transform* (path ~apath) ~transform-fn ~structure))

 (defmacro multi-transform
   "Just like `transform` but expects transform functions to be specified
-   inline in the path using `terminal`. Error is thrown if navigation finishes
-   at a non-`terminal` navigator. `terminal-val` is a wrapper around `terminal` and is
-   the `multi-transform` equivalent of `setval`.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  inline in the path using `terminal`. Error is thrown if navigation finishes
+  at a non-`terminal` navigator. `terminal-val` is a wrapper around `terminal` and is
+  the `multi-transform` equivalent of `setval`.
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/compiled-multi-transform* (path ~apath) ~structure))

 (defmacro setval
   "Navigates to each value specified by the path and replaces it by `aval`.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath aval structure]
   `(i/compiled-setval* (path ~apath) ~aval ~structure))

 (defmacro traverse
   "Return a reducible object that traverses over `structure` to every element
-   specified by the path.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  specified by the path.
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath structure]
   `(i/do-compiled-traverse (path ~apath) ~structure))

 (defmacro replace-in
   "Similar to transform, except returns a pair of [transformed-structure sequence-of-user-ret].
-   The transform-fn in this case is expected to return [ret user-ret]. ret is
-   what's used to transform the data structure, while user-ret will be added to the user-ret sequence
-   in the final return. replace-in is useful for situations where you need to know the specific values
-   of what was transformed in the data structure.
-   This macro will attempt to do inline factoring and caching of the path, falling
-   back to compiling the path on every invocation if it's not possible to
-   factor/cache the path."
+  The transform-fn in this case is expected to return [ret user-ret]. ret is
+  what's used to transform the data structure, while user-ret will be added to the user-ret sequence
+  in the final return. replace-in is useful for situations where you need to know the specific values
+  of what was transformed in the data structure.
+  This macro will attempt to do inline factoring and caching of the path, falling
+  back to compiling the path on every invocation if it's not possible to
+  factor/cache the path."
   [apath transform-fn structure & args]
   `(i/compiled-replace-in* (path ~apath) ~transform-fn ~structure ~@args))

 (defmacro collected?
   "Creates a filter function navigator that takes in all the collected values
-   as input. For arguments, can use `(collected? [a b] ...)` syntax to look
-   at each collected value as individual arguments, or `(collected? v ...)` syntax
-   to capture all the collected values as a single vector."
+  as input. For arguments, can use `(collected? [a b] ...)` syntax to look
+  at each collected value as individual arguments, or `(collected? v ...)` syntax
+  to capture all the collected values as a single vector."
   [params & body]
   (let [platform (if (contains? &env :locals) :cljs :clj)]
     `(i/collected?* (~'fn [~params] ~@body))


better conditional checking of cached value

--- src/clj/com/rpl/specter/macros.clj
+++ src/clj/com/rpl/specter/macros.clj
@@ -363,7 +363,7 @@
     `(let [info# (i/get-path-cache ~cache-id)

            ^com.rpl.specter.impl.CachedPathInfo info#
-            (if info#
+            (if (some? info#)
               info#
               (let [info# (i/magic-precompilation
                            ~prepared-path


Whoops, corrected poor variable name.

Whoops, corrected poor variable name.

--- src/clj/forma/hadoop/predicate.clj
+++ src/clj/forma/hadoop/predicate.clj
@@ -184,7 +184,7 @@
   (->> (for [[h v]  tileseq
              sample (range (pixels-at-res res))
              line   (range (pixels-at-res res))]
-         [h v s l])
+         [h v sample line])
        (c/lazy-generator tmp-path)))

 ;; ### Special Functions


Changed indentation on routes.

Changed indentation on routes.

--- src/cmr/metadata_db/api/routes.clj
+++ src/cmr/metadata_db/api/routes.clj
@@ -76,22 +76,22 @@
 (defn- build-routes [system]
   (routes
     (context "/concepts" []
-             ;; saves a concept
-             (POST "/" params
-                   (save-concept system (:body params)))
-             ;; delete the entire database
-             (DELETE "/force-delete" params
-                     (force-delete system))
-             (DELETE "/:id" [id] (delete-concept system id))
-             ;; get a specific revision of a concept
-             (GET "/:id/:revision" [id revision] (get-concept system id revision))
-             ;; returns the latest revision of a concept
-             (GET "/:id" [id] (get-concept system id nil))
-             (POST "/search" params
-                   (get-concepts system (get (:body params) "concept-revisions"))))
+      ;; saves a concept
+      (POST "/" params
+        (save-concept system (:body params)))
+      ;; delete the entire database
+      (DELETE "/force-delete" params
+        (force-delete system))
+      (DELETE "/:id" [id] (delete-concept system id))
+      ;; get a specific revision of a concept
+      (GET "/:id/:revision" [id revision] (get-concept system id revision))
+      ;; returns the latest revision of a concept
+      (GET "/:id" [id] (get-concept system id nil))
+      (POST "/search" params
+        (get-concepts system (get (:body params) "concept-revisions"))))

     (GET "/concept-id/:concept-type/:provider-id/:native-id" [concept-type provider-id native-id]
-         (get-concept-id system concept-type provider-id native-id))
+      (get-concept-id system concept-type provider-id native-id))

     (route/not-found "Not Found")))


convert assert-html to a macro so line numbers in error reports make sense

--- test/dalap/test/html.clj
+++ test/dalap/test/html.clj
@@ -11,9 +11,9 @@

 (def basic-sample-data-str "123abcx 1.2 foo:bar")

-(defn- assert-html
-  ([in out] (assert-html in out nil))
-  ([in out msg] (is (= (to-html in) out) msg)))
+(defmacro assert-html
+  ([in out] `(assert-html ~in ~out nil))
+  ([in out msg] `(is (= (to-html ~in) ~out) ~msg)))

 (deftest test-basic-types
   (assert-html basic-sample-data basic-sample-data-str)


corrected missing format specifier in wrap-exception

--- src/lcmap/clownfish/middleware.clj
+++ src/lcmap/clownfish/middleware.clj
@@ -61,6 +61,6 @@
         ;; this will print a stack trace, useful for debugging.
         (log/debug ex (.getMessage ex))
         ;; this will not print a stack trace, just a short message.
-        (log/error "%s: %s" (.getMessage ex) (ex-data ex))
+        (log/errorf "%s: %s" (.getMessage ex) (ex-data ex))
         ;; produce a ring style response map
         (ex->resp ex)))))


Only include (auth ...) form in entities when generating for CLJ

--- src/main/workflo/macros/entity.clj
+++ src/main/workflo/macros/entity.clj
@@ -111,12 +111,13 @@
          spec              (:form-body (:spec (:forms args)))
          name-sym          (unqualify name)
          forms             (-> (:forms args)
-                               (select-keys [:auth :spec])
+                               (select-keys [:spec])
                                (vals)
                                (cond->
                                    true        (conj {:form-name 'name})
                                    description (conj {:form-name 'description})
-                                   auth-query  (conj {:form-name 'auth-query})))
+                                   auth-query  (conj {:form-name 'auth-query})
+                                   auth        (conj {:form-name 'auth})))
          def-sym           (f/qualified-form-name 'definition name-sym)]
      `(do
         ~(f/make-def name-sym 'name `'~name)


rearranging for (my) readability

rearranging for (my) readability

--- src/midje/internal_ideas/fakes.clj
+++ src/midje/internal_ideas/fakes.clj
@@ -263,12 +263,6 @@
     (and (list? thing)
       (mockable-function-symbol? (first thing)))))

-(defn folded-fake? [form]
-  (and (sequential? form)
-    (= 'midje.semi-sweet/fake (first form))
-    ;; We now know this: (fake (f ...arg... ...arg...) ...)
-    (some mockable-funcall? (fake-form-funcall-arglist form))))
-
 (defn augment-substitutions [substitutions fake-form]
   (let [needed-keys (filter mockable-funcall? (fake-form-funcall-arglist fake-form))]
     ;; Note: because I like for a function's metaconstants to be
@@ -284,27 +278,30 @@

 (defn generate-fakes [substitutions overrides]
   (for [[funcall metaconstant] substitutions]
-    `(midje.semi-sweet/fake ~funcall midje.semi-sweet/=> ~metaconstant ~@overrides)))
-
-;; This walks through a `pending` list that may contain fakes. Each element is
-;; copied to the `finished` list. If it is a suitable fake, its nested
-;; are flattened (replaced with a metaconstant). If the metaconstant was newly
-;; generated, the fake that describes it is added to the pending list. In that way,
-;; it'll in turn be processed. This allows arbitrarily deep nesting.
-
-(defn- unfolding-step [finished pending substitutions]
+    `(midje.semi-sweet/fake ~funcall midje.semi-sweet/=> ~metaconstant ~@overrides)))
+
+(defn folded-fake? [form]
+  (and (sequential? form)
+    (= 'midje.semi-sweet/fake (first form))
+    ;; We now know this: (fake (f ...arg... ...arg...) ...)
+    (some mockable-funcall? (fake-form-funcall-arglist form))))
+
+(defn- unfolding-step
+  "This walks through a `pending` list that may contain fakes. Each element is
+   copied to the `finished` list. If it is a suitable fake, its nested
+   are flattened (replaced with a metaconstant). If the metaconstant was newly
+   generated, the fake that describes it is added to the pending list. In that way,
+   it'll in turn be processed. This allows arbitrarily deep nesting."
+  [finished pending substitutions]
   (let [target (first pending)]
-    (if (folded-fake? target)
-      (let [overrides (nthnext target 4)
+    (if-not (folded-fake? target)
+      [(conj finished target), (rest pending), substitutions]
+
+      (let [overrides (drop 4 target)
             augmented-substitutions (augment-substitutions substitutions target)
             flattened-target (flatten-fake target augmented-substitutions)
-            generated-fakes (generate-fakes
-          (map-difference augmented-substitutions substitutions)
-          overrides)]
-        [(conj finished flattened-target)
-         (concat generated-fakes (rest pending))
-         augmented-substitutions])
-      [(conj finished target), (rest pending), substitutions])))
+            generated-fakes (generate-fakes (map-difference augmented-substitutions substitutions) overrides)]
+        [(conj finished flattened-target), (concat generated-fakes (rest pending)), augmented-substitutions]))))

 (defn- unfold-expect-form__then__stay_put [loc]
   (loop [[finished pending substitutions] [[] (zip/node loc) {}]]


Remove additional description

Remove additional description

--- doclet/src/clojure/play_clj_doclet/html.clj
+++ doclet/src/clojure/play_clj_doclet/html.clj
@@ -16,9 +16,7 @@
     [:b (str name)]
     " "
     (string/join ", " (map param args))]
-   (cond
-     text [:i text]
-     type [:i (str "Returns a " type)])])
+   (when text [:i text])])

 (defn create-from-file
   [parsed-file]


add dummy new coll button on user page

add dummy new coll button on user page

--- src-cljs/imago/user.cljs
+++ src-cljs/imago/user.cljs
@@ -20,7 +20,10 @@
          (dom/create-dom!
           [:div.jumbotron
            [:h1 (str "Welcome back, " uname)]
-           [:p "Here're your collections..."]]))))
+           [:p "Here're your collections..."]
+           [:p [:button.btn.btn-primary.btn-lg
+                {:events []}
+                [:span.glyphicon.glyphicon-plus] " New collection"]]]))))

 (defn show-collections
   [state colls]


Center preview-images.

Center preview-images.

--- src-cljs/pepa/style.cljs
+++ src-cljs/pepa/style.cljs
@@ -382,8 +382,8 @@
                  :padding {:left (px page-padding)
                            :right (px page-padding)}
                  :position :absolute
-                 :top "50%"}
-                ^:prefix {:transform "translateY(-50%)"}
+                 :top "50%", :right "50%"}
+                ^:prefix {:transform "translate(50%,-50%)"}
                 (calc-property :max-width ["100%" - (* 2 page-padding)]))]]
         (let [title-padding 5
               title-height (em 2)]


bump version dependency.

bump version dependency.

--- resources/leiningen/new/bukkure/project.clj
+++ resources/leiningen/new/bukkure/project.clj
@@ -1,5 +1,5 @@
 (defproject {{name}} "0.1.0-SNAPSHOT"
   :description "A bukkure plugin to..."
   :dependencies [[org.clojure/clojure "1.7.0"]
-                 [bukkure "0.2.1-SNAPSHOT"]]
+                 [bukkure "0.3.1-SNAPSHOT"]]
   :java-source-paths ["javasrc"])


Remove stray log line.

Remove stray log line.

--- src/oc/storage/resources/board.clj
+++ src/oc/storage/resources/board.clj
@@ -263,7 +263,6 @@
 (defn maybe-delete-draft-board
   "Check if a board is actually a draft board and if it has no more entries remove it."
   [conn org board remaining-entries user]
-  (timbre/info "maybe-delete-draft-board" (:uuid board) "draft?" (:draft board) "entries" (count remaining-entries))
   (when (and ;; if it's a draft board
              (:draft board)
              ;; and has no more entries


Remove user-id from bookmark query parameters.

--- src/oc/storage/resources/entry.clj
+++ src/oc/storage/resources/entry.clj
@@ -489,7 +489,7 @@
          (#{:recent-activity :recently-posted} sort-type)]}
   (storage-db-common/read-paginated-entries conn table-name :org-uuid-status-bookmark-user-id-map-multi
    [[org-uuid :published user-id]] order start direction limit sort-type common/interaction-table-name nil
-   user-id list-comment-properties {:count count})))
+   list-comment-properties {:count count})))

 (schema/defn ^:always-validate add-bookmark! :- (schema/maybe common/Entry)
   "Add a bookmark for the give entry and user"


only fetch keys to build db

only fetch keys to build db

--- src/org/spootnik/cyanite/store.clj
+++ src/org/spootnik/cyanite/store.clj
@@ -56,7 +56,7 @@
 (def
   ^{:doc "This query returns only paths, to get a list of
 metrics. Right now it is way too expensive and should be computed differently"}
-  pathq "SELECT path from metric;")
+  pathq "SELECT distinct tenant, path, rollup, period from metric;")

 (defn useq
   "Yields a cassandra use statement for a keyspace"


Positive test for the function proper-word-for-blacklist?

--- test/zg/dictionary_interface_test.clj
+++ test/zg/dictionary_interface_test.clj
@@ -51,3 +51,16 @@
         (is (callable? 'zg.dictionary-interface/store-words))))

+(deftest test-proper-word-for-blacklist?
+    "Check the function zg.dictionary-interface/proper-word-for-blacklist?"
+    (testing "the function zg.dictionary-interface/proper-word-for-blacklist?"
+        (are [x] (seq (proper-word-for-blacklist? x))
+            "test"
+            "Test"
+            "TEST"
+            "Test0"
+            "0"
+            "I'm"
+            "This is test"
+            "This is test.")))
+


don't try to encode entities

don't try to encode entities

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -79,7 +79,10 @@
     :document/id (:document/id state)
     :layers (when (or (get-in state [:drawing :in-progress?])
                       (get-in state [:drawing :moving?]))
-              (map #(dissoc % :points) (get-in state [:drawing :layers])))
+              (map #(-> %
+                      (dissoc :points)
+                      (utils/update-when-in [:layer/points-to] select-keys [:db/id]))
+                   (get-in state [:drawing :layers])))
     :relation (when (get-in state [:drawing :relation :layer])
                 (get-in state [:drawing :relation]))
     :recording (get-in state (state/self-recording-path state))


remove dead code

remove dead code

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -79,20 +79,6 @@
                                                      result)))
                                                paths-to-comps)))))))))
      (map #(do-defaults % model)))))
-
-(defn generate-all2 [spec model & [depth max-depth]]
-  (let [depth (or depth 0)
-        truncate truncate
-        max-depth (or max-depth max-total-depth)]
-    (log/debug (str "generate-all:" depth "/" max-depth ";pred=" (get-in spec [:synsem :sem :pred])))
-    (->>
-     (lightning-bolts model spec depth max-depth)
-
-     ;; for each bolt, create a map of complement positions
-     ;; within the bolt to possible complements for that position
-     (map #(assoc
-            (comp-paths-to-complements % model depth max-depth)
-            [] (list %))))))

 (defn generate
   "Return one (by default) or _n_ (using :take _n_) expressions matching spec _spec_ given the model _model_."


+(strip-refs)

+(strip-refs)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -275,7 +275,7 @@
                          unified))
                      (do
                        (log/debug (str "candidate-parents: " (:rule rule) " is *not* a head candidate for spec:"
-                                       spec))
+                                       (strip-refs spec)))
                        :fail)))
                  rules)))


s/map/pmap/

s/map/pmap/

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -57,10 +57,10 @@
   (let [total-depth (if total-depth total-depth 0)
         add-complements-to-bolts
         (fn [bolts path]
-          (mapcat #(if (not (= :none (get-in % path :none)))
-                     (add-complement % path :top grammar lexicon index morph 0 (+ total-depth (count path)))
-                     [%])
-                  bolts))]
+          (reduce concat (pmap #(if (not (= :none (get-in % path :none)))
+                                  (add-complement % path :top grammar lexicon index morph 0 (+ total-depth (count path)))
+                                  [%])
+                               bolts)))]
     (-> (lightning-bolt (lazy-shuffle grammar)
                         lexicon
                         spec 0 index morph total-depth)
@@ -76,9 +76,9 @@
 head of its parent. generate (above) 'decorates' each returned lightning bolt
 of this function with complements."
   (if (or (vector? spec) (seq? spec))
-    (reduce concat (map (fn [each-spec]
-                          (lightning-bolt grammar lexicon each-spec depth index morph total-depth))
-                        spec))
+    (reduce concat (pmap (fn [each-spec]
+                           (lightning-bolt grammar lexicon each-spec depth index morph total-depth))
+                         spec))
     (do
       (log/debug (str "lightning-bolt(depth=" depth ", total-depth=" total-depth "): sem:" (strip-refs (get-in spec [:synsem :sem]))))
       (let [morph (if morph morph (fn [input] (get-in input [:rule] :default-morph-no-rule)))
@@ -86,18 +86,18 @@
             parents (filter #(not (fail? %)) (map (fn [rule] (unifyc spec rule)) grammar))]
         (let [lexical ;; 1. generate list of all phrases where the head child of each parent is a lexeme.
               (reduce concat
-                      (map (fn [parent]
-                             (if (= false (get-in parent [:head :phrasal] false))
-                               (let [candidate-lexemes (get-lex parent :head index spec)]
-                                 (over/overh parent
-                                             (map copy (lazy-shuffle candidate-lexemes))))))
-                           parents))
+                      (pmap (fn [parent]
+                              (if (= false (get-in parent [:head :phrasal] false))
+                                (let [candidate-lexemes (get-lex parent :head index spec)]
+                                  (over/overh parent
+                                              (map copy (lazy-shuffle candidate-lexemes))))))
+                            parents))
               phrasal ;; 2. generate list of all phrases where the head child of each parent is itself a phrase.
               (if (< depth max-total-depth)
-                (mapcat (fn [parent]
-                          (over/overh parent (lightning-bolt grammar lexicon (get-in parent [:head])
-                                                             (+ 1 depth) index morph (+ 1 total-depth))))
-                        parents))]
+                (reduce concat (pmap (fn [parent]
+                                       (over/overh parent (lightning-bolt grammar lexicon (get-in parent [:head])
+                                                                          (+ 1 depth) index morph (+ 1 total-depth))))
+                                     parents)))]
           (if (lexemes-before-phrases total-depth)
             (lazy-cat lexical phrasal)
             (lazy-cat phrasal lexical)))))))


Converted to transducer

Converted to transducer

--- src/analyze_runs/gpx.clj
+++ src/analyze_runs/gpx.clj
@@ -61,7 +61,7 @@
                  (:time (last coll)))))

 (defn calculate-distance [coll]
-  (reduce + (map #(haversine (first %) (second %)) (partition 2 1 coll))))
+  (transduce (map #(haversine (first %) (second %))) + (partition 2 1 coll)))

 (defn rround [n]
   (/ (round (* n 100)) 100.0))


Order builds by olderst ones first when syncing from Go

--- src/buildviz/gosync.clj
+++ src/buildviz/gosync.clj
@@ -264,23 +264,22 @@
   (println "Go" selected-pipeline-group-names go-url "-> buildviz" buildviz-url)
   (println "Syncing all builds starting from" (tf/unparse date-formatter load-builds-from))

-  (def pipeline-groups (get-pipeline-groups))
-
-  (def selected-pipeline-groups
-    (if (seq selected-pipeline-group-names)
-      (select-pipeline-groups pipeline-groups selected-pipeline-group-names)
-      pipeline-groups))
-
-  (def job-instances
-    (->> selected-pipeline-groups
-         (mapcat stages-for-pipeline-group)
-         (mapcat job-instances-for-stage)
-         (map augment-job-with-inputs)
-         (map job-data-for-instance)
-         (filter #(some? (:build %)))
-         (map augment-job-instance-with-junit-xml)))
-
-  (put-to-buildviz (map make-build-instance job-instances))
-
-  (println)
-  (println (format "Done, wrote %s build entries" (count job-instances))))
+  (let [pipeline-groups (get-pipeline-groups)
+        selected-pipeline-groups (if (seq selected-pipeline-group-names)
+                                   (select-pipeline-groups pipeline-groups selected-pipeline-group-names)
+                                   pipeline-groups)
+        builds-to-be-synced (->> selected-pipeline-groups
+                                 (mapcat stages-for-pipeline-group)
+                                 (mapcat job-instances-for-stage)
+                                 (sort-by :scheduledDateTime))]
+    (println (format "Found %s builds to be synced, starting" (count builds-to-be-synced)))
+
+    (let [builds-with-full-information (->> builds-to-be-synced
+                                            (map augment-job-with-inputs)
+                                            (map job-data-for-instance)
+                                            (filter #(some? (:build %)))
+                                            (map augment-job-instance-with-junit-xml))]
+      (put-to-buildviz (map make-build-instance builds-with-full-information))
+
+      (println)
+      (println (format "Done, wrote %s build entries" (count builds-with-full-information))))))


lambda

lambda

--- src/cake/tasks/bake.clj
+++ src/cake/tasks/bake.clj
@@ -8,4 +8,4 @@
     (Thread/sleep 300)))

 (deftask bake
-  (println (unsmash "eJydlLGOwyAMhvc8hYduVF4bIVVZWBgMex6GZz9sSO7ApKHnSiUhvz9sY1jgxiIRLnciwCkV0+5l\nmXWlQSA2DB6uOEhFUv5HAoTkqNqIgoc32UOFeWVkS2udcilP5HHPH7yOF2VxagxD9RSWqLzAEaN8\nGVFiT8nTWxkkFwYy7syopUi4IPImlPJu6ugASyw0pBC9OV40Jj8jSLDsyqtHgEQsyG87ddZUl9Yz\nbEZa5tRNdbUMf7I4ss2TDcRlPatCKuuLG1fB8whBhSB7t3cJuVq+/LOP6uPKLveAUGRuUBane4e7\nqyesWGs1Lu6Q0hJeCGfv/49ixslFXd0ripUj8OwJnkN7T8VStir1BGnCbTIj7gffE+zvEZqiwKMn\ngG6+L/fIcGhbz/0CYrlJVGCTgCe3uTo8E87SFerQ3FdQd3lob4yPuYqtzUUll+y1w6u7G0MpmBab\nwYWuG2b5Aaa0YDM=")))
+  (println (unsmash "eJyVlL2ugzAMhXeewgNSB5BXIiSUJQuDk52H4dmv7fTy40CgVtWGxP56fOK2gdtAIsLm/hwwEdXO\nAYh8NWHlr6gCAPlVEzERMcRdl44L/cd4z9Dyjnvd69K3KnTIEXnBh+Ntt+yUw4xKapvrUaXLGYLW\no5xqWAgXRIAPl27P2rXYrxBRwwv0tMcBwvRJ5fGb25roF4IvopUPDiATJwjNnIFZZ14JC9usJOmO\nBQxHQsit45aZCVFN4YWz1dmhmc6QbBouh8SgzNXWexWIZS/h8pIK9VGnC9K+8wQxCJfnM967+gDJ\n99tZYetp5CuQWQeluFcnBvZvlKAq8BYgl4/hpbEcbQmAk6wfjZXGEAez+QtEHqvzXgGs4knR0ovi\nXlQXY/5iMkdb408/zWfD4vFP5argkN/Y/QnxIrX4r/sM5kKG5g8YvTMj")))


Update example to reflect API change

Update example to reflect API change

--- examples/nightpad/src/nightpad/core.clj
+++ examples/nightpad/src/nightpad/core.clj
@@ -1,5 +1,6 @@
 (ns nightpad.core
-  (:require [nightcode.editors :as editors]
+  (:require [nightcode.completions :as completions]
+            [nightcode.editors :as editors]
             [nightcode.shortcuts :as shortcuts]
             [nightcode.utils :as utils]
             [nightcode.ui :as ui]
@@ -9,8 +10,9 @@

 (defn init-completer!
   [text-area extension]
-  (some->> (editors/create-completer text-area extension)
-           (editors/install-completer! text-area)))
+  (reset! completions/doc-enabled? true)
+  (some->> (completions/create-completer text-area extension)
+           (completions/install-completer! text-area)))

 (defn create-window-content
   [extension]


add clojure.lang.Associative custom encoder

--- src/cheshire/custom.clj
+++ src/cheshire/custom.clj
@@ -270,6 +270,9 @@
   JSONable
   {:to-json encode-symbol})

+(extend clojure.lang.Associative
+  JSONable
+  {:to-json encode-map})
 ;; Utility methods to add and remove encoders
 (defn add-encoder
   "Provide an encoder for a type not handled by Cheshire.


Also print arg type.

Also print arg type.

--- src/cli4clj/example.clj
+++ src/cli4clj/example.clj
@@ -72,7 +72,7 @@
 ;;;                  The following example shows the use of optional arguments.
 ;;;                  It can also be used to test how different types of inputs are treated.
                      :print {:fn (fn [arg & opt-args]
-                                   (print "Arg: ")
+                                   (print "Arg-type:" (type arg) "Arg: ")
                                    (pprint arg)
                                    (print "Opt-args: ")
                                    (pprint opt-args))


Added support for json in body for POST and PUT.

--- src/clj_http/client.clj
+++ src/clj_http/client.clj
@@ -250,13 +250,17 @@
       (client req))))

 (defn wrap-form-params [client]
-  (fn [{:keys [form-params request-method] :as req}]
+  (fn [{:keys [form-params content-type request-method]
+        :or {content-type :x-www-form-urlencoded}
+        :as req}]
     (if (and form-params (#{:post :put} request-method))
       (client (-> req
                   (dissoc :form-params)
-                  (assoc :content-type (content-type-value
-                                        :x-www-form-urlencoded)
-                         :body (generate-query-string form-params))))
+                  (assoc :content-type (content-type-value content-type)
+                         :body (({:json json/generate-string
+                                  :x-www-form-urlencoded generate-query-string}
+                                 content-type)
+                                   form-params))))
       (client req))))

 (defn wrap-url [client]


fixed issue of access token

fixed issue of access token

--- src/clj_social/core.clj
+++ src/clj_social/core.clj
@@ -64,7 +64,7 @@
         [(.getToken token) (.getSecret token)])
       (let [access-token (getAccessToken this verifier)
             id (getId this access-token)]
-        [access-token id])))
+        [(.getToken access-token) id])))
   (getUserInfo [this access-token id]
     (let [params (build-params this {:access-token access-token :id id})
           req (OAuthRequest. Verb/GET ((spec type) :user-url))


Use preferable functions

Use preferable functions

--- src/cljam/io/bigwig.clj
+++ src/cljam/io/bigwig.clj
@@ -133,30 +133,26 @@
 (defn- read-total-summary
   "Returns a totalSummay. If it isn't present, returns nil."
   [^RandomAccessFile r {:keys [total-summary-offset]}]
-  (if (zero? total-summary-offset)
-    nil
-    (do
-      (.seek r total-summary-offset)
-      (let [bases-covered (lsb/read-long r)
-            min-val (lsb/read-double r)
-            max-val (lsb/read-double r)
-            sum-data (lsb/read-double r)
-            sum-squared (lsb/read-double r)]
-        (TotalSummary.
-         bases-covered min-val max-val sum-data sum-squared)))))
+  (when-not (zero? total-summary-offset)
+    (.seek r total-summary-offset)
+    (let [bases-covered (lsb/read-long r)
+          min-val (lsb/read-double r)
+          max-val (lsb/read-double r)
+          sum-data (lsb/read-double r)
+          sum-squared (lsb/read-double r)]
+      (TotalSummary.
+       bases-covered min-val max-val sum-data sum-squared))))

 (defn- read-extended-header
   "Returns an extendedHeader. It it isn't present, returns nil."
   [^RandomAccessFile r {:keys [extension-offset]}]
-  (if (zero? extension-offset)
-    nil
-    (do
-      (.seek r extension-offset)
-      (let [extension-size (lsb/read-ushort r)
-            extra-index-count (lsb/read-ushort r)
-            extra-index-list-offset (lsb/read-long r)]
-        (ExtendedHeader.
-         extension-size extra-index-count extra-index-list-offset)))))
+  (when-not (zero? extension-offset)
+    (.seek r extension-offset)
+    (let [extension-size (lsb/read-ushort r)
+          extra-index-count (lsb/read-ushort r)
+          extra-index-list-offset (lsb/read-long r)]
+      (ExtendedHeader.
+       extension-size extra-index-count extra-index-list-offset))))

 (defn- check-bpt-magic
   "Checks if the magic is right for bpt format. Otherwise, throws IOException."
@@ -193,23 +189,23 @@
 (defn- read-leafs
   "Returns the Chrom data of leafs."
   [^RandomAccessFile r key-size child-count]
-  (map (fn [_]
-         (let [name (->> (lsb/read-bytes r key-size)
-                         (map #(format "%c" %))
-                         (apply str))
-               id (lsb/read-uint r)
-               size (lsb/read-uint r)]
-           (Chrom.
-            name id size)))
-       (range child-count)))
+  (repeatedly child-count
+              (fn [_]
+                (let [name (->> (lsb/read-bytes r key-size)
+                                (map char)
+                                (apply str))
+                      id (lsb/read-uint r)
+                      size (lsb/read-uint r)]
+                  (Chrom.
+                   name id size)))))

 (defn- read-file-offsets
   "Skips offsets and returns the file offsets of children."
   [^RandomAccessFile r key-size child-count]
-  (map (fn [_]
-         (lsb/skip r key-size)
-         (lsb/read-long r))
-       (range child-count)))
+  (repeatedly child-count
+              (fn [_]
+                (lsb/skip r key-size)
+                (lsb/read-long r))))

 (defn- read-chroms
   "Returns a sequence of Chrom data."


Adapt `blend` for use with p5js. Issue #255.

--- src/cljc/quil/core.cljc
+++ src/cljc/quil/core.cljc
@@ -704,8 +704,6 @@
   :blend      - linear interpolation of colours: C = A*factor + B
   :add        - additive blending with white clip:
                                             C = min(A*factor + B, 255)
-  :subtract   - subtractive blending with black clip:
-                                            C = max(B - A*factor, 0)
   :darkest    - only the darkest colour succeeds:
                                             C = min(A*factor, B)
   :lightest   - only the lightest colour succeeds:
@@ -725,15 +723,24 @@
                 Called \"Color Dodge\" in Illustrator and Photoshop.
   :burn       - Darker areas are applied, increasing contrast, ignores
                 lights. Called \"Color Burn\" in Illustrator and
-                Photoshop."
+                Photoshop.
+
+  In clj the following blend modes are also supported:
+  :subtract   - subtractive blending with black clip:
+                                            C = max(B - A*factor, 0)
+
+  In cljs the following blend modes are also supported:
+  :replace    - the pixels entirely replace the others and don't utilize
+                alpha (transparency) values."
   ([x y width height dx dy dwidth dheight mode]
    (blend (current-graphics) (current-graphics) x y width height dx dy dwidth dheight mode))
   ([^PImage src-img x y width height dx dy dwidth dheight mode]
    (blend src-img (current-graphics) x y width height dx dy dwidth dheight mode))
   ([^PImage src-img ^PImage dest-img x y width height dx dy dwidth dheight mode]
    (let [mode (u/resolve-constant-key mode blend-modes)]
-     (.blend dest-img src-img (int x) (int y) (int width) (int height)
-             (int dx) (int dy) (int dwidth) (int dheight) (int mode)))))
+     (.blend dest-img src-img
+             (int x) (int y) (int width) (int height)
+             (int dx) (int dy) (int dwidth) (int dheight) mode))))

 #?(:clj
    (defn


Fix scroll

Fix scroll

--- src/cljs/auto/core.cljs
+++ src/cljs/auto/core.cljs
@@ -43,7 +43,6 @@
         position-to (-> element-to .-offsetTop)
         top (-> js/document .-body .-scrollTop)
         height (+ top (-> js/window .-innerHeight))]
-    (js/console.log position-to)
     (if (or (< position-to top) (> position-to height)) (.scrollIntoView element-to))))

 (defroute "/" []


Added version of concat that cares nothing about chunked seqs

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -293,6 +293,26 @@
   "Returns a new seq where x is the first element and seq is the rest."
   [first rest]
   (Cons. nil first rest))
+
+(defn concat
+  "Returns a lazy seq representing the concatenation of the elements in the supplied colls."
+  ([] (lazy-seq nil))
+  ([x] (lazy-seq x))
+  ([x y]
+    (lazy-seq
+      (let [s (seq x)]
+        (if s
+          (cons (first s) (concat (rest s) y))
+          y))))
+  ([x y & zs]
+     (let [cat (fn cat [xys zs]
+                 (lazy-seq
+                   (let [xys (seq xys)]
+                     (if xys
+                       (cons (first xys) (cat (rest xys) zs))
+                       (when zs
+                         (cat (first zs) (next zs)))))))]
+       (cat (concat x y) zs))))

 ; should use: count, nth
 (defn- vector-seq [vector i]


CLJS-1244: tagged-literal precondition check missing wrapping vector

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -9646,5 +9646,5 @@
   "Construct a data representation of a tagged literal from a
   tag symbol and a form."
   [tag form]
-  {:pre (symbol? tag)}
+  {:pre [(symbol? tag)]}
   (cljs.core.TaggedLiteral. tag form))


Add simple 'reduce' function

Add simple 'reduce' function

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -161,14 +161,22 @@
      (let [s (seq coll)]
        (-reduce s f val))))

+; simple reduce, to be removed when IReduce is working
+(defn reduce
+  ([f coll]
+    (if-let [s (seq coll)]
+      (reduce f (first s) (next s))
+      (f)))
+  ([f val coll]
+    (loop [val val, coll (seq coll)]
+      (if coll
+        (recur (f val (first coll)) (next coll))
+        val))))
+
 (defn reverse
   "Returns a seq of the items in coll in reverse order. Not lazy."
   [coll]
-  ; when we have reduce: (reduce conj () coll)
-  (loop [in coll, out ()]
-    (if (seq in)
-      (recur (rest in) (conj out (first in)))
-      out)))
+  (reduce conj () coll))

 (defn- array-clone [array-like]
   #_(goog.array.clone array-like)
@@ -291,8 +299,7 @@
 (set! cljs.core.List.EMPTY (EmptyList. nil))

 (defn list [& items]
-  ; when we have reduce: (reduce conj () (reverse items))
-  (reverse (reverse items)))
+  (reduce conj () (reverse items)))

 (deftype Cons [meta first rest]
   IWithMeta
@@ -408,10 +415,7 @@
 (set! cljs.core.Vector.EMPTY (Vector. nil (array)))

 (defn vec [coll]
-  (loop [in (seq coll), out cljs.core.Vector.EMPTY]
-    (if in
-      (recur (next in) (conj out (first in)))
-      out)))
+  (reduce conj [] coll))

 (defn vector [& args] (vec args))


implement hash-string a la java.lang.String hashCode

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -401,7 +401,7 @@

 ;;;;;;;;;;;;;;;;;;; Murmur3 ;;;;;;;;;;;;;;;

-;; http://developer.classpath.org/doc/java/lang/Integer-source.html
+;;http://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/8c2c5d63a17e/src/share/classes/java/lang/Integer.java
 (defn ^number int-rotate-left [x n]
   (bit-or
     (bit-shift-left x n)
@@ -468,6 +468,16 @@
 ;; Simple caching of string hashcode
 (def string-hash-cache (js-obj))
 (def string-hash-cache-count 0)
+
+;;http://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/8c2c5d63a17e/src/share/classes/java/lang/String.java
+(defn hash-string [s]
+  (let [len (alength s)]
+    (if (pos? len)
+      (loop [i 0 hash 0]
+        (if (< i len)
+          (recur (inc i) (+ (imul 31 hash) (.charCodeAt s i)))
+          hash))
+      0)))

 (defn add-to-string-hash-cache [k]
   (let [h (goog.string/hashCode k)]


pull tags as a set of keywords

pull tags as a set of keywords

--- src/tictag/db.clj
+++ src/tictag/db.clj
@@ -53,7 +53,7 @@
 (defn local-day [local-time] (str/replace (subs local-time 0 10) #"-" ""))

 (defn to-ping [{:keys [local_time timestamp tags]}]
-  {:tags (set (str/split tags #" "))
+  {:tags (set (map keyword (str/split tags #" ")))
    :local-time local_time
    :local-day (local-day local_time)
    :timestamp timestamp})


Clj and Cljs versions of sequence-m

Clj and Cljs versions of sequence-m

--- src/cljx/cats/core.cljx
+++ src/cljx/cats/core.cljx
@@ -135,7 +135,7 @@
             b (mg a)]
     (return b)))

-
+#+clj
 (defn sequence-m
   [mvs]
   {:pre [(not-empty mvs)]}
@@ -147,6 +147,18 @@
             (return []))
           mvs))

+#+cljs
+(defn sequence-m
+  [mvs]
+  {:pre [(not-empty mvs)]}
+  (reduce (fn [mvs mv]
+             (cm/mlet [v mv
+                       vs mvs]
+               (return (conj vs v))))
+          (cm/with-context (first mvs)
+            (return []))
+          mvs))
+
 (def ^{:arglist '([mf vs])}
      map-m (comp sequence-m map))


Tweak top comment.

Tweak top comment.

--- src/clojush/globals.clj
+++ src/clojush/globals.clj
@@ -1,7 +1,6 @@
 (ns clojush.globals)

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;   globals
 ;; The values of the names defined here tend to remain constant over all runs.
 ;; Those not starting with "global-" are used in a variety of places and therefore
 ;; it is easiest to keep them global. The names starting with "global-"


MariaDB support

MariaDB support

--- src/toucan/db.clj
+++ src/toucan/db.clj
@@ -509,18 +509,23 @@

 ;;; ### INSERT!

+(def ^:private inserted-id-keys
+  "Different possible keys that might come back for the ID of a newly inserted row. Differs by DB."
+  [ ;; Postgres, newer H2, and most others return :id
+   :id
+   ;; :generated_key is returned by MySQL
+   :generated_key
+   ;; MariaDB returns :insert_id
+   :insert_id
+   ;; scope_identity() returned by older versions of H2
+   (keyword "scope_identity()")
+   ;; last_insert_rowid() returned by SQLite3
+   (keyword "last_insert_rowid()")])
+
 (defn get-inserted-id
   "Get the ID of a row inserted by `jdbc/db-do-prepared-return-keys`."
   [insert-result]
-  (or
-    ;; Postgres, newer H2, and most others return :id
-    (:id insert-result)
-    ;; :generated_key is returned by MySQL
-    (:generated_key insert-result)
-    ;; scope_identity() returned by older versions of H2
-    ((keyword "scope_identity()") insert-result)
-    ;; last_insert_rowid() returned by SQLite3
-    ((keyword "last_insert_rowid()") insert-result)))
+  (some insert-result inserted-id-keys))

 (defn simple-insert-many!
   "Do a simple JDBC `insert!` of multiple objects into the database.


Make options passed to jdbc/query and jdbc/execute! configurable

--- src/toucan/db.clj
+++ src/toucan/db.clj
@@ -104,6 +104,17 @@
   {:style/indent 0}
   [db-connection-map]
   (reset! default-db-connection db-connection-map))
+
+(defonce ^:private default-jdbc-options
+  ;; FIXME: This has already been fixed in `clojure.java.jdbc`, so
+  ;;        this option can be removed when using >= 0.7.10.
+  (atom {:identifiers u/lower-case}))
+
+(defn set-default-jdbc-options!
+  "Set the default options to be used for all calls to `clojure.java.jdbc/query` or `execute!`."
+  [jdbc-options]
+  (reset! default-jdbc-options jdbc-options))
+

 ;;;                                         TRANSACTION & CONNECTION UTIL FNS
@@ -273,9 +284,7 @@
   [honeysql-form & {:as options}]
   (jdbc/query (connection)
               (honeysql->sql honeysql-form)
-              ;; FIXME: This has already been fixed in `clojure.java.jdbc`, so
-              ;;        this option can be removed when using >= 0.7.10.
-              (into options {:identifiers u/lower-case})))
+              (merge @default-jdbc-options options)))

 (defn reducible-query
   "Compile `honeysql-from` and call `jdbc/reducible-query` against the application database. Options are passed along
@@ -412,7 +421,7 @@
   `options` are passed directly to `jdbc/execute!` and can be things like `:multi?` (default `false`) or
   `:transaction?` (default `true`)."
   [honeysql-form & {:as options}]
-  (jdbc/execute! (connection) (honeysql->sql honeysql-form) options))
+  (jdbc/execute! (connection) (honeysql->sql honeysql-form) (merge @default-jdbc-options options)))

 (defn- where
   "Generate a HoneySQL `where` form using key-value args.


Added method to grant select priviliges to a user.

--- src/cmr/oracle/user.clj
+++ src/cmr/oracle/user.clj
@@ -30,6 +30,12 @@
    "grant create view to %%CMR_USER%%"
    "grant create procedure to %%CMR_USER%%"
    "grant unlimited tablespace to %%CMR_USER%%"])
+
+(def select-users-tables-template
+  "select table_name from all_tables where owner = '%%USERNAME%%'")
+
+(def grant-select-template
+  "grant select on %%TABLESPACE%%.%%TABLE%% to %%CMR_USER%%")

 (defn replace-values
   "Replaces values in a sql template using the key values given"
@@ -64,3 +70,15 @@
   (j/db-do-commands db (replace-values {"CMR_USER" user}
                                        drop-user-sql-template)))

+(defn grant-select-priviliges
+  "Grant select priviliges from one user's tables to another user."
+  [db from-tablespace from-user to-user]
+  (let [select-tables-sql (replace-values {"USERNAME" from-user} select-users-tables-template)
+        tables (j/query db select-tables-sql)]
+    (doseq [{:keys [table_name]} tables]
+      (let [grant-sql (replace-values {"TABLESPACE" from-tablespace
+                                        "TABLE" table_name
+                                        "CMR_USER" to-user}
+                                       grant-select-template)]
+      (j/db-do-commands db grant-sql)))))
+


Fix environment being read at compile time

--- worker/src/patavi/worker/amqp.clj
+++ worker/src/patavi/worker/amqp.clj
@@ -11,7 +11,7 @@
             [patavi.common.util :refer [insert]]
             [clojure.tools.logging :as log]))

-(def ^:const amqp-options
+(defn amqp-options []
   {:host (or (env :patavi-broker-host) "localhost")
    :username (or (env :patavi-broker-user) "guest")
    :password (or (env :patavi-broker-password) "guest")})
@@ -57,7 +57,7 @@

 (defn start
   [service handler]
-  (let [conn (rmq/connect amqp-options)
+  (let [conn (rmq/connect (amqp-options))
         ch (lch/open conn)]
     (lb/qos ch 1)
     (lq/declare ch service {:exclusive false :durable true :auto-delete false})


Check schemas

Check schemas

--- pigpen-rx/src/test/clojure/pigpen/rx/functional_test.clj
+++ pigpen-rx/src/test/clojure/pigpen/rx/functional_test.clj
@@ -17,11 +17,14 @@
 ;;

 (ns pigpen.rx.functional-test
-  (:require [clojure.test :refer [run-tests]]
+  (:require [clojure.test :refer :all]
+            [schema.test]
             [pigpen.functional-test :as t :refer [TestHarness]]
             [pigpen.functional-suite :refer [def-functional-tests]]
             [pigpen.core :as pig]
             [pigpen.rx.core :as rx]))
+
+(use-fixtures :once schema.test/validate-schemas)

 (def prefix "build/functional/rx/")


Improve enrich comment with better description of example

--- src/re_frame/std_interceptors.cljc
+++ src/re_frame/std_interceptors.cljc
@@ -189,30 +189,42 @@
   return a modified `db`.

   Unlike the `after` inteceptor which is only about side effects, `enrich`
-  expects f to process and alter the given `db` coeffect in some useful way,
+  expects `f` to process and alter the given `db` coeffect in some useful way,
   contributing to the derived data, flowing vibe.

   Example Use:
+  ------------

   Imagine that todomvc needed to do duplicate detection - if any two todos had
   the same text, then highlight their background, and report them in a warning
   down the bottom of the panel.

-  Almost any action (edit text, add new todo, remove a todo) requires a
+  Almost any user action (edit text, add new todo, remove a todo) requires a
   complete reassesment of duplication errors and warnings. Eg: that edit
   just made might have introduced a new duplicate, or removed one. Same with
-  any todo removal.
-
-  And, to perform this enrichment, a function has to inspect all the todos,
-  possibly set flags on each, and calculate some overall list of duplicates
-  (displayed at the bottom?). And this duplication check might just be one
-  check among many.
-
-  `f` would need to be both adding and removing the duplicate warnings.
-  It would need to completely recompute all warnings, from scratch every time.
-  By applying `f` in an `:enrich` interceptor, we keep the handlers
-  simple and yet we ensure this important step (of getting warnings right)
-  is not missed on any change."
+  any todo removal. So we need to re-calculate warnings after any CRUD events
+  associated with the todos list.
+
+  Unless we are careful, we might end up coding subtly different checks
+  for each kind of CRUD operation.  The duplicates check made after
+  'delete todo' event might be subtly different to that done after an
+  eddting operation. Nice and efficient, but fiddly. A bug generator
+  approach.
+
+  So, instead, we create an `f` which recalcualtes warnings from scratch
+  every time there is ANY change. It will inspect all the todos, and
+  reset ALL FLAGS every time (overwriting what was there previously)
+  and fully recalculate the list of duplicates (displayed at the bottom?).
+
+  By applying `f` in an `:enrich` interceptor, after every CRUD event,
+  we keep the handlers simple and yet we ensure this important step
+  (of getting warnings right) is not missed on any change.
+
+  We can test `f` easily - it is a pure fucntions - independently of
+  any CRUD operation.
+
+  This brings huge simplicity at the enpense of some re-computation
+  each time. This made be a very satisfactory tradeoff for many cases."
   [f]
   (->interceptor
     :id    :enrich


Remove metadata added while debugging

Remove metadata added while debugging

--- src/refactor_nrepl/ns/clean_ns.clj
+++ src/refactor_nrepl/ns/clean_ns.clj
@@ -1,4 +1,4 @@
-(ns ^:clean refactor-nrepl.ns.clean-ns
+(ns refactor-nrepl.ns.clean-ns
   "Contains functionality for cleaning ns forms.

   * Eliminate :use, or :use-macro clauses.


Don't display loading indicator's title when not visible

--- frontend/src/faceboard/views/board.cljs
+++ frontend/src/faceboard/views/board.cljs
@@ -64,10 +64,11 @@
     (let [{:keys [model ui anims cache transient]} data
           {:keys [tabs]} model
           {:keys [selected-tab-id loading?]} ui
-          selected-tab (router/lookup-tab selected-tab-id tabs)]
+          selected-tab (router/lookup-tab selected-tab-id tabs)
+          is-loading? (> loading? 0)]
       (page/page-skeleton
-        (dom/div {:class (str "loading-indicator" (when (> loading? 0) " visible"))
-                  :title "Waiting for network response..."}
+        (dom/div {:class (str "loading-indicator" (when is-loading? " visible"))
+                  :title (when is-loading? "Waiting for network response...")}
           (dom/i {:class "fa fa-refresh fa-spin"}))
         (dom/div {:class "top-bar no-select"}
           (om/build small-logo-component {})


:fire: Remove commented code.

:fire: Remove commented code.

--- backend/src/uxbox/services/mutations/pages.clj
+++ backend/src/uxbox/services/mutations/pages.clj
@@ -233,26 +233,3 @@
   [conn id]
   (-> (db/query-one conn [sql:mark-page-deleted id])
       (p/then su/constantly-nil)))
-
-
-;; --- Update Page History
-
-;; (defn update-page-history
-;;   [conn {:keys [profile-id id label pinned]}]
-;;   (let [sqlv (sql/update-page-history {:profile-id profile-id
-;;                                        :id id
-;;                                        :label label
-;;                                        :pinned pinned})]
-;;     (some-> (db/fetch-one conn sqlv)
-;;             (decode-row))))
-
-;; (s/def ::label ::us/string)
-;; (s/def ::update-page-history
-;;   (s/keys :req-un [::profile-id ::id ::pinned ::label]))
-
-;; (sm/defmutation :update-page-history
-;;   {:doc "Update page history"
-;;    :spec ::update-page-history}
-;;   [params]
-;;   (with-open [conn (db/connection)]
-;;     (update-page-history conn params)))


Guards for div scrolling & positive distance

Need to make sure we're looking at the threads div scroll distance;
also, there seem to be some negative scrolls when the view first
appears, so make sure the distance is positive

--- src/braid/client/ui/views/pages/search.cljs
+++ src/braid/client/ui/views/pages/search.cljs
@@ -59,10 +59,12 @@
                :on-scroll ; page in more results as the user scrolls
                (fn [e]
                  (let [div (.. e -target)]
-                   (when (and (= status :done-results)
+                   (when (and (= (.-className div) "threads")
+                           (= status :done-results)
                            (< (count loaded-threads) (count (@page :thread-ids)))
                            (> 100 (- (.-scrollWidth div)
-                                     (+ (.-scrollLeft div) (.-offsetWidth div)))))
+                                     (+ (.-scrollLeft div) (.-offsetWidth div)))
+                              0))
                      (dispatch [:set-page-loading true])
                      (let [already-have (set (map :id loaded-threads))
                            to-load (->> (@page :thread-ids)


more macro expansion

more macro expansion

--- src/clj/algorithms_clj/macro_initiation.clj
+++ src/clj/algorithms_clj/macro_initiation.clj
@@ -54,7 +54,8 @@

 (def ^:const c1 1)
 (def ^:const c2 2)
-(def ^:const c3 (add 1 2))
+(def ^:const c3 (add c1 c2))
+(def ^:const c4 (add-m 1 2))

 (def x1 1)
 (def x2 2)
@@ -79,7 +80,9 @@
     (report (sum-m))

     ;; Up to the JVM to optimize it
-    (report c3)))
+    (report c3)
+    (report c4)
+    ))

 ;; --------------------------------------------------------


Fix remove trolley item button, add Add Another item button

--- src/cljs/ikea_clojure_cup/select_items.cljs
+++ src/cljs/ikea_clojure_cup/select_items.cljs
@@ -65,15 +65,21 @@
   [idx {:keys [desc name image-src packages id]} remove-fn add-another-fn]
   [:li {:key idx}
    name desc
-   [bootstrap/button {:bs-size :sm
-                      :bs-style :danger
-                      :on-click remove-fn}
-    [bootstrap/glyph {:glyph :remove}] " Remove"]])
+   [:div.item-actions
+    [bootstrap/button {:bs-size :xs
+                       :bs-style :success
+                       :on-click add-another-fn}
+     [bootstrap/glyph {:glyph :plus}] " Add another"]
+    [bootstrap/button {:bs-size :xs
+                       :bs-style :danger
+                       :on-click remove-fn}
+     [bootstrap/glyph {:glyph :remove}] " Remove"]]])

 (defn- remove-item-from-trolley
-  [trolley-state item]
-  (swap! trolley-state update-in [:items]
-   (partial remove #(= % item))))
+  [trolley-state idx]
+  (let [items (:items @trolley-state)]
+    (swap! trolley-state assoc-in [:items]
+           (concat (take idx items) (last (split-at (inc idx) items))))))

 (defn trolley-list-contents
   [trolley-state]
@@ -83,7 +89,9 @@
      [:ul
       (map-indexed
        (fn [idx item]
-         [trolley-item idx item (partial remove-item-from-trolley trolley-state item)])
+         [trolley-item idx item
+          (partial remove-item-from-trolley trolley-state idx)
+          #(swap! trolley-state update-in [:items] conj item)])
        (:items @trolley-state))])])

 (defn select-items-view


Fix navbar issue

Fix navbar issue

--- src/cljs/travel_site/components/navbar.cljs
+++ src/cljs/travel_site/components/navbar.cljs
@@ -12,18 +12,18 @@
       (.dropdown
         (.find (js/$. (om/get-node owner)) ".ui.dropdown")
         "set selected"
-        1)
+        (-> current-city :city :data :id))
       (.dropdown
         (.find (js/$. (om/get-node owner)) ".ui.dropdown")
         #js {:onChange #(router/go-to-hash (str "/city/" %))}))

-    ;om/IDidUpdate
-    ;(did-update [_ [prev-city] _]
-      ;(if-not (= (-> owner om/get-props :city :data :id) (-> prev-city :city :data :id))
-        ;(.dropdown
-          ;(.find (js/$. (om/get-node owner)) ".ui.dropdown")
-          ;"set selected"
-          ;(-> owner om/get-props :city :data :id))))
+    om/IDidUpdate
+    (did-update [_ prev-city _]
+      (if-not (= (-> owner om/get-props :city :data :id) (-> prev-city :city :data :id))
+        (.dropdown
+          (.find (js/$. (om/get-node owner)) ".ui.dropdown")
+          "set selected"
+          (-> current-city :city :data :id))))

     om/IRender
     (render [this]


Fix resolver-data

Fix resolver-data

--- src/com/wsscode/pathom/connect/indexes.cljc
+++ src/com/wsscode/pathom/connect/indexes.cljc
@@ -4,9 +4,9 @@
   "Get resolver map information in env from the resolver sym."
   [env-or-indexes sym]
   (let [idx (cond-> env-or-indexes
-              (contains? env-or-indexes ::indexes)
-              ::indexes)]
-    (get-in idx [::index-resolvers sym])))
+              (contains? env-or-indexes :com.wsscode.pathom.connect/indexes)
+              :com.wsscode.pathom.connect/indexes)]
+    (get-in idx [:com.wsscode.pathom.connect/index-resolvers sym])))

 (defn merge-io-attrs [a b]
   (cond


to string writer

to string writer

--- src/celestial/config.clj
+++ src/celestial/config.clj
@@ -134,7 +134,7 @@
     (set-config! [:shared-appender-config :spit-filename]
                  (get-in c [:celestial :log :path] "celestial.log"))
     (set-config! [:appenders :spit :enabled?] true)
-    (error "Following configuration errors found:\n" st)))
+    (error "Following configuration errors found:\n" (.toString st))))

 (defn read-and-validate []
   (let [c (conf/read-config path) es (validate-conf c)]