Merging over new helper functions for the new syntax.  Adding docs

--- src/fogus/me/trammel.clj
+++ src/fogus/me/trammel.clj
@@ -13,25 +13,60 @@

 (ns fogus.me.trammel)

-(defn build-constraints-map
-  "Takes a list of the contract expectation bodies for each arity, of the form:
-
-    (:requires (foo x) (bar x) :ensures (baz %))
+(defn- keys-apply [f ks m]
+  "Takes a function, a set of keys, and a map and applies the function to the map on the given keys.
+   A new map of the results of the function applied to the keyed entries is returned."
+  (let [only (select-keys m ks)]
+    (zipmap (keys only) (map f (vals only)))))
+
+(defn- manip-map [f ks m]
+  "Takes a function, a set of keys, and a map and applies the function to the map on the given keys.
+   A modified version of the original map is returned with the results of the function applied to each
+   keyed entry."
+  (conj m (keys-apply f ks m)))
+
+(defn- build-pre-post-map
+  "Takes a vector of the form `[pre ... => post ...]` and infers the expectations described
+   therein.  The map that comes out will look like Clojure's default pre- and post-conditions
+   map.
+  "
+  [cnstr]
+  (let [[L M R] (partition-by #{'=>} cnstr)]
+    {:pre  (when (not= L '(=>)) L)
+     :post (if (= L '(=>)) M R)}))
+
+(defn- funcify
+  "Performs the *magic* of the Trammel syntax.  That is, it currently identifies isolated functions and
+   wraps them in a list with the appropriate args.  It also recognizes keywords and does the same under
+   the assumption that a map access is required.  It then returns the vector of calls expected by the
+   Clojure pre- and post-conditions map."
+  [args cnstr]
+  (vec (map (fn [e]
+              (if (or (symbol? e) (keyword? e))
+                (list* e args)
+                e))
+            cnstr)))
+
+(defn- build-constraints-map
+  "Takes the corresponding arglist and a vector of the contract expectations, the latter of which looks
+   like any of the following:
+
+    [(= 0 _)] or [number?] ;; lists only the pre-condition
+    [number? => number?]   ;; lists a pre- and post-condition
+    [=> number?]           ;; lists only a post-condition
+    [foo bar => baz]       ;; lists a pre- and post-condition

    It then takes this form and builds a pre- and post-condition map of the form:

     {:pre  [(foo x) (bar x)]
      :post [(baz %)]}
-
-   At the moment this function expects that the constraint functions are explicitly
-   wrapped in a list with the argument(s) likewise explicit.
-  "
-  [expectations]
-  (merge {}
-         (when (:requires expectations)
-           {:pre (:requires expectations)})
-         (when (:ensures expectations)
-           {:post (:ensures expectations)})))
+  "
+  [args cnstr]
+  [args
+   (->> (build-pre-post-map cnstr)
+        (manip-map (partial funcify '[%]) [:post])
+        (manip-map (partial funcify args) [:pre]))])
+

 (defn build-contract
   "Expects a list representing an arity-based expectation of the form:


Restructure

Restructure

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -24,47 +24,9 @@
 (def select-command-order
   [QueryBuilder Select$Selection Select Select$Where])

-(defn from
-  [^String table-name]
-  [2 (fn from-query [^Select$Selection query-builder]
-       (.from query-builder (name table-name))
-       )])

-(defn distinct*
-  [column]
-  (fn distinct-query [query-builder]
-    (.distinct (.column query-builder column))))

-(defn as
-  [wrapper alias]
-  (fn distinct-query [query-builder]
-    (.as (wrapper query-builder) alias)))

-(defn all
-  []
-  [1 (fn all-query [^Select$Selection query-builder]
-       (.all query-builder))]
-  )
-
-(defn column
-  [column & {:keys [as]}]
-  [1 (fn column-query [^Select$Selection query-builder]
-       (let [c (.column query-builder column)]
-         (if as
-           (.as c as)
-           c)))])
-
-(defn columns
-  [columns]
-  [1 (fn [^Select$Selection query-builder]
-       (reduce (fn [^Select$Selection builder column]
-                 (if (string? column)
-                   (.column builder column)
-                   (column builder)))
-               query-builder
-               columns))])
-
-;; Clause eq(String name, Object value)
 (defn- ^Clause eq
   [^String column ^Object value]
   (QueryBuilder/eq column value))
@@ -88,6 +50,14 @@
 (defn- ^Clause gte
   [^String column ^Object value]
   (QueryBuilder/gte column value))
+
+(defn asc
+  [^String column-name]
+  (QueryBuilder/asc (name column-name)))
+
+(defn desc
+  [^String column-name]
+  (QueryBuilder/desc column-name))

 (def ^:private query-type-map
   {:in in


Fix problem with inconsistent statements

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -196,7 +196,7 @@
   [statements]
   (let [query-map (into {} statements)]
     (if (nil? (:what query-map))
-      (conj query-map
+      (conj statements
             [:what (all)])
       statements)))

@@ -205,7 +205,6 @@
   (->> (conj statements (from (name table-name)))
        (complete-select-query)
        (sort-by #(get select-order (first %)))
-       ;; (map println)
        (map second)
        (reduce (fn [builder statement]
                  (println builder statement)


Remove redundant overflow hidden on messages

Fixes #11439

Signed-off-by: Gheorghe Pinzaru <742a0a3885ab52ea1795e48e261ec4223e194612@gmail.com>

--- src/status_im/ui/screens/chat/styles/message/message.cljs
+++ src/status_im/ui/screens/chat/styles/message/message.cljs
@@ -118,8 +118,7 @@
 (defn message-view
   [{:keys [content-type outgoing group-chat last-in-group?]}]
   (merge
-   {:overflow :hidden
-    :border-top-left-radius     16
+   {:border-top-left-radius     16
     :border-top-right-radius    16
     :border-bottom-right-radius 16
     :border-bottom-left-radius  16
@@ -314,4 +313,4 @@
           :left             0
           :position         :absolute
           :background-color :transparent
-          :border-color     colors/black-transparent}))+          :border-color     colors/black-transparent}))


added missing comment

added missing comment

--- src/main/clojure/com/contentjon/udev.clj
+++ src/main/clojure/com/contentjon/udev.clj
@@ -54,7 +54,9 @@
             next  (.udev_list_entry_get_next  library entry)]
         (cons [name value] (udev-seq next ref))))))

-(defn- enum-seq [enumeration]
+(defn- enum-seq
+  "Returns a lazy seq for an udev device enumeration"
+  [enumeration]
   (udev-seq
     (.udev_enumerate_get_list_entry library (:native enumeration))
     enumeration))
@@ -90,7 +92,8 @@
    the property value is added to the enumeration. Returns the
    modified enumeration"
   [enumeration property value]
-  (.udev_enumerate_add_match_property library (:native enumeration) property value))
+  (.udev_enumerate_add_match_property library (:native enumeration) property value)
+  enumeration)

 (defmacro enumerate-devices
   "Takes a udev context and a number of queries expressions. The expressions are


refined activity chart

refined activity chart

--- iwaswhere-web/src/cljs/iwaswhere_web/ui/stats.cljs
+++ iwaswhere-web/src/cljs/iwaswhere_web/ui/stats.cljs
@@ -71,23 +71,7 @@
          [:svg
           {:viewBox (str "0 0 600 " chart-h)}
           [:g
-           [:polyline
-            {:fill :none :stroke :steelblue :stroke-width 2 :points points}]]
-          [:g
            [chart-title title]
-           (for [[idx v] (filter #(:weight (second %)) indexed)]
-             (let [mouse-enter-fn (mouse-enter-fn local v)
-                   mouse-leave-fn (mouse-leave-fn local v)]
-               ^{:key (str "weight" idx)}
-               [:circle {:cx             (+ (* 10 idx) 5)
-                         :cy             (- chart-h
-                                            (* 20 (- (:value (:weight v)) 90)))
-                         :r              4
-                         :stroke         :steelblue
-                         :stroke-width   1
-                         :fill           :lightblue
-                         :on-mouse-enter mouse-enter-fn
-                         :on-mouse-leave mouse-leave-fn}]))
            (for [[idx v] indexed]
              (let [h (* y-scale (stats-key v))
                    mouse-enter-fn (mouse-enter-fn local v)
@@ -103,7 +87,23 @@
            [path "M 0 50 l 600 0 z"]
            [path "M 0 100 l 600 0 z"]
            [path "M 0 150 l 600 0 z"]
-           [path "M 0 200 l 600 0 z"]]]
+           [path "M 0 200 l 600 0 z"]]
+          [:g
+           [:polyline
+            {:fill :none :stroke :steelblue :stroke-width 2 :points points}]
+           (for [[idx v] (filter #(:weight (second %)) indexed)]
+             (let [mouse-enter-fn (mouse-enter-fn local v)
+                   mouse-leave-fn (mouse-leave-fn local v)]
+               ^{:key (str "weight" idx)}
+               [:circle {:cx             (+ (* 10 idx) 5)
+                         :cy             (- chart-h
+                                            (* 20 (- (:value (:weight v)) 90)))
+                         :r              4
+                         :stroke         :steelblue
+                         :stroke-width   1
+                         :fill           :lightblue
+                         :on-mouse-enter mouse-enter-fn
+                         :on-mouse-leave mouse-leave-fn}]))]]
          (when (:mouse-over @local)
            [:div.mouse-over-info
             {:style {:top  (- (:y (:mouse-pos @local)) 20)


no need for separate channels

no need for separate channels

--- labs/architecture-examples/om/src/todomvc/app.cljs
+++ labs/architecture-examples/om/src/todomvc/app.cljs
@@ -20,15 +20,12 @@
 (defn main [todos opts]
   (dom/component
     (dom/section #js {:id "main"}
-      (dom/input #js {:id "toggle-all"
-                      :type "checkbox"
+      (dom/input #js {:id "toggle-all" :type "checkbox"
                       :onChange #(toggle-all % todos)})
       (dom/ul #js {:id "todo-list"}
         (into-array
           (map #(om/render item/todo-item todos
-                  {:path [%]
-                   :opts opts
-                   :key :id
+                  {:path [%] :opts opts :key :id
                    :fn (fn [todo]
                          (if (= (:id todo) (:editing opts))
                            (assoc todo :editing true)
@@ -36,14 +33,14 @@
             (range (count todos))))))))

 (defn footer [{:keys [todos] :as app} opts]
-  (let [{:keys [active completed showing chans]} opts
+  (let [{:keys [active completed showing comm]} opts
         clear-button (when (pos? completed)
                        (dom/button
                          #js {:id "clear-completed"
-                              :onClick #(put! (:clear chans) (now))}
+                              :onClick #(put! comm [:clear (now)])}
                          (str "Clear completed " completed)))
-        selected (-> (zipmap [:all :active :completed] (repeat ""))
-                     (assoc showing "selected"))]
+        sel (-> (zipmap [:all :active :completed] (repeat ""))
+                (assoc showing "selected"))]
     (dom/component
       (dom/footer #js {:id "footer"}
         (dom/span #js {:id "todo-count"}
@@ -51,14 +48,11 @@
           (str " " (pluralize active "item") " left"))
         (dom/ul #js {:id "filters"}
           (dom/li nil
-            (dom/a #js {:href "#/" :className (selected :all)}
-              "All"))
+            (dom/a #js {:href "#/" :className (sel :all)} "All"))
           (dom/li nil
-            (dom/a #js {:href "#/active" :className (selected :active)}
-              "Active"))
+            (dom/a #js {:href "#/active" :className (sel :active)} "Active"))
           (dom/li nil
-            (dom/a #js {:href "#/completed" :className (selected :completed)}
-              "Completed")))
+            (dom/a #js {:href "#/completed" :className (sel :completed)} "Completed")))
         clear-button))))

 ;; =============================================================================
@@ -73,9 +67,7 @@
   (when (identical? (.-which e) ENTER_KEY)
     (let [new-field (dom/get-node owner "newField")]
       (om/update! app [:todos] conj
-        {:id (guid)
-         :title (.-value new-field)
-         :completed false})
+        {:id (guid) :title (.-value new-field) :completed false})
       (set! (.-value new-field) ""))
     false))

@@ -96,51 +88,48 @@
   (om/replace! app [:editing] nil))

 (defn clear-completed [app]
-  (om/replace! app [:todos]
-    (into [] (remove :completed (:todos app)))))
+  (om/replace! app [:todos] (into [] (remove :completed (:todos app)))))
+
+(defn handle-event [app [type val]]
+  (case type
+    :toggle  (toggle-todo val)
+    :destroy (destroy-todo app val)
+    :edit    (edit-todo app val)
+    :save    (let [[todo text] val]
+               (save-todo todo text))
+    :clear   (clear-completed app)
+    :cancel  (cancel-action app)
+    nil))

 (defn todo-app [{:keys [todos] :as app}]
   (reify
     dom/IWillMount
     (-will-mount [_ owner]
-      (let [[toggle destroy edit save clear cancel :as cs]
-            (take 6 (repeatedly chan))]
-        (dom/set-state! owner :chans
-          (zipmap [:toggle :destroy :edit :save :clear :cancel] cs))
-        (go
-          (while true
-            (alt!
-              toggle ([todo] (toggle-todo todo))
-              destroy ([todo] (destroy-todo app todo))
-              edit ([todo] (edit-todo app todo))
-              save ([[todo text]] (save-todo todo text))
-              clear ([v] (clear-completed app))
-              cancel ([v] (cancel-action app)))))))
+      (let [comm (chan)]
+        (dom/set-state! owner :comm comm)
+        (go (while true
+              (let [[e c] (<! comm)]
+                (handle-event app e))))))
     dom/IDidUpdate
     (-did-update [_ _ _ _ _]
       (store "todos" app))
     dom/IRender
     (-render [_ owner]
-      (let [active (reduce
-                     #(if (not (:completed %2)) (inc %1) %1)
-                     0 todos)
+      (let [active (reduce #(if (not (:completed %2)) (inc %1) %1) 0 todos)
             completed (- (count todos) active)
-            chans (dom/get-state owner :chans)]
+            comm (dom/get-state owner :comm)]
         (dom/div nil
           (dom/header #js {:id "header"}
             (dom/h1 nil "todos")
             (dom/input
-              #js {:ref "newField"
-                   :id "new-todo"
+              #js {:ref "newField" :id "new-todo"
                    :placeholder "What needs to be done?"
                    :onKeyDown #(handle-new-todo-keydown % app owner)})
             (om/render main app
-              {:path [:todos]
-               :opts {:chans chans :editing (:editing app)}})
+              {:path [:todos] :opts {:comm comm :editing (:editing app)}})
             (om/render footer app
-              {:path []
-               :opts {:active active :completed completed
-                      :chans chans :showing :all}})))))))
+              {:path [] :opts {:active active :completed completed
+                               :comm comm :showing :all}})))))))

 (om/root app-state todo-app (.getElementById js/document "todoapp"))


query: fix a couple of obvious bugs. more to follow.

--- src/io/cyanite/query.clj
+++ src/io/cyanite/query.clj
@@ -7,7 +7,8 @@
             [io.cyanite.query.path   :as path]
             [io.cyanite.index        :as index]
             [io.cyanite.store        :as store]
-            [io.cyanite.engine       :as engine]))
+            [io.cyanite.engine       :as engine]
+            [clojure.tools.logging   :refer [debug]]))

 (defn path-leaves
   [index paths]
@@ -20,15 +21,23 @@
        (reduce merge {})))

 (defn run-query!
-  [index store engine from to query]
+  [store index engine from to query]
+  (debug "running query: " (pr-str query))
   (let [tokens  (parser/query->tokens query)
         paths   (path/tokens->paths tokens)
         by-path (path-leaves index paths)
         leaves  (->> (mapcat val by-path)
-                     (partial engine/resolution from)
+                     (map (partial engine/resolution engine from))
                      (remove nil?)
                      (set))
         series  (store/query! store from to (seq leaves))
         merged  (merge-paths by-path series)
         params  (select-keys series [:from :to :step])]
+    (debug "merged series:" (pr-str merged))
+    (debug "tokens:" (pr-str tokens))
     (assoc params :series (ast/run-query! tokens merged))))
+
+
+(comment
+  (parser/query->tokens "STRESS.host.ip-0.com.graphite.stresser.a.mean")
+  )


Internal error response is now JSON.

Internal error response is now JSON.

--- src/liber/middleware.clj
+++ src/liber/middleware.clj
@@ -1,6 +1,8 @@
 (ns liber.middleware
   "Compojure middlewares"
   (:require [clojure.string :as string]
+            [liber.util :as util]
+            [cheshire.core :as json]
             [clojure.tools.logging :refer [debug info warn error]])
   (:import com.fasterxml.jackson.core.JsonParseException) )

@@ -13,7 +15,10 @@
       (catch Exception e
         (error e "Handling request " (str req) " failed")
         {:status 500
-         :body {:error "Internal error"}}))))
+         :body (json/generate-string {:error "Internal error"}
+                                     {:prettyPrint true})
+         :headers {"Content-Type" "application/json;charset=UTF-8"}
+         }))))

 (defn wrap-x-forwarded-for
   "Replace value of remote-addr -header with value of X-Forwarded-for -header if available."


Add image-width and image-height

Add image-width and image-height

--- src/play_clj/core_2d.clj
+++ src/play_clj/core_2d.clj
@@ -38,6 +38,18 @@
     (-> ^String val Texture. TextureRegion.)
     (TextureRegion. ^TextureRegion val)))

+(defn image-width
+  ([^TextureRegion img]
+    (.getRegionWidth img))
+  ([^TextureRegion img val]
+    (.setRegionWidth img val)))
+
+(defn image-height
+  ([^TextureRegion img]
+    (.getRegionHeight img))
+  ([^TextureRegion img val]
+    (.setRegionHeight img val)))
+
 (defn split-image
   ([val size]
     (split-image val size size))


Move ns docstring from meta to docstring position.

--- hystrix-contrib/hystrix-clj/src/main/clojure/com/netflix/hystrix/core.clj
+++ hystrix-contrib/hystrix-clj/src/main/clojure/com/netflix/hystrix/core.clj
@@ -1,4 +1,4 @@
-(ns ^{:doc
+(ns com.netflix.hystrix.core
   "THESE BINDINGS ARE EXPERIMENTAL AND SUBJECT TO CHANGE

   Functions for defining and executing Hystrix dependency commands and collapsers.
@@ -120,9 +120,7 @@

   The com.netflix.hystric.core/defcollapser macro is a helper for defining this map and storing it
   in a callable var.
-
-  " }
-  com.netflix.hystrix.core
+  "
   (:require [clojure.set :as set])
   (:import [java.util.concurrent Future]
            [com.netflix.hystrix


created hot streams of keypresses

created hot streams of keypresses

--- browser/cljs/settings.cljs
+++ browser/cljs/settings.cljs
@@ -1,5 +1,5 @@
 (ns mediakeys.browser.settings
-    (:use [cljs.core.async :only [chan <! map< filter< put!]])
+    (:use [cljs.core.async :only [chan <! map< split put!]])
     (:use-macros [cljs.core.async.macros :only [go]]))

 (def keypresses (chan))
@@ -10,15 +10,29 @@
         18 "alt"
     })

+(defn modifier? [code]
+    (contains? modifier-codes code))
+
 (.addEventListener js/document "keydown"
     (fn [event]
         (put! keypresses event)))

+(def keycodes
+    (map< #(.-keyCode %) keypresses))
+(def split-codes
+    (split modifier? keycodes))
+
 (def modifiers
-    (->> keypresses
-        (map<  #(.-keyCode %))
-        (filter< #(contains? modifier-codes %))
-        (map<  #(modifier-codes % ))))
+    (map<  modifier-codes
+        (first split-codes)))
+(def characters
+    (map< (.-fromCharCode js/String)
+        (second split-codes)))
+
+(go
+    (while true
+        (let [thing (<! characters)]
+            (.log js/console thing))))
 (go
     (while true
         (let [thing (<! modifiers)]


Fix arity bug in darwin.server

Fix arity bug in darwin.server

--- src/polismath/darwin/server.clj
+++ src/polismath/darwin/server.clj
@@ -390,7 +390,7 @@
   ["/" {"ping"      ping-handler
         "datadump/" {"get"     (partial get-datadump-handler darwin)
                      "status"  (partial get-datadump-status-handler darwin)
-                     "results" (partial filename-request-handler darwin aws-cred)}}])
+                     "results" (partial filename-request-handler darwin)}}])

 (defn make-handler [darwin]
   (bidi.ring/make-handler (routes darwin)))


Fixed a bug with the LM-only retina generation.

--- src/main/clojure/brainardlab/nben/retina/util.clj
+++ src/main/clojure/brainardlab/nben/retina/util.clj
@@ -117,7 +117,7 @@
         mosaics
         (for [retina-size (get plan :sizes [20])
               spacing (get plan :spacings [1])
-              blur (get plan :blurs)]
+              blur (get plan :blurs [nil])]
           (mosaic :size retina-size :blur blur :spacing spacing))]
     (for [retina-type (get plan :types [:trichromat])
           surround (get plan :surrounds [[0.25 3.0]])
@@ -140,9 +140,12 @@
       (retina :type retina-type
               :surround surround
               :mosaic mosaic
-              :cones (cond (= retina-type :trichromat) [:L :M :S]
-                           (= retina-type :tetrachromat) [:L :A :M :S]
-                           (= retina-type :dichromat) [:L :S])
+              :cones (let [start-cones (cond (= retina-type :trichromat) [:L :M :S]
+                                             (= retina-type :tetrachromat) [:L :A :M :S]
+                                             (= retina-type :dichromat) [:L :S])]
+                       (if (= :none S-cone-flags)
+                         (butlast start-cones)
+                         start-cones))
               :cone-makeup (let [allbutS (cond (= retina-type :trichromat)
                                                {:L (first L-to-M)
                                                 :M (fnext L-to-M)}
@@ -158,7 +161,8 @@
                                    (and (number? S-cone-flags) (> S-cone-flags 0))
                                    (assoc allbutS :S S-cone-flags)
                                    :else (throw (IllegalArgumentException. "invalid s-cone flag"))))
-              :lambda-max lmaxs))))
+              :lambda-max (cond (= S-cone-flags :none) (dissoc lmaxs :S)
+                                :else lmaxs)))))

 ;; yields a filename for writing out a simulation
 (defn simulation-filename [r image-count run-id]


Adjust sound! macro

Adjust sound! macro

--- src/play_clj/core_global.clj
+++ src/play_clj/core_global.clj
@@ -136,4 +136,5 @@
 (defmacro sound!
   "Calls a single method on a `sound`"
   [object k & options]
-  `(u/call! ^Sound ~object ~k ~@options))
+  `(let [^Sound object# ~object]
+     (u/call! object# ~k ~@options)))


wip on adjudicators ui

wip on adjudicators ui

--- src/tango/cljs/main.cljs
+++ src/tango/cljs/main.cljs
@@ -156,58 +156,41 @@
    0
    class-result))

-(def new-adj-data
-  {:competition/name "TurboMegatävling"
-   :competition/date "2014 11 22"
-   :competition/location "THUNDERDOME"
-   :competition/panels
-   [{:adjudicator-panel/name "1"
-     :adjudicator-panel/adjudicators
-     [{:adjudicator/name "Anders"
-       :adjudicator/id 1
-       :adjudicator/country "Sweden"}
-      {:adjudicator/name "Bertil"
-       :adjudicator/id 2
-       :adjudicator/country ""}]
-     :adjudicator-panel/id 4}
-    {:adjudicator-panel/name "2"
-     :adjudicator-panel/adjudicators
-     [{:adjudicator/name "Bertil"
-       :adjudicator/id 2
-       :adjudicator/country ""}
-      {:adjudicator/name "Cesar"
-       :adjudicator/id 3
-       :adjudicator/country ""}]
-     :adjudicator-panel/id 5}]
-   :competition/adjudicators
-   [{:adjudicator/name "Anders"
-     :adjudicator/id 1
-     :adjudicator/country "Sweden"}
-    {:adjudicator/name "Bertil"
-     :adjudicator/id 2
-     :adjudicator/country "Uganda"}
-    {:adjudicator/name "Cesar"
-     :adjudicator/id 3
-     :adjudicator/country "Tibet"}]
-   :competitor/activities []
-   :competition/classes []})
-
-(defn new-adjudictors-component []
-  [:div
-   [:h3 "Domare"]
-   [:table.table
-    [:thead
-     [:tr
-      [:th {:with "20"} "#"]
-      [:th {:with "200"} "Name"]
-      [:th {:with "20"} "Country"]]]
-    [:tbody
-     (for [adjudicator (sort-by :adjudicator/id (:competition/adjudicators new-adj-data))]
-       ^{:key adjudicator}
-       [:tr
-        [:td (:adjudicator/id adjudicator)]
-        [:td (:adjudicator/name adjudicator)]
-        [:td (:adjudicator/country adjudicator)]])]]])
+;; (def new-adj-data
+;;   {:competition/name "TurboMegatävling"
+;;    :competition/date "2014 11 22"
+;;    :competition/location "THUNDERDOME"
+;;    :competition/panels
+;;    [{:adjudicator-panel/name "1"
+;;      :adjudicator-panel/adjudicators
+;;      [{:adjudicator/name "Anders"
+;;        :adjudicator/id 1
+;;        :adjudicator/country "Sweden"}
+;;       {:adjudicator/name "Bertil"
+;;        :adjudicator/id 2
+;;        :adjudicator/country ""}]
+;;      :adjudicator-panel/id 4}
+;;     {:adjudicator-panel/name "2"
+;;      :adjudicator-panel/adjudicators
+;;      [{:adjudicator/name "Bertil"
+;;        :adjudicator/id 2
+;;        :adjudicator/country ""}
+;;       {:adjudicator/name "Cesar"
+;;        :adjudicator/id 3
+;;        :adjudicator/country ""}]
+;;      :adjudicator-panel/id 5}]
+;;    :competition/adjudicators
+;;    [{:adjudicator/name "Anders"
+;;      :adjudicator/id 1
+;;      :adjudicator/country "Sweden"}
+;;     {:adjudicator/name "Bertil"
+;;      :adjudicator/id 2
+;;      :adjudicator/country "Uganda"}
+;;     {:adjudicator/name "Cesar"
+;;      :adjudicator/id 3
+;;      :adjudicator/country "Tibet"}]
+;;    :competitor/activities []
+;;    :competition/classes []})

 (defn adjudictors-component []
   [:div
@@ -215,16 +198,36 @@
    [:table.table
     [:thead
      [:tr
-      [:th {:with "20"} "#"]
+      ;[:th {:with "20"} "#"]
       [:th {:with "200"} "Name"]
       [:th {:with "20"} "Country"]]]
     [:tbody
-     (for [adjudicator (sort-by :adjudicator/id (:competition/adjudicators (:competition @app-state)))]
+     (for [adjudicator
+           (sort-by :adjudicator/name (:competition/adjudicators (:competition @app-state)))
+                                        ;(sort-by :adjudicator/id (:competition/adjudicators (:competition @app-state)))
+           ]
        ^{:key adjudicator}
        [:tr
-        [:td (:adjudicator/id adjudicator)]
+        ;[:td (:adjudicator/id adjudicator)]
         [:td (:adjudicator/name adjudicator)]
         [:td (:adjudicator/country adjudicator)]])]]])
+
+;; (defn adjudictors-component []
+;;   [:div
+;;    [:h3 "Domare"]
+;;    [:table.table
+;;     [:thead
+;;      [:tr
+;;       ;[:th {:with "20"} "#"]
+;;       [:th {:with "200"} "Name"]
+;;       [:th {:with "20"} "Country"]]]
+;;     [:tbody
+;;      (for [adjudicator (sort-by :adjudicator/id (:competition/adjudicators (:competition @app-state)))]
+;;        ^{:key adjudicator}
+;;        [:tr
+;;         ;[:td (:adjudicator/id adjudicator)]
+;;         [:td (:adjudicator/name adjudicator)]
+;;         [:td (:adjudicator/country adjudicator)]])]]])

 (defn new-adjudictor-panels-component []
   [:div
@@ -235,7 +238,7 @@
       [:th {:with "20"} "#"]
       [:th {:with "200"} "Domare"]]]
     [:tbody
-     (for [adjudicator-panel (sort-by :adjudicator-panel/id (:competition/panels new-adj-data))]
+     (for [adjudicator-panel (sort-by :adjudicator-panel/id (:competition/panels (:competition @app-state)))]
        ^{:key adjudicator-panel}
        [:tr
         [:td (:adjudicator-panel/id adjudicator-panel)]
@@ -316,8 +319,8 @@
                             :on-click #(dispatch [:select-page :classes])}]
    [:input.btn.btn-default {:type "button" :value "Time Schedule"
                             :on-click #(dispatch [:select-page :events])}]
-   [:input.btn.btn-default {:type "button" :value "NewAdjudicators"
-                            :on-click #(dispatch [:select-page :new-adjudicators])}]
+   ;; [:input.btn.btn-default {:type "button" :value "NewAdjudicators"
+   ;;                          :on-click #(dispatch [:select-page :new-adjudicators])}]
    [:input.btn.btn-default {:type "button" :value "NewAdjudicator panels"
                             :on-click #(dispatch [:select-page :new-adjudicator-panels])}]
    [:input.btn.btn-default {:type "button" :value "Adjudicators"
@@ -445,8 +448,8 @@
      (condp = (:selected-page @app-state)
        :classes [classes-component]
        :events [events-component]
+       ;:adjudicators [adjudictors-component]
        :adjudicators [adjudictors-component]
-       :new-adjudicators [new-adjudictors-component]
        :new-adjudicator-panels [new-adjudictor-panels-component]
        :adjudicator-panels [adjudictor-panels-component])]))


Pub/sub listener now catches handler exceptions (thanks tamasjung)

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -348,7 +348,9 @@
      (future-call ; Thread to long-poll for messages
       (bound-fn []
         (while true ; Closes when conn closes
-          (@handler-atom# (protocol/get-basic-reply! in# false) @state-atom#))))
+          (try
+            (@handler-atom# (protocol/get-basic-reply! in# false) @state-atom#)
+            (catch Throwable _#)))))

      (protocol/with-context conn# ~@body)
      (Listener. conn# handler-atom# state-atom#)))


Housekeeping

Housekeeping

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -76,7 +76,21 @@
 ;; * Async API.
 ;; * Auto throughput adjusting.

+;;;; API - exceptions
+
+(def ^:const ex "DynamoDB API exceptions. Use #=(ex _) for `try` blocks, etc."
+  {:conditional-check-failed            ConditionalCheckFailedException
+   :internal-server-error               InternalServerErrorException
+   :item-collection-size-limit-exceeded ItemCollectionSizeLimitExceededException
+   :limit-exceeded                      LimitExceededException
+   :provisioned-throughput-exceeded     ProvisionedThroughputExceededException
+   :resource-in-use                     ResourceInUseException
+   :resource-not-found                  ResourceNotFoundException})
+
 ;;;; Coercion - values
+
+;; TODO Consider alternative approaches to freezing that would _not_ serialize
+;; unwrapped binary data; this is too presumptuous.

 (deftype Frozen [value])
 (defn freeze [x] (Frozen. x))
@@ -244,9 +258,9 @@
   QueryResult         (as-map [r] (am-query|scan-result r))
   ScanResult          (as-map [r] (am-query|scan-result r))

-  CreateTableResult   (as-map [r]) ; TODO
-  UpdateTableResult   (as-map [r]) ; TODO
-  DeleteTableResult   (as-map [r]) ; TODO
+  CreateTableResult   (as-map [r] r) ; TODO
+  UpdateTableResult   (as-map [r] r) ; TODO
+  DeleteTableResult   (as-map [r] r) ; TODO

   BatchGetItemResult
   (as-map [r]
@@ -284,6 +298,16 @@

 ;;;; API - tables

+(defn list-tables "Returns a list of tables."
+  [creds] (->> (db-client creds) (.listTables) (.getTableNames) (mapv keyword)))
+
+(defn describe-table
+  "Returns a map describing a table, or nil if the table doesn't exist."
+  [creds table]
+  (try (as-map (.describeTable (db-client creds)
+                (doto (DescribeTableRequest.) (.setTableName (name table)))))
+       (catch ResourceNotFoundException _ nil)))
+
 (defn create-table
   "Creates a table with the given map of options:
     :name       - (required) table name.
@@ -295,23 +319,17 @@
   [creds {table-name :name
           :keys [throughput hash-key range-key indexes]
           :or   {throughput {:read 1 :write 1}}}]
-  (.createTable (db-client creds)
-   (let [attr-defs (->> (conj [] hash-key range-key)
-                        (concat (map :range-key indexes))
-                        (filter identity))]
-     (doto (CreateTableRequest.)
-       (.setTableName (name table-name))
-       (.setKeySchema (key-schema hash-key range-key))
-       (.setAttributeDefinitions  (attribute-definitions attr-defs))
-       (.setProvisionedThroughput (provisioned-throughput throughput))
-       (.setLocalSecondaryIndexes (local-indexes hash-key indexes))))))
-
-(defn describe-table
-  "Returns a map describing a table, or nil if the table doesn't exist."
-  [creds table]
-  (try (as-map (.describeTable (db-client creds)
-                (doto (DescribeTableRequest.) (.setTableName (name table)))))
-       (catch ResourceNotFoundException _ nil)))
+  (as-map
+   (.createTable (db-client creds)
+     (let [attr-defs (->> (conj [] hash-key range-key)
+                          (concat (map :range-key indexes))
+                          (filter identity))]
+       (doto (CreateTableRequest.)
+         (.setTableName (name table-name))
+         (.setKeySchema (key-schema hash-key range-key))
+         (.setAttributeDefinitions  (attribute-definitions attr-defs))
+         (.setProvisionedThroughput (provisioned-throughput throughput))
+         (.setLocalSecondaryIndexes (local-indexes hash-key indexes)))))))

 (defn ensure-table "Creates a table iff it doesn't already exist."
   [creds {table-name :name :as opts}]
@@ -321,20 +339,29 @@
   "Updates a table. Ref. http://goo.gl/Bj9TC for important throughput
   upgrade/downgrade limits."
   [creds {:keys [table throughput]}]
-  (.updateTable (db-client creds)
-   (let [utr (UpdateTableRequest.)]
-     (when table      (.setTableName utr (name table)))
-     (when throughput (.setProvisionedThroughput utr (provisioned-throughput
-                                                      throughput))))))
+  (as-map
+   (.updateTable (db-client creds)
+     (let [utr (UpdateTableRequest.)]
+       (when table      (.setTableName utr (name table)))
+       (when throughput (.setProvisionedThroughput utr (provisioned-throughput
+                                                        throughput)))))))

 (defn delete-table "Deletes a table."
   [creds table-name]
-  (.deleteTable (db-client creds) (DeleteTableRequest. (name table-name))))
-
-(defn list-tables "Returns a list of tables."
-  [creds] (->> (db-client creds) (.listTables) (.getTableNames) (mapv keyword)))
+  (as-map (.deleteTable (db-client creds) (DeleteTableRequest. (name table-name)))))

 ;;;; API - items
+
+(defn get-item
+  "Retrieves an item from a table by its hash key, {attr match-value}."
+  [creds table hash-key & [{:keys [consistent? attrs-to-get]}]]
+  (as-map
+   (.getItem (db-client creds)
+    (doto (GetItemRequest.)
+      (.setTableName      (name table))
+      (.setKey            (clj-item->db-item hash-key))
+      (.setConsistentRead  consistent?)
+      (.setAttributesToGet attrs-to-get)))))

 (defn put-item
   "Adds an item (Clojure map) to a table with options:
@@ -354,30 +381,6 @@
        (.setExpected     (expected-values expected))
        (.setReturnValues (utils/enum return))))))

-(defn delete-item
-  "Deletes an item from a table by its hash key, {attr match-value}.
-  See `put-item` for option docs."
-  [creds table hash-key & [{:keys [return expected]
-                            :or   {return :none}}]]
-  (as-map
-   (.deleteItem (db-client creds)
-     (doto (DeleteItemRequest.)
-       (.setTableName    (name table))
-       (.setKey          (clj-item->db-item hash-key))
-       (.setExpected     (expected-values expected))
-       (.setReturnValues (utils/enum return))))))
-
-(defn get-item
-  "Retrieves an item from a table by its hash key, {attr match-value}."
-  [creds table hash-key & [{:keys [consistent? attrs-to-get]}]]
-  (as-map
-   (.getItem (db-client creds)
-    (doto (GetItemRequest.)
-      (.setTableName      (name table))
-      (.setKey            (clj-item->db-item hash-key))
-      (.setConsistentRead  consistent?)
-      (.setAttributesToGet attrs-to-get)))))
-
 (defn update-item
   "Updates an item in a table by its hash key, {attr match-value}.
   See `put-item` for option docs."
@@ -391,6 +394,19 @@
        (.setAttributeUpdates nil) ; TODO
        (.setExpected         (expected-values expected))
        (.setReturnValues     (utils/enum return))))))
+
+(defn delete-item
+  "Deletes an item from a table by its hash key, {attr match-value}.
+  See `put-item` for option docs."
+  [creds table hash-key & [{:keys [return expected]
+                            :or   {return :none}}]]
+  (as-map
+   (.deleteItem (db-client creds)
+     (doto (DeleteItemRequest.)
+       (.setTableName    (name table))
+       (.setKey          (clj-item->db-item hash-key))
+       (.setExpected     (expected-values expected))
+       (.setReturnValues (utils/enum return))))))

 ;;;; TODO Continue code walk-through below

@@ -441,10 +457,10 @@
         (for [[k v] item]
           {(name k) (clj-val->db-val v)})))))

-(defn- write-request [verb item]
+(defn- write-request [action item]
   (let [wr (WriteRequest.)]
-    (case verb :delete (.setDeleteRequest wr (delete-request item))
-               :put    (.setPutRequest    wr (put-request    item)))
+    (case action :delete (.setDeleteRequest wr (delete-request item))
+                 :put    (.setPutRequest    wr (put-request    item)))
     wr))

 (defn batch-write-item
@@ -464,7 +480,7 @@
         (.setRequestItems
          (utils/name-map
           (fn [reqs]
-            (reduce (fn [v [verb _ item]] (conj v (write-request verb item)))
+            (reduce (fn [v [action _ item]] (conj v (write-request action item)))
                     [] (partition 3 (flatten reqs))))
           (group-by (fn [[_ table _]] table) requests)))))))

@@ -563,15 +579,4 @@
   (let [[range options] (extract-range range-and-options)]
     (as-map
      (.query (db-client creds)
-       (query-request table hash-key range options)))))
-
-;;;; API - exceptions
-
-(def ^:const ex "Use #=(ex _) for `try` blocks, etc."
-  {:conditional-check-failed            ConditionalCheckFailedException
-   :internal-server-error               InternalServerErrorException
-   :item-collection-size-limit-exceeded ItemCollectionSizeLimitExceededException
-   :limit-exceeded                      LimitExceededException
-   :provisioned-throughput-exceeded     ProvisionedThroughputExceededException
-   :resource-in-use                     ResourceInUseException
-   :resource-not-found                  ResourceNotFoundException})
+       (query-request table hash-key range options)))))


factor out fuzzy

factor out fuzzy

--- src/strictly_specking/strict_keys.clj
+++ src/strictly_specking/strict_keys.clj
@@ -1,9 +1,10 @@
 (ns strictly-specking.strict-keys
   (:require
-   [strictly-specking.parse-spec :as parse :refer [parse-keys-args spec-from-registry]]
+   [clojure.set :as set]
+   [clojure.spec :as s]
    [clojure.string :as string]
-   [clojure.set :as set]
-   [clojure.spec :as s]))
+   [strictly-specking.fuzzy :refer [similar-key]]
+   [strictly-specking.parse-spec :as parse :refer [parse-keys-args spec-from-registry]]))

 #_(s/explain :fig-opt/builds [{:compiler 1
                                :id 1
@@ -23,37 +24,6 @@
 ;; TODO memoization of fuzzy-conform-helper on a per call basis
 ;; TODO extract the find key path behavior into its own file
 ;; TODO extract strict-keys into its own file
-
-
-
-(defn- next-row
-  [previous current other-seq]
-  (reduce
-    (fn [row [diagonal above other]]
-      (let [update-val (if (= other current)
-                          diagonal
-                          (inc (min diagonal above (peek row))))]
-        (conj row update-val)))
-    [(inc (first previous))]
-    (map vector previous (next previous) other-seq)))
-
-(defn levenshtein
-  "Compute the levenshtein distance between two [sequences]."
-  [sequence1 sequence2]
-  (peek
-    (reduce (fn [previous current] (next-row previous current sequence2))
-            (map #(identity %2) (cons nil sequence2) (range))
-            sequence1)))
-
-(defn similar-key* [thresh ky ky2]
-  (and (keyword? ky)
-       (keyword? ky2)
-       #_(= (namespace ky) (namespace ky2))
-       (let [dist (levenshtein (str ky) (str ky2))]
-         (when (<= dist thresh)
-           dist))))
-
-(def similar-key (partial similar-key* 3))

 (defn spelling-suggestions [kys ky]
   (->> kys


Wire up bootstrapping a Doctopus

Wire up bootstrapping a Doctopus

--- src/doctopus/doctopus.clj
+++ src/doctopus/doctopus.clj
@@ -15,19 +15,28 @@

   I think: Doctopus has several Heads, which each have many Tentacles. I think."
   (:require [doctopus.doctopus.head :as h]
-            [doctopus.doctopus.tentacle :as t]))
+            [doctopus.doctopus.tentacle :as t]
+            [me.raynes.fs :as fs])
+  (:import [doctopus.doctopus.head Head]))

 ;; Here there be Peculiar Metaphors for Information Dissemination
 (defprotocol DoctopusMethods
+  (bootstrap-heads [this])
   (list-tentacles [this])
   (list-tentacles-by-head [this head]))

 (defrecord Doctopus
-    [heads]
+    [configuration]
   DoctopusMethods
+  (bootstrap-heads [this]
+    (let [heads-dir (:heads-dir configuration)
+          dirs (fs/list-dir heads-dir)
+          head-names (map #(.getName %) dirs)
+          heads (map #(h/Head. %) head-names)]
+      (assoc this :heads (doall (map #(h/bootstrap-tentacles % heads-dir) heads)))))
   (list-tentacles [this]
-    (into {} (for [head (:heads this)
+    (into [] (for [head (:heads this)
                    :let [tentacles (h/list-tentacles head)]]
                [head tentacles])))
   (list-tentacles-by-head [this head]


update core.clj to https://github.com/clojure/clojurescript/commit/6b251ba9e46c5fff647229d771f4c8f55989a6ef

--- src/main/clojure/clojure/tools/analyzer/js/cljs/core.clj
+++ src/main/clojure/clojure/tools/analyzer/js/cljs/core.clj
@@ -206,31 +206,10 @@
       (core/inc (core/quot c 32)))))

 (defmacro str [& xs]
-  ;; Eagerly stringify any string or char literals.
-  (let [clean-xs (reduce (fn [acc x]
-                     (core/cond
-                       (core/or (core/string? x) (core/char? x))
-                       (if (core/string? (peek acc))
-                         (conj (pop acc) (core/str (peek acc) x))
-                         (conj acc (core/str x)))
-                       (core/nil? x) acc
-                       :else (conj acc x)))
-                   [] xs)
-        ;; clean-xs now has no nils, chars, or string-adjoining-string. bools,
-        ;; ints and floats will be emitted literally to allow JS string coersion.
-        strs (->> clean-xs
-                  (map #(if (core/or (core/string? %) (core/integer? %)
-                                     (core/float? %) (core/true? %)
-                                     (core/false? %))
-                            "~{}"
-                            "cljs.core.str.cljs$core$IFn$_invoke$arity$1(~{})"))
-                  (interpose "+")
-                  (apply core/str))]
-    ;; Google closure advanced compile will stringify and concat strings and
-    ;; numbers at compilation time.
-    (list* 'js* (core/str (if (core/string? (first clean-xs)) "(" "(''+")
-                          strs ")")
-           clean-xs)))
+  (let [strs (->> (repeat (count xs) "cljs.core.str(~{})")
+                (interpose ",")
+                (apply core/str))]
+    (list* 'js* (core/str "[" strs "].join('')") xs)))

 (defn bool-expr [e]
   (vary-meta e assoc :tag 'boolean))


udpate core.clj to https://github.com/clojure/clojurescript/commit/7397ae2e089612fc05b8e16d7dc1497cbddc47a1

--- src/main/clojure/clojure/tools/analyzer/js/cljs/core.clj
+++ src/main/clojure/clojure/tools/analyzer/js/cljs/core.clj
@@ -1684,10 +1684,9 @@
                      (symbol ~(name sym-ns) ~(name sym-name))
                      (merge
                       {:ns (symbol ~(name sym-ns))
-                       :name (symbol ~(name sym-name))
-                       :file ~(:file (meta info))
-                       :line ~(:line (meta info))
-                       :column ~(:column (meta info))}
+                       :name (symbol ~(name sym-name))}
+                      ~(select-keys (meta info) [:file :line :column :doc])
+                      {:arglists ~(list 'quote (-> info meta :arglists))}
                       ~(when (:test info)
                          `{:test (.-cljs$lang$test ~sym)})))))


fixed time stamping so it happens on the same swap as the state change, so dupe triggers of atom watchers do not happen

--- src/untangled/state.cljs
+++ src/untangled/state.cljs
@@ -75,8 +75,10 @@
         old-state @state-atom
         history-entry (h/set-reason (h/new-point-in-time old-state undoable compressable) reason)]
     (swap! history-atom #(h/record % history-entry))
-    (swap! state-atom #(update-in % path operation))
-    (swap! state-atom #(assoc % :time (h/now)))
+    (swap! state-atom (fn [old-state]
+                        (-> old-state
+                            (assoc :time (h/now))
+                            (update-in path operation))))
     (app/state-changed application old-state @state-atom)
     ))


Fix union test

Fix union test

--- test/com/wsscode/pathom/connect/planner_readers_test.cljc
+++ test/com/wsscode/pathom/connect/planner_readers_test.cljc
@@ -491,10 +491,14 @@
                                               (fn [env _] {:joined-item [{:id 1 :name "name" :age 24}
                                                                          {:id2 2 :name "other" :age 42}]}))]}]
                 ::query     '[{:joined-item {:id  [:id :name]
-                                             :id2 [:id2 :age]}}]})
+                                             :id2 [:id2 :age]}}
+                              ::foreign-calls]})
              {:joined-item    [{:id 1 :name "name"}
                                {:id2 2 :age 42}]
-              ::foreign-calls '{remote [[(:param-value {:param-x 42})]]}})))))
+              ::foreign-calls '{remote [[{:joined-item [:id
+                                                        :name
+                                                        :id2
+                                                        :age]}]]}})))))

 (defn constantly-resolver-async
   "Like pc/constantly-resolver, but returns an async response."


CMR-2118 Fixes validate-and-parse- in ingest-service.

--- ingest-app/src/cmr/ingest/services/ingest_service.clj
+++ ingest-app/src/cmr/ingest/services/ingest_service.clj
@@ -49,8 +49,8 @@

   (let [collection (umm/parse-concept collection-concept)]
     (when (ingest-validation-enabled?)
-      (v/validate-collection-umm context collection validate-keywords?)
-      collection)))
+      (v/validate-collection-umm context collection validate-keywords?))
+    collection))

 (defn-timed validate-collection
   "Validate the collection. Throws a service error if any validation issues are found."


suggestions factored out of editable-md-render fn

--- iwaswhere-web/src/cljs/iwaswhere_web/ui/markdown.cljs
+++ iwaswhere-web/src/cljs/iwaswhere_web/ui/markdown.cljs
@@ -18,6 +18,39 @@
                            (u/reducer (:mentions entry) u/mentions-replacer))]
       [:div {:dangerouslySetInnerHTML {:__html (md/md->html formatted-md)}}])))

+(defn suggestions
+  "Renders suggestions for hashtags or mentions if either occurs before the current caret position.
+  It does so by getting the selection from the DOM API, which can be used to determine the position
+  and a string before that position, then finding either a hashtag or mention fragment right at the
+  and of that substring. For these, auto-suggestions are displayed, which are entities that begin
+  with the tag fragment before the caret position. When any of the suggestions are clicked, the
+  fragment will be replaced with the clicked item."
+  [entry hashtags mentions local-saved-entry local-display-entry]
+  (let [ts (:ts entry)
+        selection (.getSelection js/window)
+        cursor-pos (.-anchorOffset selection)
+        anchor-node (aget selection "anchorNode")
+        node-value (str (when anchor-node (aget anchor-node "nodeValue")) "")
+        md (:md @local-saved-entry)
+        before-cursor (subs node-value 0 cursor-pos)
+        current-tag (re-find (js/RegExp. (str "(?!^)#" h/tag-char-class "+$") "m") before-cursor)
+        current-tag-regex (js/RegExp. current-tag "i")
+        tag-substr-filter (fn [tag] (when current-tag (re-find current-tag-regex tag)))
+        current-mention (re-find (js/RegExp. (str "@" h/tag-char-class  "+$") "m") before-cursor)
+        current-mention-regex (js/RegExp. current-mention "i")
+        mention-substr-filter (fn [mention] (when current-mention (re-find current-mention-regex mention)))
+        tags-fn (fn [tag-substr-filter curr-tag-regex tags]
+                  (for [tag (filter tag-substr-filter tags)]
+                    ^{:key (str ts tag)}
+                    [:div
+                     {:on-click #(let [updated (merge entry (h/parse-entry (s/replace md curr-tag-regex tag)))]
+                                  (reset! local-saved-entry updated)
+                                  (reset! local-display-entry updated))}
+                     [:span.hashtag tag]]))]
+    [:div.suggestions
+     (tags-fn tag-substr-filter (js/RegExp (str current-tag "(?!" h/tag-char-class ")") "i") hashtags)
+     (tags-fn mention-substr-filter current-mention mentions)]))
+
 (defn editable-md-render
   "Renders markdown in a pre>code element, with editable content. Sends update message to store
   component on any change to the component. The save button sends updated entry to the backend."
@@ -29,7 +62,6 @@
     (fn [entry hashtags mentions put-fn toggle-edit]
       (let [latest-entry (dissoc entry :comments)
             md-string (or (:md @local-display-entry) "edit here")
-            ts (:timestamp entry)
             get-content #(aget (.. % -target -parentElement -parentElement -firstChild -firstChild) "innerText")
             update-temp-fn #(reset! local-saved-entry (merge latest-entry (h/parse-entry (get-content %))))
             save-fn #(put-fn [:text-entry/update @local-saved-entry])
@@ -53,34 +85,7 @@
                         :on-input         update-temp-fn
                         :on-key-down      on-keydown-fn}
                  md-string]]]
-         (let [selection (.getSelection js/window)
-               cursor-pos (.-anchorOffset selection)
-               anchor-node (aget selection "anchorNode")
-               node-value (str (when anchor-node (aget anchor-node "nodeValue")) "")
-               md (:md @local-saved-entry)
-               before-cursor (subs node-value 0 cursor-pos)
-               current-tag (re-find (js/RegExp. (str "(?!^)#" h/tag-char-class "+$") "m") before-cursor)
-               current-tag-regex (js/RegExp. current-tag "i")
-               tag-substr-filter (fn [tag] (when current-tag (re-find current-tag-regex tag)))
-               current-mention (re-find (js/RegExp. (str "@" h/tag-char-class  "+$") "m") before-cursor)
-               current-mention-regex (js/RegExp. current-mention "i")
-               mention-substr-filter (fn [mention] (when current-mention (re-find current-mention-regex mention)))]
-           [:div.suggestions
-            (for [tag (filter tag-substr-filter hashtags)]
-              ^{:key (str ts tag)}
-              [:div
-               {:on-click #(let [curr-tag-regex (js/RegExp (str current-tag "(?!" h/tag-char-class ")") "i")
-                                 updated (merge entry (h/parse-entry (s/replace md curr-tag-regex tag)))]
-                            (reset! local-saved-entry updated)
-                            (reset! local-display-entry updated))}
-               [:span.hashtag tag]])
-            (for [mention (filter mention-substr-filter mentions)]
-              ^{:key (str ts mention)}
-              [:div
-               {:on-click #(let [updated (merge entry (h/parse-entry (s/replace md current-mention mention)))]
-                            (reset! local-saved-entry updated)
-                            (reset! local-display-entry updated))}
-               [:span.mention mention]])])
+         [suggestions entry hashtags mentions local-saved-entry local-display-entry]
          (when (not= @last-saved @local-saved-entry)
            [:span.not-saved {:on-click save-fn} [:span.fa.fa-floppy-o] "  click to save"])]))))


fixed #110

fixed #110

--- src/frontend/uploads.cljs
+++ src/frontend/uploads.cljs
@@ -127,9 +127,19 @@
                     (start-upload first-inactive-upload))))))

 (defn handle-unpause! [uploads uploads-order upload-slots active-uploads upload-id]
-  (if (> (count (active-uploads uploads-order uploads))
-          upload-slots)
-    (let [upload-to-stop-id (last (active-uploads uploads-order uploads))
+  (println uploads)
+  (println "ACTIVE-UPLOADS "  (active-uploads uploads-order uploads))
+  (println "Upload slots:" upload-slots)
+  (if-not (active? (uploads upload-id))
+    (swap! app-state/app-state
+           assoc
+           :uploads
+           (assoc (:uploads @app-state/app-state)
+                  upload-id
+                  (start-upload (uploads upload-id)))))
+  (if (> (count (active-uploads uploads-order (:uploads @app-state/app-state)))
+         upload-slots)
+    (let [upload-to-stop-id (last (active-uploads uploads-order (:uploads @app-state/app-state)))
           upload-to-stop (uploads upload-to-stop-id)]
       (println "upload-to-stop" upload-to-stop-id)
       (swap! app-state/app-state
@@ -137,14 +147,7 @@
              :uploads
              (assoc (:uploads @app-state/app-state)
                     upload-to-stop-id
-                    (stop-upload upload-to-stop))))
-    (if-not (active? (uploads upload-id))
-      (swap! app-state/app-state
-             assoc
-             :uploads
-             (assoc (:uploads @app-state/app-state)
-                    upload-id
-                    (start-upload (uploads upload-id)))))))
+                    (stop-upload upload-to-stop))))))

 (defn upload-file! [file]
   (let [upload-id (.v4 js/uuid)
@@ -166,7 +169,8 @@
                                      (handle-pause! uploads uploads-order upload-slots))
                                  (= action :unpaused)
                                    (do
-                                     (.pipe blob-stream stream)
+                                     (when (:started? upload)
+                                       (.pipe blob-stream stream))
                                      (handle-unpause! uploads
                                                       uploads-order
                                                       upload-slots


Fix count in the label response.

Fix count in the label response.

--- src/oc/storage/representations/label.clj
+++ src/oc/storage/representations/label.clj
@@ -42,7 +42,7 @@
 (defn label-for-render [org label user]
   (as-> label lb
     (assoc lb :links (label-links org label))
-    (assoc lb :count (some #(when (= (:used-id %) (:user-id user)) (:count %)) (:used-by label)))
+    (assoc lb :count (or (some #(when (= (:used-id %) (:user-id user)) (:count %)) (:used-by label)) 0))
     (apply dissoc lb reserved-props)))

 (defn render-label [org label user]


Refactor template rendering

Refactor template rendering

--- src/schedule/web/handler.clj
+++ src/schedule/web/handler.clj
@@ -1,26 +1,29 @@
 (ns schedule.web.handler
-  (:use [clostache.parser])
   (:require
+   [clostache.parser :as clo]
    [compojure.route :as route]
    [compojure.handler :as handler]
    [compojure.core :refer [defroutes GET context routes]]
    [ring.middleware.defaults :refer [wrap-defaults site-defaults]]
    [reloaded.repl :refer [system]]))

-(def common-partials {:footer (render-resource "templates/footer.mustache")})
+(def common-partials {:footer (clo/render-resource "templates/footer.mustache")})

 (def common-features
-  {:header #(-> (render-resource "templates/header.mustache") (clojure.string/replace "%TITLE%" %))})
+  {:header #(-> (clo/render-resource "templates/header.mustache") (clojure.string/replace "%TITLE%" %))})
+
+(defn render [template values]
+  (clo/render-resource
+   template
+   (merge common-features values)
+   common-partials))

 (defn index [db]
-  (render-resource
-   "templates/index.mustache"
-   (assoc common-features
-          :conventions (get db :conventions))
-   common-partials))
+  (render "templates/index.mustache"
+          {:conventions (get db :conventions)}))

 (defn new-convention [db]
-  (render-resource "templates/new-convention.mustache" common-features common-partials))
+  (render "templates/new-convention.mustache" {}))

 (let [db (:db system)]
   (defroutes convention-routes


Downgrade logging in observe to debug

Downgrade logging in observe to debug

--- src/yetibot/core/commands/observe.clj
+++ src/yetibot/core/commands/observe.clj
@@ -33,7 +33,7 @@
 ;; Use a single obs-hook to monitor all dynamic observers. That way when it's
 ;; removed from the database, it won't be checked here either.
 (defn obs-handler [{:keys [body user chat-source event-type] :as event-info}]
-  (info "obs-handler" (color-str :blue event-info))
+  (debug "obs-handler" (color-str :blue event-info))
   (let [observers (model/find-all)
         channel (:room chat-source)
         username (:username user)]


use a link to submit the form

use a link to submit the form

--- src/pc/views/blog/interactive_layers.clj
+++ src/pc/views/blog/interactive_layers.clj
@@ -9,16 +9,15 @@
    (list
     [:article
      [:p "In this tutorial, we'll show you how to use Precursor's simple interactive layers to prototype complex user flows."]
-     [:p "We'll prototype a simple iPhone app with three different views."]]
-
-    [:article.cta
-     [:form {:method "post" :action "/duplicate/interactive-demo" :target "_blank"}
+     [:p "We'll prototype a simple iPhone app with three different views."]
+     [:form {:id "interactive-demo-form" :method "post" :action "/duplicate/interactive-demo"}
       [:input {:type "hidden" :name "__anti-forgery-token"
                :value ring.middleware.anti-forgery/*anti-forgery-token*}]
-      [:button.blog-cta-button {:href "/"
-                                :role "button"
-                                :title "Make something."}
-       "Reproduce this demo"]]]
+      [:p "You can "
+       ;; falls back to email welcome gif if js doesn't execute for some reason
+       [:a {:onclick "event.preventDefault(); document.getElementById('interactive-demo-form').submit()" :href "/email/welcome/interactive-demo.gif"}
+        "follow along on Precursor"]
+       "  with your own copy of the document we created for this tutorial."]]]

     [:figure [:img {:src "/email/interactive-demo.gif"}]]


(PCP-385) Parse address:port when determining remote address

When instantiating a Connection, use only the IP address and port for
determining the remote-address entry.

This prevents having the initial '/' in case Jetty fails to determine
the host name (which is the first part of the string we currently
parse).

--- src/puppetlabs/pcp/broker/connection.clj
+++ src/puppetlabs/pcp/broker/connection.clj
@@ -1,5 +1,6 @@
 (ns puppetlabs.pcp.broker.connection
-  (:require [puppetlabs.experimental.websockets.client :as websockets-client]
+  (:require [clojure.string :as str]
+            [puppetlabs.experimental.websockets.client :as websockets-client]
             [puppetlabs.kitchensink.core :as ks]
             [puppetlabs.pcp.protocol :as p]
             [schema.core :as s]
@@ -45,17 +46,26 @@
 (s/defn make-connection :- Connection
   "Return the initial state for a websocket"
   [websocket :- Websocket codec :- Codec]
-  (map->Connection {:state :open
-                    :websocket websocket
-                    :codec codec
-                    :remote-address (try+ (.. websocket (getSession) (getRemoteAddress) (toString))
-                                          (catch Exception _
-                                            ""))
-                    :common-name (try+ (when-let [cert (first (websockets-client/peer-certs websocket))]
-                                         (ks/cn-for-cert cert))
-                                       (catch Exception _
-                                         nil))
-                    :created-at (ks/timestamp)}))
+  ;; NOTE(ale): the 'map->...' constructor comes from schema.core's defrecord
+  (map->Connection
+    {:state          :open
+     :websocket      websocket
+     :codec          codec
+     ;; NOTE(ale): Extract IP address and port out of the string representation
+     ;; of the InetAddress instance ('hostname/socket' format), so that we
+     ;; don't end up with a remote-address like '/0:0:0:0:0:0:0:1:56824'. See:
+     ;; http://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html#getHostAddress%28%29
+     ;; http://stackoverflow.com/questions/6932902/apache-mina-how-to-get-the-ip-from-a-connected-client
+     :remote-address (try+
+                       (second
+                         (str/split (.. (websockets-client/remote-addr websocket) (toString)) #"/"))
+                       (catch Exception _
+                         ""))
+     :common-name    (try+ (when-let [cert (first (websockets-client/peer-certs websocket))]
+                             (ks/cn-for-cert cert))
+                           (catch Exception _
+                             nil))
+     :created-at     (ks/timestamp)}))

 (s/defn -summarize :- ConnectionLog
   [connection :- Connection]


Add James, Mark, and Isaac to members.clj.

--- resources/members.clj
+++ resources/members.clj
@@ -6,4 +6,7 @@
  {:name "Chris Bilson"}
  {:name "Stan Dyck" :url "http://sgd.homelinux.net"}
  {:name "Nick Dimiduk" :url "http://www.n10k.com"}
- {:name "Justin Lilly" :url "http://justinlilly.com"}]
+ {:name "Justin Lilly" :url "http://justinlilly.com"}
+ {:name "James Cooper" :url "http://bitmechanic.com"}
+ {:name "Mark Engelberg"}
+ {:name "Isaac Hodes" :url "http://copperthoughts.com"}]


Document properties namespace

Document properties namespace

--- src/simple_check/properties.clj
+++ src/simple_check/properties.clj
@@ -1,6 +1,7 @@
 (ns simple-check.properties
   (:require [simple-check.generators :as gen]))

+;; NOTES:
 ;; The fields that should be returned from each test
 ;; run:
 ;;
@@ -15,7 +16,7 @@
 ;; stamp: haskell QC nomenclature for stats/values collected
 ;; callbacks: maybe this is where printing/clojure.test stuff goes?

-(defn apply-gen
+(defn- apply-gen
   [function]
   (fn [args]
     [:gen (fn [random-seed size]
@@ -26,6 +27,15 @@
          :args args}))]))

 (defn for-all*
+  "Creates a property (properties are also generators). A property
+  is a generator that generates the result of applying the function
+  under test with the realized arguments. Once realized, the arguments
+  will be applied to `function` with `apply`.
+
+  Example:
+
+    (for-all* [gen/int gen/int] fn [a b] (>= (+ a b) a))
+  "
   [args function]
   (gen/bind (gen/tuple args)
             (apply-gen function)))
@@ -39,6 +49,16 @@
   (map second (partition 2 bindings)))

 (defmacro for-all
+  "Macro sugar for `for-all*`. `for-all` lets you name the parameter
+  and use them in expression, without wrapping them in a lambda. Like
+  `for-all*`, it returns a property.
+
+  Examples
+
+    (for-all [a gen/int
+              b gen/int]
+      (>= (+ a b) a))
+  "
   [bindings expr]
   `(for-all* ~(vec (binding-gens bindings))
              (fn [~@(binding-vars bindings)]


Better handle exceptions when loading immutant.init [IMMUTANT-132]

--- modules/core/src/main/clojure/immutant/runtime.clj
+++ modules/core/src/main/clojure/immutant/runtime.clj
@@ -52,11 +52,15 @@
     (do
       (log/info "Initializing " (util/app-name) "via" init-fn)
       (require-and-invoke init-fn))
-    (try (println "ns") (require 'immutant.init)
-         (catch java.io.FileNotFoundException _
-           (log/warn "No :init fn or immutant.init namespace found for"
-                     (util/app-name)
-                     "- no initialization will be performed"))))
+    (try (require 'immutant.init)
+         (catch java.io.FileNotFoundException e
+           ;; make sure it's a failure to find immutant.init, and not
+           ;; something within init throwing a FNFE
+           (if (re-find #"immmutant/init" (.getMessage e))
+             (log/warn "No :init fn or immutant.init namespace found for"
+                       (util/app-name)
+                       "- no initialization will be performed")
+             (throw e)))))

   (repl/init-repl (into {} config-hash)))


Snapshot version

Snapshot version

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


Fix failing tests & method preference

Fix failing tests & method preference

--- src/tabular/grafter/tabular.clj
+++ src/tabular/grafter/tabular.clj
@@ -6,7 +6,8 @@
             [grafter.tabular.common :as tabc :refer [lift->vector map-keys]]
             [incanter.core :as inc]
             [potemkin.namespaces :refer [import-vars]]
-            [grafter.pipeline.types :as types]))
+            [grafter.pipeline.types :as types])
+  (:import incanter.core.Dataset))

 ;; Load protocol definitions.  This could occur in the ns definition but putting
 ;; them in their means that namespace refactoring tools can clear them out
@@ -38,6 +39,8 @@
   (read-dataset val))

 (swap! types/parameter-types derive incanter.core.Dataset ::types/tabular-dataset)
+
+(prefer-method types/parse-parameter [String ::types/file] [String java.util.Map])

 (defn test-dataset
   "Constructs a test dataset of r rows by c cols e.g.


revert elasticsearch policy change

revert elasticsearch policy change

--- src/terraboot/elasticsearch.clj
+++ src/terraboot/elasticsearch.clj
@@ -66,18 +66,19 @@
                           nginx])))

 (defn elasticsearch-policy
-  [iam-root es-arn-*]
-  (json/generate-string
-   {
-    "Statement" [
-                 {
-                  "Action" "es:*"
-                  "Effect" "Allow"
-                  "Principal" {
-                                 "AWS" iam-root
-                                 }
-                   "Resource" es-arn-*}]
-    "Version" "2012-10-17"}))
+  []
+  (json/generate-string {"Version" "2012-10-17",
+                         "Statement" [{"Action" "es:*",
+                                       "Principal" "*",
+                                       "Resource" "$${es-arn}",
+                                       ;; There is currently a bug which means 'Resource' needs adding after the
+                                       ;; cluster is created or it will constantly say it needs to change.
+                                       ;; https://github.com/hashicorp/terraform/issues/5067
+                                       "Effect" "Allow",
+                                       "Condition"
+                                       {
+                                        "IpAddress"
+                                        {"aws:SourceIp" ["$${allowed-ips}"]}}}]}))

 (defn elasticsearch-cluster [name {:keys [es-endpoint vpc-name account-number region azs default-ami mesos-ami vpc-cidr-block cert-name key-name] :as spec}]
   ;; http://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-createupdatedomains.html#es-createdomain-configure-ebs
@@ -89,12 +90,11 @@
         vpc-security-group (partial scoped-security-group vpc-unique)
         elb-listener (account-elb-listener account-number)
         es-arn (str "arn:aws:es:" region ":" account-number ":domain/" name)
-        iam-root (str "arn:aws:iam::" account-number ":root")
         es-arn-* (str es-arn "/*")]

     (merge-in
      (template-file (vpc-unique "elasticsearch-policy")
-                    (elasticsearch-policy iam-root es-arn-*)
+                    (elasticsearch-policy)
                     {:es-arn es-arn-*
                      :allowed-ips  (vpc-output-of "aws_eip" "logstash" "public_ip")})


fix macro condition

fix macro condition

--- src/jx/reporter/karma.clj
+++ src/jx/reporter/karma.clj
@@ -5,7 +5,7 @@

 (defmacro tests-count
   [& namespaces]
-  `(+ ~@(map (fn [[quote ns]]
+  `(+ ~@(map (fn [[_ ns]]
                (count
                  (filter #(true? (get-in % [1 :test]))
                          (cljs.analyzer.api/ns-publics ns))))
@@ -14,23 +14,22 @@
 (defmacro run-tests
   "Runs all tests in the given namespaces."
   [karma & namespaces]
-  (if (nil? karma)
-    `(cljs.test/run-tests ~@namespaces)
-    `(do (jx.reporter.karma/start ~karma (tests-count ~@namespaces))
-        (cljs.test/run-tests (cljs.test/empty-env ::karma) ~@namespaces))))
+  `(if (nil? ~karma)
+     (cljs.test/run-tests ~@namespaces)
+     (do (jx.reporter.karma/start ~karma (tests-count ~@namespaces))
+         (cljs.test/run-tests (cljs.test/empty-env ::karma) ~@namespaces))))

 (defmacro run-all-tests
   "Runs all tests in all namespaces.
   Optional argument is a regular expression; only namespaces with
   names matching the regular expression (with re-matches) will be
   tested."
-  ([karma] `(run-all-tests ~karma nil))
+  ([karma]
+   `(jx.reporter.karma/run-all-tests ~karma #".*"))
   ([karma re]
-   (if (nil? karma)
-     `(cljs.test/run-all-tests ~re)
-     (let [namespaces# (map
-                         (fn [ns] `(quote ~ns))
-                         (cond->> (api/all-ns)
-                                  re (filter #(re-matches re (name %)))))]
-       `(do (jx.reporter.karma/start ~karma (tests-count ~@namespaces#))
-            (cljs.test/run-all-tests ~re (cljs.test/empty-env ::karma)))))))
+   `(jx.reporter.karma/run-tests
+      ~karma
+      ~@(into '()
+              (comp (filter #(re-matches re (name %)))
+                    (map (fn [ns] `(quote ~ns))))
+              (api/all-ns)))))


cleanup wait-for-git code (#1)

cleanup wait-for-git code (#1)

--- src/lambdacd_git/core.clj
+++ src/lambdacd_git/core.clj
@@ -9,57 +9,59 @@
             [clojure.java.io :as io])
   (:import (java.util.regex Pattern)))

-(defn report-git-exception [branch repo-uri e]
-  (log/warn e (str "could not get current revision for branch " branch " on " repo-uri))
-  (println "could not get current revision for branch" branch "on" repo-uri ":" (.getMessage e)))
-
-(defn- find-changed-ref [old-revisions new-revisions]
-  (let [[_ new-entries _]  (diff old-revisions new-revisions)
+(defn- find-changed-revision [old-revisions new-revisions]
+  (let [[_ new-entries _] (diff old-revisions new-revisions)
         changed-ref        (->> new-entries
                                 (first)
                                 (key))
         last-seen-revision (get old-revisions changed-ref)
         new-revision       (get new-revisions changed-ref)]
-    {:status :success
-     :revision new-revision
-     :old-revision last-seen-revision
-     :all-revisions new-revisions}))
+    {:revision     new-revision
+     :old-revision last-seen-revision}))

-(defn- revisions-changed-from [last-seen-revisions repo-uri branch]
+(defn- report-git-exception [branch repo-uri e]
+  (log/warn e (str "could not get current revision for branch " branch " on " repo-uri))
+  (println "could not get current revision for branch" branch "on" repo-uri ":" (.getMessage e)))
+
+(defn- current-revision-or-nil [repo-uri branch]
   (try
-    (let [new-revisions (git/current-revisions repo-uri branch)]
-      (log/debug "waiting for new revision. current revisions:" new-revisions "last seen:" last-seen-revisions)
-      (when (not= last-seen-revisions new-revisions)
-        (find-changed-ref last-seen-revisions new-revisions)))
+    (git/current-revisions repo-uri branch)
     (catch Exception e
       (report-git-exception branch repo-uri e)
-      {:status :failure})))
+      nil)))

-(defn- wait-for-revision-changed-from [last-seen-revisions repo-uri branch ctx ms-between-polls]
-    (async/>!! (:result-channel ctx) [:status :waiting])
-    (println "Last seen revisions:" (or last-seen-revisions "None") ". Waiting for new commit...")
-    (loop [result (revisions-changed-from last-seen-revisions repo-uri branch)]
-      (support/if-not-killed ctx
-                             (if (= :success (:status result))
-                               (do
-                                 (println "Found new commit: " (:revision result) ".")
-                                 result)
-                               (do (Thread/sleep ms-between-polls)
-                                   (recur (revisions-changed-from last-seen-revisions repo-uri branch)))))))
+(defn- found-new-commit [last-seen-revisions current-revisions]
+  (let [changes (find-changed-revision last-seen-revisions current-revisions)]
+    (println "Found new commit: " (:revision changes) ".")
+    {:status        :success
+     :revision      (:revision changes)
+     :old-revision  (:old-revision changes)
+     :all-revisions current-revisions}))

-(defn- last-seen-revisions-for-this-step [ctx repo-uri branch]
-  (let [last-step-result (pipeline-state/most-recent-step-result-with :_git-last-seen-revisions ctx)
-        last-seen-revisions-in-history (:_git-last-seen-revisions last-step-result)]
-    (if-not (nil? last-seen-revisions-in-history)
-      last-seen-revisions-in-history
-      (try
-        (git/current-revisions repo-uri branch)
-        (catch Exception e
-          (report-git-exception branch repo-uri e)
-          nil)))))
+(defn- wait-for-revision-changed [last-seen-revisions repo-uri branch ctx ms-between-polls]
+  (println "Last seen revisions:" (or last-seen-revisions "None") ". Waiting for new commit...")
+  (loop [last-seen-revisions last-seen-revisions]
+    (support/if-not-killed ctx
+      (let [current-revisions (current-revision-or-nil repo-uri branch)]
+        (if (and
+              (not (nil? current-revisions))
+              (not= current-revisions last-seen-revisions))
+          (found-new-commit last-seen-revisions current-revisions)
+          (do
+            (Thread/sleep ms-between-polls)
+            (recur current-revisions)))))))
+
+(defn- last-seen-revisions-from-history [ctx]
+  (let [last-step-result (pipeline-state/most-recent-step-result-with :_git-last-seen-revisions ctx)]
+    (:_git-last-seen-revisions last-step-result)))
+
+(defn- initial-revisions [ctx repo-uri branch]
+  (or
+    (last-seen-revisions-from-history ctx)
+    (current-revision-or-nil repo-uri branch)))

 (defn- persist-last-seen-revisions [wait-for-result last-seen-revisions ctx]
-  (let [current-revisions (:all-revisions wait-for-result)
+  (let [current-revisions    (:all-revisions wait-for-result)
         revisions-to-persist (or current-revisions last-seen-revisions)]
     (async/>!! (:result-channel ctx) [:_git-last-seen-revisions revisions-to-persist]) ; by sending it through the result-channel, we can be pretty sure users don't overwrite it
     (assoc wait-for-result :_git-last-seen-revisions revisions-to-persist)))
@@ -73,15 +75,20 @@
     (regex? branch-spec) (git/match-branch-by-regex branch-spec)
     :else branch-spec))

+(defn- report-waiting-status [ctx]
+  (async/>!! (:result-channel ctx) [:status :waiting]))
+
 (defn wait-for-git
   "step that waits for the head of a branch to change"
   [ctx repo-uri & {:keys [branch ms-between-polls]
                    :or   {ms-between-polls (* 10 1000)
                           branch           "master"}}]
   (support/capture-output ctx
-      (let [last-seen-revisions (last-seen-revisions-for-this-step ctx repo-uri (to-branch-pred branch))
-            wait-for-result (wait-for-revision-changed-from last-seen-revisions repo-uri (to-branch-pred branch) ctx ms-between-polls)]
-        (persist-last-seen-revisions wait-for-result last-seen-revisions ctx))))
+    (report-waiting-status ctx)
+    (let [branch-pred       (to-branch-pred branch)
+          initial-revisions (initial-revisions ctx repo-uri branch-pred)
+          wait-for-result   (wait-for-revision-changed initial-revisions repo-uri branch-pred ctx ms-between-polls)]
+      (persist-last-seen-revisions wait-for-result initial-revisions ctx))))

 (defn clone [ctx repo ref cwd]
   (support/capture-output ctx


Finish off splatter sections

Finish off splatter sections

--- src/uk/co/tombooth/pollock.cljs
+++ src/uk/co/tombooth/pollock.cljs
@@ -309,13 +309,15 @@
 ;; vector as this is the direction it will leave its current position.

 ;; The equation to bounce a vector, $V$, off a plane with normal, $N$, is:
-;; **needs rewriting http://mathworld.wolfram.com/Reflection.html**
 ;;
 ;;    - $N$ is the normal vector of the plane
 ;;    - $V$ = the incoming vector
 ;;    - $B$ is the outgoing, bounced, vector
 ;;
 ;;  $B = V - (2 * (V.N) * N)$
+;;
+;; You can find out a bit more about the derivation on this [Wolfram
+;; page](http://mathworld.wolfram.com/Reflection.html).

 ;; We are missing a few of the required vector operations used in this
 ;; equation so we should define some more functions before trying to
@@ -343,8 +345,7 @@

 ;; Using the above functions we can now implement the vector bouncing
 ;; equation. I have pulled $(2 * (V.N) * N)$ out into a variable
-;; called extreme for clarity. **I don't think extreme is a much
-;; better name than blah**
+;; called extreme for clarity.

 (defn bounce-vector [vector normal]
   (let [vector-dot-normal (dot-product vector normal)
@@ -353,12 +354,11 @@

 ;; When an impact splatters it will only take a fraction of the
-;; velocity, otherwise know as being na inelastic rather than elastic
+;; velocity, otherwise know as being an inelastic rather than elastic
 ;; collision. We can define a constant that will be
 ;; used to reduce the total velocity of the bounced vector to reflect
 ;; this elasticity.

-;; **should this splatter vector be randomised a little bit?**

 (def splatter-dampening-constant 0.7)


add two new mappings

add two new mappings


Refactred test to emulate service behavior

--- test/puppetlabs/master/certificate_authority_test.clj
+++ test/puppetlabs/master/certificate_authority_test.clj
@@ -277,12 +277,13 @@
                        :serial    (str cadir "/serial")
                        :load-path []}
       cadir-contents  (settings->cadir-paths ca-settings)
-      ssldir-contents {:requestdir  (str ssldir "/certificate_requests")
+      master-settings {:requestdir  (str ssldir "/certificate_requests")
                        :certdir     (str ssldir "/certs")
                        :hostcert    (str ssldir "/certs/master.pem")
                        :localcacert (str ssldir "/certs/ca.pem")
                        :hostprivkey (str ssldir "/private_keys/master.pem")
-                       :hostpubkey  (str ssldir "/public_keys/master.pem")}]
+                       :hostpubkey  (str ssldir "/public_keys/master.pem")}
+      ssldir-contents (settings->master-dir-paths master-settings)]

   (deftest initialize-ca!-test
     (try


Analog Dreamers.

Analog Dreamers.

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -75,14 +75,17 @@

    "Analog Dreamers"
    {:abilities [{:cost [:click 1] :msg "make a run on R&D"
-                 :effect (effect (run :rd
-                                      {:replace-access
-                                       {:prompt "Choose a card to shuffle into R&D"
-                                        :choices {:req #(and (not (= (:type %) "ICE"))
-                                                             (not (:rezzed %))
-                                                             (not (:advance-counter %)))}
-                                        :effect (req (move state :corp target :deck) (shuffle! state :corp :deck))
-                                        :msg "shuffle a card into R&D"}}))}]}
+                 :effect (effect (run :rd {:replace-access
+                                           {:prompt "Choose a card to shuffle into R&D"
+                                            :choices {:req #(and (not (= (:type %) "ICE"))
+                                                                 (not (:rezzed %))
+                                                                 (not (:advance-counter %)))}
+                                            :effect (req (move state :corp target :deck)
+                                                         (shuffle! state :corp :deck)
+                                                         (swap! state update-in [:runner :prompt] rest)
+                                                         (handle-end-run state side)) ; remove the replace-access prompt
+                                            :msg "shuffle a card into R&D"}} card))}]}
+

    "Andromeda: Dispossessed Ristie"
    {:effect (effect (gain :link 1) (draw 4)) :mulligan (effect (draw 4))}
@@ -1956,20 +1959,11 @@
                             card nil)))}}

    "Sneakdoor Beta"
-   {:abilities [{:cost [:click 1] :msg "make a run on R&D"
-                 :effect (effect (run :rd
-                                      {:replace-access
-                                       {:prompt "Choose a card to shuffle into R&D"
-                                        :choices {:req #(and (not (= (:type %) "ICE"))
-                                                             (not (:rezzed %))
-                                                             (not (:advance-counter %)))}
-                                        :effect (req (move state :corp target :deck) (shuffle! state :corp :deck))
-                                        :msg "shuffle a card into R&D"}} card))}]}
-   ;{:abilities [{:cost [:click 1] :msg "make a run on Archives"
-   ;              :effect (effect (run :archives
-   ;                                {:successful-run
-   ;                                 {:msg "make a successful run on HQ"
-   ;                                  :effect (req (swap! state assoc-in [:run :server] [:hq]))}} card))}]}
+   {:abilities [{:cost [:click 1] :msg "make a run on Archives"
+                 :effect (effect (run :archives
+                                   {:successful-run
+                                    {:msg "make a successful run on HQ"
+                                     :effect (req (swap! state assoc-in [:run :server] [:hq]))}} card))}]}

    "Snare!"
    {:access {:optional {:req (req (not= (first (:zone card)) :discard))


Detect original image content type base on content, not on extension

--- src/vignette/util/thumbnail.clj
+++ src/vignette/util/thumbnail.clj
@@ -103,12 +103,12 @@
   The original will be removed after the thumbnailing is completed."
   [store thumb-map original]
   (if-let [original (or original (get-original store thumb-map))]
-    (let [original-mime-type (mime-type-of (or (filename original) ""))]
-      (if (is-passthrough-required original-mime-type thumb-map)
+    (let [original-content-type (content-type original)]
+      (if (is-passthrough-required original-content-type thumb-map)
           original
           (when-let [local-original (original->local original)]
             (try+
-              (let [thumb-params (webp-override original-mime-type thumb-map)]
+              (let [thumb-params (webp-override original-content-type thumb-map)]
                 (when-let [thumb (original->thumbnail local-original thumb-params)]
                   (perf/publish {:generate-thumbail 1})
                   (background-check-and-delete-original


PLATFORM-2995: Log slow thumbnailer runs (#140)

* Log slow thumbnailer runs

--- src/vignette/util/thumbnail.clj
+++ src/vignette/util/thumbnail.clj
@@ -55,8 +55,18 @@
           thumb-map))

 (defn run-thumbnailer
-  [args]
-  (perf/timing :imagemagick (apply sh args)))
+  ([args thumb-map]
+    (let [start-ms (System/currentTimeMillis)
+          result (perf/timing :imagemagick (apply sh args))
+          elapsed-ms (- (System/currentTimeMillis) start-ms)]
+      (if (> elapsed-ms 5000)
+          (do
+            (log/info "slow-thumbnailer-call" {:time_ms elapsed-ms :thumb_map thumb-map})
+            result)
+          result)
+      ))
+  ([args]
+    (run-thumbnailer args {})))

 (defn original->thumbnail
   [resource thumb-map]


Change `doall`s to `dorun`s

Change `doall`s to `dorun`s

--- test/wonko/export/prometheus_test.clj
+++ test/wonko/export/prometheus_test.clj
@@ -12,7 +12,7 @@
           thread-pool (Executors/newFixedThreadPool 10)
           process-fn #(swap! registries conj (sut/get-or-create-registry "registry-test-service"))]

-      (doall (for [i (range 99999)] (.submit thread-pool ^Runnable process-fn)))
+      (dorun (for [i (range 99999)] (.submit thread-pool ^Runnable process-fn)))
       (.shutdown thread-pool)
       (.awaitTermination thread-pool Integer/MAX_VALUE TimeUnit/MILLISECONDS)

@@ -25,7 +25,7 @@
           metric-attrs {:metric-name "metric" :metric-type "counter"}
           process-fn #(swap! metrics conj (sut/get-or-create-metric registry metric-attrs))]

-      (doall (for [i (range 99999)] (.submit thread-pool ^Runnable process-fn)))
+      (dorun (for [i (range 99999)] (.submit thread-pool ^Runnable process-fn)))
       (.shutdown thread-pool)
       (.awaitTermination thread-pool Integer/MAX_VALUE TimeUnit/MILLISECONDS)


actually generate a CSS file again

actually generate a CSS file again

--- src/main/om_css/core.cljc
+++ src/main/om_css/core.cljc
@@ -326,4 +326,4 @@
                (println))))))))

 #?(:clj
-   (if-cljs (setup-io!) nil))
+   (setup-io!))


Update token names

Update token names

Signed-off-by: Andrea Maria Piana <39e16ece3c2d27e1889178b15ddb376e524032f8@gmail.com>

--- src/status_im/utils/ethereum/tokens.cljs
+++ src/status_im/utils/ethereum/tokens.cljs
@@ -27,15 +27,15 @@
                     :address  "0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0"
                     :decimals 18}
                    {:symbol   :OMG
-                    :name     "OmiseGo"
+                    :name     "OMGToken"
                     :address  "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07"
                     :decimals 18}
                    {:symbol   :PPT
-                    :name     "Populous"
+                    :name     "Populous Platform"
                     :address  "0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a"
-                    :decimals 18}
+                    :decimals 8}
                    {:symbol   :REP
-                    :name     "Augur"
+                    :name     "Reputation"
                     :address  "0xe94327d07fc17907b4db788e5adf2ed424addff6"
                     :decimals 18}
                    {:symbol   :POWR
@@ -43,13 +43,13 @@
                     :address  "0x595832f8fc6bf59c85c527fec3740a1b7a361269"
                     :decimals 6}
                    {:symbol   :PAY
-                    :name     "TenXPay"
+                    :name     "TenX Pay Token"
                     :address  "0xB97048628DB6B661D4C2aA833e95Dbe1A905B280"
                     :decimals 18}
-                   {:symbol   :VERI
-                    :name     "Veros"
+                   {:symbol   :VRS
+                    :name     "VEROS"
                     :address  "0xedbaf3c5100302dcdda53269322f3730b1f0416d"
-                    :decimals 18}
+                    :decimals 5}
                    {:symbol   :GNT
                     :name     "Golem Network Token"
                     :address  "0xa74476443119A942dE498590Fe1f2454d7D4aC0d"
@@ -71,7 +71,7 @@
                     :address  "0xdd974d5c2e2928dea5f71b9825b8b646686bd200"
                     :decimals 18}
                    {:symbol   :DGD
-                    :name     "DGD"
+                    :name     "Digix DAO"
                     :address  "0xe0b7927c4af23765cb51314a0e0521a9645f0e2a"
                     :decimals 9}
                    {:symbol   :AE
@@ -82,8 +82,8 @@
                     :name     "Tronix"
                     :address  "0xf230b790e05390fc8295f4d3f60332c93bed42e2"
                     :decimals 6}
-                   {:symbol   :ETHOS
-                    :name     "Ethos"
+                   {:symbol   :BQX
+                    :name     "Bitquence"
                     :address  "0x5af2be193a6abca9c8817001f45744777db30756"
                     :decimals 8}
                    {:symbol   :RDN
@@ -91,7 +91,7 @@
                     :address  "0x255aa6df07540cb5d3d297f0d0d4d84cb52bc8e6"
                     :decimals 18}
                    {:symbol   :SNT
-                    :name     "Status Network Token"
+                    :name     "Status Network"
                     :address  "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
                     :decimals 18}
                    {:symbol   :SNGLS
@@ -167,21 +167,21 @@
                     :address  "0xb63b606ac810a52cca15e44bb630fd42d8d1d83d"
                     :decimals 8}
                    {:symbol   :LRC
-                    :name     "LoopringCoin"
+                    :name     "loopring"
                     :address  "0xEF68e7C694F40c8202821eDF525dE3782458639f"
                     :decimals 18}
                    {:symbol   :ZSC
-                    :name     "Zeus Shield Token"
+                    :name     "Zeus Shield Coin"
                     :address  "0x7A41e0517a5ecA4FdbC7FbebA4D4c47B9fF6DC63"
                     :decimals 18}
                    {:symbol   :DATA
-                    :name     "Streamr DATAcoin"
+                    :name     "DATAcoin"
                     :address  "0x0cf0ee63788a0849fe5297f3407f701e122cc023"
                     :decimals 18}
                    {:symbol   :RCN
                     :name     "Ripio Credit Network Token"
                     :address  "0xf970b8e36e23f7fc3fd752eea86f8be8d83375a6"
-                    :decimals 9}
+                    :decimals 18}
                    {:symbol   :WINGS
                     :name     "WINGS"
                     :address  "0x667088b212ce3d06a1b553a7221E1fD19000d9aF"
@@ -215,7 +215,7 @@
                     :address  "0xe7775a6e9bcf904eb39da2b68c5efb4f9360e08c"
                     :decimals 6}
                    {:symbol   :GRID
-                    :name     "GRID+ Token"
+                    :name     "GRID Token"
                     :address  "0x12b19d3e2ccc14da04fae33e63652ce469b3f2fd"
                     :decimals 12}
                    {:symbol   :SAN
@@ -235,7 +235,7 @@
                     :address  "0x12480e24eb5bec1a9d4369cab6a80cad3c0a377a"
                     :decimals 2}
                    {:symbol   :MANA
-                    :name     "Decentraland MANA"
+                    :name     "Decentraland"
                     :address  "0x0f5d2fb29fb7d3cfee444a200298f468908cc942"
                     :decimals 18}
                    {:symbol   :AST
@@ -243,17 +243,17 @@
                     :address  "0x27054b13b1b798b345b591a4d22e6562d47ea75a"
                     :decimals 4}
                    {:symbol   :R
-                    :name     "R Token"
+                    :name     "R token"
                     :address  "0x48f775efbe4f5ece6e0df2f7b5932df56823b990"
                     :decimals 0}
                    {:symbol   :1ST
-                    :name     "FirstBlood Token"
+                    :name     "Firstblood"
                     :address  "0xaf30d2a7e90d7dc361c8c4585e9bb7d2f6f15bc7"
                     :decimals 18}
                    {:symbol   :CFI
                     :name     "Cofoundit"
                     :address  "0x12fef5e57bf45873cd9b62e9dbd7bfb99e32d73e"
-                    :decimals 2}
+                    :decimals 18}
                    {:symbol   :ENG
                     :name     "Enigma"
                     :address  "0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4"
@@ -298,7 +298,7 @@
                     :name     "district0x Network Token"
                     :address  "0x0abdace70d3790235af448c88547603b945604ea"
                     :decimals 18}
-                   {:symbol   :DCN
+                   {:symbol   :٨
                     :name     "Dentacoin"
                     :address  "0x08d32b0da63e2C3bcF8019c9c5d849d7a9d791e6"
                     :decimals 0}
@@ -307,7 +307,7 @@
                     :address  "0xced4e93198734ddaff8492d525bd258d49eb388e"
                     :decimals 18}
                    {:symbol   :CSNO
-                    :name     "BitDice"
+                    :name     "BitDice CSNO"
                     :address  "0x29d75277ac7f0335b2165d0895e8725cbf658d73"
                     :decimals 8}
                    {:symbol   :COB
@@ -319,11 +319,11 @@
                     :address  "0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c"
                     :decimals 18}
                    {:symbol   :AVT
-                    :name     "AVT"
+                    :name     "AVENTUS"
                     :address  "0x0d88ed6e74bbfd96b831231638b66c05571e824f"
                     :decimals 18}
                    {:symbol   :TIME
-                    :name     "TIME"
+                    :name     "Chronobank TIME"
                     :address  "0x6531f133e6deebe7f2dce5a0441aa7ef330b4e53"
                     :decimals 8}
                    {:symbol   :CND
@@ -331,7 +331,7 @@
                     :address  "0xd4c435f5b09f855c3317c8524cb1f586e42795fa"
                     :decimals 18}
                    {:symbol   :STX
-                    :name     "STOX"
+                    :name     "Stox"
                     :address  "0x006BeA43Baa3f7A6f765F14f10A1a1b08334EF45"
                     :decimals 18}
                    {:symbol   :XAUR
@@ -339,15 +339,15 @@
                     :address  "0x4DF812F6064def1e5e029f1ca858777CC98D2D81"
                     :decimals 8}
                    {:symbol   :VIB
-                    :name     "Vibe"
+                    :name     "VIB"
                     :address  "0x2c974b2d0ba1716e644c1fc59982a89ddd2ff724"
                     :decimals 18}
                    {:symbol   :PRG
-                    :name     "PRG"
+                    :name     "ParagonCoin"
                     :address  "0x7728dFEF5aBd468669EB7f9b48A7f70a501eD29D"
                     :decimals 6}
                    {:symbol   :DPY
-                    :name     "Delphy"
+                    :name     "Delphy Token"
                     :address  "0x6c2adc2073994fb2ccc5032cc2906fa221e9b391"
                     :decimals 18}
                    {:symbol   :CDT
@@ -359,7 +359,7 @@
                     :address  "0x08f5a9235b08173b7569f83645d2c7fb55e8ccd8"
                     :decimals 8}
                    {:symbol   :DRT
-                    :name     "DomRaider Token"
+                    :name     "Domraider"
                     :address  "0x9af4f26941677c706cfecf6d3379ff01bb85d5ab"
                     :decimals 8}
                    ;; NOTE(goranjovic) : the following three tokens are removed from the Manage Assets list
@@ -367,17 +367,17 @@
                    ;; them listed here in order to correctly display any previous transactions the user had
                    ;; in their history prior to the upgrade. So, we're just hiding them, not actually deleting from the
                    ;; app.
-                   {:symbol   :Centra
-                    :name     "Centra Token"
+                   {:symbol   :CTR
+                    :name     "Centra"
                     :address  "0x96A65609a7B84E8842732DEB08f56C3E21aC6f8a"
                     :decimals 18
                     :hidden?  true}
                    {:symbol   :ROL
-                    :name     "Dice"
+                    :name     "DICE"
                     :address  "0x2e071D2966Aa7D8dECB1005885bA1977D6038A65"
                     :decimals 16
                     :hidden?  true}
-                   {:symbol   :ATMChain
+                   {:symbol   :ATM
                     :name     "Attention Token of Media"
                     :address  "0x9B11EFcAAA1890f6eE52C6bB7CF8153aC5d74139"
                     :decimals 8


Fix command tests to include the generated register-command! call

--- src/test/workflo/macros/command_test.clj
+++ src/test/workflo/macros/command_test.clj
@@ -12,7 +12,9 @@
               vector?)
             (def user-create-definition
               {:data-spec pod/user-create-data-spec
-               :implementation pod/user-create-implementation}))
+               :implementation pod/user-create-implementation})
+            (workflo.macros.command/register-command!
+             'user/create pod/user-create-definition))
          (macroexpand-1 `(defcommand user/create [~'vector?]
                            ~'(:foo :bar))))))

@@ -30,7 +32,9 @@
             (def user-update-definition
               {:data-spec pod/user-update-data-spec
                :cache-query pod/user-update-cache-query
-               :implementation pod/user-update-implementation}))
+               :implementation pod/user-update-implementation})
+            (workflo.macros.command/register-command!
+             'user/update pod/user-update-definition))
          (macroexpand-1 `(defcommand user/update [~'[user [name email]]
                                                   ~'vector?]
                            {:some :data})))))
@@ -48,7 +52,9 @@
             (def user-update-definition
               {:foo pod/user-update-foo
                :implementation pod/user-update-implementation
-               :data-spec pod/user-update-data-spec}))
+               :data-spec pod/user-update-data-spec})
+            (workflo.macros.command/register-command!
+             'user/update pod/user-update-definition))
          (macroexpand-1 `(defcommand user/update [~'vector?]
                            (~'foo [:bar])
                            {:implementation :result})))))
@@ -71,7 +77,9 @@
               {:foo pod/user-create-foo
                :implementation pod/user-create-implementation
                :cache-query pod/user-create-cache-query
-               :data-spec pod/user-create-data-spec}))
+               :data-spec pod/user-create-data-spec})
+            (workflo.macros.command/register-command!
+             'user/create pod/user-create-definition))
          (macroexpand-1 `(defcommand user/create [~'[db [id]] ~'map?]
                            (~'foo [:bar])
                            :result)))))


removed commented out version of routes macro

--- cljs/macros/vix/macros.clj
+++ cljs/macros/vix/macros.clj
@@ -19,11 +19,4 @@
   (when-let [[route-segments body & clauses] clauses]
     `(if-let [~'params (vix.core/route-matches ~route-segments ~uri-path)]
       ~body
-      (routes ~uri-path ~@clauses))))
-
-(comment
-  (defmacro routes [uri-path & clauses]
-  (when-let [[route-segments body & clauses] clauses]
-    `(if-let [~'params (route-matches ~route-segments (str ~@uri-path))]
-       ~body
-       (routes ~uri-path ~@clauses)))))+      (routes ~uri-path ~@clauses))))