exclude select-keys in re-db.d

exclude select-keys in re-db.d

--- src/re_db/d.cljs
+++ src/re_db/d.cljs
@@ -1,5 +1,5 @@
 (ns re-db.d
-  (:refer-clojure :exclude [get get-in contains?])
+  (:refer-clojure :exclude [get get-in contains? select-keys])
   (:require [re-db.core :as d])
   (:require-macros [re-db.d]))


fix broken .exist call

fix broken .exist call

--- src/main/shadow/cljs/devtools/server/npm_deps.clj
+++ src/main/shadow/cljs/devtools/server/npm_deps.clj
@@ -157,7 +157,7 @@
           (into ["cmd" "/C"] full-cmd)
           full-cmd)

-        _ (when-not (.exist install-package-json)
+        _ (when-not (.exists install-package-json)
             (io/make-parents install-package-json)
             (spit install-package-json "{}"))


Updated db walking code to traverse FKs

Updated db walking code to traverse FKs

--- src/sql_walker/core.clj
+++ src/sql_walker/core.clj
@@ -2,6 +2,9 @@
   (:require [clojure.string :as s]
             [clojure.java.jdbc :as j]
             [sql-walker.config :as config]))
+
+(def nl "
+")

 (def db config/db)

@@ -10,8 +13,10 @@
   (j/query db query))

 (def query q)
+
 (def qm
   (memoize q))
+
 (defn s
   [t]
   (q (str "select * from " t)))
@@ -31,7 +36,7 @@

 (def entity-tables '("AcdhhApplicationComment" "AcdhhAZTEDP_Applications" "AcdhhContacts" "AcdhhEquipment" "AcdhhEquipmentHistory" "AcdhhLicensure_ApplicationDeficiencies" "AcdhhLicensure_ApplicationFiles" "AcdhhLicensure_Applications" "AcdhhTransactionAdditionalReasons" "AcdhhTransactions" "AcdhhVouchers"))

-(def query-get-foreign-key-sql
+(def query-get-foreign-keys-sql
   (str
 "    SELECT"
 "    FK_Table = FK.TABLE_NAME,"
@@ -67,6 +72,8 @@
       query-get-foreign-key-sql
       " WHERE FK.TABLE_NAME = '" t "'")))

+
+
 (defn query-get-primary-key
   [t]
   (qm (str
@@ -75,6 +82,7 @@
        " on tc.constraint_name = cu.constraint_name"
        " where tc.table_name = '" t "'"
        " and constraint_type = 'PRIMARY KEY'")))
+

 (defn query-get-columns
   [t]
@@ -104,31 +112,58 @@
   [t]
   (not (is-entity? t)))

+(defn sw-get-foreign-key
+  [t col]
+  (first (filter (fn [fk] (= (:fk_column fk) col)) (query-get-constraints t))))
+
 (defn walk-database
   [start-t]
-  (let [already-walked []
-        inserted-values {}]
+  (let [already-walked (transient [])
+        inserted-values (transient {})]
     (defn walk-table
       [t]
+      (defn get-inserted-value
+        "Retrieves the primary key of an inserted entity"
+        [t]
+        (print "get-inserted-value " t nl))
+
+      (defn get-lookup-value
+        [t]
+        (print "get-lookup-value " t nl))
+
+      (defn query-get-parent-table
+        [t col]
+        (print "query-get-parent-table " t col nl))
+
+      (defn get-lookup-value
+        [t]
+        (print "get-lookup-value " t nl))
+      (defn deal-with-primitive
+        [t col]
+        (print "deal with primitive " t col nl))
       (defn deal-with-pk
         [t col]
-        nil)
+        (print "deal with pk: " t col nl))
       (defn deal-with-fk
         [t col]
-        (case
-            (is-entity? (query-get-parent-table t col))
-          (if (.contains already-walked t)
-            (get-inserted-value t)
-            (walk-table (query-get-parent-table t col)))
-          (is-lookup? t)
-          (get-lookup-value )))
+        (print "deal with fk: " t col nl)
+        (let [parent (:pk_table (sw-get-foreign-key t (:column_name col)))]
+          (cond
+            (is-entity? parent)
+            (if (.contains (persistent! already-walked) parent)
+              (get-inserted-value parent)
+              (walk-table parent))
+            (is-lookup? t) (get-lookup-value parent))))
       (defn deal-with-col
-        [t col]
-        (case (is-pk? col) (deal-with-pk t col)
-              (is-fk? col) (deal-with-fk-col t col)
-              :else (deal-with-primitive-col t col)))
+        [col]
+        (cond (is-pk? t col) (deal-with-pk t col)
+              (is-fk? t col) (deal-with-fk t col)
+              :else (deal-with-primitive t col)))
+
       (let [cols  (query-get-columns start-t)]
-        ()))))
+        (map deal-with-col cols)))
+    (walk-table start-t)))
+

 ;; from https://stackoverflow.com/questions/925738/how-to-find-foreign-key-dependencies-in-sql-server
 ;;   SELECT


Point to CoreMIDI4J rather than MMJ.

Point to CoreMIDI4J rather than MMJ.

--- src/afterglow/controllers/ableton_push.clj
+++ src/afterglow/controllers/ableton_push.clj
@@ -1570,9 +1570,13 @@

   Initializes the display, and starts the UI updater thread. Since
   SysEx messages are required for updating the display, if you are on
-  a Mac, you must install
-  [mmj](http://www.humatic.de/htools/mmj.htm) to provide a
-  working implementation.
+  a Mac, you must
+  install [CoreMIDI4J](https://github.com/DerekCook/CoreMidi4J) to
+  provide a working implementation. (If you need to work with Java
+  1.6, you can instead
+  use [mmj](http://www.humatic.de/htools/mmj.htm), but that is no
+  longer developed, and does not support connecting or disconnecting
+  MIDI devices after Java has started.)

   If you have more than one Ableton Push connected, or have renamed
   how it appears in your list of MIDI devices, you need to supply a


Reorg, fix name mess

Reorg, fix name mess

--- src/angelic/search/implicit/dash_astar.clj
+++ src/angelic/search/implicit/dash_astar.clj
@@ -55,6 +55,7 @@
 ;; TODO TODO: fix names.
 ;; TODO: turn kill back on

+;; --> TODO: merge stubs and subproblems!

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

@@ -104,7 +105,7 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;      Tree Summarizers      ;;;;;;;;;;;;;;;;;;;;;;;;;;

-(declare sp-ts get-stub-output norm-name)
+(declare sp-ts get-stub-output stub-name sp-name tree-summarizer)

 (defprotocol TreeSummarizer
   (ts-stub [ts])
@@ -122,7 +123,7 @@
               (ts-stub [ts] stb)
               (subsuming-sps [ts] (keys subsuming-sp-set))
               (add-subsuming-sp! [ts subsuming-sp]
-                (util/assert-is (= (norm-name (stub-name stb)) (norm-name (sp-name subsuming-sp))))
+                (util/assert-is (= (stub-name stb) (sp-name subsuming-sp)))
                 (when-not (.containsKey subsuming-sp-set subsuming-sp)
                   (.put subsuming-sp-set subsuming-sp true)
                   (summaries/connect-subsumed! (sp-ts subsuming-sp) ts)))
@@ -162,7 +163,7 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Used by stubs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-
+(declare stub)
 ;; Note: putting ts stuff here rather than watching above ensures things happen
 ;; in desired order.
 ;; TODO: set stub to -inf here, simplify other code?
@@ -273,7 +274,8 @@
   Subproblem (stub            [s] stb)
              (output-set      [s] out-set)
              (terminal?       [s] term?)
-             (refine-input    [s ni] (ri-fn s ni)))
+             (refine-input    [s ni] #_ (ri-fn s ni)
+                              (let [ret  (ri-fn s ni)] (util/assert-is (= (stub-name stb) (stub-name ret))) ret)))

 ;; Note: summary-fn should take subsuming-bound into account.
 (defn- make-simple-subproblem [stub out-set terminal? summary-fn ri-fn]
@@ -292,98 +294,19 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     Wrappers     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;     Output Collection     ;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defn oc-name [inner-name] [:OC inner-name])
-
-(declare make-output-collecting-subproblem)
-(defn- make-output-collecting-stub [inner-stub]
-  (assert (not (= (first (stub-name inner-stub)) :OC)))
-  (assert (not (= (first (stub-name inner-stub)) :SA)))
-  (make-wrapping-stub
-   [(oc-name (stub-name inner-stub)) (input-set inner-stub)]
-   inner-stub make-output-collecting-subproblem))
-
-(defn- =-state-sets [s1 s2]
-  (util/assert-is (= (state/current-context s1) (state/current-context s2)) "%s" [s1 s2])
-  (= s1 s2))
-
-(defn- make-output-collecting-subproblem [stb inner-sp]
-  (let [ret (traits/reify-traits
-             [summaries/or-summarizable
-              (simple-subproblem stb (output-set inner-sp) false
-                #(doto (if (= (input-set stb) %2) stb (refine-input inner-sp %2))
-                   (-> stub-name first #{:SA :OC} assert)))])] ;Needed when SA off
-    (connect-and-watch! ret inner-sp
-      (fn child-watch [o]
-        (if (=-state-sets (output-set inner-sp) (output-set o))
-          (do (connect-and-watch! ret o child-watch)
-              (summaries/summary-changed! ret))
-          (let [c (if (#{:SA :OC} (first (sp-name o))) (stub o) (make-output-collecting-stub (stub o)))]
-            (add-sp-child-stub! ret c false)))))
-    ret))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;     State Abstraction     ;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defn sa-name [inner-name] [:SA inner-name])
-
-(declare make-state-abstracted-subproblem)
-
-(defn- make-eager-state-abstracted-stub [inner-stub in-set]
-  (make-wrapping-stub
-   [(sa-name (stub-name inner-stub)) in-set]
-   inner-stub make-state-abstracted-subproblem))
-
-;; tODO: force ts? reward?
-(defn- make-deliberate-state-abstracted-stub [inner-stub in-set]
-  (if-let [out (get-stub-output inner-stub)]
-    (let [done? (atom false)
-          ret
-          (traits/reify-traits
-           [(simple-stub [:SA (stub-name inner-stub) in-set] in-set)]
-           summaries/Summarizable
-           (summarize [s]
-            (if @done? summary/+worst-simple-summary+
-                (summary/make-live-simple-summary
-                 (summary/max-reward (summaries/summary (sp-ts out))) s)))
-           Evaluable
-           (evaluate! [s] (reset! done? true)
-            (set-stub-output! s (make-state-abstracted-subproblem s out))))]
-      (summaries/connect! ret out)
-      ret)
-    (make-eager-state-abstracted-stub inner-stub in-set)))
-
-
-(defn- make-state-abstracted-stub [inner-stub in-set]
-  ((case *state-abstraction*
-     :eager make-eager-state-abstracted-stub
-     :deliberate make-deliberate-state-abstracted-stub)
-   inner-stub in-set))
-
-
-;; Note: subsumed subproblems can have different irrelevant vars
-(defn- make-state-abstracted-subproblem [stb inner-sp]
-  (let [in  (input-set stb)
-        out (state/transfer-effects in (output-set inner-sp))
-        ri-fn #(if (=-state-sets %2 in) stb (refine-input inner-sp %2))
-        ret (traits/reify-traits
-             [summaries/or-summarizable (simple-subproblem stb out (terminal? inner-sp) ri-fn)])]
-    (connect-and-watch! ret inner-sp
-      (fn [o] (add-sp-child-stub! ret (make-state-abstracted-stub (stub o) in) true)))
-    ret))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;     Core Subproblems     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      Names       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn atomic-name [fs] [:Atomic fs])
+
+(declare oc-name sa-name)
+(defn wrapped-atomic-name [fs]
+  (let [in  (atomic-name fs)
+        mid (if *collect-equal-outputs* (oc-name in) in)]
+    (if *state-abstraction* (sa-name mid) mid)))
+
 (defn pair-name [l r] [:Pair l r])

 (defn left-factor [is]
@@ -396,16 +319,16 @@
 (defn- make-fs-seq-name [fs-seq]
   (assert (seq fs-seq))
   ((if *left-recursive* left-factor right-factor)
-   (map atomic-name fs-seq)))
+   (map wrapped-atomic-name fs-seq)))

 ;; TODO: flatten as well?
-(defn norm-name [n]
-  (case (first n)
-    :Atomic n
-    :Pair   [:Pair (norm-name (nth n 1)) (norm-name (nth n 2))]
-    :SA     (norm-name (second n))
-    :OC     (norm-name (second n))))
-
+(comment
+  (defn norm-name [n]
+   (case (first n)
+     :Atomic n
+     :Pair   [:Pair (norm-name (nth n 1)) (norm-name (nth n 2))]
+     :SA     (norm-name (second n))
+     :OC     (norm-name (second n)))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;      Atomic       ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@@ -455,31 +378,8 @@
             (do (reset! state :go) (summaries/summary-changed! s))))))))

-;; Note: we must always wrap in S-A stub to get effects out of logger.
-(defmethod get-stub :Atomic [[_ fs :as n] inp-set]
-  (let [cache-key [n (if *state-abstraction* (fs/extract-context fs inp-set) inp-set)]
-        output-collect #(if *collect-equal-outputs* (make-output-collecting-stub %) %)
-        make-stub #(output-collect (make-atomic-stub n %))]
-    (if-let [^HashMap dc *decompose-cache*]
-      (if *state-abstraction*
-        (let [stub (util/cache-with dc cache-key (make-stub (fs/get-logger fs inp-set)))]
-          (make-state-abstracted-stub stub inp-set))
-        (util/cache-with dc cache-key (make-stub inp-set)))
-      (make-stub inp-set))))
-
-;; TO do names properly, outers should always guard inners. ?
-;;
-(comment
- (defmethod get-stub :OC [[_ inner-n :as n] inp-set]
-            (make-output-collecting-stub (get-stub inner-n inp-set)))
-
-;; Gotta go all the way in.
- (defmethod get-stub :SA [[_ inner-n :as n] inp-set]
-            (make-state-abstracted-stub (get-stub inner-n (fs/get-logger )))
-
-            (make-output-collecting-stub (get-stub inner-n inp-set))))
-
-
+(defmethod get-stub :Atomic [[_ fs :as n] inp-set]
+  (make-atomic-stub n (if *state-abstraction* (fs/get-logger fs inp-set) inp-set)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;   Sequences    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -564,6 +464,115 @@
   (make-pair-stub1 n (get-stub left-name inp) #(get-stub right-name %)))

+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;     Wrappers     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;     Output Collection     ;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn oc-name [inner-name] [:OC inner-name])
+
+(declare make-output-collecting-subproblem)
+(defn- make-output-collecting-stub [inner-stub]
+  (assert (not (= (first (stub-name inner-stub)) :OC)))
+  (assert (not (= (first (stub-name inner-stub)) :SA)))
+  (make-wrapping-stub
+   [(oc-name (stub-name inner-stub)) (input-set inner-stub)]
+   inner-stub make-output-collecting-subproblem))
+
+(defn- =-state-sets [s1 s2]
+  (util/assert-is (= (state/current-context s1) (state/current-context s2)) "%s" [s1 s2])
+  (= s1 s2))
+
+(defn- make-output-collecting-subproblem [stb inner-sp]
+  (let [ret (traits/reify-traits ;; TODO: can we use make-simple-sub?
+             [summaries/or-summarizable
+              (simple-subproblem stb (output-set inner-sp) false
+                (fn [s ni]
+                  (if (= (input-set stb) ni)
+                    stb
+                    (if (= :Atomic (-> stb stub-name second first))
+                      (let [ret (get-stub (stub-name stb) ni)]
+                        (add-subsuming-sp! (tree-summarizer ret) inner-sp)
+                        ret)
+                      (make-output-collecting-stub (refine-input inner-sp ni))))))])]
+    (connect-and-watch! ret inner-sp
+      (fn child-watch [o]
+        (if (=-state-sets (output-set inner-sp) (output-set o))
+          (do (connect-and-watch! ret o child-watch)
+              (summaries/summary-changed! ret))
+          (let [c (if (#{:SA :OC} (first (sp-name o))) (stub o) (make-output-collecting-stub (stub o)))]
+            (add-sp-child-stub! ret c false)))))
+    ret))
+
+(defn get-cache-key [atomic-name inp-set]
+  [atomic-name
+   (if *state-abstraction*
+     (util/match [[:Atomic ~fs] atomic-name] (fs/extract-context fs inp-set))
+     inp-set)])
+
+(defmethod get-stub :OC [[_ inner-n :as n] inp-set]
+  (let [make-stub #(make-output-collecting-stub (get-stub inner-n inp-set))]
+    (if-let [^HashMap dc *decompose-cache*]
+      (util/cache-with dc (get-cache-key inner-n inp-set) (make-stub))
+      (make-stub))))
+
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;     State Abstraction     ;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn sa-name [inner-name] [:SA inner-name])
+
+(declare make-state-abstracted-subproblem)
+
+(defn- make-eager-state-abstracted-stub [inner-stub in-set]
+  (make-wrapping-stub
+   [(sa-name (stub-name inner-stub)) in-set]
+   inner-stub make-state-abstracted-subproblem))
+
+;; tODO: force ts? reward?
+(defn- make-deliberate-state-abstracted-stub [inner-stub in-set]
+  (if-let [out (get-stub-output inner-stub)]
+    (let [done? (atom false)
+          ret
+          (traits/reify-traits
+           [(simple-stub [:SA (stub-name inner-stub) in-set] in-set)]
+           summaries/Summarizable
+           (summarize [s]
+            (if @done? summary/+worst-simple-summary+
+                (summary/make-live-simple-summary
+                 (summary/max-reward (summaries/summary (sp-ts out))) s)))
+           Evaluable
+           (evaluate! [s] (reset! done? true)
+            (set-stub-output! s (make-state-abstracted-subproblem s out))))]
+      (summaries/connect! ret out)
+      ret)
+    (make-eager-state-abstracted-stub inner-stub in-set)))
+
+
+(defn- make-state-abstracted-stub [inner-stub in-set]
+  (assert (= :OC (first (stub-name inner-stub))))
+  ((case *state-abstraction*
+     :eager make-eager-state-abstracted-stub
+     :deliberate make-deliberate-state-abstracted-stub)
+   inner-stub in-set))
+
+
+;; Note: subsumed subproblems can have different irrelevant vars
+(defn- make-state-abstracted-subproblem [stb inner-sp]
+  (let [in  (input-set stb)
+        out (state/transfer-effects in (output-set inner-sp))
+        ri-fn #(if (=-state-sets %2 in) stb (make-state-abstracted-stub (refine-input inner-sp %2) %2))
+        ret (traits/reify-traits
+             [summaries/or-summarizable (simple-subproblem stb out (terminal? inner-sp) ri-fn)])]
+    (connect-and-watch! ret inner-sp
+      (fn [o] (add-sp-child-stub! ret (make-state-abstracted-stub (stub o) in) true)))
+    ret))
+
+(defmethod get-stub :SA [[_ inner-n :as n] inp-set]
+  (make-state-abstracted-stub (get-stub inner-n inp-set) inp-set))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Planning ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -597,6 +606,8 @@
      choice-fn local? evaluate!
      #(let [n (fs/fs-name (second (sp-name %)))] (when-not (= (first n) :noop) n)))))

+
+
 ;; (do (use '[angelic env hierarchy] 'angelic.domains.nav-switch 'angelic.search.implicit.fah-astar-expand 'angelic.search.implicit.fah-astar-eval 'angelic.search.implicit.dash-astar 'angelic.domains.discrete-manipulation) (require '[angelic.search.explicit.hierarchical :as his]))

 ;; (do (use '[angelic env hierarchy] 'angelic.domains.nav-switch  'angelic.search.implicit.dash-astar 'angelic.domains.discrete-manipulation) (require '[angelic.search.explicit.hierarchical :as his]))


hide sm box when stats plugin is not enabled

--- src/cljs/salava/admin/ui/stats_helper.cljs
+++ src/cljs/salava/admin/ui/stats_helper.cljs
@@ -323,6 +323,7 @@
          [:div])]]])))

 (defn social-media-box [state]
+ (when (some #(= "extra/stats" %) (session/get :plugins))
   (let [data-atom (atom {:value {} :ctime nil})
         {:keys [id value ctime]} @data-atom
         {:keys [facebook linkedin pinterest twitter]} value
@@ -385,4 +386,4 @@
                  (path-for url true)
                  {:handler (fn [data]
                               (reset! data-atom data))}))))
-       500))})))
+       500))}))))


refactor to use show variable

refactor to use show variable

--- src/lights/my_show.clj
+++ src/lights/my_show.clj
@@ -241,9 +241,9 @@

 (defn light-sawtooth
   "Change light according to sawtooth osc"
-  [beat-ratio]
+  []
   (let [light-param (params/build-oscillated-param
-    (oscillators/sawtooth-beat :beat-ratio beat-ratio :down? true) :max :max-lightness)]
+    (oscillators/sawtooth-beat :beat-ratio :osc-beat-ratio :down? true) :max :max-lightness)]
     (show/add-effect! :color (global-color-effect
       (params/build-color-param :h :main-hue :s 100 :l light-param)))
   )
@@ -253,7 +253,7 @@
   "Change light according to sine osc"
   [beat-ratio]
   (let [light-param (params/build-oscillated-param
-    (oscillators/sine-beat :beat-ratio beat-ratio :down? true :phase 0.5) :max :max-lightness)]
+    (oscillators/sine-beat :beat-ratio :osc-beat-ratio :down? true :phase 0.5) :max :max-lightness)]
     (show/add-effect! :color (global-color-effect
       (params/build-color-param :h :main-hue :s 100 :l light-param)))
   )
@@ -261,12 +261,12 @@

 (defn light-sawtooth-phase
   "Change light of fixtures with phase shift. WIP."
-  [beat-ratio]
+  []
   (let [phase-gradient (params/build-spatial-param  ; Spread a phase shift across fixtures
       (show/all-fixtures)
       (fn [head] (- (:x head) (:min-x @(:dimensions *show*)))) :max 1)]
     (let [light-param (params/build-oscillated-param
-      (oscillators/sawtooth-beat :beat-ratio beat-ratio :down? true :phase phase-gradient) :max :max-lightness)]
+      (oscillators/sawtooth-beat :beat-ratio :osc-beat-ratio :down? true :phase phase-gradient) :max :max-lightness)]
       (show/add-effect! :color (global-color-effect
         (params/build-color-param :s 100 :l light-param :h :main-hue))
       )
@@ -276,11 +276,11 @@

 (defn light-sawtooth-color
   "Change light according to sawtooth osc & hue phase"
-  [beat-ratio]
+  []
   (let [light-param (params/build-oscillated-param
-    (oscillators/sawtooth-beat :beat-ratio beat-ratio :down? true) :max :max-lightness)
+    (oscillators/sawtooth-beat :beat-ratio :osc-beat-ratio :down? true) :max :max-lightness)
         hue-param (params/build-oscillated-param
-    (oscillators/square-beat :beat-ratio (* beat-ratio 2) :down? true) :max 90)
+    (oscillators/square-beat :beat-ratio 16 :down? true) :max 90)
   ]
     (show/add-effect! :color (global-color-effect
       (params/build-color-param :h :main-hue :s 100 :l light-param :adjust-hue hue-param)))
@@ -293,7 +293,7 @@
   (let [light-param (params/build-oscillated-param
     (oscillators/sawtooth-beat :beat-ratio :osc-beat-ratio :down? true) :max :max-lightness)
         hue-param (params/build-oscillated-param
-    (oscillators/square-beat :beat-ratio 8 :down? true) :max 90)
+    (oscillators/square-beat :beat-ratio 16 :down? true) :max 90)
   ]
     (show/add-effect! :color (global-color-effect
       (params/build-color-param :h :main-hue :s 100 :l param)))


lein-release plugin: preparing 0.1.10 release

--- re_view_hiccup/project.clj
+++ re_view_hiccup/project.clj
@@ -1,4 +1,4 @@
-(defproject re-view-hiccup "0.1.10-SNAPSHOT"
+(defproject re-view-hiccup "0.1.10"
   :description "Hiccup parser for re-view"

   :url "https://www.github.com/braintripping/re-view/tree/master/re_view_hiccup"


Fix three typos

Fix three typos

--- src/tutorial/untangled_tutorial/A_Quick_Tour.cljs
+++ src/tutorial/untangled_tutorial/A_Quick_Tour.cljs
@@ -270,7 +270,7 @@
   (om/transact! this `[(counter/increment {:id ~id})])
   ```

-  in the above transaction, we must use Clojure syntax quoting so that we can list an abstract muation (which looks like
+  in the above transaction, we must use Clojure syntax quoting so that we can list an abstract mutation (which looks like
   a function call, but is not) and parameters that themselves are derived from the environment (in this case
   an id). If you're not a Clojure(script) programmer, we understand that the above expression looks a little scary. The
   '`' means 'treat the following thing literally', and the '~' means 'don't treat this thing literally'. It's a way
@@ -441,7 +441,7 @@
   In this quick tour we're faking the networking so you can easily explore what the server and client look like in a
   single file.

-  The `:started-callback` is triggered as the application loads. This is where you can use Untagled's networking layer
+  The `:started-callback` is triggered as the application loads. This is where you can use Untangled's networking layer
   to pre-fetch data from the server. In our case, we want to get all of the counters. Note that we can (and should) use UI
   queries. This triggers auto-normalization of the response. The `:post-mutation` is triggered after the load, and
   can modify the database to construct various views of the loaded data. In our case, it moves the counters onto
@@ -532,6 +532,6 @@

   You can, of course, play with the source code of this example in the devcards.

-  We certainly hope you will continue reading into the deatils of all of these features. You should start with the
+  We certainly hope you will continue reading into the details of all of these features. You should start with the
   [next chapter](#!/untangled_tutorial.B_UI) on UI.
   ")


starting ai

starting ai

--- src/tictactoe/core.cljs
+++ src/tictactoe/core.cljs
@@ -18,8 +18,6 @@
 (defonce app-state (atom {:text "Welocome to tic-tac-toe!!"
                           :board (new-board board-size)
                           :status :in-progress}))
-
-(prn (new-board board-size))

 (defn free-spots [board]
   (for  [i (range board-size)
@@ -47,6 +45,23 @@
     (for [i (range board-size)] (horizontal board i))
     (for [i (range board-size)] (vertical board i))))

+(defn vertical-coords [y]
+  (map #(vector % y) (range board-size)))
+
+(defn horizontal-coords [x]
+  (map #(-> % rseq vec) (vertical-coords x)))
+
+(defn diagonal-down-coords []
+  (for [i (range board-size)]  [i i]))
+
+(defn diagonal-up-coords []
+  (for [i (range board-size)] [i (- (dec board-size) i)]))
+
+(defn all-lines-coords []
+  (concat  [(diagonal-down board) (diagonal-up board)]
+    (for [i (range board-size)] (horizontal board i))
+    (for [i (range board-size)] (vertical board i))))
+
 (defn winning-by? [player line]
   (every? #(= % player) (take winning-k line)))

@@ -64,6 +79,9 @@
 (defn computer-move [board]
   (let [move (rand-nth (free-spots board))]
     (assoc-in board move "O")))
+
+(defn block-attempt [board]
+  ())

 (defn blank [i j]
       [:rect {:width 0.95


loosening scene spec

loosening scene spec

--- src/timsg/scene_var.clj
+++ src/timsg/scene_var.clj
@@ -20,7 +20,7 @@
 (s/def ::def-entity-args
   (s/cat
     :name symbol?
-    :scenes (s/? (s/coll-of string? :kind vector?))
+    :scenes (s/? vector)
     :tails (s/alt
              :single-arity ::tail-impl
              :n-arities (s/* (s/spec ::tail-impl)))))


Fix Issue #326: 	Typing backslash causes Java Heap exception

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -294,24 +294,25 @@
              }
     :list [open-list :expr* ")"]
     :chimera
-             #{ [open-list :expr* eof]
-                [open-vector :expr* eof]
-                [open-map :expr* eof]
-                [open-fn :expr* eof]
-                [open-set :expr* eof]
-                (p/unspaced open-string #"(?:\\.|[^\\\"])++(?!\")" :? eof)
-                (p/unspaced open-regex #"(?:\\.|[^\\\"])++(?!\")" :? eof)
-                [open-quote eof]
-                [open-meta :expr :? eof]
-                [open-deprecated-meta :expr :? eof]
-                [open-deref eof]
-                [open-syntax-quote eof]
-                [open-var eof]
-                [open-discard eof]
-                [open-unquote-splicing eof]
-                [open-unquote eof]
-                (p/unspaced open-char eof)
-                }
+             #{
+               [open-list :expr* eof]
+               [open-vector :expr* eof]
+               [open-map :expr* eof]
+               [open-fn :expr* eof]
+               [open-set :expr* eof]
+               ;(p/unspaced open-string #"(?:\\.|[^\\\"])++(?!\")" :? eof)
+               ;(p/unspaced open-regex #"(?:\\.|[^\\\"])++(?!\")" :? eof)
+               [open-quote eof]
+               [open-meta :expr :? eof]
+               [open-deprecated-meta :expr :? eof]
+               [open-deref eof]
+               [open-syntax-quote eof]
+               [open-var eof]
+               [open-discard eof]
+               [open-unquote-splicing eof]
+               [open-unquote eof]
+               (p/unspaced open-char eof)
+               }
     :vector [open-vector :expr* "]"]
     :map [open-map :expr* "}"]
     :set [open-set :expr* "}"]


corrected a problem with the parser, and changed the seq on string to direct string index access

--- src/paredit/parser.clj
+++ src/paredit/parser.clj
@@ -15,84 +15,80 @@
 	 TODO: make the parser restartable at a given offset given a state ...
 	 TODO: make the parser fully incremental (via chunks of any possible size ...)"
 	[text stop-offset]
-  (let [r (StringBuilder.) ; result string builder
-        append-spaces (fn [n-spaces] (dotimes [_ n-spaces] (.append r " ")))
-       ]
-    (loop [
-           s (seq text) ; current string, stream of chars
-           { :keys [parents offset line col] :as state} { :parents [{:type nil :offset 0 :line 0 :col 0}] :offset 0 :line 0 :col 0}]
-        (if (or (not s) (>= offset stop-offset))
-          state
-          (let [c (first s)] ; c: current char
-            (cond
-              (*opening-brackets* c)
-                (cond
-                  (= \" (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  (= \; (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  :else
-		                (recur
-		                  (next s)
-		                  (assoc state
-		                    :parents (conj parents {:type c :line line :col col :offset offset})
-		                    :offset (inc offset)
-		                    :col (inc col))))
-              (*closing-brackets* c)
-                (cond
-                  (= \" (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  (= \; (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  :else
-		                (recur
-		                  (next s)
-		                  (assoc state
-		                    :parents (pop parents)
-		                    :offset (inc offset)
-		                    :col (inc col))))
-              (= (first "\r") c)
-                (recur (next s) (assoc state :offset (inc offset))) ; we do not increment the column
-              (= \newline c)
-                (cond
-                  (= \" (-> parents pop :type))
-		                (recur (next s) (assoc state :offset (inc offset) :line (inc line) :col 0))
-                  (= \; (-> parents pop :type))
-                    ; we take care of going out of comments, if we are in comments !
-		                (recur (next s) (assoc state :parents (if (= \; (-> parents pop :type)) (pop parents) parents) :offset (inc offset) :line (inc line) :col 0))
-                  :else
-		                (recur (next s) (assoc state :offset (inc offset) :line (inc line) :col 0)))
-              #_(#{\space \tab \,} c)
-                #_(cond
-                  (= \" (-> parents pop :type))
-                  (= \; (-> parents pop :type))
-                  :else
-                )
-              (= \" c)
-                (cond
-                  (= \" (-> parents pop :type))
-                    (if (= offset 0)
-                      (recur (next s) (assoc state :offset (inc offset) :col (inc col) :parents (conj {:type c :line line :col col :offset offset})))
-                      (if (= \\ (.charAt text (dec offset)))
-                        (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                        (recur (next s) (assoc state :parents (pop parents) :offset (inc offset) :col (inc col)))))
-                  (= \; (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  :else
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col) :parents (conj parents {:type c :line line :col col :offset offset}))))
-              (= \; c)
-                (cond
-                  (= \" (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  (= \; (-> parents pop :type))
-                    (recur (next s) (assoc state :offset (inc offset) :col (inc col)))
-                  :else
-                    (recur (next s) (assoc state :parents (conj parents {:type c :offset offset :col col :line line}) state :offset (inc offset) :col (inc col))))
-              :else
-                (recur (next s) (assoc state :offset (inc offset) :col (inc col)))))))))
+  (loop [{ :keys [parents offset line col] :as state} { :parents [{:type nil :offset 0 :line 0 :col 0}] :offset 0 :line 0 :col 0}]
+      (if (>= offset stop-offset)
+        state
+        (let [c (.charAt text offset)] ; c: current char
+          (cond
+            (*opening-brackets* c)
+              (cond
+                (= \" (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                (= \; (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                :else
+	                (recur
+	                  (assoc state
+	                    :parents (conj parents {:type c :line line :col col :offset offset})
+	                    :offset (inc offset)
+	                    :col (inc col))))
+            (*closing-brackets* c)
+              (cond
+                (= \" (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                (= \; (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                :else
+	                (recur
+	                  (assoc state
+	                    :parents (pop parents)
+	                    :offset (inc offset)
+	                    :col (inc col))))
+            (= (first "\r") c)
+              (recur (assoc state :offset (inc offset))) ; we do not increment the column
+            (= \newline c)
+              (cond
+                (= \" (-> parents pop :type))
+	                (recur (assoc state :offset (inc offset) :line (inc line) :col 0))
+                (= \; (-> parents pop :type))
+                  ; we take care of going out of comments, if we are in comments !
+	                (recur (assoc state :parents (pop parents) :offset (inc offset) :line (inc line) :col 0))
+                :else
+	                (recur (assoc state :offset (inc offset) :line (inc line) :col 0)))
+            #_(#{\space \tab \,} c)
+              #_(cond
+                (= \" (-> parents pop :type))
+                (= \; (-> parents pop :type))
+                :else
+              )
+            (= \" c)
+              (cond
+                (= \" (-> parents pop :type))
+                  (if (= offset 0)
+                    (recur (assoc state :offset (inc offset) :col (inc col) :parents (conj {:type c :line line :col col :offset offset})))
+                    (if (= \\ (.charAt text (dec offset)))
+                      (recur (assoc state :offset (inc offset) :col (inc col)))
+                      (recur (assoc state :parents (pop parents) :offset (inc offset) :col (inc col)))))
+                (= \; (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                :else
+                  (recur (assoc state :offset (inc offset) :col (inc col) :parents (conj parents {:type c :line line :col col :offset offset}))))
+            (= \; c)
+              (cond
+                (= \" (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                (= \; (-> parents pop :type))
+                  (recur (assoc state :offset (inc offset) :col (inc col)))
+                :else
+                  (recur (assoc state :parents (conj parents {:type c :offset offset :col col :line line}) :offset (inc offset) :col (inc col))))
+            :else
+              (recur (assoc state :offset (inc offset) :col (inc col))))))))

 (defn parse-core []
-  (time (let [s (slurp "/home/lpetit/projects/clojure/src/clj/clojure/core.clj")] (parse s (.length s)) (.length s))))
+  (time
+    (let [s (slurp "/home/lpetit/projects/clojure/src/clj/clojure/core.clj")]
+      (parse s (.length s))
+      (.length s))))

 #_(deftest test-format-code
   (testing "parens combinatorics"


cleanup the default routes a bit

cleanup the default routes a bit

--- src/pc/http/routes.clj
+++ src/pc/http/routes.clj
@@ -61,35 +61,38 @@

             (and (auth/logged-in? req)
                  (not (:team req)))
-
-            {:status 200
-             :body "Claim this domain for your team"}
+            {:status 200
+             :body (hiccup.page/html5
+                    {}
+                    "Please email hi@precursorapp.com to claim this domain for your team")}

             (and (auth/logged-in? req)
                  (:team req)
                  (not (auth/has-team-permission? db (:team req) (:auth req) :admin))
                  (seq (access-request-model/find-by-team-and-cust (pcd/default-db) (:team req) (get-in req [:auth :cust]))))
-
-            {:status 200
-             :body "Thanks for requesting access, we'll send you an email when your request is granted."}
+            {:status 200
+             :body (hiccup.page/html5
+                    {}
+                    [:p "Thanks for requesting access, we'll send you an email when your request is granted."]
+                    [:p "In the meantime, you can make something on " [:a {:href (urls/root)}
+                                                                       (urls/root)]])}

             (and (auth/logged-in? req)
                  (:team req)
                  (not (auth/has-team-permission? db (:team req) (:auth req) :admin)))
-
             {:status 200
              :body (hiccup.page/html5
                     {}
                     [:html
                      [:body
-                      [:form {:action "/request-team-permission" :method "post"}
-                       (anti-forgery-field)
-                       [:input {:type "submit" :value "Request permission"}]]]])}
+                      [:span
+                       [:form {:action "/request-team-permission" :method "post"}
+                        (anti-forgery-field)
+                        [:input {:type "submit" :value "Request permission to join this team"}]]]]])}

             (and (auth/logged-in? req)
                  (:team req)
                  (auth/has-team-permission? db (:team req) (:auth req) :admin))
-
             (let [doc (doc-model/create-team-doc!
                        (:team req)
                        (merge {:document/chat-bot (rand-nth chat-bot-model/chat-bots)}


Convert the subscription cache from an atom to a ratom

This allows it to be used in monitoring/debugging tools elsewhere.

--- src/re_frame/subs.cljc
+++ src/re_frame/subs.cljc
@@ -15,7 +15,7 @@
 ;; De-duplicate subscriptions. If two or more equal subscriptions
 ;; are concurrently active, we want only one handler running.
 ;; Two subscriptions are "equal" if their query vectors test "=".
-(def query->reaction (atom {}))
+(def query->reaction (re-frame.interop/ratom {}))

 (defn clear-subscription-cache!
   "Causes all subscriptions to be removed from the cache.


Check if session implements com.datastax.driver.core.Session, not is one

Cluster#connect always returns an instance of SessionManager, which
implements Session, so we should check for the interface, not concrete
implementation

Should have belonged to @arr-ee, I just fixed it in a different way initially. Avoiding merge conflicts.

--- src/clojure/clojurewerkz/cassaforte/client.clj
+++ src/clojure/clojurewerkz/cassaforte/client.clj
@@ -19,7 +19,7 @@
             [clojurewerkz.cassaforte.conversion :as conv]
             [qbits.hayt.cql :as cql]
             [clojurewerkz.cassaforte.query :as query])
-  (:import [com.datastax.driver.core Statement ResultSet ResultSetFuture Host SessionManager Cluster
+  (:import [com.datastax.driver.core Statement ResultSet ResultSetFuture Host Session Cluster
             Cluster$Builder SimpleStatement PreparedStatement HostDistance PoolingOptions
             ConsistencyLevel]
            [com.google.common.util.concurrent Futures FutureCallback]
@@ -121,16 +121,16 @@
 ;; Client-related
 ;;

-(defprotocol DummySessionManager
+(defprotocol DummySession
   (executeAsync [_ query]))

-(deftype DummySessionManagerImpl []
-  DummySessionManager
+(deftype DummySessionImpl []
+  DummySession
   (executeAsync [_ query] (throw (Exception. "Not connected"))))

 (def ^:dynamic *default-cluster*)
-(def ^:dynamic *default-session* (DummySessionManagerImpl.))
+(def ^:dynamic *default-session* (DummySessionImpl.))
 (def ^:dynamic *async* false)
 (def ^:dynamic *debug* false)

@@ -201,10 +201,10 @@
    This assumes that query is valid. Returns the prepared statement corresponding to the query."
   ([^String query]
      (prepare *default-session* query))
-  ([^SessionManager session ^String query]
+  ([^Session session ^String query]
      (if-let [cached (get @prepared-statement-cache [session query])]
        cached
-       (let [prepared (.prepare ^SessionManager session query)]
+       (let [prepared (.prepare ^Session session query)]
          (swap! prepared-statement-cache #(assoc % [session query] prepared))
          prepared))))

@@ -270,7 +270,7 @@
       (.withLoadBalancingPolicy builder load-balancing-policy))
     (.build builder)))

-(defn ^SessionManager connect
+(defn ^Session connect
   "Connects to the Cassandra cluster. Use `build` function to build cluster with all required options."
   ([^Cluster cluster]
      (flush-prepared-statement-cache!)
@@ -293,14 +293,14 @@
     session))

 (defn disconnect!
-  "0-arity version disconnects the (only) active SessionManager and shuts down the cluster.
-
-   1-arity version receives SessionManager, and shuts it down. It doesn't shut down all other sessions
+  "0-arity version disconnects the (only) active Session and shuts down the cluster.
+
+   1-arity version receives Session, and shuts it down. It doesn't shut down all other sessions
    on same cluster."
   ([]
      (.shutdown *default-session*)
      (.shutdown *default-cluster*))
-  ([^SessionManager session]
+  ([^Session session]
      (.shutdown session)))

 (defn shutdown-cluster
@@ -333,7 +333,7 @@
        explicitly, because `execute` is considered to be a low-level function."
   [& args]

-  (let [[session query & {:keys [prepared]}] (if (= (type (first args)) SessionManager)
+  (let [[session query & {:keys [prepared]}] (if (instance? Session (first args))
                                                args
                                                (cons *default-session* args))
         ^Statement statement (if prepared
@@ -351,7 +351,7 @@

 (defn ^String export-schema
   "Exports the schema as a string"
-  [^SessionManager client]
+  [^Session client]
   (-> client
       .getCluster
       .getMetadata
@@ -359,7 +359,7 @@

 (defn get-hosts
   "Returns all nodes in the cluster"
-  [^SessionManager session]
+  [^Session session]
   (map (fn [^Host host]
          {:datacenter (.getDatacenter host)
           :address    (.getHostAddress (.getAddress host))


get non-excluded macros in doc generator (close #31)

--- cljs-api-parser/src/core.clj
+++ cljs-api-parser/src/core.clj
@@ -31,7 +31,9 @@
   {"cljs.core"              {"clojurescript" {"core.cljs"        "src/cljs/cljs/core.cljs"
                                               "core.clj"         "src/clj/cljs/core.clj"}
                              "clojure"       {"core.clj"         "src/clj/clojure/core.clj"
-                                              "core_deftype.clj" "src/clj/clojure/core_deftype.clj"}}
+                                              "core_deftype.clj" "src/clj/clojure/core_deftype.clj"
+                                              "core_print.clj"   "src/clj/clojure/core_print.clj"
+                                              "core_proxy.clj"   "src/clj/clojure/core_proxy.clj"}}
    "cljs.reader"            {"clojurescript" {"reader.cljs"      "src/cljs/cljs/reader.cljs"}}
    "clojure.set"            {"clojurescript" {"set.cljs"         "src/cljs/clojure/set.cljs"}}
    "clojure.string"         {"clojurescript" {"string.cljs"      "src/cljs/clojure/string.cljs"}}
@@ -184,26 +186,32 @@

 (defn parse-defn-or-macro
   [form]
-  (let [docstring (let [ds (nth form 2)]
+  (let [fn-or-macro ({'defn "function" 'defmacro "macro"} (first form))
+        args (drop 2 form)
+        docstring (let [ds (first args)]
                     (when (string? ds)
                       ds))
-        attr-map (let [m (nth form (if docstring 3 2))]
+        args (if docstring (rest args) args)
+        attr-map (let [m (first args)]
                    (when (map? m) m))
+        args (if attr-map (rest args) args)
+        private? (:private attr-map)
         doc-forms (cond-> []
                     docstring (conj docstring)
                     attr-map (conj attr-map))
-        sig-body-forms (drop (+ 2 (count doc-forms)) form)
-        signatures (if (vector? (first sig-body-forms))
-                     (take 1 sig-body-forms)
-                     (map first sig-body-forms))
+        signatures (if (vector? (first args))
+                     (take 1 args)
+                     (map first args))
         expected-docs (try-locate-docs
                         {:whole form
                          :head (take 2 form)
                          :doc doc-forms
-                         :sig-body sig-body-forms})]
-    {:expected-docs expected-docs
-     :docstring (fix-docstring docstring)
-     :signatures signatures}))
+                         :sig-body args})]
+    (when-not private?
+      {:expected-docs expected-docs
+       :docstring (fix-docstring docstring)
+       :signatures signatures
+       :fn-or-macro fn-or-macro})))

 (defn parse-def-fn
   [form]
@@ -213,10 +221,9 @@
         signatures (when-let [arglists (:arglists m)]
                      (when (= 'quote (first arglists))
                        (second arglists)))]
-    (when (= 'let name-)
-      (println "let"))
     {:docstring docstring
-     :signatures signatures}))
+     :signatures signatures
+     :fn-or-macro "function"}))

 (defmulti parse-form*
   (fn [form]
@@ -239,15 +246,15 @@

 (defmethod parse-form* "def fn"
   [form]
-  (assoc (parse-def-fn form) :fn-or-macro "function"))
+  (parse-def-fn form))

 (defmethod parse-form* "defn"
   [form]
-  (assoc (parse-defn-or-macro form) :fn-or-macro "function"))
+  (parse-defn-or-macro form))

 (defmethod parse-form* "defmacro"
   [form]
-  (assoc (parse-defn-or-macro form) :fn-or-macro "macro"))
+  (parse-defn-or-macro form))

 (defmethod parse-form* nil
   [form]
@@ -295,27 +302,43 @@
       (doall (keep #(parse-form % ns- repo) forms)))))

 (defn get-imported-macro-api
-  [ns- repo file macro-api]
-  (let [forms (get-forms ns- repo file)
-        macro-names (-> (filter #(= 'import-macros (first %)) forms)
-                        first (nth 2) set)]
+  [forms macro-api]
+  (let [get-imports #(match % (['import-macros 'clojure.core x] :seq) x :else nil)
+        macro-names (->> forms (keep get-imports) first set)]
     (filter #(macro-names (:name %)) macro-api)))

+(defn get-non-excluded-macro-api
+  [forms macro-api]
+  (let [ns-form (first (filter #(= 'ns (first %)) forms))
+        get-excludes #(match % ([:refer-clojure :exclude x] :seq) x :else nil)
+        macro-names (->> ns-form (drop 2) (keep get-excludes) first set)]
+    (remove #(macro-names (:name %)) macro-api)))
+
 ;;------------------------------------------------------------
 ;; Namespace API parsing
 ;;------------------------------------------------------------

 (defmulti parse-ns-api (fn [ns-] ns-))

+(defn parse-extra-macros-from-clj
+  []
+  (let [clj-api (concat (parse-api "cljs.core" "clojure" "core.clj")
+                        (parse-api "cljs.core" "clojure" "core_deftype.clj")
+                        (parse-api "cljs.core" "clojure" "core_print.clj")
+                        (parse-api "cljs.core" "clojure" "core_proxy.clj"))
+        clj-api (filter #(= "macro" (:fn-or-macro %)) clj-api)
+        cljs-forms   (get-forms "cljs.core" "clojurescript" "core.clj")
+        imports      (get-imported-macro-api     cljs-forms clj-api)
+        non-excludes (get-non-excluded-macro-api cljs-forms clj-api)]
+    (println "   " (count imports) "imported clojure.core macros")
+    (println "   " (count non-excludes) "non-excluded clojure.core macros")
+    (concat imports non-excludes)))
+
 (defmethod parse-ns-api "cljs.core" [ns-]
-  (let [clj-api       (parse-api ns- "clojure"       "core.clj")
-        clj-type-api  (parse-api ns- "clojure"       "core_deftype.clj")
-        clj-cljs-api  (parse-api ns- "clojurescript" "core.clj")
-        cljs-cljs-api (parse-api ns- "clojurescript" "core.cljs")
-        import-macro-api (get-imported-macro-api ns- "clojurescript" "core.clj" (concat clj-api clj-type-api))]
-    (concat import-macro-api
-            clj-cljs-api
-            cljs-cljs-api)))
+  (let [clj-api  (parse-api ns- "clojurescript" "core.clj")
+        cljs-api (parse-api ns- "clojurescript" "core.cljs")
+        extra-macro-api (parse-extra-macros-from-clj)]
+    (concat extra-macro-api clj-api cljs-api)))

 (defmethod parse-ns-api "cljs.reader" [ns-]
   (parse-api ns- "clojurescript" "reader.cljs"))
@@ -412,7 +435,7 @@

     ;; Build the docs.
     (doseq [ns- (keys cljs-ns-paths)]
-      (println "   " ns-)
+      (println " " ns-)
       (dump-api-docs! (parse-ns-api ns-)))

     (println "\nDone.")


complete name generation using sequences.

--- clojure/robot-name/robot.clj
+++ clojure/robot-name/robot.clj
@@ -1,33 +1,29 @@
 (ns robot)

-(def numbers (range 1000))
-
-(def name-seq (atom ["A" "A" 1]))
-
-(defn- max-for [part]
-  999)
-
-(defn- next-part [part]
-  (partial inc))
-
-(defn- inc-name-seq [curr-seq]
-  (update-in curr-seq [2] inc)
-  (loop [part 2]
-    ;; which piece of the name seq are we dealing with
-    (if (= (curr-seq part) (max-for part))
-      (recur (dec part))
-      (update-in curr-seq [part] next-part)))
-  )
+(def letters (map char (range (int \A) (inc (int \B)))))
+(def numbers (range 5))
+(def starting-vals [letters letters numbers])
+(def name-seq (atom starting-vals))

 (defn- format-name [name]
   (apply format "%s%s%03d" name))

 (defn- generate-name []
-  (format-name @name-seq))
+  (format-name (map first @name-seq)))
+
+(defn- inc-name-seq []
+  (loop [part 2]
+    (if (seq (@name-seq part))
+      (swap! name-seq update-in [part] rest)
+      (do
+        (reset! name-seq
+                (assoc-in @name-seq [part]
+                          (starting-vals part)))
+        (recur (dec part))))))

 (defn- next-name []
   (let [name (generate-name)]
-    (swap! name-seq inc-name-seq)
+    (inc-name-seq)
     name))

 (defn robot []


-analyze :const -> analyze-const

-analyze :const -> analyze-const

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -423,7 +423,7 @@
     (if (and meta (= :map (:op meta)))
       (let [const-map (zipmap (mapv const-val (:keys meta))
                               (mapv const-val (:vals meta)))]
-        (assoc-in ast [:meta] (ana/-analyze :const const-map env)))
+        (assoc-in ast [:meta] (ana/-analyze-const const-map env)))
       ast)))

 (def default-passes


make libs task work with modules and write to fs

--- tasklib/src/migae/boot_gae.clj
+++ tasklib/src/migae/boot_gae.clj
@@ -4,12 +4,15 @@
             [clojure.string :as str]
             [clojure.set :as set]
             [clojure.pprint :as pp]
+            [me.raynes.fs :as fs]
             [stencil.core :as stencil]
             [boot.user]
             [boot.pod :as pod]
             [boot.core :as boot]
             [boot.util :as util]
-            [boot.task.built-in :as builtin])
+            [boot.task.built-in :as builtin]
+            [boot.file            :as file]
+            [boot.from.digest     :as digest])
   (:import [com.google.appengine.tools KickStart]
            [java.io File]
            [java.net URL URLClassLoader]))
@@ -421,10 +424,10 @@
   "construct ear dir"
   [k keep bool "keep intermediate .clj files"
    i meta-inf META-INF str "META-INF dir path"
-   m modules MODULES edn "modules map"
+   ;; m modules MODULES edn "modules map"
    v verbose bool "Print trace messages."]
-  (println "EAR: " modules)
-  (let [paths (set (map #(:war %) modules))
+  ;; (println "EAR: " modules)
+  (let [;; paths (set (map #(:war %) modules))
         m (or meta-inf "./")
         tmpdir (boot/tmp-dir!)

@@ -440,36 +443,66 @@
         co-jars    (->> checkouts (map (comp :jar val)))
         co-dirs    (->> checkouts (map (comp :dir val)))

-        ;; coords '[tmp/greetings "0.1.0-SNAPSHOT"]
-        ;; jar-path (pod/resolve-dependency-jar (boot/get-env) coords)
-        jar-path (.getPath (first co-jars))
-        target-path "greetings"
-
-        out (io/file (.getPath tmpdir) target-path)
-
-        ;; pod-env (update-in (boot/get-env) [:dependencies]
-        ;;                    #(identity %2)
-        ;;                    (concat '[[boot/aether "2.6.0-SNAPSHOT"]
-        ;;                              [boot/core "2.6.0-SNAPSHOT"]
-        ;;                              [boot/pod "2.6.0-SNAPSHOT"]
-        ;;                              [tmp/greetings "0.1.0-SNAPSHOT"]]))
-        ;;                              ;; (vector coords)))
-        ;; ear-pod (future (pod/make-pod pod-env))
+        checkout-vec (-> (boot/get-env) :checkouts)
+        cos (map #(assoc (apply hash-map %) :coords [(first %) (second %)]) checkout-vec)
         ]
-    (println "boot-env deps: " (:dependencies (boot/get-env)))
-    ;; (println "pod-env deps: " (:dependencies pod-env))
-    (println "jar-path:" jar-path)
-    (println "out path:" out)
-    (println "checkouts: " checkouts)
-    (println "co-jars: " (type (first co-jars)))
+    ;; (println "checkouts: " checkouts)
+    (println "checkout-vec: " checkout-vec)
     (println "co-dirs: " co-dirs)
+    (println "cos: " cos)
+    (boot/with-pre-wrap [fileset]
+      (loop [cos cos
+             fs fileset]
+        (if (empty? cos)
+          fs
+          (let [co (first cos)]
+                (println "CO: " co)
+                (println "COORDS: " (:coords co))
+                (println "MODULE: " (:module co))
+                (let [target-path (:module co)
+                      out (io/file (.getPath tmpdir) target-path)
+                      corec (get checkouts (first (:coords co)))
+                      co-dir (:dir corec)
+                      jar-path (.getPath (:jar corec))
+                      ;; jar-path (pod/resolve-dependency-jar (boot/get-env) (:coords co))
+
+                      ;; in-file (boot/tmp-file (boot/tmp-get fileset path))
+                      tmpdir (boot/tmp-dir!)
+                      out-dir (doto (io/file tmpdir (:module co)) io/make-parents)
+                      newfs (boot/new-fileset)
+                      ]
+                  (println "OUTDIR: " out-dir)
+                  (fs/copy-dir co-dir out-dir)
+                  ;; (println "checkout: " corec)
+                  (println "jar-path: " jar-path)
+                  (println "co-dir: " (.getPath co-dir))
+                  ;; (pp/pprint (file-seq out-dir))
+                  (println "target-path: " target-path)
+                  (recur (rest cos)
+                         (-> fs
+                             (boot/add-asset tmpdir :exclude #{(re-pattern (str "/META-INF/.*"))})
+                             ;; (builtin/sift :include #{(re-pattern (str mod "/META-INF/.*"))}
+                             ;;               :invert true)
+                             (boot/commit!))))))))))
+
+        ;; (comp
+        ;;  (builtin/sift :add-asset #{co-dir})
+        ;;  (builtin/sift :move {#"(^.*)" (str mod "/$1")})
+        ;;  (builtin/sift :include #{(re-pattern (str "^" mod "/META-INF/.*"))} :invert true)
+        ;;  (builtin/sift :add-asset #{"assets"}))
+        ;; ))))
+
+    ;; (println "boot-env deps: " (:dependencies (boot/get-env)))
+    ;; ;; (println "pod-env deps: " (:dependencies pod-env))
+    ;; (println "jar-path:" jar-path)
+    ;; (println "out path:" out)
+    ;; (println "co-jars: " (type (first co-jars)))
     ;; (builtin/sift :move {(re-pattern (.getPath (first co-dirs))) "foobar"})
     ;; (builtin/sift :add-asset #{"foobar"})
-    (comp
-     (builtin/sift :add-asset #{(.getPath (first co-dirs))})
-     (builtin/sift :move {#"(^.*)" "foo/$1"})
-     (builtin/sift :add-asset #{"assets"}))
-    ))
+
+
+
+
     ;; #_(comp
     ;;  (boot/with-pre-wrap [fileset]
     ;;    (pod/unpack-jar jar-path out)
@@ -683,15 +716,141 @@
           (pod/unpack-jar jar-path (.getParent sdk-dir))))
       fileset)))

+;;(core/deftask buber
+(defn buber
+  [tgt]
+  (println "BUBER ")
+  (let [;; tgt        (boot/tmp-dir!)
+        cache      (boot/cache-dir! ::uber :global true)
+        dfl-scopes #{"compile" "runtime"}
+        scopes     dfl-scopes
+        ;; scopes     (-> dfl-scopes
+        ;;                (set/union include-scope)
+        ;;                (set/difference exclude-scope))
+        _ (println "SCOPES: " dfl-scopes)
+        scope?     #(contains? scopes (:scope (util/dep-as-map %)))
+        jars       (-> pod/env ;; (boot/get-env)
+                       (update-in [:dependencies] (partial filter scope?))
+                       pod/resolve-dependency-jars)
+        _ (println "JARS: " jars)
+        jars       (remove #(.endsWith (.getName %) ".pom") jars)
+        checkouts  (->> (boot/get-checkouts)
+                        (filter (comp scope? :dep val))
+                        (into {}))
+        co-jars    (->> checkouts (map (comp :jar val)))
+        ;; co-dirs    (->> checkouts (map (comp :dir val)))
+        ;; exclude    (or exclude pod/standard-jar-exclusions)
+        ;; merge      (or merge pod/standard-jar-mergers)
+        ;; reducer    (fn [xs jar]
+        ;;              (boot/add-cached-resource
+        ;;                xs (digest/md5 jar) (partial pod/unpack-jar jar)
+        ;;                :include include :exclude exclude :mergers merge))
+        ;; co-reducer #(boot/add-resource
+        ;;               %1 %2 :include include :exclude exclude :mergers merge)
+        ]
+    ;; (boot/with-pre-wrap [fs]
+    ;; (println "co jars: " co-jars)
+      (when (seq jars)
+        (doseq [jar jars] ;; (reduce into [] [jars co-jars])]
+          (let [dest (doto (io/file tgt (.getName jar)) io/make-parents)]
+            (println "dest: " dest)
+            (file/copy-atomically jar dest))))))
+
+      ;;       (when-not (.exists src)
+      ;;         (println "CACHING " name)
+      ;;         (util/dbug* "Caching jar %s...\n" name)
+      ;;         (file/copy-atomically jar src))
+      ;;       (util/dbug* "Adding cached jar %s...\n" name)
+      ;;       (println (format "Adding cached jar %s...\n" name))
+      ;;       (file/hard-link src (io/file tgt name)))))
+      ;; #_(boot/commit! (if as-jars
+      ;;                 (boot/add-resource fs tgt)
+      ;;                 (reduce co-reducer (reduce reducer fs jars) co-dirs)))))
+
 ;; FIXME:  for dev phase, we want to include deps in test scope
 (boot/deftask libs
   ""
   [v verbose bool "Print trace messages."]
-  (comp
-   (builtin/uber :as-jars true :exclude-scope #{"provided"})
-   ;; (builtin/sift :include #{#"zip$"} :invert true)
-   ;; (builtin/sift :include #{#".*appengine-api-.*jar$"} :invert true)
-   (builtin/sift :move {#"(.*\.jar$)" (str lib-dir "/$1")})))
+  (let [checkout-vec (-> (boot/get-env) :checkouts)
+        cos (map #(assoc (apply hash-map %) :coords [(first %) (second %)]) checkout-vec)
+
+        dfl-scopes #{"compile" "runtime" "provided"}
+        scopes dfl-scopes
+        ;; scopes     (-> dfl-scopes
+        ;;                (set/union include-scope)
+        ;;                (set/difference exclude-scope))
+        scope?     #(contains? scopes (:scope (util/dep-as-map %)))
+        checkouts  (->> (boot/get-checkouts)
+                        (filter (comp scope? :dep val))
+                        (into {}))
+        cache      (boot/cache-dir! ::uber :global true)
+        ]
+    ;; (println "CACHE: " cache)
+    ;; (println "COS: " cos)
+    (boot/with-pre-wrap [fileset]
+      (let [tmpdir     (boot/tmp-dir!)]
+      (doseq [co cos]
+        (let [mod (if (:default co) "default"
+                      (if-let [mod (:module co)]
+                        mod "default"))
+              coords (:coords co)
+              pod-env (update-in (dissoc (boot/get-env) :checkouts)
+                                 [:dependencies] #(identity %2)
+                                 (concat '[[boot/core "2.6.0-SNAPSHOT"]
+                                           [boot/pod "2.6.0-SNAPSHOT"]]
+                                         (vector coords)))
+              pod (future (pod/make-pod pod-env))]
+          (if verbose (println "MODULE: " mod))
+          (pod/with-eval-in @pod
+              (require '[boot.pod :as pod]
+                       '[boot.task.built-in :as builtin]
+                       '[boot.util :as util]
+                       '[boot.core :as boot]
+                       '[boot.from.digest :as digest]
+                       '[boot.file :as file]
+                       '[clojure.java.io :as io])
+              (let [dfl-scopes #{"compile" "runtime" "test"}
+                    scopes dfl-scopes
+                    scope? #(contains? scopes (:scope (util/dep-as-map %)))
+                    co-jar (pod/resolve-dependency-jar (boot/get-env) '~coords)
+                    jars   (remove #(= (str co-jar) (.getPath %))
+                                   (-> pod/env
+                                       (update-in [:dependencies] (partial filter scope?))
+                                       (pod/resolve-dependency-jars true)))]
+                (doseq [jar jars]
+                  (let [hash (digest/md5 jar)
+                        name (str hash "-" (.getName jar))
+                        tmpjar-path (str ~mod "/WEB-INF/lib/" (.getName jar))
+                        cached-jar  (io/file ~(.getPath cache) hash)]
+                    (when-not (.exists cached-jar)
+                      (if ~verbose (util/info "Caching jar %s...\n" name))
+                      (file/copy-atomically jar cached-jar))
+                    (if ~verbose (util/info "Adding cached jar %s...\n" tmpjar-path))
+                    (file/hard-link cached-jar (doto (io/file ~(.getPath tmpdir) tmpjar-path)
+                                                 io/make-parents))))))))
+      (boot/commit! (boot/add-resource fileset tmpdir))))))
+
+                  ;; (recur (rest jars)
+                  ;;        fs
+
+              ;;     ;;(println "dest: " dest)
+              ;;     (file/hard-link jar dest)
+              ;;     #_(file/copy-atomically jar dest)))
+              ;; ;;~(buber out-dir) ;; :as-jars true :exclude-scope #{"provided"})
+              ;; ))))))
+
+            ;; #_(pod/copy-dependency-jar-entries pod/env
+            ;;                                    ~(.getPath out-dir)
+            ;;                                    '~coords
+            ;;                                    #"^.*clj$"
+            ;;                                    )))))))
+
+    ;; #_(comp
+    ;;  (builtin/uber :as-jars true :exclude-scope #{"provided"})
+    ;;  ;; (builtin/sift :include #{#"zip$"} :invert true)
+    ;;  ;; (builtin/sift :include #{#".*appengine-api-.*jar$"} :invert true)
+    ;;  (builtin/sift :move {#"(.*\.jar$)" (str mod "/" lib-dir "/$1")})
+    ;;  (builtin/sift :include #{#".*jar$"}))))

 ;; FIXME: drive this from logging.edn
 (boot/deftask logging
@@ -1111,6 +1270,7 @@
           (appengine :verbose verbose)
           (builtin/sift :move {#"(.*clj$)" (str classes-dir "/$1")})
           (builtin/sift :move {#"(.*\.class$)" (str classes-dir "/$1")})
+          (builtin/sift :move {#"(^.*)" (str mod "/$1")})
           ;; FIXME: use cache instead?
           ;; (builtin/target :dir #{(str "target/" mod)})
           )))
@@ -1119,25 +1279,28 @@
   "dev build, source only"
   [v verbose bool "verbose"]
   (let [mod (str (-> (boot/get-env) :gae :module))
-        rgx (re-pattern (str "(^" mod "/.*clj$)"))
-        prev (atom nil)]
-    (println "MODULE: " mod)
-    (println "REGEX: " rgx)
-    ;; (comp
-    (boot/with-pre-wrap [fileset]
-      (let [changes (->> (boot/fileset-diff @prev fileset)
-                         boot/output-files
-                         (map :path))
-            fs (boot/new-fileset)
-            cache-dir (boot/cache-dir! :boot-gae/build)]
-        (doseq [path changes]
-          (if verbose (util/info (str "changed: " path "\n")))
-          (let [in-file (boot/tmp-file (boot/tmp-get fileset path))
-                out-file (if (str/ends-with? path "clj")
-                           (doto (io/file cache-dir classes-dir path) io/make-parents)
-                           (doto (io/file cache-dir path) io/make-parents))]
-            (io/copy in-file out-file))))
-      (reset! prev fileset))))
+        prev (atom nil)
+        cache-dir (boot/cache-dir! :boot-gae/build)]
+    ;; (println "MODULE: " mod)
+    (comp
+     (boot/with-pre-wrap [fileset]
+       (let [changes (->> (boot/fileset-diff @prev fileset)
+                          boot/output-files
+                          (map :path))
+             fs (boot/new-fileset)]
+         (doseq [path changes]
+           (if verbose (util/info (str "changed: " path "\n")))
+           (let [in-file (boot/tmp-file (boot/tmp-get fileset path))
+                 out-file (if (str/ends-with? path "clj")
+                            (doto (io/file cache-dir classes-dir path) io/make-parents)
+                            (doto (io/file cache-dir path) io/make-parents))]
+             (io/copy in-file out-file)))
+         (reset! prev fileset)))
+     (builtin/sift :include #{#".*"} :invert true)
+     (boot/with-pre-wrap [fileset]
+      (-> fileset
+          (boot/add-asset cache-dir)
+          boot/commit!)))))

 (boot/deftask prod
   "make a prod build"


Add support for collection as HashMap keys. Refs #10

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -657,6 +657,9 @@
   IEquiv
   (-equiv [coll other] (equiv-sequential coll other))

+  IHash
+  (-hash [coll] (hash-coll coll))
+
   ISeqable
   (-seq [coll] (seq (lazy-seq-value coll)))

@@ -705,6 +708,9 @@
   IEquiv
   (-equiv [coll other] (equiv-sequential coll other))

+  IHash
+  (-hash [coll] (hash-coll coll))
+
   ISeqable
   (-seq [coll] coll)

@@ -739,6 +745,9 @@
   IEquiv
   (-equiv [coll other] (equiv-sequential coll other))

+  IHash
+  (-hash [coll] (hash-coll coll))
+
   ISeqable
   (-seq [coll] nil)

@@ -773,6 +782,9 @@
   ISequential
   IEquiv
   (-equiv [coll other] (equiv-sequential coll other))
+
+  IHash
+  (-hash [coll] (hash-coll coll))

   ISeqable
   (-seq [coll] coll)
@@ -978,6 +990,9 @@
   IEquiv
   (-equiv [coll other] (equiv-sequential coll other))

+  IHash
+  (-hash [coll] (hash-coll coll))
+
   ISeqable
   (-seq [coll]
     (when (> (.length array) 0)
@@ -1028,7 +1043,18 @@
   goog.global.Number (-hash [o] o))

 (defn hash [o]
-  (when o (-hash o)))
+  (if o
+    (-hash o)
+    0))
+
+(defn hash-combine [seed hash]
+  ; a la boost
+  (bit-xor (+ hash 0x9e3779b9
+              (bit-shift-left seed 6)
+              (bit-shift-right seed 2))))
+
+(defn- hash-coll [coll]
+  (reduce hash-combine (map hash coll)))

 (defn- scan-array [incr k array]
   (let [len (.length array)]
@@ -1061,6 +1087,9 @@

   IEquiv
   (-equiv [coll other] (equiv-map coll other))
+
+  IHash
+  (-hash [coll] (hash-coll coll))

   ISeqable
   (-seq [coll]


* src/cljs/cljs/core.cljs: simple string hash caching

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -828,8 +828,44 @@
          (recur ret (first ks) (next ks))
          ret))))

+;; Simple approach probably something better
+;; and faster out there
+(def hash-cache-purge-threshold 256)
+(def hash-cache (js-obj))
+(def hash-cache-count 0)
+(def hash-cache-mru-size 32)
+(def hash-cache-mru (array))
+
+(defn update-hash-cache-mru [k h]
+  (.push hash-cache-mru (array k h))
+  (when (> (alength hash-cache-mru) hash-cache-mru-size)
+    (.shift hash-cache-mru)))
+
+(defn add-to-hash-cache [k]
+  (let [h (goog.string/hashCode k)]
+    (aset hash-cache k h)
+    (update-hash-cache-mru k h)
+    (set! hash-cache-count (inc hash-cache-count))
+    h))
+
+(defn check-hash-cache [k]
+  (if (> hash-cache-count hash-cache-purge-threshold)
+    (let [mrul (alength hash-cache-mru)]
+      (set! hash-cache (js-obj))
+      (dotimes [i mrul]
+        (let [kv (aget hash-cache-mru i)]
+          (aset hash-cache (aget kv 0) (aget kv 1))))
+      (set! hash-cache-count mrul)
+      (add-to-hash-cache k))
+    (let [h (aget hash-cache k)]
+      (if-not (nil? h)
+        h
+        (add-to-hash-cache k)))))
+
 (defn hash [o]
-  (-hash o))
+  (if ^boolean (goog/isString o)
+    (check-hash-cache o)
+    (-hash o)))

 (defn ^boolean empty?
   "Returns true if coll has no items - same as (not (seq coll)).


CLJS-1101 cljs.test might throw when trying to detect file-and-line

--- src/cljs/cljs/test.cljs
+++ src/cljs/cljs/test.cljs
@@ -372,19 +372,18 @@
       default)))

 (defn file-and-line [exception depth]
-  (let [stack (.-stack exception)]
-      (if (and stack (string? stack))
-        ;; TODO: flesh out
-        (let [stacktrace
-              (vec (map string/trim
-                     (string/split stack #"\n")))
-              stack-element (nth stacktrace depth)
-              fname (js-filename stack-element)
-              [line column] (js-line-and-column stack-element)
-              [fname line column] (mapped-line-and-column fname line column)]
-          {:file fname :line line :column column})
-        {:file (.-fileName exception)
-         :line (.-lineNumber exception)}))  )
+  ;; TODO: flesh out
+  (if-let [stack-element (and (string? (.-stack exception))
+                              (some-> (.-stack exception)
+                                      string/split-lines
+                                      (get depth)
+                                      string/trim))]
+    (let [fname (js-filename stack-element)
+          [line column] (js-line-and-column stack-element)
+          [fname line column] (mapped-line-and-column fname line column)]
+      {:file fname :line line :column column})
+    {:file (.-fileName exception)
+     :line (.-lineNumber exception)}))

 (defn do-report [m]
   (let [m (case (:type m)


document async testing

document async testing

--- src/cljs/cljs/test.cljs
+++ src/cljs/cljs/test.cljs
@@ -101,6 +101,20 @@
    \"(arithmetic addition)\", in failure reports.  You can use nested
    tests to set up a context shared by several tests.

+   DEFINING ASYNC TESTS
+
+   (deftest addition
+     (async done
+       (is (= 4 (+ 2 2)))
+       (is (= 7 (+ 3 4)))
+       (done)))
+
+   Async tests are constructed with the async macro. The first argument to
+   the macro is the test completion callback. The body of the async macro may
+   be any series of expressions. The completion callback must be invoked when
+   all assertions have run. There is no support for asynchronous coordination -
+   core.async is recommended for this. Note the body of the async test must be
+   truly asynchronous to avoid stack overflow.

    RUNNING TESTS


Limit width of collection boxes to minimum necessary

Don't let containers for collections span the full
width of the page, even if they are display:block.

--- src/cljs_formatter.cljs
+++ src/cljs_formatter.cljs
@@ -71,6 +71,19 @@
         child-box (.toBox (style/getBounds child))]
     (< (.-right parent-box) (.-right child-box))))

+
+(defn max-inline-width [elem container]
+  (let [child (d/single-node elem)
+        parent (.-parentNode (d/single-node elem))
+        container-node (d/single-node container)
+        left-bound (.-left (.toBox (style/getBounds child)))
+        parent-right-bound (.-right (.toBox (style/getBounds parent)))
+        container-right-bound (.-right (.toBox (style/getBounds container-node)))]
+    (- (min parent-right-bound container-right-bound) left-bound)))
+
+(defn width [elem]
+  (.-width (style/getBounds (d/single-node elem))))
+
 (declare arrange-element!)

 ;; Colors chosen with the help of Adobe Kuler
@@ -118,7 +131,12 @@
       (if (d/has-class? child "separator")
         (d/set-styles! child {:display "none"})
         (do (arrange-element! (next-state state) child container)
-            (d/set-styles! child {:display "block"}))))))
+            (d/set-styles! child {:display "block"}))))
+    ;; Make containing box no wider than it needs to be
+    (d/set-styles! elem {:width (str (+ (width contents)
+                                        (width opener)
+                                        (width closer))
+                                      "px")})))

 (defn remove-all-styles! [elem]
   ;; remove-attr! doesn't always work
@@ -140,18 +158,6 @@

 (defn arrange! [elem container]
   (arrange-element! initial-arrange-state elem container))
-
-(defn max-inline-width [elem container]
-  (let [child (d/single-node elem)
-        parent (.-parentNode (d/single-node elem))
-        container-node (d/single-node container)
-        left-bound (.-left (.toBox (style/getBounds child)))
-        parent-right-bound (.-right (.toBox (style/getBounds parent)))
-        container-right-bound (.-right (.toBox (style/getBounds container-node)))]
-    (- (min parent-right-bound container-right-bound) left-bound)))
-
-(defn width [elem]
-  (.-width (style/getBounds (d/single-node elem))))

 (defn condense-collection! [elem container]
   (let [[opener contents closer] (d/children elem)


Indentation fixes

Indentation fixes

--- src/clojure/neko/ui.clj
+++ src/clojure/neko/ui.clj
@@ -44,10 +44,10 @@
   [kw]
   (let [first-level-parents (-> @keyword-mapping kw :parents)]
     (->> first-level-parents
-      (mapcat all-parents)
-      (concat first-level-parents)
-      distinct)))
-
+         (mapcat all-parents)
+         (concat first-level-parents)
+         distinct)))
+
 (defn keyword-add-value
   "Associate the value keyword with the provided value for the given keyword representing the UI element."
   [element-kw value-kw value]
@@ -66,7 +66,7 @@
     value
     (or (-> @keyword-mapping element-kw :values value)
         (symbol (str (.getName (classname element-kw)) \/ (kw-to-static-field value))))))
-
+
 ;; These would be moved somewhere at some point.
 ;;
 (do
@@ -137,10 +137,10 @@

 Taken from clj-android by remvee."
   ([width height weight]
-    (let [real-width (attribute-value :layout-params (or width :wrap))
-          real-height (attribute-value :layout-params (or height :wrap))
-          real-weight (or weight 0)]
-      `(new LinearLayout$LayoutParams ~real-width ~real-height ~real-weight))))
+     (let [real-width (attribute-value :layout-params (or width :wrap))
+           real-height (attribute-value :layout-params (or height :wrap))
+           real-weight (or weight 0)]
+       `(new LinearLayout$LayoutParams ~real-width ~real-height ~real-weight))))

 (defmethod transform-attributes :layout-params [el-type obj attributes
                                                 generated-code]
@@ -170,7 +170,7 @@
                             (attribute-value el-type value)
                             value)]
            `(~(symbol (str ".set" (capitalize (name attr)))) ~obj ~real-value)))
-         attributes))
+       attributes))

 (defn process-attributes
   "Takes an UI element type, its object symbol and a map of


CMR-5201: Fixes for size estimate utility functions.

--- src/cmr/sizing/core.clj
+++ src/cmr/sizing/core.clj
@@ -93,13 +93,14 @@
            :params params})
         ;; Stage 3
         [services vars params bounding-info s3-errs s3-warns]
-        (stage3 component
-                service-ids
-                vars
-                bounding-box
-                {:endpoint search-endpoint
-                 :token user-token
-                 :params params})
+        (ous/stage3
+          component
+          service-ids
+          vars
+          bounding-box
+          {:endpoint search-endpoint
+           :token user-token
+           :params params})
         warns s3-warns
         ;; Error handling for all stages
         errs (errors/collect


Adding «implication-context»

Adding «implication-context»

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

--- src/conexp/fca/more.clj
+++ src/conexp/fca/more.clj
@@ -243,6 +243,23 @@
                    (disj min-attrs m)
                    neighbours))))))

+;;; Certain contexts
+
+(defn implication-context
+  "Returns a context for a non-negative number n which has as it's
+  extents the closure systems on the set {0 .. (n-1)} and as it's
+  intents the corresponding implicational theory."
+  [n]
+  (assert (and (number? n) (<= 0 n))
+          "Must be given a non-negative number.")
+  (let [base-set  (set-of-range 0 n)
+        base-sets (subsets base-set)]
+    (make-context base-sets
+                  (set-of (make-implication A #{x}) |
+                          A base-sets
+                          x (difference base-set base-sets))
+                  respects?)))
+
 ;;;

 nil


Remove code comment [skip ci]

Remove code comment [skip ci]

--- backend/test/akvo/lumen/test_utils.clj
+++ backend/test/akvo/lumen/test_utils.clj
@@ -35,7 +35,7 @@
           status (:status job)
           res (when (and status (not= "PENDING" status))
                 (if (= "OK" status)
-                  (:dataset_id ds-job) ;;job
+                  (:dataset_id ds-job)
                   job-execution-id))]
       (when res
         (if with-job?


Proper exporter for components to chapter mapping

--- src/hurvinek/server.clj
+++ src/hurvinek/server.clj
@@ -317,7 +317,7 @@
           product-id    (get params "product-id")
           components    (db-interface/read-components-to-chapter product-id)
           output-format (get-output-format request)
-          output-data   (exporter/components-output-data output-format components)
+          output-data   (exporter/components-to-chapter-mapping-output-data output-format components)
           mime-type     (mime-type output-format)]
         (-> (http-response/response output-data)
             (http-response/content-type mime-type))))


Use atom's node for worker-thread

Use atom's node for worker-thread

atom ships with its own node - https://github.com/atom/atom-shell/tree/master/vendor.
No weird behavior is observed e.g. chromium getting spun up.
This change removes the need to package LT with a node binary.

--- src/lt/objs/thread.cljs
+++ src/lt/objs/thread.cljs
@@ -57,16 +57,19 @@
                   :reaction (fn [app]
                               (object/raise worker :kill!)))

-(defn node-exe []
-  (if (platform/win?)
-    "/plugins/node/node.exe"
-    "/plugins/node/node"))
-
+;; Provides a forked thread, mainly for use with background macro. Parent thread
+;; sends messages to child thread. Child thread performs work and sends results
+;; back to parent thread.
 (object/object* ::worker-thread
                 :tags #{:worker-thread}
                 :queue []
                 :init (fn [this]
-                        (let [worker (.fork cp (files/lt-home "/core/node_modules/lighttable/background/threadworker.js") (clj->js ["--harmony"]) (clj->js {:execPath (files/lt-home (node-exe)) :silent true}))]
+                        (let [worker (.fork cp (files/lt-home "/core/node_modules/lighttable/background/threadworker.js")
+                                            (clj->js ["--harmony"])
+                                            (clj->js {:execPath js/process.execPath
+                                                      :silent true
+                                                      :env {"ATOM_SHELL_INTERNAL_RUN_AS_NODE" 1}
+                                                      :cwd files/pwd}))]
                           (.on (.-stdout worker) "data" (fn [data]
                                                           (console/loc-log {:file "thread"
                                                                             :line "stdout"


Return an error when validating the manifest and there is none

--- src/mdr2/production.clj
+++ src/mdr2/production.clj
@@ -46,7 +46,7 @@
   returns an empty list"
   [production]
   (if (not (manifest? production))
-    []
+    ["No manifest found"]
     (->> (range (:volumes production))
          (map inc)
          (map #(path/manifest-path production %))


Oops, *actually* don't log ping events

Oops, *actually* don't log ping events

--- src/braid/core/server/sync_handler.clj
+++ src/braid/core/server/sync_handler.clj
@@ -30,7 +30,7 @@

 (defn event-msg-handler* [{:as ev-msg :keys [id ?data event]}]
   (when-not (= event [:chsk/ws-ping])
-    (when (not= event :braid.client/ping)
+    (when-not (= event [:braid.client/ping])
       (debugf "User: %s Event: %s" (get-in ev-msg [:ring-req :session :user-id]) event))

     (when-let [user-id (get-in ev-msg [:ring-req :session :user-id])]


small fix

small fix

--- src/clj/salava/metabadge/metabadge.clj
+++ src/clj/salava/metabadge/metabadge.clj
@@ -94,7 +94,7 @@
                                                         (first v)
                                                         (if (some #(= (str (:user_badge_id %)) (str user_badge_id)) v)
                                                           (->> (remove #(not (= (str user_badge_id) (str (:user_badge_id %)))) v) first)
-                                                          (->> v (sort-by :issued_on <) first))))) []))
+                                                          (->> v (sort-by :issued_on <) (sort-by :deleted) first))))) []))
         not-received-required-badges (some->> all-required-badges
                                               (remove (fn [badge] (some #(= (select-keys badge [:required_badge_id]) (select-keys % [:required_badge_id])) received-required-badges))))]
     (assoc {} :required_badges ((comp flatten concat) received-required-badges not-received-required-badges)


Improve printing of ClojureScript conditions and document what is missing.

--- src/cljx/active/clojure/condition.cljx
+++ src/cljx/active/clojure/condition.cljx
@@ -28,8 +28,31 @@
   (and #+clj (instance? ExceptionInfo x)
        (contains? (ex-data x) ::condition)))

-#+clj
 (declare print-condition)
+
+;; Printing conditions in ClojureScript:
+;;
+;; TODO `print-method` does not exist in ClojureScript and there is no
+;; other way to define how an object should print itself.  For now,
+;; you have to call `print-condition` yourself.
+;;
+;; TODO `*ns*` does not exist in ClojureSript.  Therefore, it would be
+;; nice to have at least file name and line number information stored
+;; in `ex-info-msg`, but this does not work:
+;;
+;; (let [e (new js/Error "message" "file" 23)]
+;;   (println (.-message e))
+;;   (println (.-fileName e))
+;;   (println (.-lineNumber e)))
+;;
+;; as it prints
+;;
+;; message
+;; nil
+;; nil
+;;
+;; TODO Also, there is no run-time-independent way to get a stack
+;; trace in ClojureScript.

 #+clj
 (defmethod print-method ExceptionInfo [^ExceptionInfo exc ^java.io.Writer w]
@@ -40,8 +63,9 @@
 #+cljs
 (def *ns* "<cljs>")

-(def ^:private ex-info-msg
-  (str "This is a " *ns* " util.condition."))
+(defn ^:private ex-info-msg
+  [namespace]
+  (str "This is a " namespace " active.clojure.condition."))

 (defrecord ConditionType
     [name supertype field-names total-field-count])
@@ -81,7 +105,8 @@

   For internal use only."
   [condition-components]
-  (ex-info ex-info-msg
+  (ex-info #+clj (ex-info-msg *ns*)
+           #+cljs (ex-info-msg "<cljs>")
            {::condition true
             ::components condition-components}))

@@ -122,7 +147,7 @@
       local-index)))

 #+cljs
-(defrecord Error [str])
+(def Error js/Error)

 (defn condition-accessor
   "Create an an accessor for `field-name` for conditions of type `type`."
@@ -137,7 +162,7 @@
                             comp))
                      (::components (ex-data cond)))]
         (nth (:arguments comp) i)
-        (throw (Error. (str cond " is not a condition of type " type)))))))
+        (throw (new Error (str cond " is not a condition of type " type)))))))

 (defmacro define-condition-type
   "    (define-condition-type <condition-type>
@@ -399,3 +424,26 @@
           (pr irritant))
         (.write w "\n")))
     (print-stack-trace-of c)))
+
+#+cljs
+(defn print-condition
+  [c]
+  (let [[type who message stuff] (decode-condition c)]
+    (print (name type))
+    (print ": ")
+    (if (string? message)
+      (let [s message]
+        (print s))
+      (print message))
+    (let [spaces
+          (apply str (repeat (+ (count (name type)) 2)
+                             \space))]
+      (when who
+        (print " [")
+        (print who)
+        (print "]"))
+      (doseq [irritant stuff]
+        (print "\n")
+        (print spaces)
+        (pr irritant))
+      (print "\n"))))


up version

up version

--- kafka-clj/project.clj
+++ kafka-clj/project.clj
@@ -1,4 +1,4 @@
-(defproject kafka-clj "0.5.0-SNAPSHOT"
+(defproject kafka-clj "0.5.1-SNAPSHOT"
   :description "fast kafka library implemented in clojure"
   :url "https://github.com/gerritjvv/kafka-fast"
   :license {:name "Eclipse Public License"


+(deftest infinitive-vp)

+(deftest infinitive-vp)

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -1,7 +1,7 @@
 (ns babel.test.en
   (:refer-clojure :exclude [get-in])
   (:require [babel.engine :as engine]
-            [babel.english :refer [analyze fo-ps generate parse]]
+            [babel.english :refer [analyze fo-ps generate parse sentences]]
             [babel.english.grammar :as grammar]
             [babel.english.lexicon :refer [lexicon]]
             [babel.english.morphology :refer [fo get-string]]
@@ -254,3 +254,19 @@
                        :model medium)]
     (is (= (fo expr)
            "the chair is in front of itself"))))
+
+(deftest infinitive-vp
+  (let [medium (grammar/medium)
+        vp-infinitive (:vp-infinitive (:grammar-map medium))
+        expr (-> vp-infinitive
+                 (overh (get (:lexicon medium) "speak"))
+                 (overc (generate {:synsem {:sem {:pred :word
+                                                  :mod '()
+                                                  :spec {:def :def
+                                                         :pred :definite}}
+                                            :cat :noun}})))]
+    (is true)))
+
+
+
+


working on comp-paths-to-lightning-bolts idea

--- test/babel/test/en.cljc
+++ test/babel/test/en.cljc
@@ -378,11 +378,22 @@
                                         "read"))
                                lbs))

-        comp-comp-spec (get-in good-lb [:comp :comp])
-        comp-spec (get-in good-lb [:comp])]
-
-    (is (not (empty? (babel.generate/lightning-bolts med (get-in good-lb [:head :comp]) 0 0))))
-    (is (empty? (babel.generate/lightning-bolts med (get-in good-lb [:comp]) 0 0)))))
+        comp-paths (babel.generate/find-comp-paths good-lb)
+        paths-to-specs (zipmap
+                        comp-paths
+                        (map #(get-in good-lb %)
+                             comp-paths))
+        paths-to-lbs
+        (zipmap
+         comp-paths
+         (map #(babel.generate/lightning-bolts
+                med
+                (get-in good-lb %)
+                0 0)
+              comp-paths))]
+
+    (is (not (empty? (get paths-to-lbs [:head :comp]))))
+    (is (empty? (get paths-to-lbs [:comp])))))

 (deftest rathole-check-2
   (let [med (medium)
@@ -566,3 +577,20 @@
     (is (= "I am eating" (morph (generate progressive))))))

+(deftest lb1
+  (let [comp-paths (babel.generate/find-comp-paths good-lb)
+        paths-to-specs (zipmap
+                        comp-paths
+                        (map #(get-in good-lb %)
+                             comp-paths))
+        paths-to-lbs
+        (zipmap
+         comp-paths
+         (map #(babel.generate/lightning-bolts
+                med
+                (get-in good-lb %)
+                0 0)
+              comp-paths))]
+
+    (is (not (empty? (get paths-to-lbs [:head :comp]))))
+    (is (not (empty? (get paths-to-lbs [:comp]))))))


add comments about roundtrip-np-grammar test

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -97,10 +97,14 @@
 (deftest roundtrip-np-grammar
   (let [do-this-many 100
         expressions (take do-this-many
-                          (engine/generate-all {:synsem {:sem {:spec {:def :top}
-                                                               :mod {:pred :top}
+                          (engine/generate-all {:synsem {:sem {:mod {:pred :top}
                                                                :number :top
-                                                               :pred :top}}}
+                                                               :pred :top
+                                                               :spec {:def :top}}}}
+                                               ;; change the above
+                                               ;; generic spec to something more specific
+                                               ;; if this test fails and you want to investigate
+                                               ;; why.
                                                np-grammar))]
     (is (= do-this-many
            (count (map-fn (fn [expr]


testing "clocks"

testing "clocks"

--- test/java_time_test.clj
+++ test/java_time_test.clj
@@ -495,8 +495,18 @@
       (is (not (j/not-before? i i+5)))))

   (testing "clocks"
-    (is (j/after? (j/fixed-clock 1000) (j/fixed-clock 0)))
-    (is (j/before? (j/fixed-clock 1000) (j/fixed-clock 5000))))
+    (let [fc (j/fixed-clock 0)
+          fc+1000 (j/fixed-clock 1000)]
+      (is (j/after? fc+1000 fc))
+      (is (not (j/after? fc fc+1000)))
+      (is (j/before? fc fc+1000))
+      (is (not (j/before? fc+1000 fc)))
+      (is (j/not-after? fc fc))
+      (is (j/not-after? fc fc+1000))
+      (is (not (j/not-after? fc+1000 fc)))
+      (is (j/not-before? fc fc))
+      (is (j/not-before? fc+1000 fc))
+      (is (not (j/not-before? fc fc+1000)))))

   (testing "fields"
     (is (j/after? (j/day-of-week :saturday) :thursday))


add test for upgrading composite profiles (see #61).

--- test/leiningen/ancient/artifact/files_test.clj
+++ test/leiningen/ancient/artifact/files_test.clj
@@ -132,3 +132,28 @@
             artifacts => (contains #{'[artifact  [:dependencies 2]]})
             artifacts => (contains #{'[artifact2 [:dependencies 3]]})
             (write-string! upgraded) => expected))))
+
+(fact "about project file upgrading with profiles."
+      (let [opts (const-opts "0.1.1")
+            mk #(format
+                  (str "(defproject project-x \"0.1.1-SNAPSHOT\"\n"
+                       "  :dependencies [[artifact %s]\n"
+                       "                 [other \"0.1.5\"]\n"
+                       "                 [other2 \"0.1.3\"]]\n"
+                       "  :profiles {:dev {:dependencies [[artifact2 %s]]}\n"
+                       "             :build [:dev\n"
+                       "                     {:dependencies [[artifact3 %s]]}]})")
+                  (pr-str %)
+                  (pr-str %)
+                  (pr-str %))]
+        (with-temp-file [tmp (mk "0.1.0")]
+          (let [f (read! (project-file tmp))
+                outdated (check! f opts)
+                artifacts (map (juxt (comp :symbol :artifact) :path) outdated)
+                upgraded (upgrade! f outdated)
+                expected (mk "0.1.1")]
+            (count outdated) => 3
+            artifacts => (contains #{'[artifact  [:dependencies 0]]})
+            artifacts => (contains #{'[artifact2 [:profiles :dev :dependencies 0]]})
+            artifacts => (contains #{'[artifact3 [:profiles :build 1 :dependencies 0]]})
+            (write-string! upgraded) => expected))))


Formatting.

Formatting.

--- clj_record/test/model/manufacturer.clj
+++ clj_record/test/model/manufacturer.clj
@@ -3,8 +3,7 @@
             [clj-record.validation.built-ins :as vfn]))

-; def'd here to illustrate that validation messages
-; don't have to live inline in the init-model form.
+; def'd here to illustrate that validation messages don't have to live inline in the init-model form.
 (def my-grade-validation-message "negative!")

 (defn infer-full-year [year]


delaney.clj: made (invariant) a bit more lazy

--- clojure/org/gavrog/clojure/delaney.clj
+++ clojure/org/gavrog/clojure/delaney.clj
@@ -99,9 +99,9 @@
 (defn invariant [ds]
   (when (pos? (size ds))
     (let [idcs (indices ds)]
-      (apply lexicographically-smallest
-             (for [D (elements ds)]
-               (protocol ds idcs (pretty-traversal ds idcs [D])))))))
+      (reduce lexicographically-smallest
+              (for [D (elements ds)]
+                (protocol ds idcs (pretty-traversal ds idcs [D])))))))

 (defn orbit-reps
   ([ds indices seeds]


Adjust log levels

Adjust log levels

--- src/muon_clojure/rx.clj
+++ src/muon_clojure/rx.clj
@@ -16,27 +16,28 @@
 (defn subscription [s ch]
   (reify Subscription
     (request [this n]
-      (log/info "::::: SUBSCRIPTION" s ":: request" n)
+      (log/trace "::::: SUBSCRIPTION" s ":: request" n)
       (go
         (loop [remaining n]
           (when-not (= 0 remaining)
             (if-let [item (<! ch)]
               (do
-                (log/info "onNext" (dekeywordize item))
+                (log/trace "onNext" (dekeywordize item) remaining)
                 (.onNext s (dekeywordize item))
                 (recur (dec remaining)))
               (close-subscription s ch))))))
     (cancel [this]
-      (close! ch))))
+      (close! ch)
+      (log/debug "subscription cancelled"))))

 (defn publisher [gen-fn params]
-  (log/info (str "::::::::::::::::::::::::::::::: " (pr-str params)))
+  (log/debug (str "::::::::::::::::::::::::::::::: " (pr-str params)))
   (reify Publisher
     (^void subscribe [this ^Subscriber s]
-     (log/info "subscribe::::::::: SUBSCRIBER" s)
+     (log/debug "subscribe::::::::: SUBSCRIBER" s)
      (let [ch (gen-fn (keywordize params))
            sobj (subscription s ch)]
-       (log/info "Assigned channel:" (.hashCode ch))
+       (log/trace "Assigned channel:" (.hashCode ch))
        (.onSubscribe s sobj)))))

 (defn subscriber [n]
@@ -50,32 +51,35 @@
                    (alter requested #(+ % x))))
         s (reify Subscriber
             (^void onSubscribe [this ^Subscription s]
-             (log/info "onSubscribe" s)
+             (log/debug "onSubscribe" s)
              (dosync
-              (alter active-s (fn [_] s))
-              (request n)))
+              (alter active-s (fn [_] s)))
+             (request n))
             (^void onNext [this ^Object obj]
              (when-not (nil? @active-s)
                (log/debug "onNext:::::::::::: CLIENTSIDE[-> " (.hashCode ch)
-                          "][" (.hashCode this) "]" obj)
+                          "][" (.hashCode this) "]" obj "/" (.count buf))
                (let [res (>!! ch obj)]
-                 (log/trace "Push:" res)
+                 (log/trace "Push:" obj res @requested)
                  (dosync
                   (alter requested dec)
                   (if res
-                    (if (= 0 @requested)
+                    (if (<= @requested 0)
                       (request n))
-                    (do
-                      (.cancel @active-s)
-                      (alter active-s (fn [_] nil))))))))
+                    (let [a-s @active-s]
+                      (alter active-s (fn [_] nil))
+                      (when-not (nil? a-s)
+                        (.cancel a-s))))))))
             (^void onError [this ^Throwable t]
-             (log/info "onError" (.getMessage t))
+             (log/error "onError" (.getMessage t))
              (put! ch t))
             (^void onComplete [this]
              (when-not (nil? @active-s)
-               (log/info "onComplete")
+               (log/debug "onComplete")
                (close! ch)
                (dosync
-                (.cancel @active-s)
-                (alter active-s (fn [_] nil))))))]
+                (let [a-s @active-s]
+                  (alter active-s (fn [_] nil))
+                  (when-not (nil? a-s)
+                    (.cancel a-s)))))))]
     [s ch]))


Move ch up.

Move ch up.

--- src/onyx/coordinator/async.clj
+++ src/onyx/coordinator/async.clj
@@ -18,8 +18,8 @@

 (def completion-ch (chan 1000))

-(defn mark-peer-birth [log sync peer]
-  (extensions/await-death sync dead-peer-ch)
+(defn mark-peer-birth [log sync peer death-cb]
+  (extensions/await-death sync death-cb)
   (extensions/mark-peer-born log peer))

 (defn mark-peer-death [log peer]
@@ -36,12 +36,12 @@
   (extensions/delete sync task)
   (extensions/evict log task))

-(defn offer-task [log sync]
+(defn offer-task [log sync ack-cb complete-cb]
   (when (extensions/next-task log)
     (extensions/create-ack-node sync)
     (extensions/create-completion-node sync)
-    (extensions/await-ack sync ack-ch)
-    (extensions/await-completion sync completion-ch)
+    (extensions/await-ack sync ack-cb)
+    (extensions/await-completion sync complete-cb)
     (extensions/mark-offered log)
     (extensions/write-payload sync)))

@@ -53,7 +53,7 @@
 (defn born-peer-ch-loop [log sync]
   (loop []
     (let [peer (<!! born-peer-ch)]
-      (mark-peer-birth log sync peer)
+      (mark-peer-birth log sync peer #(>!! dead-peer-ch %))
       (>!! offer-ch peer)
       (recur))))

@@ -87,7 +87,9 @@
 (defn offer-ch-loop [log sync]
   (loop []
     (let [event (<!! offer-ch)]
-      (when (offer-task log sync)
+      (when (offer-task log sync
+                        #(>!! ack-ch %)
+                        #(>!! completion-ch %))
         (thread (<!! (timeout eviction-delay))
                 (>!! evict-ch nil)))
       (recur))))