[#797] WIP searching for the most probably patterns

--- backend/src/akvo/lumen/import.clj
+++ backend/src/akvo/lumen/import.clj
@@ -36,7 +36,7 @@
                                   :table-name table-name
                                   :imported-table-name imported-table-name
                                   :version 1
-                                  :columns (mapv (fn [{:keys [title id type key multiple-type multiple-id]}]
+                                  :columns (mapv (fn [{:keys [title id type key multiple-type multiple-id splitable]}]
                                                    {:columnName (name id)
                                                     :direction nil
                                                     :hidden false
@@ -44,6 +44,7 @@
                                                     :multipleId multiple-id
                                                     :multipleType multiple-type
                                                     :sort nil
+                                                    :splitable splitable
                                                     :title (string/trim title)
                                                     :type (name type)})
                                                  columns)
@@ -54,7 +55,6 @@
   (update-failed-job-execution conn {:id job-execution-id
                                      :reason [reason]})
   (drop-table conn {:table-name table-name}))
-

 (defn val->geometry-pgobj
   [v]
@@ -70,57 +70,32 @@
   org.postgis.Point
   (sql-value [v] (val->geometry-pgobj v)))

-
 (defn l [t o]
   (log/error t o)
   o)

+(defn fun*fun [c v]
+  (let [regex "[^a-zA-Z0-9\\s]"
+        freqs (frequencies (re-seq (re-pattern regex) v))]
+    (reset! c
+            (reduce (fn [c2 [k v2]]
+                      (assoc c2 k
+                             {:max-coincidences-in-one-row (max v2 (get-in c2 [k :max-coincidences-in-one-row] 0))
+                              :total-row-coincidences (inc (get-in c2 [k :total-row-coincidences] 0))
+                              :total-coincidences (+ v2 (get-in c2 [k :total-coincidences] 0))}))
+                    @c freqs))))

-(frequencies (re-seq (re-pattern "[^a-zA-Z0-9\\s]") "lkjasd f&8(/&"))
-
-
-(def regex "[^a-zA-Z0-9\\s]")
-
-(let [data ["uss/" "a·bc1&&&&???????23de?f" "lk&&&&&&&jasdf& 8"]
-      res (->>
-           data
-           (reduce
-            (fn [c v]
-              (let [f (frequencies (re-seq (re-pattern regex) v))]
-                (reduce (fn [c2 [k v2]]
-                          (assoc c2 k {:max-by-row (max v2 (get-in c2 [k :by-row] 0))
-                                       :row-coincidences (inc (get-in c2 [k :row-coincidences] 0))
-                                       :total (+ v2 (get-in c2 [k :total] 0))}))
-                        c f)))
-            {}))]
-  {:total-count (count data)
-   :max-by-row  (seq (into (sorted-map-by >) (group-by (fn [c] (:max-by-row (val c))) res)))
-   :row-coincidences  (seq (into (sorted-map-by >) (group-by (fn [c] (:row-coincidences (val c))) res)))
-   :total-rows (seq (into (sorted-map-by >) (group-by (fn [c] (:total (val c))) res)))})
-
-
-{:max-by-row
- [[8
-   [["&" {:max-by-row 8, :row-coincidences 2, :total 12}]
-    ["?" {:max-by-row 8, :row-coincidences 1, :total 8}]]]
-  [1
-   [["/" {:max-by-row 1, :row-coincidences 1, :total 1}]
-    ["·" {:max-by-row 1, :row-coincidences 1, :total 1}]]]],
- :row-coincidences
- [[2 [["&" {:max-by-row 8, :row-coincidences 2, :total 12}]]]
-  [1
-   [["/" {:max-by-row 1, :row-coincidences 1, :total 1}]
-    ["·" {:max-by-row 1, :row-coincidences 1, :total 1}]
-    ["?" {:max-by-row 8, :row-coincidences 1, :total 8}]]]],
- :total-count 3,
- :total-rows
- [[12 [["&" {:max-by-row 8, :row-coincidences 2, :total 12}]]]
-  [8 [["?" {:max-by-row 8, :row-coincidences 1, :total 8}]]]
-  [1
-   [["/" {:max-by-row 1, :row-coincidences 1, :total 1}]
-    ["·" {:max-by-row 1, :row-coincidences 1, :total 1}]]]]}
-
-
+(defn splitable [stores columns record]
+  (log/debug :splitable stores columns)
+  (reduce-kv
+   (fn [result k v]
+     (let [column (first (filter #(= k (:id %)) columns))]
+       (when (= :text (:type column))
+         (let [store (get stores column)]
+           (fun*fun store v)))))
+   {}
+   record)
+  record)

 (defn do-import
   "Import runs within a future and since this is not taking part of ring
@@ -131,13 +106,19 @@
       (let [spec (:spec (data-source-spec-by-job-execution-id conn {:job-execution-id job-execution-id}))]
         (with-open [importer (import/dataset-importer (get spec "source") config)]
           (let [columns (import/columns importer)
-                records (import/records importer)]
+                records (import/records importer)
+                stores (apply assoc {} (interleave columns (repeatedly #(atom {}))))
+                rows-count (atom 0)]
             (import/create-dataset-table conn table-name columns)
             (import/add-key-constraints conn table-name columns)
-            (doseq [record (map (comp import/coerce-to-sql (partial l :raw-row)) records)]
-              (l :coerced record)
+            (doseq [record (map (comp import/coerce-to-sql (partial splitable stores columns)) records)]
+              (swap! rows-count inc)
               (jdbc/insert! conn table-name record))
-            (successful-import conn job-execution-id table-name columns spec claims data-source))))
+            (successful-import conn job-execution-id table-name
+                               (map #(assoc % :splitable
+                                            (map (fn [[k v]] [k (assoc v :rows @rows-count)]) @(last %2)))
+                                    columns stores)
+                               spec claims data-source))))
       (catch Throwable e
         (failed-import conn job-execution-id (.getMessage e) table-name)
         (log/error e)


[#1189] Use update on top level element

[#1189] Use update on top level element

--- backend/src/akvo/lumen/update.clj
+++ backend/src/akvo/lumen/update.clj
@@ -83,7 +83,7 @@
           {:keys [transformations] :as dataset-version} (latest-dataset-version-by-dataset-id
                                                          conn {:dataset-id dataset-id})]
       (with-open [importer (import/dataset-importer (get data-source-spec "source") config)]
-        (let [columns (map #(update-in % [:title] string/trim)
+        (let [columns (map #(update % :title string/trim)
                            (import/columns importer))]
           (if-not (compatible-columns? imported-columns columns)
             (failed-update conn job-execution-id "Column mismatch")


Use snapshot version of cider-nrepl

Use snapshot version of cider-nrepl

--- roles/clojure/files/profiles.clj
+++ roles/clojure/files/profiles.clj
@@ -7,7 +7,7 @@
                        [slamhound "1.5.3"]
                        [spyscope "0.1.4"]]

-        :plugins [[cider/cider-nrepl "0.7.0"]
+        :plugins [[cider/cider-nrepl "0.8.0-SNAPSHOT"]
                   [codox "0.6.6"]
                   [jonase/eastwood "0.1.4"]
                   [lein-ancient "0.5.5" :exclusions [commons-codec]]


adding basic data structures

adding basic data structures

--- src-cljs/graph.cljs
+++ src-cljs/graph.cljs
@@ -2,7 +2,8 @@
   (:refer-clojure :exclude
    [ get get-in vals
      concat mapcat
-     into-array])
+     into-array
+     vector hash-map set])
   (:require
     [graph.core :as graph]
     [clojure.string :refer [join]]))
@@ -88,6 +89,10 @@
 (def ^:export mapcat cljs.core/mapcat)
 (def ^:export into-array cljs.core/into-array)

+(def ^:export vector cljs.core/vector)
+(def ^:export hash-map cljs.core/hash-map)
+(def ^:export set cljs.core/set)
+
 (def ^:export clj-to-js cljs.core/clj->js)
 (defn ^:export js-to-clj
   ([x] (cljs.core/js->clj x))


MMT-1382 update preview gem to UMM-C v1.10

--- collection-renderer-lib/project.clj
+++ collection-renderer-lib/project.clj
@@ -14,7 +14,7 @@
    the hardcoded commit id during dev integration with cmr_metadata_preview project.
    The hardcoded commit id should be updated when MMT releases a new version of the gem."
   (or (System/getenv "CMR_METADATA_PREVIEW_COMMIT")
-      "038b76b94f2"))
+      "487bb407418"))

 (def gem-install-path
   "The directory within this library where Ruby gems are installed."


finally worked out all the code!

finally worked out all the code!

--- code/clj/nihil/src/nihil/core.clj
+++ code/clj/nihil/src/nihil/core.clj
@@ -4,11 +4,10 @@
 (defn -main
   "I don't do a whole lot ... yet."
   [& args]
-  (def x (set '(nil)))
-  (defn test-null
-    [x]
-    (empty x)
-    (not-empty x)
-    (true? x)
-    (false? x))
-  (test-null x))
+  (let [f #(
+    (println "empty?" (empty? %))
+    (println "empty" (not (nil? (empty %))))
+    (println "not-empty" (not (nil? (not-empty %))))
+    (println "true?" (true? %))
+    (println "false?" (false? %)))]
+  (f (set '(nil)))))


more diagnostics about comps failing to unify with a rule

--- src/babel/over.cljc
+++ src/babel/over.cljc
@@ -146,12 +146,16 @@
 (defn comp-pre-checks2 [parent child]
   (some #(= :fail %)
         (map (fn [pair]
-               (let [result
-                     (unifyc (get-in parent (:parent pair))
-                             (get-in child (:childc pair)))]
+               (let [parent-value (get-in parent (:parent pair) :top)
+                     child-value (get-in parent (:childc pair) :top)
+                     result
+                     (unifyc parent-value child-value)]
                  (if (fail? result)
                    (do
                      (log/debug (str "comp precheck failed  for pair: " pair))
+                     (log/debug (str "comp precheck failed: parent wanted:" (strip-refs parent-value) ";"
+                                     "child has: " (strip-refs child-value)))
+                     (log/debug (str " child is: " (strip-refs child)))
                      :fail)
                    (do
                      (log/debug (str "comp precheck success for pair: " pair))


Fix spelling

Fix spelling

--- app/src/cljs/app/components.cljs
+++ app/src/cljs/app/components.cljs
@@ -63,7 +63,7 @@
     [:div.mdl-cell-mdl-cell--8-col.employmentdescription
      [:p (:description employment)]]]])

-(defn emploment-component
+(defn employment-component
   [employments]
   [:div#employment
    [section-component


Renamed to fenced-dispatcher.

Renamed to fenced-dispatcher.

--- src/cbfg/fence.cljs
+++ src/cbfg/fence.cljs
@@ -21,41 +21,37 @@
 ;; request format
 ;; {:rq function-to-call :fence true-or-false}

-(defn make-rq-processor [max-inflights]
-  (let [in-channel (chan 100)
-        out-channel (chan)]
-    (go-loop
-        [inflights #{}            ; chans of requests currently being processed.
-         fenced nil               ; chan of last, inflight "fenced" request.
-         fenced-res nil]          ; last received result from last fenced request.
-      (let [i (vec (if (or fenced ; if we're fenced or too many inflight requests,
-                           (>= (count inflights) max-inflights))
-                     inflights    ; then ignore in-channel & finish existing inflight requests.
-                     (conj inflights in-channel)))
-            [v ch] (if (empty? i) ; empty when in-channel is closed and no inflights.
-                     [nil nil]
-                     (alts! i))]
-        (cond
-         (= nil v ch) (close! out-channel)
-         (= ch in-channel) (if (nil? v)
-                             (recur inflights out-channel nil)
-                             (let [new-inflight ((:rq v))]
-                               (recur (conj inflights new-inflight)
-                                      (if (:fence v) new-inflight nil)
-                                      nil)))
-         (= v nil) (let [new-inflights (disj inflights ch)] ; an inflight request is done.
-                     (if (empty? new-inflights)
-                       (do (when fenced-res                 ; all inflight requests are done, so we can
-                             (>! out-channel fenced-res))   ; send the fenced-res that we've been keeping.
-                           (recur new-inflights nil nil))
-                       (recur new-inflights fenced fenced-res)))
-         (= ch fenced) (do (when fenced-res
-                             (>! out-channel fenced-res))   ; send off any previous fenced-res so
-                           (recur inflights fenced v))      ; we can keep v as fenced-res.
-         :else (do (>! out-channel v)
-                   (recur inflights fenced fenced-res)))))
-    {:in in-channel
-     :out out-channel}))
+(defn make-fenced-dispatcher [in-channel out-channel max-inflights]
+  (go-loop
+      [inflights #{}            ; chans of requests currently being processed.
+       fenced nil               ; chan of last, inflight "fenced" request.
+       fenced-res nil]          ; last received result from last fenced request.
+    (let [i (vec (if (or fenced ; if we're fenced or too many inflight requests,
+                         (>= (count inflights) max-inflights))
+                   inflights    ; then ignore in-channel & finish existing inflight requests.
+                   (conj inflights in-channel)))
+          [v ch] (if (empty? i) ; empty when in-channel is closed and no inflights.
+                   [nil nil]
+                   (alts! i))]
+      (cond
+       (= nil v ch) (close! out-channel)
+       (= ch in-channel) (if (nil? v)
+                           (recur inflights out-channel nil)
+                           (let [new-inflight ((:rq v))]
+                             (recur (conj inflights new-inflight)
+                                    (if (:fence v) new-inflight nil)
+                                    nil)))
+       (= v nil) (let [new-inflights (disj inflights ch)] ; an inflight request is done.
+                   (if (empty? new-inflights)
+                     (do (when fenced-res                 ; all inflight requests are done, so we can
+                           (>! out-channel fenced-res))   ; send the fenced-res that we've been keeping.
+                         (recur new-inflights nil nil))
+                     (recur new-inflights fenced fenced-res)))
+       (= ch fenced) (do (when fenced-res
+                           (>! out-channel fenced-res))   ; send off any previous fenced-res so
+                         (recur inflights fenced v))      ; we can keep v as fenced-res.
+       :else (do (>! out-channel v)
+                 (recur inflights fenced fenced-res))))))

 (def test-requests
   [{:rq #(add-two 1 2000)}
@@ -70,7 +66,9 @@
    ])

 (defn test-rq-processor []
-  (let [{:keys [in out]} (make-rq-processor 2)
+  (let [in (chan 100)
+        out (chan)
+        fdp (make-fenced-dispatcher in out 2)
         gch (go-loop [acc nil]
               (let [result (<! out)]
                 (if result


scheduler: Prevent possible NullPointerException during rebalance.

--- scheduler/src/cook/mesos/rebalancer.clj
+++ scheduler/src/cook/mesos/rebalancer.clj
@@ -233,7 +233,7 @@
                                             (into {}))
         task->scored-task (into (pm/priority-map-keyfn (case category
                                                          :normal (comp - :dru)
-                                                         :gpu -))
+                                                         :gpu (fnil - 0)))
                                 (case category
                                   :normal (dru/sorted-task-scored-task-pairs user->sorted-running-task-ents user->dru-divisors)
                                   :gpu (dru/gpu-task-scored-task-pairs user->sorted-running-task-ents user->dru-divisors)))]


Don't need to fix results since EDN

Don't need to fix results since EDN

--- src-backend/cljs/cljs_webrepl/repl.cljs
+++ src-backend/cljs/cljs_webrepl/repl.cljs
@@ -15,7 +15,7 @@
                           ["/src/cljs" "/js/compiled/out"]
                           replumb-io/fetch-file!)
          {:no-pr-str-on-value true
-          :warning-as-error   false
+          :warning-as-error   true
           :verbose            false}))

 (def current-ns replumb-repl/current-ns)
@@ -33,7 +33,7 @@
       :else           (assoc acc (keyword key) value))))

 (defn- obj->map
-  "Workaround for `TypeError: Cannot convert object to primitive value`s
+  "Workaround for `TypeError: Cannot convert object to primitive values`
   caused by `(js->clj (.-body  exp-req) :keywordize-keys true)` apparently
   failing to correctly identify `(.-body exp-req)` as an object. Not sure
   what's causing this problem."
@@ -58,20 +58,14 @@
         (object? value) (obj->map value)
         :default        (str value)))

-(defn fix-result [result]
-  (-> result
-      (update :value fix-value)
-      (update :error err->map)))
-
 (defn on-repl-eval [[num expression] from-repl repl-opts]
+  (debugf "on-repl-eval: %s %s" num expression)
   (put! from-repl [:repl/eval num (replumb-repl/current-ns) expression])

   (let [print-fn  #(put! from-repl [:repl/print num %])
-        result-fn #(put! from-repl [:repl/result num (replumb-repl/current-ns) (fix-result %)])]
+        result-fn #(put! from-repl [:repl/result num (replumb-repl/current-ns) %])]
     (binding [cljs.core/*print-newline* true
               cljs.core/*print-fn*      print-fn]
-      (tracef "REPL: %s" expression)
-      ;; Use the 3rd argument to put! so the :init event is sent first
       (replumb/read-eval-call repl-opts result-fn expression))))

 (defn repl-loop [from-repl to-repl repl-opts]


use boot time as a corruption check

use boot time as a corruption check

--- src-cljs/frontend/components/admin.cljs
+++ src-cljs/frontend/components/admin.cljs
@@ -131,7 +131,7 @@
     om/IRender
     (render [_]
       (let [fleet-state (->> (get-in app state/fleet-state-path)
-                             (filter #(-> % :ec2_instance_type not-empty)) ;; remove corrupt entries
+                             (filter #(-> % :boot_time not-empty)) ;; remove corrupt entries
                              (remove #(-> % :builder_tags (= ["os:none"])))
                              (sort-by :instance_id))
             summary-counts (get-in app state/build-system-summary-path)


Remove LD flag from beta icon

Remove LD flag from beta icon

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -525,15 +525,14 @@
                   [:div.nav-label "Changelog"]]))

-             (when (ld/feature-on? "beta-sidebar-icon")
-               [:a.aside-item {:data-placement "right"
+             [:a.aside-item {:data-placement "right"
                                :data-trigger "hover"
                                :title "What's New"
                                :target "_blank"
                                :href "https://circleci.com/beta-access/"
                                :on-click #(aside-nav-clicked owner :changelog-icon-clicked)}
                (icon/engine-2)
-               [:div.nav-label "What's New"]])
+               [:div.nav-label "What's New"]]

              (when (:admin user)
                [:a.aside-item {:class (when (= :admin-settings current-route) "current")


Revert "bump max container pill count to 20"

This reverts commit 342d2e4db239dcd3f1e144539ba31b8f49f486d6.

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -333,7 +333,7 @@
             (om/build container-result-icon {:name icon-name})]]
           (om/build container-duration-label {:actions (:actions container)})])))))

-(def paging-width 20)
+(def paging-width 10)

 (defrender container-controls [{:keys [current-filter containers categorized-containers]} owner]
   (let [filters [{:filter :all


:bug: Fix bug in fixtures (intoduced in renaming).

--- backend/src/app/cli/fixtures.clj
+++ backend/src/app/cli/fixtures.clj
@@ -86,7 +86,7 @@
                                :fullname (str "Profile " index)
                                :password "123123"
                                :demo? true
-                               :email (str "profile" index ".test@app.io")})))
+                               :email (str "profile" index ".test@uxbox.io")})))

         create-profiles
         (fn [conn]


fix assumedTrue

fix assumedTrue

--- src/datest1/ret.clj
+++ src/datest1/ret.clj
@@ -13,34 +13,68 @@
     )

 (defmacro assumedTrue
-  [x & all]
+  "will throw if any of the passed expressions evaluate to false or nil"
+  [& all]
   `(do
-;   (let [f# ~x eva# (eval f#)]
-     (prn '~(rest &form))
-  true)
-;      (prn f# eva#)
-;      (when-not eva#
-;        (do
-;          (throw
-;            (AssertionError.
-;              (str
-;                "assumedTrue failed " ;
+     (let [myname# '~(first &form) allp# '~(rest &form)]
+       (cond (<= (count allp#) 0)
+         (throw
+            (AssertionError.
+              (str "you passed no parameters to `" myname# "`"
+                   )
+              )
+            )
+         )
+     (loop [allparams# allp#]
+   (let [
+         ;f# ~x eva# (eval f#)
+         ;allparams# '~(rest &form)
+         exactform# (first allparams#)
+         evalled# (eval exactform#)
+         ]
+     ;(prn "all params:" '~(rest &form))
+     (prn "exactform#:" exactform#)
+     (prn "evalled:" evalled# "rest count:" (count allparams#))
+     ;(prn "third:" evalled#)
+     ;true)
+      ;(prn "aT:" (quote ~x) f# eva#)
+      (when-not evalled#
+        (do
+          (throw
+            (AssertionError.
+              (str
+                myname# " failed "
+                exactform#
+                " was "
+                evalled#
 ;                (prn-str
-;                  f#
-;                  "was"
-;                  eva#)
-;                )
-;              )
-;            )
-;          )
-;        )
-;      (if ~(empty? all)
-;        true
-;        false
-;        (assumedTrue ~(first all) ~(rest all))
-;        )
-;     )
+;                  exactform#
+;                  "is"
+;                  evalled#)
+                )
+              )
+            )
+          )
+        )
+;      ~(prn "teh:" all)
+;      true
+
+      (cond (<= (count allparams#) 1);aka no more ;~@(empty? all)
+        true
+        :else
+        (do
+          (prn "COUNT:" (count allparams#) "rest:" (rest allparams#))
+          ( recur (rest allparams#))
+          ;'(assumedTrue (rest allparams#))
+          )
+        )
+     )
   )
+)))
+
+;TODO: make tests for this macro
+;(assumedTrue 1 2 3 (> 2 1) (= :a :a) (= 1 2))
+;(assumedTrue)

 ;(println *file*)

@@ -51,7 +85,8 @@

 (defn comparator_AZ_order [key1 key2]
   {:pre [ (assumedTrue (keyword? key1) (keyword? key2)) ]
-   }
+   }
+  (prn "comparatorAZ:" key1 key2 (keyword? key1) (keyword? key2))
   (compare key1 key2)
   )

@@ -83,6 +118,7 @@
 (defn
   ^:private
 add_new_key [quoted_key_name thekey]
+  ( println "add_new_key: " quoted_key_name thekey)
   (swap! -allkeys
          assoc2
          quoted_key_name thekey


We should return the deployment ID when undoing a deployment

--- src/exploud/web.clj
+++ src/exploud/web.clj
@@ -203,7 +203,9 @@
          (if-let [deployment (first (store/get-deployments {:application application
                                                             :environment environment
                                                             :size 1}))]
-           (dep/start-deployment (:id (dep/prepare-undo deployment)))
+           (let [{:keys [id]} (dep/prepare-deployment deployment)]
+             (dep/start-deployment id)
+             (response {:id id}))
            (error-response "No previous deployment" 500)))

    (POST "/applications/:application/rollback"


Refactor preloading

Refactor preloading

--- src/asciinema/player/source.cljs
+++ src/asciinema/player/source.cljs
@@ -88,30 +88,15 @@
                        (deliver (recording-fn res))))))))

 (defn report-metadata
-  "Waits for recording to load and then reports its size and duration to the
-  player."
-  [{:keys [recording-ch-fn]} msg-ch]
-  (go
-    (let [{:keys [duration width height]} (<! (@recording-ch-fn false))]
-      (>! msg-ch (m/->SetMetadata width height duration))
-      (>! msg-ch (m/->TriggerCanPlay)))))
+  "Reports recording dimensions and duration to the player."
+  [{:keys [width height duration]} msg-ch]
+  (put! msg-ch (m/->SetMetadata width height duration))
+  (put! msg-ch (m/->TriggerCanPlay)))

 (defn show-poster
-  "Forces loading of recording and sends 'poster' at a given time to the
-  player."
-  [{:keys [recording-ch-fn]} time msg-ch]
-  (go
-    (let [{:keys [frames]} (<! (@recording-ch-fn true))]
-      (>! msg-ch (m/->UpdateScreen (screen-at time frames))))))
-
-(defn show-loading
-  "Reports 'loading' to the player until the recording is loaded."
-  [{:keys [recording-ch-fn]} msg-ch]
-  (when-not (poll! (@recording-ch-fn false))
-    (go
-      (>! msg-ch (m/->SetLoading true))
-      (<! (@recording-ch-fn false))
-      (>! msg-ch (m/->SetLoading false)))))
+  "Sends 'poster' at a given time to the player."
+  [{:keys [frames]} time msg-ch]
+  (put! msg-ch (m/->UpdateScreen (screen-at time frames))))

 (defn emit-coll
   "Starts sending frames as events with a given name, stopping when out-ch
@@ -169,9 +154,9 @@
       (>! msg-ch (m/->SetPlaying false))
       stopped-at)))

-(defn start-event-loop!
+(defn start-event-loop
   "Main event loop of the Recording."
-  [{:keys [recording-ch-fn start-at speed loop?] :as source} command-ch msg-ch]
+  [{:keys [start-at speed loop? command-ch]} msg-ch data]
   (let [pri-ch (chan 10)]
     (go-loop [start-at start-at
               speed speed
@@ -183,12 +168,10 @@
         (condp = command
           :start (if stop-ch
                    (recur start-at speed end-ch stop-ch)
-                   (do
-                     (show-loading source msg-ch)
-                     (let [{:keys [frames duration]} (<! (@recording-ch-fn true))
-                           stop-ch (chan)
-                           end-ch (play! msg-ch frames duration start-at speed loop? stop-ch)]
-                       (recur nil speed end-ch stop-ch))))
+                   (let [{:keys [frames duration]} data
+                         stop-ch (chan)
+                         end-ch (play! msg-ch frames duration start-at speed loop? stop-ch)]
+                     (recur nil speed end-ch stop-ch)))
           :stop (if stop-ch
                   (do
                     (close! stop-ch)
@@ -212,35 +195,49 @@
           :exit nil
           :internal/rewind (recur 0 speed nil nil)
           :internal/seek (let [start-at arg
-                               {:keys [frames duration]} (<! (@recording-ch-fn true))
+                               {:keys [frames duration]} data
                                start-at (util/adjust-to-range start-at 0 duration)]
                            (>! msg-ch (m/->UpdateTime start-at))
                            (>! msg-ch (m/->UpdateScreen (screen-at start-at frames)))
                            (recur start-at speed end-ch stop-ch)))))))

-(defrecord Recording [recording-ch-fn command-ch start-at speed auto-play? loop? preload? poster-time]
+(defn start-preloader [{:keys [recording-ch-fn command-ch force-load-ch preload? poster-time] :as recording} msg-ch]
+  (go
+    (let [recording-ch (recording-ch-fn (or preload? poster-time))
+          [v c] (alts! [recording-ch force-load-ch])
+          data (condp = c
+                 recording-ch v
+                 force-load-ch (do
+                                 (>! msg-ch (m/->SetLoading true))
+                                 (let [data (<! (recording-ch-fn true))]
+                                   (>! msg-ch (m/->SetLoading false))
+                                   data)))]
+      (when poster-time
+        (show-poster data poster-time msg-ch))
+      (report-metadata data msg-ch)
+      (start-event-loop recording msg-ch data))))
+
+(defrecord Recording [recording-ch-fn command-ch force-load-ch start-at speed auto-play? loop? preload? poster-time]
   Source
   (init [this]
     (let [msg-ch (chan)]
-      (start-event-loop! this command-ch msg-ch)
-      (report-metadata this msg-ch)
-      (when preload?
-        (@recording-ch-fn true))
-      (if auto-play?
-        (start this)
-        (when poster-time
-          (show-poster this poster-time msg-ch)))
+      (start-preloader this msg-ch)
+      (when auto-play?
+        (start this))
       msg-ch))
   (close [this]
     (put! command-ch [:stop])
     (put! command-ch [:exit]))
   (start [this]
+    (close! force-load-ch)
     (put! command-ch [:start]))
   (stop [this]
     (put! command-ch [:stop]))
   (toggle [this]
+    (close! force-load-ch)
     (put! command-ch [:toggle]))
   (seek [this time]
+    (close! force-load-ch)
     (put! command-ch [:seek time]))
   (change-speed [this speed]
     (put! command-ch [:change-speed speed])))
@@ -251,9 +248,11 @@
                                                         js/JSON.parse
                                                         (js->clj :keywordize-keys true)
                                                         initialize-asciicast)))
-        command-ch (chan 10)]
-    (->Recording (atom recording-ch-fn)
+        command-ch (chan 10)
+        force-load-ch (chan)]
+    (->Recording recording-ch-fn
                  command-ch
+                 force-load-ch
                  start-at
                  speed
                  auto-play


fix published message in extract2/simple-extract_content

--- src/brainbot/nozzle/extract2.clj
+++ src/brainbot/nozzle/extract2.clj
@@ -28,10 +28,10 @@
                   (vfs/extract-content fs path)
                   (catch Throwable err
                     nil))
-        new-entry (if extract
-                    (assoc entry :extract extract)
-                    entry)]
-    (publish "import_file" new-entry)))
+        new-body (if extract
+                   (assoc body :extract extract)
+                   body)]
+    (publish "import_file" new-body)))

 (defn build-handle-connection


add some links and nodes

add some links and nodes

--- src/clj/ceres_analytics/core.clj
+++ src/clj/ceres_analytics/core.clj
@@ -17,6 +17,7 @@
             [compojure.handler :refer [site api]]
             [taoensso.timbre :refer [info debug error warn] :as timbre]
             [org.httpkit.server :refer [with-channel on-receive on-close run-server send!]]))
+

 (timbre/refer-timbre)

@@ -42,13 +43,38 @@

 (def links ["mentions" "shares" "replies" "retweets" "urlrefs" "tagrefs" "unknown"])

+(defn get-random-links []
+  (let [publications (map
+                      (fn [{:keys [_id name] :as user}]
+                        [user
+                         (map
+                          #(mc/find-map-by-id @db "messages" (:target %))
+                          (mc/find-maps @db "pubs" {:source _id
+                                                    :ts {$gt (t/date-time 2015 3 19 8)
+                                                         $lt (t/date-time 2015 3 19 9)}}))])
+                      (mc/find-maps @db "users" {:name {$in news-accounts}}))]
+    (loop [pubs publications
+           result {:nodes []
+                   :links []}
+           user-counter 0]
+      (if (empty? pubs)
+        result
+        (let [[user messages] (first pubs)
+              n (count messages)
+              nodes (concat [{:name (:_id user) :value (:name user) :group 1}] (map (fn [{:keys [text _id]}] {:name _id :value text :group 2}) messages))
+              links (map (fn [i] {:source i :target user-counter}) (range (inc user-counter) (+ user-counter n 1)))]
+          (recur (rest pubs)
+                 (-> result
+                     (update-in [:nodes] concat nodes)
+                     (update-in [:links] concat links))
+                 (+ user-counter n 1)))))))

 (defn dispatch-request
   "Dispatch incoming requests"
   [{:keys [topic data]}]
   (case topic
-    :graph {:nodes [10 20 30] :links [[10 20] [20 30] [30 10]]}
+    :graph (get-random-links)
     :unrelated))

@@ -81,11 +107,10 @@

-  (let [messages (mc/find-maps @db "messages" {:ts {$gt (t/date-time 2015 3 18 8)
-                                                    $lt (t/date-time 2015 3 18 8 10)}})
-        retweets (map  (fn [{:keys [_id text]}]
-                         [text (mc/find-maps @db "retweets" {:target _id})]) messages)]
-    )
+  (def users )
+
+
+

   )


Fixed tag not being added from Joshua B.

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -248,9 +248,9 @@
    {:events {:runner-turn-begins
              {:optional {:prompt "Use Joshua B. to gain [Click]?"
                          :yes-ability {:msg "gain [Click]"
-                                       :effect (effect (gain :click 1))}}}
-             :end-turn {:effect (effect (tag-runner 1))
-                        :msg "gain 1 tag"}}}
+                                       :effect (effect (gain :click 1))
+                                       :end-turn {:effect (effect (tag-runner 1))
+                                                  :msg "gain 1 tag"}}}}}}

    "Kati Jones"
    {:abilities


Add validation states and help texts to the forms

in particular to the two hyphenation and the word forms

--- src/cljs/hyphen_keeper/core.cljs
+++ src/cljs/hyphen_keeper/core.cljs
@@ -17,6 +17,7 @@

 (def spelling (reagent/cursor app-state [:spelling]))
 (def word (reagent/cursor app-state [:word]))
+(def hyphenations (reagent/cursor app-state [:hyphenations]))
 (def hyphenation (reagent/cursor app-state [:hyphenation]))
 (def suggested-hyphenation (reagent/cursor app-state [:suggested-hyphenation]))

@@ -95,22 +96,24 @@
 (defn- hyphenation-pattern-edit-ui
   [word new-hyphenation stop save]
   (let [valid? (hyphenation-valid? @new-hyphenation word)
-        klass (if valid? "form-group" "form-group has-error")]
+        klass (when-not valid? "has-error")
+        help-text (when-not valid? "The hyphenation is not valid")]
     [:tr
      [:td word]
      [:td
-      [:div
+      [:div.form-group
        {:class klass}
        [:input.form-control
         {:type "text"
          :auto-focus true
+         :aria-describedby "hyphenationEditHelp"
          :on-change #(reset! new-hyphenation (-> % .-target .-value))
          :on-key-down #(case (.-which %)
                          27 (stop)
                          nil)
          :value @new-hyphenation}]
-       (when-not valid?
-         [:span.sr-only "(error)"])]]
+       (when help-text
+         [:span#hyphenationEditHelp.help-block help-text])]]
      [:td
       [:div.btn-group
        [:button.btn.btn-default
@@ -137,30 +140,48 @@
           [hyphenation-pattern-edit-ui word new-hyphenation stop save])))))

 (defn word-ui []
-  [:div.form-group
-   [:label {:for "wordInput"} "Word"]
-   [:input.form-control
-    {:id "wordInput"
-     :type "text"
-     :placeholder "Word"
-     :auto-focus true
-     :value @word
-     :on-change (fn [e]
-                  (reset! word (-> e .-target .-value string/lower-case))
-                  (load-hyphenation-patterns! @spelling @word))
-     :on-blur #(lookup-hyphenation-pattern! @spelling @word)}]])
+  (let [label "Word"
+        already-defined? (contains? @hyphenations @word)
+        klass (when already-defined? "has-warning")
+        help-text (when already-defined? "Word has already been defined. Use Edit to change it")]
+    [:div.form-group
+     {:class klass}
+     [:label.control-label {:for "wordInput"} label]
+     [:input.form-control
+      {:id "wordInput"
+       :type "text"
+       :placeholder label
+       :auto-focus true
+       :aria-describedby "wordHelp"
+       :value @word
+       :on-change (fn [e]
+                    (reset! word (-> e .-target .-value string/lower-case))
+                    (load-hyphenation-patterns! @spelling @word))
+       :on-blur #(lookup-hyphenation-pattern! @spelling @word)}]
+     (when help-text
+       [:span#wordHelp.help-block help-text])]))

 (defn hyphenation-ui []
   (let [label "Corrected Hyphenation"
-        klass (if (hyphenation-valid? @hyphenation @word) "form-group" "form-group has-error")]
-    [:div
+        valid? (hyphenation-valid? @hyphenation @word)
+        same-as-suggested? (= @hyphenation @suggested-hyphenation)
+        klass (cond
+                (not valid?) "has-error"
+                same-as-suggested? "has-warning")
+        help-text (cond
+                    (not valid?) "The hyphenation is not valid"
+                    (= @hyphenation @suggested-hyphenation) "The hyphenation is the same as the suggestion")]
+    [:div.form-group
      {:class klass}
-     [:label {:for "hyphenationInput"} label]
+     [:label.control-label {:for "hyphenationInput"} label]
      [:input.form-control
       {:type "text"
        :placeholder label
+       :aria-describedby "hyphenationHelp"
        :value @hyphenation
-       :on-change #(reset! hyphenation (-> % .-target .-value string/lower-case))}]]))
+       :on-change #(reset! hyphenation (-> % .-target .-value string/lower-case))}]
+     (when help-text
+       [:span#hyphenationHelp.help-block help-text])]))

 (defn- hyphenation-add-ui []
   [:div.form-group


Loop outside binding and fix CLJS master issue (#366)

It looks like the CLJS compiler is now not permitting to recur inside a binding
form. This works around the issue in the only place we do it: print-error.

--- src/cljs/snapshot/lumo/repl.cljs
+++ src/cljs/snapshot/lumo/repl.cljs
@@ -483,28 +483,31 @@
    (print-error error stacktrace? nil))
   ([error stacktrace? printed-message]
    (binding [*print-fn* *print-err-fn*]
-     (print-error-column-indicator error)
-     (let [error (extract-cljs-js-error error)
-           message (ex-message error)]
-       (when (or (not ((fnil string/starts-with? "") printed-message message))
-                 stacktrace?)
-         (println (str message (when (reader-error? error)
-                                 (location-info error)))))
-       #_(when-let [data (and print-ex-data? (ex-data error))]
-         (print-value data {::as-code? false}))
-       (when stacktrace?
-         (let [canonical-stacktrace (st/parse-stacktrace
-                                      {}
-                                      (.-stack error)
-                                      {:ua-product :nodejs}
-                                      {:output-dir "file://(/goog/..)?"})]
-           (println
-             (st/mapped-stacktrace-str
+     (loop [error error
+            stacktrace? stacktrace?
+            printed-message printed-message]
+       (print-error-column-indicator error)
+       (let [error (extract-cljs-js-error error)
+             message (ex-message error)]
+         (when (or (not ((fnil string/starts-with? "") printed-message message))
+                   stacktrace?)
+           (println (str message (when (reader-error? error)
+                                   (location-info error)))))
+         #_(when-let [data (and print-ex-data? (ex-data error))]
+             (print-value data {::as-code? false}))
+         (when stacktrace?
+           (let [canonical-stacktrace (st/parse-stacktrace
+                                       {}
+                                       (.-stack error)
+                                       {:ua-product :nodejs}
+                                       {:output-dir "file://(/goog/..)?"})]
+             (println
+              (st/mapped-stacktrace-str
                canonical-stacktrace
                {}
                nil))))
-       (when-let [cause (.-cause error)]
-         (recur cause stacktrace? message))))))
+         (when-let [cause (.-cause error)]
+           (recur cause stacktrace? message)))))))

 (defn- handle-error [error stacktrace?]
   (print-error error stacktrace?)


thomsky: Fix horrible typos, clarify

thomsky: Fix horrible typos, clarify

 - I don't know what I was doing. Fix mistakes in spelling and grammar.

 - Clarify some statements in the docs.

 - Correct a line length.

--- src/cljs/theatralia/thomsky.cljs
+++ src/cljs/theatralia/thomsky.cljs
@@ -40,10 +40,10 @@
 ;;
 ;; If the application is getting slow, your first step towards a diagnosis
 ;; should be to uncomment the line below and watch in the console when and how
-;; often bind is called. – If it only gets cold as many times as there are binds
-;; in the code and only on application load, your problem lies something else.
-;; If it gets called more often than that and while the application runs (for
-;; example, when you click or type), there are two likely causes:
+;; often bind is called. – If it only gets called as many times as there are
+;; binds in the code and only on application load, your problem lies somewhere
+;; else. If it gets called more often than that and while the application runs
+;; (for example, when you click or type), there are two likely causes:
 ;;
 ;;  - You've wrapped a call to bind in a reagent.ratom/reaction. In this case
 ;;    bind gets called whenever the app-db changes, which is not what you want.
@@ -51,12 +51,12 @@
 ;;  - You've used a Form-1 component where you should use a Form-2 component.
 ;;    See https://github.com/Day8/re-frame/wiki/Creating-Reagent-Components.
 ;;
-;; If it wasn't repeated bind calls, you might want to filter out scratch
-;; changes. At tag filter-scratch you can find a change that introduced that,
-;; but wasn't needed at the time.
+;; If it wasn't repeated bind calls, you might want to exclude scratch changes
+;; from being checked for novelties. At tag filter-scratch you can find a
+;; commit that introduced that, but wasn't needed at the time.
 (defn bind
-  "Returns a ratom containing the result of query Q on the value of the database
-  behind CONN with the arguments Q-ARGS."
+  "Returns a ratom containing the result of query Q with the arguments Q-ARGS on
+  the value of the database behind CONN."
   [q conn & q-args]
   ;(println "bind called" q) ; Commented out on purpose. – See note above.
   (let [k (uuid/make-random-uuid)
@@ -75,14 +75,14 @@
     state))

 (defn unbind
-  "Stops updates on ratom STATE from changes in CONN."
+  "Stops changes in CONN from causing updates of ratom STATE."
   [conn state]
   (d/unlisten! conn (.-__key state)))

 (defn pure-datascript
   "Adaptation of the re-frame middleware 'pure' for Thomsky.

-  The HANDLER wrapped with this middleware will receive the current value behind
+  The HANDLER wrapped in this middleware will receive the current value behind
   CONN and has to return a Datascript transaction data structure that will be
   transact!ed over CONN.

@@ -103,7 +103,8 @@
       (d/transact! conn txd))))

 (defn register-handler
-  "Handler registration procedure that provides the right defaults for Theatralia.
+  "Handler registration procedure that provides the right defaults for
+  Theatralia.

   In re-frame, the default handler registration procedure applies only the
   'pure' middleware to a handler. Here we apply the respective 'pure-datascript'


REST API handler for jobs should store HTML results

--- src/emender_service/rest_api.clj
+++ src/emender_service/rest_api.clj
@@ -164,8 +164,8 @@
     (map #(str path-to-tests "/" % ".lua") tests))

 (defn process-results
-    [job-name repo-url branch results]
-        (db-interface/log-job-results job-name repo-url branch results)
+    [job-name repo-url branch results html]
+        (db-interface/log-job-results job-name repo-url branch results html)
         (println "job name" job-name)
         (println "results:" results)
         ;(results/add-new-results job-name results)
@@ -182,11 +182,12 @@
     (let [tests+paths (create-tests+paths path-to-tests tests)]
         (apply exec/exec "scripts/start_proceed" path-to-emender path-to-tests book-directory tests+paths))
         (try
-            (let [results (-> (str book-directory "/results.json") slurp json/read-str)]
+            (let [results (-> (str book-directory "/results.json") slurp json/read-str)
+                  html    (-> (str book-directory "/results.html") slurp)]
                 (if delete-workdirs?
                     (file-utils/remove-temporary-directory book-directory))
-                (if results
-                    (process-results job-name repo-url branch results)
+                (if (and results html)
+                    (process-results job-name repo-url branch results html)
                     (send-response {:status :reading-job-result-failed})))
             (catch Exception e
                 (if delete-workdirs?


Solving 3.10, 3.11 and 3.12

Solving 3.10, 3.11 and 3.12

--- src/fpinscala/datastructures.clj
+++ src/fpinscala/datastructures.clj
@@ -31,7 +31,7 @@
   (loop [cnt n l xs]
     (if (= cnt 0)
       l
-      (recur (dec cnt) (tail-option-2 l)))))                  ;There was bug in tail-option-2 (see above) which has been fixed
+      (recur (dec cnt) (tail-option-2 l)))))                ;There was bug in tail-option-2 (see above) which has been fixed
 ;fpinscala
 ;uses pattern matching but same/similar idea :)
 ;-----------------------------------------------------------------------
@@ -99,6 +99,43 @@

 ;3.10
 ;mine
+(defn fold-left [xs z f]
+  (loop [[x & others] xs acc z]
+    (if (nil? others)
+      (f x acc)
+      (recur others (f x acc)))))
+;
+;fpins
+;relies on @tailrec scala annotation
+;and explicit recursive function invocation
+;but basically mine is equivalent solution as
+;clojure is using loop->recur for tail recursive calls
+;@annotation.tailrec
+;def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match {
+; case Nil => z
+; case Cons (h, t) => foldLeft (t, f (z, h)) (f)
+; }
+;-----------------------------------------------------------------------

-;
+;3.11
+;mine
+(defn sum-fl [xs]
+  (fold-left xs 0 +))
+(defn product-fl [xs]
+  (fold-left xs 1 *))
+(defn len-fl [xs]
+  (fold-left xs  0 (fn [_ x] (+ 1 x))))
+;fpins
+;All are basically same :)
+;-----------------------------------------------------------------------
+
+;3.12
+;mine
+(defn my-reverse [xs]
+  (fold-left xs '() cons))
+(defn my-reverse2 [xs]
+  (fold-right xs [] #(conj %2 %)))                           ;This is
+;way to do it with fold-right as list does not support adding at the end
+;fpins
+;It is done via f-l as in my first attempt
 ;-----------------------------------------------------------------------


Add some clarifications and simplfy some code

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -227,6 +227,9 @@
                                    (let [mw-sym (gensym "mw_sym__")]
                                      [(assoc middleware mw-spec mw-sym) mw-sym]))
             ns (-> verb-fn-sym namespace symbol the-ns)
+            ;; Seems like we should just do the *ns* binding trick once
+            ;; per namespace. Possilby as an additional map passed into
+            ;; analyze*
             ns-metadata (meta ns)
             metadata (merge (reduce-kv (fn [out k v]
                                          (assoc out
@@ -243,6 +246,7 @@
             arglist (first (:arglists metadata))
             arg-resolvers (merge
                             extra-arg-resolvers
+                            ;; Only metadata on the namespace needs this trick (since it is unevaluated)
                             (binding [*ns* ns]
                               (eval (:arg-resolvers metadata))))
             handler (cond->
@@ -401,15 +405,19 @@

 (defn- resolver-entry
   [arg resolver]
-  (if (keyword? resolver)
+  (cond
+    (keyword? resolver)
     (if-let [f (get standard-resolver-factories resolver)]
       [arg (f arg)]
       (throw (ex-info (format "Keyword %s does not identify a known argument resolver." resolver)
-               {:arg arg :resolver resolver})))
-    (if (ifn? resolver)
-      [arg resolver]
-      (throw (ex-info (format "Argument resolver value `%s' is neither a keyword not a function." resolver)
-               {:arg arg :resolver resolver})))))
+                      {:arg arg :resolver resolver})))
+
+    (ifn? resolver)
+    [arg resolver]
+
+    :else
+    (throw (ex-info (format "Argument resolver value `%s' is neither a keyword not a function." resolver)
+                    {:arg arg :resolver resolver}))))

 (defn- maybe-resolver-by-tag
   [arg]
@@ -424,6 +432,11 @@
                {:arg arg :resolver-tags resolver-ks})))))

 (defn- resolvers-for
+  "Peforms a first pass at argument resolution, looking for various meta-data or
+  naming conventions to convert from an argument, to an argument resolver factory, to
+  an argument resolver.
+
+  Returns a map from argument to argument resolver."
   [arglist resolvers-map]
   (into {}
     (keep (fn [arg]


Tweak route params handling to make dispatch maps easier to examine at the REPL

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -332,10 +332,11 @@
              (recur (next pathvec) dispatch' (conj route-params seg))
              ;; no match on path
              not-found-response))
-         (if-let [h (or (get dispatch (:request-method request))
-                        (get dispatch :all))]
-           (h (assoc request
-                :route-params (zipmap (:route-params (meta h)) route-params)))
+         (if-let [{:keys [handler route-param-keys]}
+                  (or (get dispatch (:request-method request))
+                      (get dispatch :all))]
+           (handler (assoc request
+                      :route-params (zipmap route-param-keys route-params)))
            ;; unsupported method for path
            not-found-response))))))

@@ -506,7 +507,8 @@
         dispatch-path (conj pathvec' method)
         route-params  (filterv variable? pathvec)]
     (assoc-in dispatch-map dispatch-path
-      (with-meta handler {:route-params (mapv keyword route-params)}))))
+      {:handler handler
+       :route-param-keys (mapv keyword route-params)})))

 (defn- build-dispatch-map
   "Returns a dispatch-map for use with map-traversal-dispatcher."


New improved threading macros (#65)

New improved threading macros (#65)

--- src/main/clojure/conexp/base.clj
+++ src/main/clojure/conexp/base.clj
@@ -36,6 +36,45 @@
   ([name orig doc]
      (list `defalias (with-meta name (assoc (meta name) :doc doc)) orig)))

+(defn- expand-form-at-first
+  "Expands a form with name at the first position. If f is a symbol
+  returns '(f name)."
+  [name f]
+  (cond
+    (symbol? f) (list f name)
+    (some #(= name %) f) f
+    true (list '-> name f)))
+
+(defn- expand-form-at-last
+  "Expands a form with name at the last position. If f is a symbol
+  returns '(f name)."
+  [name f]
+  (cond
+    (symbol? f) (list f name)
+    (some #(= name %) f) f
+    true (list '->> name f)))
+
+(defmacro asd->
+  "Like functions like 'as-> but with '-> as default iff name is not
+  contained in the form or only a symbol is provided."
+  [expr name & forms]
+  (let [dforms (map #(expand-form-at-first name %) forms)]
+    `(let [~name ~expr
+           ~@(interleave (repeat name) (butlast dforms))]
+       ~(if (empty? forms)
+          name
+          (last dforms)))))
+
+(defmacro asd->>
+  "Like functions like 'as-> but with '->> as default iff name is not
+  contained in the form or only a symbol is provided."
+  [expr name & forms]
+  (let [dforms (map #(expand-form-at-last name %) forms)]
+    `(let [~name ~expr
+           ~@(interleave (repeat name) (butlast dforms))]
+       ~(if (empty? forms)
+          name
+          (last dforms)))))
 ;;; Namespace tools

 (defn immigrate


Fix typo.

Fix typo.

--- src/oc/storage/resources/org.clj
+++ src/oc/storage/resources/org.clj
@@ -27,7 +27,7 @@
 (def default-promoted false)

 (def content-visibility {:disallow-secure-links false
-                         :disallow-public-links false
+                         :disallow-public-board false
                          :disallow-public-share false})

 ;; ----- Utility functions -----


Minor readability and commenting improvements

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -335,23 +335,25 @@
 (defn assign-windows
   [{:keys [onyx.core/monitoring onyx.core/replica onyx.core/state onyx.core/messenger
            onyx.core/windows onyx.core/task-map onyx.core/window-state onyx.core/state-log onyx.core/results] :as event}]
-  (let [id-key (:window/unique-key task-map)]
-    (when (seq windows)
+  (when (seq windows)
+    (let [id-key (:onyx/uniqueness-key task-map)]
       (doall
         (map
           (fn [leaf fused-ack]
             (let [start-time (System/currentTimeMillis)
+                  ;; Message should only be acked when all log updates have been written
+                  ;; As we filter out messages seen before, some replay can be accepted
                   ack-fn (fn []
                            (when (dec-count! fused-ack)
                              (let [link (operation/peer-link @replica state event (:completion-id fused-ack))]
                                (extensions/internal-ack-segment messenger event link fused-ack)))
                            (emit-latency-value :window-log-write-entry monitoring (- (System/currentTimeMillis) start-time)))]
-
               (run!
                 (fn [message]
                   (let [segment (:message message)
-                        unique-id (if id-key (get segment id-key))]
-                    (when-not (and unique-id (state-extensions/filter? (:filter @window-state) event unique-id))
+                        unique-id (if id-key (get segment id-key))
+                        seen? (and unique-id (state-extensions/filter? (:filter @window-state) event unique-id))]
+                    (when-not seen?
                       (inc-count! fused-ack)
                       (->> windows
                            (map (fn [w]


Open and close state-log ony if it is required

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -540,7 +540,10 @@

 (defn resolve-log [pipeline]
-  (assoc pipeline :onyx.core/state-log (state-extensions/initialise-log :atom pipeline)))
+  (assoc pipeline :onyx.core/state-log (if (or (not-empty (:onyx.core/windows pipeline))
+                                               (not-empty (:onyx.core/triggers pipeline)))
+                                         (state-extensions/initialise-log :bookkeeper pipeline))))
+
 ;; place outside of task-lifecycle for testing persistence
 (def test-entries-log (atom {}))

@@ -660,6 +663,8 @@
   (stop [component]
     (taoensso.timbre/info (format "[%s] Stopping Task LifeCycle for %s" id (:onyx.core/task (:pipeline-data component))))
     (when-let [event (:pipeline-data component)]
+      (when-let [state-log (:onyx.core/state-log event)]
+        (state-extensions/close-log state-log event))
       ;; Ensure task operations are finished before closing peer connections
       (close! (:seal-ch component))
       (<!! (:task-lifecycle-ch component))


Simplified by removing transition record.

The functionality has been removed because it wasn't used and complicated
debugging (by creating very large structures) rather than helping it. If this
functionality is added again it should be rethought and done in such a way that
it doesn't complicate the existing functions.

--- src/plugboard/core/plugboard.clj
+++ src/plugboard/core/plugboard.clj
@@ -83,15 +83,7 @@
       (throw (Exception. (format "No transition for tuple: %s" tuple)))
       res)))

-(defn add-transition-record [state step1 decision-result step2]
-  (let [existing-trace (:status-trace state) tuple [step1 decision-result step2]]
-    (assoc state :status-trace
-           (if (nil? existing-trace) (list tuple)
-               (conj existing-trace tuple))))
-)
-
 ;; Returns [next-step new-state]
-;; TODO: Simplify.
 (defn perform-step [step decision-map state]
   (let [decision (lookup-decision decision-map step)]
     (cond
@@ -100,17 +92,17 @@
        (cond
         (bool? decision-result)
         (let [next (lookup-next [step decision-result])]
-          [next (add-transition-record state step decision-result next)])
+          [next state])

         (vector? decision-result)
         (let [next (lookup-next [step (first decision-result)])]
-          [next (add-transition-record (merge state (second decision-result)) step decision-result next)]
+          [next (merge state (second decision-result))]
           )

         :otherwise (throw (IllegalStateException. (format "Step %s. Function %s must result in a boolean" step decision-result)))))

      (bool? decision)
-     (let [next (lookup-next [step decision])] [next (add-transition-record state step decision next)])
+     (let [next (lookup-next [step decision])] [next state])

      :otherwise (throw (IllegalStateException.)))))

@@ -124,16 +116,11 @@

 ;; Ultimately returns [status state]
 (defn get-status-with-state [decision-map state]
-  (let [reverse-transition-trace (fn [state]
-                 (if (contains? state :status-trace)
-                   (assoc state :status-trace (reverse (:status-trace state)))
-                   state))
-        [status new-state]
-        (trampoline flow-step :B1 decision-map (reverse-transition-trace state))
-        ]
-    [status (reverse-transition-trace new-state)]
+  (let [[status new-state]
+        (trampoline flow-step :B1 decision-map state)]
+    [status new-state]
     ))

 (defn get-status [decision-map state]
-  (let [[status state] (get-status-with-state decision-map state)]
+  (let [[status _] (get-status-with-state decision-map state)]
     status))


Force filter package list into String array

--- src/radicalzephyr/boot_junit.clj
+++ src/radicalzephyr/boot_junit.clj
@@ -32,7 +32,7 @@
             (setScanners (into-array Scanner [(TypeAnnotationsScanner.)
                                               (MethodAnnotationsScanner.)]))
             (filterInputsBy (.. (FilterBuilder.)
-                                (includePackage package))))
+                                (includePackage (into-array String [package])))))
         reflections (Reflections. config)
         test-methods (.getMethodsAnnotatedWith reflections
                                                org.junit.Test)]


core: defn-

core: defn-

--- core/data/core.clj
+++ core/data/core.clj
@@ -2399,6 +2399,12 @@
      `(when-not ~x
         (throw (ex-info (str "Assert failed: " ~message "\n" '~x)))))))

+(defmacro defn-
+  "same as defn, yielding non-public def"
+  {:added "1.0"}
+  [name & decls]
+  (list* `defn (with-meta name (assoc (meta name) :private true)) decls))
+
 (defn empty?
   "Returns true if coll has no items - same as (not (seq coll)).
   Please use the idiom (seq x) rather than (not (empty? x))"


code-ids is now using storage

code-ids is now using storage

--- src/clj/backtype/storm/daemon/nimbus.clj
+++ src/clj/backtype/storm/daemon/nimbus.clj
@@ -724,17 +724,13 @@
       (throw (AlreadyAliveException. (str storm-name " is already active"))))
     ))

-(defn code-ids [conf]
-  (-> conf
-      master-stormdist-root
-      read-dir-contents
-      set
-      ))
-
-(defn cleanup-storm-ids [conf storm-cluster-state]
+(defn code-ids [storage]
+  (set (.list storage (nimbus-storage-stormdist-root))))
+
+(defn cleanup-storm-ids [storage storm-cluster-state]
   (let [heartbeat-ids (set (.heartbeat-storms storm-cluster-state))
         error-ids (set (.error-topologies storm-cluster-state))
-        code-ids (code-ids conf)
+        code-ids (code-ids storage)
         assigned-ids (set (.active-storms storm-cluster-state))]
     (set/difference (set/union heartbeat-ids error-ids code-ids) assigned-ids)
     ))
@@ -797,15 +793,16 @@
 (defn do-cleanup [nimbus]
   (let [storm-cluster-state (:storm-cluster-state nimbus)
         conf (:conf nimbus)
+        storage (:storage nimbus)
         submit-lock (:submit-lock nimbus)]
     (let [to-cleanup-ids (locking submit-lock
-                           (cleanup-storm-ids conf storm-cluster-state))]
+                           (cleanup-storm-ids storage storm-cluster-state))]
       (when-not (empty? to-cleanup-ids)
         (doseq [id to-cleanup-ids]
           (log-message "Cleaning up " id)
           (.teardown-heartbeats! storm-cluster-state id)
           (.teardown-topology-errors! storm-cluster-state id)
-          (rmr (master-stormdist-root conf id))
+          (.delete storage (nimbus-storage-stormdist-root id))
           (swap! (:heartbeats-cache nimbus) dissoc id))
         ))))

@@ -826,7 +823,7 @@

 (defn cleanup-corrupt-topologies! [nimbus]
   (let [storm-cluster-state (:storm-cluster-state nimbus)
-        code-ids (set (code-ids (:conf nimbus)))
+        code-ids (code-ids (:storage nimbus))
         active-topologies (set (.active-storms storm-cluster-state))
         corrupt-topologies (set/difference active-topologies code-ids)]
     (doseq [corrupt corrupt-topologies]


Fix some issues on body-params handler.

Fix some issues on body-params handler.

--- src/clojure/catacumba/handlers/parse.clj
+++ src/clojure/catacumba/handlers/parse.clj
@@ -85,12 +85,18 @@

   This function optionally accept a used defined method
   or multimethod where to delegate the body parsing."
-  ([] (body-params {}))
+  ([] (body-params nil))
   ([{:keys [parsefn attr] :or {parsefn parse-body attr :data}}]
-   (fn [context]
-     (let [^Context ctx (:catacumba/context context)]
-       (if (= (:method context) :get)
+   (fn [{:keys [method body] :as context}]
+     (let [ctx (ctx/get-context* context)]
+       (cond
+         (= method :get)
          (ctx/delegate {attr nil})
-         (p/then (ctx/get-body! ctx)
-                 (fn [^TypedData body]
-                   (ctx/delegate {attr (parsefn ctx body)}))))))))
+
+         body
+         (ctx/delegate {attr (parsefn ctx body)})
+
+         (nil? body)
+         (->> (ctx/get-body! ctx)
+              (p/map (fn [^TypedData body]
+                       (ctx/delegate {attr (parsefn ctx body)})))))))))


control-choice now chooses the first item as default

and checks choices to be non-empty and even.

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

--- src/conexp/contrib/draw/control/util.clj
+++ src/conexp/contrib/draw/control/util.clj
@@ -125,6 +125,8 @@
   arguments [frame scene buttons] and can be used with
   with-layout-modifiers, for example."
   [& choices]
+  (assert (second choices))
+  (assert (even? (count choices)))
   (let [choices (apply hash-map choices)]
     (fn [frame scene buttons]
       (let [^JPanel
@@ -144,7 +146,8 @@
             (do-swing
              (.removeAll choice-pane)
              (control frame scene choice-pane)
-             (.validate frame))))))))
+             (.validate frame))))
+        (.setSelectedIndex combo-box 0)))))

 (defmacro with-layout-modifiers
   "Installs given methods to scene with buttons."


Fix test for writequit.org

Fix test for writequit.org

--- test/clj_http/test/core_test.clj
+++ test/clj_http/test/core_test.clj
@@ -561,7 +561,7 @@
   (try
     (is (thrown? SocketTimeoutException
                  (client/request {:scheme :http
-                                  :server-name "www.writequit.org"
+                                  :server-name "writequit.org"
                                   :server-port 80
                                   :request-method :get :uri "/"
                                   :conn-timeout 10})))))


New test: dictionary-status

New test: dictionary-status

--- test/clj_mrazik/irc_bot_test.clj
+++ test/clj_mrazik/irc_bot_test.clj
@@ -311,3 +311,9 @@
             (is (not (more-words-like-this? ""))) ; no wildchars
 )))

+(deftest test-dictionary-status
+    "Check the behaviour of function clj-dopey.irc-bot/dictionary-status"
+    (testing "the function dictionary-status"
+        (with-redefs [dictionary/term-count (fn [] 42)]
+            (is (= (dictionary-status) "Number of terms in dictionary: 42")))))
+


RR: fix test for chart selector items

RR: fix test for chart selector items

--- test/hatti/views/chart_test.cljs
+++ test/hatti/views/chart_test.cljs
@@ -32,7 +32,7 @@

 (deftest charts-render-properly
   (let [container (chart-container chart-form)
-        sel1qs (filter f/categorical? chart-form)
+        sel1qs (into (f/meta-fields chart-form :with-submission-details? true) chart-form)
         stringqs (filter f/text? chart-form)]
     (testing "chart-chooser menu renders properly"
       (is (every? (-> container (sel :li.submenu-list) texts set)
@@ -40,10 +40,15 @@
       ;; First icon is a clock, for submission time
       (is (= "fa fa-clock-o"
              (-> container (sel1 :ul) (sel :i.fa) first (dommy/attr :class))))
-      ;; Rest of the items should be horizontal chart (for select one)
-      (is (= (repeat (count sel1qs) "fa fa-bar-chart fa-flip-h-rotate-90")
-             (->> (-> container (sel1 :ul) (sel :i.fa) rest)
-                  (map #(dommy/attr % :class))))))
+      ;; Rest of the items should be horizontal chart
+      (->> (map #(f/get-icon %) sel1qs)
+           (map (fn [i] (dommy/attr i :class)))
+           rest)
+      (is (=  (->> (map #(f/get-icon %) sel1qs)
+                   (map (fn [i] (dommy/attr i :class)))
+                   rest)
+              (->> (-> container (sel1 :ul) (sel :i.fa) rest)
+                   (map #(dommy/attr % :class))))))
     (testing "string questions are unclickable on the chart menu"
       (let [stringq-texts (map :label stringqs)
             num-stringqs (count stringqs)


CMR-5677: Fix intermittent jruby error.

CMR-5677: Fix intermittent jruby error.

--- dev-system/project.clj
+++ dev-system/project.clj
@@ -68,7 +68,9 @@
                            (println (slurp "resources/text/banner.txt"))
                            (println (slurp "resources/text/loading.txt")))}
   :jvm-opts ["-XX:-OmitStackTraceInFastThrow"
-             "-Dclojure.compiler.direct-linking=true"]
+             "-Dclojure.compiler.direct-linking=true"
+             ;; Avoid race conditions when creating jruby context.
+             "-Dorg.jruby.embed.localcontext.scope=threadsafe"]
              ;; Uncomment to enable logging in jetty.
              ; "-Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StrErrLog"
              ; "-Dorg.eclipse.jetty.LEVEL=INFO"


Hide what should be a private function.

Hide what should be a private function.

--- src/rdf-common/grafter/rdf/protocols.clj
+++ src/rdf-common/grafter/rdf/protocols.clj
@@ -42,7 +42,7 @@
   (commit [repo] "Commit a transaction")
   (rollback [repo] "Rollback a transaction"))

-(defn destructure-quad [quad i default]
+(defn- destructure-quad [quad i default]
   (case i
     0 (:s quad)
     1 (:p quad)


Ensure we require nodejs 'path' module.

Ensure we require nodejs 'path' module.

--- src/aero/core.cljc
+++ src/aero/core.cljc
@@ -20,6 +20,7 @@

 #?(:cljs (def os (nodejs/require "os")))
 #?(:cljs (def fs (nodejs/require "fs")))
+#?(:cljs (def path (nodejs/require "path")))

 (defmulti reader (fn [opts tag value] tag))


Remove unused test file.

Remove unused test file.

--- test/buddy/test_buddy_auth_httpbasic.clj
+++ test/buddy/test_buddy_auth_httpbasic.clj
@@ -1,13 +0,0 @@
-(ns buddy.test_buddy_auth_httpbasic
-  (:require [clojure.test :refer :all]
-            [buddy.crypto.core :refer :all]
-            [buddy.auth.backends.httpbasic :refer [parse-httpbasic-header]]))
-
-(deftest http-basic-tests
-  (testing "Parse httpbasic header from request"
-    (let [header  (format "Basic %s" (str->base64 "foo:bar"))
-          request {:headers {"authorization" header}}
-          parsed  (parse-httpbasic-header request)]
-      (is (not (nil? parsed)))
-      (is (= (:password parsed) "bar"))
-      (is (= (:username parsed) "foo")))))


Add formatter tests for regex

Add formatter tests for regex


JC | Tidied up client_seed test

JC | Tidied up client_seed test

--- test/stonecutter/test/db/client_seed.clj
+++ test/stonecutter/test/db/client_seed.clj
@@ -1,7 +1,6 @@
 (ns stonecutter.test.db.client-seed
   (:require [midje.sweet :refer :all]
             [clauth.client :as cl-client]
-            [stonecutter.db.storage :as storage]
             [stonecutter.db.client-seed :as cs]
             [stonecutter.db.mongo :as m]
             [clauth.store :as cl-store]))
@@ -25,14 +24,14 @@

 (fact "can load client-credentials from a file"
       (cs/load-client-credentials-from-file
-        "test-var/var/test-client-credentials-file.yml") => (just [{:client-id           "7I6DTMPXGESEJ2AEEWVGZF2B5AOFGK6D"
-                                                                          :name          "Yellow File Party"
-                                                                          :client-secret "ABH7ZKGVMKQQA3OITBOXPBVSZMMD5NGS"
-                                                                          :url           "http://yellowfile.org"}
-                                                                         {:client-id     "F7ZFMTRJLS5FF6DTWMBCGWA7CXEQTH24"
-                                                                          :name          "Blue File Party"
-                                                                          :client-secret "ISLS5HVYP65QE6OROI43FLHFFOBGISOG"
-                                                                          :url           "http://bluefile.org"}]
+        "test-var/var/test-client-credentials-file.yml") => (just [{:client-id     "7I6DTMPXGESEJ2AEEWVGZF2B5AOFGK6D"
+                                                                    :name          "Yellow File Party"
+                                                                    :client-secret "ABH7ZKGVMKQQA3OITBOXPBVSZMMD5NGS"
+                                                                    :url           "http://yellowfile.org"}
+                                                                   {:client-id     "F7ZFMTRJLS5FF6DTWMBCGWA7CXEQTH24"
+                                                                    :name          "Blue File Party"
+                                                                    :client-secret "ISLS5HVYP65QE6OROI43FLHFFOBGISOG"
+                                                                    :url           "http://bluefile.org"}]
                                                                   :in-any-order))

 (fact "will load client credentials and store clients from a resource if provided a resource name"


Remove Nippy unit tests (unnecessary, out-of-sync)

--- test/taoensso/carmine/tests/main_old.clj
+++ test/taoensso/carmine/tests/main_old.clj
@@ -241,27 +241,6 @@
                       ["pmessage"    "ps-*"   "ps-foo" "four"]
                       ["pmessage"    "ps-*"   "ps-baz" "five"]]))))

-(deftest test-nippy
-  (let [k1   (test-key "stress-data")
-        k2   (test-key "stress-data-hash")
-        data (dissoc nippy/stress-data :bytes)
-        num-key    (test-key "num-key")
-        freeze-key (test-key "freeze-key")]
-    (wcar* (car/set k1 data))
-    (is (= data (wcar* (car/get k1))))
-    (wcar* (car/hmset k2 "field1" data "field2" "just a string"))
-    (is (= data (wcar* (car/hget k2 "field1"))))
-    (is (= "just a string" (wcar* (car/hget k2 "field2"))))
-
-    (wcar* (car/set num-key 10)
-           (car/set freeze-key (car/freeze 10)))
-    (is (= (wcar* (car/get num-key))      "10"))
-    (is (= (wcar* (car/get freeze-key)) 10))
-
-    (wcar* (car/set freeze-key (car/freeze "secret" {:password [:cached "p"]})))
-    (is (= "secret" (car/with-thaw-opts {:password [:cached "p"]}
-                      (wcar* (car/get freeze-key)))))))
-
 (deftest test-binary-safety
   (let [k (test-key "binary-safety")
         ba (byte-array [(byte 3) (byte 1) (byte 4)])]


Add backward compatibility alias for get-current-context.


Easier to see waiting list.

Easier to see waiting list.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -95,7 +95,7 @@
           wait-chs (:wait-chs d)]
       ["<div>" (string/join ":" (last actx))
        (if (not-empty wait-chs)
-         ["(waiting: "
+         [" -- waiting: ("
           (map (fn [kv] [(second kv) ", "]) wait-chs)
           ")"]
          [])


Render vis-html-chs.

Render vis-html-chs.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -98,7 +98,7 @@
     :end (fn [vis actx args]
            (let [[chs result] args] 2))}})

-(defn vis-html [vis actx]
+(defn vis-html-actx [vis actx]
   (if actx
     (let [d (get-in vis [:actxs actx])
           children (:children d)
@@ -115,11 +115,19 @@
        "
"
        (if (not-empty children)
          ["
children...
"
-          (map (fn [kv] ["
" (vis-html vis (first kv)) "
"]) children)
+          (map (fn [kv] ["
" (vis-html-actx vis (first kv)) "
"])
+               children)
           "

"]
          [])
        "
"])
     "no actx"))
+
+(defn vis-html-chs [vis]
+  ["
channels...
"
+   (map (fn [ch-info]
+          ["
" (:id ch-info) ": " (:msgs ch-info) "
"])
+        (vals (:chs vis)))
+   "

"])

 (defn vis-init [cmds cmd-handlers]
   (let [max-inflight (atom 10)
@@ -145,7 +153,8 @@
         (vis-event-handler vis actx args)
         (set-el-innerHTML "vis-html"
                           (apply str
-                                 (flatten (vis-html @vis @root-actx))))
+                                 (flatten [(vis-html-actx @vis @root-actx)
+                                           (vis-html-chs @vis)])))
         (set-el-innerHTML "vis"
                           (str "<circle cx='"
                                (mod num-events 500)


push! %)

push! %)

--- src/clerk/core.clj
+++ src/clerk/core.clj
@@ -1,4 +1,4 @@
-(ns clerk
+(ns clerk.core
   (use [clojure.string :only [trim-newline]]
        [clojure.tools.logging :only [info error]])
   (import [java.lang ProcessBuilder]


Improve the build process of DomNodes.

Improve the build process of DomNodes.

Several changes were made in this commit:

1) Now DomNodes and TagAttrs are declared using
   defrecord instead of deftype, this in order to
   update easily it's attributes.

2) Now TagAttrs attrs-map will keep track of the
   class key with special care, this is a sorted
   set to include and remove classes easily

3) The DomNode tag parsing is done on building time
   instead of visit time, that way visitor trackers
   can get accurate info about the DomNode.

--- src/dalap/html.clj
+++ src/dalap/html.clj
@@ -1,6 +1,7 @@
 (ns dalap.html
   (:import [clojure.lang IPersistentVector])

+  (:use [clojure.set :only [union]])
   (:require [clojure.core.match :as match])

   (:use [dalap.escape :only [safe]]
@@ -28,35 +29,59 @@
   (set (map name
     '(area base br col frame hr img input link meta p param))))

-(deftype TagAttrs [tag attrs-map]
+(defrecord TagAttrs [tag attrs-map]
   HtmlSerializable
   (visit [_ w] (w (for [[k v] attrs-map]
                     [" " (name k) (safe \= \") v (safe \")]))))

-(deftype DomNode [tag attrs content]
+(defrecord DomNode [tag attrs content]
   HtmlSerializable
   (visit [_ w]
-    (let [[_ tag id class] (re-matches re-tag (name tag))
-          tag-name (name tag)
-          attrs (TagAttrs.
-                 tag
-                 (merge (into {} (filter (fn [[k v]] (not (nil? v)))
-                                         {:id id :class class}))
-                        attrs))
-          is-empty (and (maybe-empty-tags tag) (empty? content))
+    (let [tag-name (name tag)
+          is-empty (and (maybe-empty-tags tag-name) (empty? content))
           open-tag [(safe \<) tag-name attrs
                     (if is-empty (safe " />") (safe \>))]
           close-tag [(safe "</") tag-name (safe \>)]]
       (w [open-tag (if-not is-empty [content close-tag])]) )))

+(defn- make-set [x]
+  (cond
+    (nil? x) (sorted-set)
+    (seq? x) (sorted-set x)
+    :else (sorted-set (vector x))))
+
+(defn- nil-or-empty? [x]
+  (or (nil? x)
+      (empty? x)))
+
+(defn- merge-tag-attrs [tag-attrs id clazz]
+  (let [
+    base-attrs (->> {:id id :class clazz}
+                    (filter #(not (nil-or-empty? (nth % 1))))
+                    (into {}))
+    attr-merge (fn [result [k v]]
+                 (cond
+                   (= k :class) (union (:class result #{}) (make-set v))
+                   :else (assoc result k v)))
+  ]
+  (reduce attr-merge base-attrs tag-attrs)))
+
+(defn- build-dom-node [tag attrs content]
+  (let [[_ tag id class] (re-matches re-tag (name tag))
+        tag-name (name tag)
+        tag-attrs (TagAttrs.
+                   tag-name
+                   (merge-tag-attrs attrs id (make-set class)))]
+    (DomNode. tag-name tag-attrs content)))
+
 (defn visit-vector [v w]
   (let [named? (fn [x] (instance? clojure.lang.Named x))]
     (match/match [v]
       [([(tag :when named?) (attrs :when map?) & content] :seq)]
-      (w (DomNode. tag attrs content))
+      (w (build-dom-node tag attrs content))

       [([(tag :when named?) & content] :seq)]
-      (w (DomNode. tag {} content))
+      (w (build-dom-node tag {} content))

       [_] (dalap.defaults/visit-seq v w))))


disables SSL backend-proto tests on Travis (#1143)

--- waiter/integration/waiter/proto_test.clj
+++ waiter/integration/waiter/proto_test.clj
@@ -16,6 +16,7 @@
 (ns waiter.proto-test
   (:require [clojure.data.json :as json]
             [clojure.test :refer :all]
+            [clojure.tools.logging :as log]
             [waiter.status-codes :refer :all]
             [waiter.util.client-tools :refer :all]
             [waiter.util.http-utils :as hu]))
@@ -119,9 +120,12 @@
     (is "test completed marker")))

 (deftest ^:parallel ^:integration-slow ^:resource-heavy test-https-backend-proto-service
-  (testing-using-waiter-url
-    (run-backend-proto-service-test waiter-url "https" "https" "HTTP/1.1")
-    (is "test completed marker")))
+  ;; Disabled on Travis: https://github.com/twosigma/waiter/issues/1137
+  (if-not (= "true" (System/getenv "TRAVIS"))
+    (testing-using-waiter-url
+      (run-backend-proto-service-test waiter-url "https" "https" "HTTP/1.1")
+      (is "test completed marker")))
+  (log/info "Skipping test in the Travis environment"))

 (deftest ^:parallel ^:integration-slow ^:resource-heavy ^:explicit test-h2c-backend-proto-service
   (testing-using-waiter-url
@@ -129,9 +133,12 @@
     (is "test completed marker")))

 (deftest ^:parallel ^:integration-slow ^:resource-heavy test-h2-backend-proto-service
-  (testing-using-waiter-url
-    (run-backend-proto-service-test waiter-url "h2" "https" "HTTP/2.0")
-    (is "test completed marker")))
+  ;; Disabled on Travis: https://github.com/twosigma/waiter/issues/1137
+  (if-not (= "true" (System/getenv "TRAVIS"))
+    (testing-using-waiter-url
+      (run-backend-proto-service-test waiter-url "h2" "https" "HTTP/2.0")
+      (is "test completed marker")))
+  (log/info "Skipping test in the Travis environment"))

 (deftest ^:parallel ^:integration-fast test-internal-protocol
   (testing-using-waiter-url


docs added a bit

docs added a bit

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -1,10 +1,8 @@
 (ns etaoin.api
   "
   The API below was written regarding to the source code
-  of different Webdriver implementations.
-
-  Sometimes, a feature you found out in W3C official standard
-  really differs from the corresponding implementation in Chrome or Firefox, etc.
+  of different Webdriver implementations. All of them partially differ
+  from the official W3C specification.

   Chrome:
   https://github.com/bayandin/chromedriver/blob/master/client/command_executor.py
@@ -77,8 +75,7 @@
 (defn get-status [driver]
   (with-resp driver :get
     [:status]
-    nil
-    resp
+    nil resp
     (:value resp)))

 (defn create-session [driver]
@@ -93,8 +90,7 @@
   (with-resp driver
     :delete
     [:session (:session @driver)]
-    nil
-    _))
+    nil _))

 ;;
 ;; actice element
@@ -271,17 +267,23 @@
     [:session (:session @driver) :url]
     {:url url} _))

-(defn back [driver]
+(defn back
+  "Move backwards in a browser's history."
+  [driver]
   (with-resp driver :post
     [:session (:session @driver) :back]
     nil _))

-(defn refresh [driver]
+(defn refresh
+  "Reload the current window."
+  [driver]
   (with-resp driver :post
     [:session (:session @driver) :refresh]
     nil _))

-(defn forward [driver]
+(defn forward
+  "Move forwards in a browser's history."
+  [driver]
   (with-resp driver :post
     [:session (:session @driver) :forward]
     nil _))
@@ -290,13 +292,17 @@
 ;; URL and title
 ;;

-(defn get-url [driver]
+(defn get-url
+  "Returns the current URL string."
+  [driver]
   (with-resp driver :get
     [:session (:session @driver) :url]
     nil resp
     (:value resp)))

-(defn get-title [driver]
+(defn get-title
+  "Returns the current window's title."
+  [driver]
   (with-resp driver :get
     [:session (:session @driver) :title]
     nil resp
@@ -307,7 +313,8 @@
 ;;

 (defn q-xpath
-  "Turns a map into xpath clause.
+  "Turns a map into an XPath clause.
+
    {:tag :div :id :content :class :test :index 2}
    //div[@id='content'][@class='test'][2]"
   [q]
@@ -325,7 +332,10 @@
         xpath (str xpath (if idx (format "[%s]" idx) ""))]
     xpath))

-(defn q-expand [driver q]
+(defn q-expand
+  "Expands a query expression into a pair of
+   [locator, term] values to pass them into low-level HTTP API."
+  [driver q]
   (cond
     (string? q)
     [(:locator @driver) q]
@@ -377,7 +387,9 @@
     resp
     (-> resp :value :ELEMENT)))

-(defn query [driver q]
+(defn query
+  "Finds an element on a page."
+  [driver q]
   (cond
     (= q :active)
     (get-active-element* driver)
@@ -486,7 +498,9 @@
     resp
     (-> resp (select-keys [:width :height]))))

-(defn get-element-size [driver q]
+(defn get-element-size
+  "Returns an element size as a map with :width and :height keys."
+  [driver q]
   (get-element-size* driver (query driver q)))

 ;;
@@ -513,6 +527,7 @@
     (-> resp (select-keys [:x :y]))))

 (defn get-element-location [driver q]
+  "Returns an element location on a page as a map with :x and :x keys."
   (get-element-location* driver (query driver q)))

 ;;


Now using (declare x) instead of (def x nil)

--- src/hyjinks.clj
+++ src/hyjinks.clj
@@ -31,9 +31,9 @@

 (defn none [pred & xs] (not (apply some pred xs)))

-;; Forward definitions to resolve circular references
-
-(def extend-tag nil)
+;; Forward declarations to resolve circular references
+
+(declare extend-tag nil)

 ;; Core types


Removed code duplication using more code-quoting

I really don't like code duplication

--- src/hyjinks.clj
+++ src/hyjinks.clj
@@ -1,14 +1,12 @@
 (ns hyjinks)

-(use '[clojure.string :only (escape split join)])
+(use '[clojure.string :only (escape split join capitalize lower-case)])

 ;; General helpers

 (defn- str-k [x] (if (keyword? x) (name x) x))

 (defn- str-join [& items] (apply str (map str-k (flatten items))))
-
-(defn- merge-assoc [m k & key-vals] (assoc m k (merge (k m) (apply hash-map key-vals))))

 (defn html-escape [s]
 	(if-not (string? s) s
@@ -19,13 +17,9 @@
 			\" """
 			\' "'"})))

-(defn- capitalize [s] (case (= s "") "" (nil? s) nil true (str (Character/toUpperCase (.charAt s 0)) (.substring s 1))))
-
 (defn- readable-string [id] (if (keyword? id) (join " " (map capitalize (split (name id) #"-"))) id))

-(defn- $ [f x] (f x))
-
-(defn- $lift [& fs] (fn [xs] (map $ fs xs)))
+(defn- $lift [& fs] (partial map #(%1 %2) fs))

 ;; Core types

@@ -54,19 +48,16 @@

 (def empty-css (Css.))

-(defn literal? [x] (instance? Literal x))
-
-(defn tag? [x] (instance? Tag x))
-
-(defn css? [x] (instance? Css x))
+(dorun (map (fn [sym] (eval `(def ~(symbol (lower-case (str sym "?"))) (partial instance? ~sym)))) [
+	'Literal 'Tag 'Css]))

 (defn attrs? [x] (and (map? x) (not (css? x)) (not (tag? x)) (not (literal? x))))

 (defn child-item? [x] (not (or (attrs? x) (css? x))))

-(defn assoc-attrs [t & key-vals] (apply merge-assoc t :attrs key-vals))
-
-(defn assoc-css [t & key-vals] (apply merge-assoc t :css key-vals))
+(dorun (map (fn [sym] (let [k (keyword sym) sym (symbol (str "assoc-" sym))]
+	(eval `(defn ~sym [~'t & ~'kvs] (assoc ~'t ~k (merge (~k ~'t) (apply hash-map ~'kvs))))))) [
+		'attrs 'css]))

 (defn css [& key-vals] (merge empty-css (apply hash-map key-vals)))

@@ -109,7 +100,7 @@

 (defn table-rows [& rows] (table (map #(row-cells (flatten %)) rows)))

-(defn map-table [m] (table (map (fn [[k v]] (tr (td (readable-string k)) (td v))) (sort-by key m))))
+(defn map-table [m] (table (map (comp tr ($lift (comp td readable-string) td)) (sort-by key m))))

 (defn definitions [term-map]
 	(dl (mapcat ($lift dt dd) (sort-by key term-map))))


Add github dependency to project.clj

Add github dependency to project.clj

--- markov-clj/project.clj
+++ markov-clj/project.clj
@@ -5,5 +5,6 @@
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.5.1"]
                  [midje "1.6.2"]
-                 [twitter-api "0.7.5"]]
+                 [twitter-api "0.7.5"]
+                 [tentacles "0.2.5"]]
   :main markov-clj.twitter)


seq is tests

seq is tests


Changes press phone number from Paul's to Laura's.

--- src-cljs/frontend/components/about.cljs
+++ src-cljs/frontend/components/about.cljs
@@ -191,7 +191,7 @@
            [:p
             "Drop a line to "
             [:a {:href "mailto:press@circleci.com"} "press@circleci.com"]
-            " or call Paul at +1 415 341 2432."]]]]]))))
+            " or call Laura at +1 415 373 4089."]]]]]))))

 (defn about [app owner]
   (reify


Add github handles to team-data

Add github handles to team-data

--- src-cljs/frontend/components/about.cljs
+++ src-cljs/frontend/components/about.cljs
@@ -142,6 +142,7 @@
     :img-path (scaled-image-path "dan")
     :visible true
     :role "Designer"
+    :github "danbeere"
     :email "daniel.beere@circleci.com"
     :bio "Dan organized Ireland’s first and second Design Jam (in Limerick and Dublin, respectively) and once climbed Kilimanjaro for charity. A recent transplant from Ireland to San Francisco, he spends his free time exploring his new city."}
    {:name "Laura Franzese"
@@ -153,11 +154,13 @@
     :img-path (scaled-image-path "marc")
     :email "marc@circleci.com"
     :role "Developer"
+    :github "marcomorain"
     :bio "Marc is a reformed game developer, based in Dublin. He still enjoys tinkering with virtual machines and C in his spare time"}
    {:name "Alexey Klochay"
     :img-path (scaled-image-path "alexey")
     :email "alexey@circleci.com"
     :role "Support Engineer"
+    :github "applemac"
     :bio "Alexey joins Circle from the sunny coasts of Spain. In between mountain biking, partying at art galleries and doing martial arts, he helps to ensure that Circle’s customers get the smoothest experience possible."}])


Nicer if transition-group doesn't take a vector

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -340,7 +340,7 @@
                          js/React.createFactory))

 (defn transition-group
-  [opts component]
+  [opts & components]
   (let [[group-name enter? leave? appear? class-name]
         (if (map? opts)
           [(:name opts)
@@ -357,7 +357,7 @@
            :transitionAppear appear?
            :component "div"
            :className class-name}
-      component)))
+      components)))

 (defn selected-container-index [data]
   (get-in data [:current-build-data :container-data :current-container-id]))
@@ -413,7 +413,7 @@
                                  :enter true
                                  :leave true
                                  :class "build-steps-animator"}
-                                [(om/build build-steps/container-build-steps
+                                (om/build build-steps/container-build-steps
                                            container-data
-                                           {:key :current-container-id})])]])])))))
-
+                                           {:key :current-container-id}))]])])))))
+


Occupancy Row.

Occupancy Row.

--- src-cljs/kixi/hecuba/tabs/profiles.cljs
+++ src-cljs/kixi/hecuba/tabs/profiles.cljs
@@ -2,6 +2,8 @@
   (:require [om.core :as om :include-macros true]
             [sablono.core :as html :refer-macros [html]]
             [kixi.hecuba.bootstrap :as bs]))
+
+(enable-console-print!)

 (defn get-profiles [selected-property-id data]
   (->>  data
@@ -11,19 +13,32 @@
         first
         :profiles))

+(defn displayable? [d]
+  (and d
+       (not (re-find #"\w" d))))
+
+(defn display [m k]
+  (if-let [d (displayable? (get m k))]
+    d
+    "N/A"))
+
 (defn occupancy-row [profiles owner]
   (reify
     om/IRenderState
     (render-state [_ state]
-      (let [occupancy-profiles []
-            profile_data {}]
-        (bs/panel
-         "Occupancy"
-         [:dl
-          [:dt "Occupancy Under 18"] [:dd (get profile_data :occupancy_under_18 "")]
-          [:dt "Occupancy 18 To 60"] [:dd (get profile_data :occupancy_18_to_60 "")]
-          [:dt "Occupancy Over 60"] [:dd (get profile_data :occupancy_over_60 "")]
-          [:dt "Occupant Change"] [:dd (get profile_data :occupant_change "")]])))))
+      (println "Number of profiles: " (count profiles))
+      (html
+       [:div.col-md-12
+        (for [profile profiles]
+          (let [profile_data (:profile_data profile)]
+            [:div.col-md-4
+             (bs/panel
+              "Occupancy"
+              [:dl
+               [:dt "Occupancy Under 18"] [:dd (display profile_data :occupancy_under_18)]
+               [:dt "Occupancy 18 To 60"] [:dd (display profile_data :occupancy_18_to_60)]
+               [:dt "Occupancy Over 60"] [:dd (display profile_data :occupancy_over_60)]
+               [:dt "Occupant Change"] [:dd (display profile_data :occupant_change)]])]))]))))

 (defn profile-rows [profiles owner]
   (reify
@@ -72,12 +87,12 @@
     om/IRender
     (render [_]
       (let [selected-property-id (-> data :active-components :properties)
-            profiles             (get-profiles selected-property-id data)]
+            profiles             (sort-by :timestamp (get-profiles selected-property-id data))]
         (html
          [:div
           [:h3 "Profiles"]
           (if (seq profiles)
-            (om/build profiles-rows profiles)
+            (om/build profile-rows profiles)
             [:div.col-md-12.text-center
              [:p.lead {:style {:padding-top 30}}
               "No profile data to display"]])])))))


Embed relevant font-awesome css

Embed relevant font-awesome css

--- src/braid/client/ui/styles/imports.cljs
+++ src/braid/client/ui/styles/imports.cljs
@@ -1,6 +1,20 @@
 (ns braid.client.ui.styles.imports
-  (:require [garden.stylesheet :refer [at-import]]))
+  (:require [garden.stylesheet :refer [at-import at-font-face]]))
+
+(def fa-at-font-face
+  (let [version "4.7.0"
+        fa-cdn-url (str "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/" version)]
+    (at-font-face
+      {:font-family "FontAwesome"
+       :src [(str "local('FontAwesome')")
+             (str "url('" fa-cdn-url "/fonts/fontawesome-webfont.eot?#iefix&v=" version "') format('embedded-opentype')")
+             (str "url('" fa-cdn-url "/fonts/fontawesome-webfont.woff2?v=" version "') format('woff2')")
+             (str "url('" fa-cdn-url "/fonts/fontawesome-webfont.woff?v=" version "') format('woff')")
+             (str "url('" fa-cdn-url "/fonts/fontawesome-webfont.ttf?v=" version "') format('truetype')")
+             (str "url('" fa-cdn-url "/fonts/fontawesome-webfont.svg?v=" version "#fontawesomeregular') format('svg')")]
+       :font-weight "normal"
+       :font-style "normal"})))

 (def imports
-  [(at-import "https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css")
+  [fa-at-font-face
    (at-import "https://fonts.googleapis.com/css?family=Open+Sans:400,300,400italic,700")])


Log after end turn

Log after end turn

--- src/clj/funstructor/cards_functions.clj
+++ src/clj/funstructor/cards_functions.clj
@@ -37,7 +37,8 @@
     :turn 1
     :messages []}
    (log-message "Game started!")
-   (log-message (str p1 " vs " p2))))
+   (log-message (str p1 " vs " p2))
+   (#(log-message % (str (:current-turn %)" moves")))))

 (defn get-game-players [game]
   (keys (:players game)))
@@ -123,7 +124,9 @@

 (defn end-turn-for-player [game]
   (-> game
+      (delete-all-messages)
       (assoc :current-turn (get-opponent game (:current-turn game)))
+      (#(log-message % (str (:current-turn %)" moves")))
       (update-in [:turn-ends] inc)))

 (defn- decrement-duration-for-player [game player]
@@ -380,19 +383,20 @@
          Args:  additional args specific for function"
   [game-map player-key card-pos & args]
   (-> game-map
+      (delete-all-messages)
       ;; TODO validate such card is present
       (#(apply apply-card % player-key (get-card game-map player-key card-pos) args))
       ;; delete card from player
       (delete-card player-key card-pos)
-      ;; (log-message (str player-key " played " (get-card game-map player-key card-pos)))
+      (log-message (str player-key " played " (get-card game-map player-key card-pos)))

       (check-for-win)
       ;; log winner
-      ;; (#(let [winner (:win %)]
-      ;;     (cond
-      ;;      (= winner :draw) (log-message % "Draw!")
-      ;;      winner (log-message % (str "Winner is " winner))
-      ;;      :else %)))
+      (#(let [winner (:win %)]
+          (cond
+           (= winner :draw) (log-message % "Draw!")
+           winner (log-message % (str "Winner is " winner))
+           :else %)))
       ))


publish events only for pro issuers

publish events only for pro issuers

--- src/clj/salava/extra/application/db.clj
+++ src/clj/salava/extra/application/db.clj
@@ -207,7 +207,7 @@
     (let [advert_id (:generated_key (replace-badge-advert<!
                                       (merge (dissoc data :remote_issuer_banner :remote_issuer_tier) (advert-content ctx data))
                                       (u/get-db ctx)))]
-      (when advert_id (do-publish ctx advert_id data))
+      (when (and advert_id (= "pro" (:remote_issuer_tier data))) (do-publish ctx advert_id data)) ;;publish events only when issuer is pro
       {:success true})
     (catch Exception ex
       (log/error "publish-badge: failed to save badge advert")


fixup! Implement write! fns.

fixup! Implement write! fns.

--- src/cljs/cljs_browser_repl/console.cljs
+++ src/cljs/cljs_browser_repl/console.cljs
@@ -24,33 +24,37 @@

 (defn write!
   "Writes a message to the input console. Type is used as class inside
-  the rendered message and should be either a string or a
-  keyword. Purely side effecting, returns nil."
+  the rendered message and should be either a string or a keyword. It
+  automatically separates messages with \n. Purely side effecting,
+  returns nil."
   [console type & messages]
-  (.Write console (apply str messages) (name type)))
+  (.Write console (str (s/join "\n" messages) "\n") (name type)))

 (defn write-error!
-  "Writes a jqconsole-error message to the input console. Purely side
-  effecting, returns nil."
+  "Writes a jqconsole-error message to the input console. It
+  automatically separates messages with \n. Purely side effecting,
+  returns nil."
   [console & messages]
   (apply write! console :jqconsole-error messages))

 (defn write-return!
-  "Writes a jqconsole-return message to the input console. Purely side
-  effecting, returns nil."
+  "Writes a jqconsole-return message to the input console. It
+  automatically separates messages with \n. Purely side effecting,
+  returns nil."
   [console & messages]
   (apply write! console :jqconsole-return messages))

 (defn write-output!
-  "Writes a jqconsole-return message to the input console. Purely side
-  effecting, returns nil."
+  "Writes a jqconsole-return message to the input console. It
+  automatically separates messages with \n. Purely side effecting,
+  returns nil."
   [console & messages]
   (apply write! console :jqconsole-output messages))

 (defn write-exception!
   [console ex]
   (if-let [cause (.-cause ex)]
-    (apply write-error! (s/join "\n" (filter (complement nil?) [cause
-                                                          (.-message cause)
-                                                          (.-stack cause)])))
-    (write-error! "Unhandled exception" ex)))
+    (apply write-error! console (filter (complement nil?) [cause
+                                                           (.-message cause)
+                                                           (.-stack cause)]))
+    (write-error! console (str "Unhandled exception: " ex))))


refactor to use nav-list and nav-item

refactor to use nav-list and nav-item

--- src/cljs/daveconservatoire/site/ui.cljs
+++ src/cljs/daveconservatoire/site/ui.cljs
@@ -56,8 +56,11 @@
     children))

 (defn nav-item [props content]
-  (dom/li #js {}
-    (dom/a (u/props->html {} props)
+  (dom/li (u/props->html
+            (cond-> {}
+              (::selected props) (assoc :className "dc-bg-orange active"))
+            (dissoc props ::r/handler))
+    (link (select-keys props [::r/handler ::r/params])
       (dom/i #js {:className "icon-chevron-right"}) content)))

 (om/defui ^:once TopicLink
@@ -199,10 +202,9 @@
     (let [{:keys [url/slug topic/title]} (om/props this)
           selected? (or (u/current-uri-slug? ::r/topic slug)
                         (= slug (om/get-computed this :ui/topic-slug)))]
-      (dom/li #js {:className (if selected? "dc-bg-orange active" "")}
-        (link {::r/handler ::r/topic ::r/params {::r/slug slug}}
-              (dom/i #js {:className "icon-chevron-right" :key "i"})
-              title)))))
+      (nav-item {::selected  selected?
+                 ::r/handler ::r/topic ::r/params {::r/slug slug}}
+        title))))

 (def topic-side-bar-link (om/factory TopicSideBarLink))

@@ -220,13 +222,13 @@
           slug (om/get-computed this :ui/topic-slug)]
       (dom/div nil
         (dom/h6 nil "Course:")
-        (dom/ul #js {:className "nav nav-list bs-docs-sidenav activetopic" :style #js {:marginTop 10}}
+        (nav-list {:className "activetopic" :style #js {:marginTop 10}}
           (dom/li #js {:className "dc-bg-yellow active activetopiclink"}
             (dom/a #js {:className "activetopiclink" :href "#"}
               title)))
         (dom/div nil
           (dom/h6 nil "Topics:")
-          (dom/ul #js {:className "nav nav-list bs-docs-sidenav"}
+          (nav-list {}
             (map (comp topic-side-bar-link #(om/computed % {:ui/topic-slug slug}))
                  topics)))))))