add diff to output

add diff to output

--- src/jx/reporter/karma.cljs
+++ src/jx/reporter/karma.cljs
@@ -1,5 +1,6 @@
 (ns jx.reporter.karma
   (:require [cljs.test]
+            [clojure.data]
             [fipp.clojure])
   (:require-macros [jx.reporter.karma :as karma]))

@@ -26,20 +27,41 @@
   (let [indentation (reduce str "" (repeat n " "))]
     (clojure.string/replace s #"\n" (str "\n" indentation))))

-(defn format-fn [[c & q]]
+(defn remove-last-new-line [s]
+  (subs s 0 (dec (count s))))
+
+(defn format-fn [indentation [c & q]]
   (let [e (->> q
                (map #(with-out-str (fipp.clojure/pprint %)))
                (apply str)
                (str "\n"))]
-    (str "(" c (indent 12 (subs e 0 (dec (count e)))) ")")))
+    (str "(" c (indent (+ indentation 2) (remove-last-new-line e)) ")")))
+
+(defn format-diff [indentation assert [c a b & q]]
+  (when (and (= c '=) (= (count assert) 3) (nil? q))
+    (let [format (fn [sign value]
+                   (str sign " "
+                        (if value
+                          (indent (+ indentation 2)
+                                  (-> value
+                                      (fipp.clojure/pprint {:width 1})
+                                      (with-out-str)
+                                      (remove-last-new-line)))
+                          "\n")))
+          [removed added] (clojure.data/diff a b)]
+      (str (format "-" removed)
+           (format (str "\n" (apply str (repeat indentation " ")) "+") added)))))

 (defn- format-log [{:keys [expected actual message] :as result}]
-  (str
-    "FAIL in   " (cljs.test/testing-vars-str result) "\n"
-    "expected: " (format-fn expected) "\n"
-    "  actual: " (format-fn (second actual)) "\n"
-    (when message
-      (str " message: " (indent 10 message) "\n"))))
+  (let [indentation (count "expected: ")]
+    (str
+      "FAIL in   " (cljs.test/testing-vars-str result) "\n"
+      "expected: " (format-fn indentation expected) "\n"
+      "  actual: " (format-fn indentation (second actual)) "\n"
+      (when-let [diff (format-diff indentation expected (second actual))]
+        (str "    diff: " diff "\n"))
+      (when message
+        (str " message: " (indent indentation message) "\n")))))

 (def test-var-result (volatile! []))


Reformat the routes for readability.

Reformat the routes for readability.

--- src/klangmeister/core.cljs
+++ src/klangmeister/core.cljs
@@ -22,28 +22,17 @@
 (defn reload! []
   (swap! state-atom identity))

-(secretary/defroute "/klangmeister/" [query-params]
-  (session/put! :gist (:gist query-params))
-  (session/put! :current-page view/about))
+(secretary/defroute "/klangmeister/"            [query-params] (session/put! :gist (:gist query-params))
+                                                               (session/put! :current-page view/about))

-(secretary/defroute "/klangmeister/index.html" [query-params]
-  (session/put! :gist (:gist query-params))
-  (session/put! :current-page view/about))
+(secretary/defroute "/klangmeister/index.html"  [query-params] (session/put! :gist (:gist query-params))
+                                                               (session/put! :current-page view/about))

-(secretary/defroute "/klangmeister/synthesis" []
-  (session/put! :current-page view/synthesis))
-
-(secretary/defroute "/klangmeister/performance" []
-  (session/put! :current-page view/performance))
-
-(secretary/defroute "/klangmeister/composition" []
-  (session/put! :current-page view/composition))
-
-(secretary/defroute "/klangmeister/reference" []
-  (session/put! :current-page view/reference))
-
-(secretary/defroute "/klangmeister/about" []
-  (session/put! :current-page view/about))
+(secretary/defroute "/klangmeister/synthesis"   [] (session/put! :current-page view/synthesis))
+(secretary/defroute "/klangmeister/performance" [] (session/put! :current-page view/performance))
+(secretary/defroute "/klangmeister/composition" [] (session/put! :current-page view/composition))
+(secretary/defroute "/klangmeister/reference"   [] (session/put! :current-page view/reference))
+(secretary/defroute "/klangmeister/about"       [] (session/put! :current-page view/about))

 (defn current-page []
   [(session/get :current-page) handle! state-atom])


switch to `cond->`

switch to `cond->`

--- src/java_time/data.clj
+++ src/java_time/data.clj
@@ -10,15 +10,15 @@

 (defn- dt-formatter
   ^DateTimeFormatter [x]
-  (if (string? x)
-    (DateTimeFormatter/ofPattern x)
-    x))
+  (cond-> x
+          (string? x)
+          (DateTimeFormatter/ofPattern)))

 (defn- zone-id
   ^ZoneId [x]
-  (if (string? x)
-    (ZoneId/of x)
-    x))
+  (cond-> x
+          (string? x)
+          (ZoneId/of)))

 (defn- julian-field
   [^TemporalAccessor o x]


Improve sample-player docstring to include out-bus param

--- src/overtone/sc/sample.clj
+++ src/overtone/sc/sample.clj
@@ -166,9 +166,12 @@

 (defn sample-player
   "Play the specified sample with either a mono or stereo player
-   depending on the number of channels in the sample. Accepts same args
-   as both players, namely: [buf 0 rate 1.0 start-pos 0.0 loop? 0 vol
-   1]"
+   depending on the number of channels in the sample. Always creates a
+   stereo signal.
+
+   Accepts same args as both players, namely:
+
+   [buf 0 rate 1.0 start-pos 0.0 loop? 0 vol 1 out-bus 0]"
   [smpl & pargs] {:pre [(sample? smpl)]}
   (let [{:keys [path args]}     smpl
         {:keys [id n-channels]} (get @cached-samples* [path args])


thru rm_lm_sites

thru rm_lm_sites

--- src/pg_demo/table_defs.clj
+++ src/pg_demo/table_defs.clj
@@ -5009,6 +5009,172 @@
               PRIMARY KEY (ENTERPRISE_ID,KEYWORD_ID)
           ); " }

+    { "rm_lm_reported"
+          "CREATE TABLE rm_lm_reported (
+              ENTERPRISE_ID numeric NOT NULL,
+              ID numeric NOT NULL,
+              DESCRIPTION varchar(50),
+              DESCRIPTION_J varchar(50),
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,ID)
+          ); " }
+
+    { "rm_lm_reporter"
+          "CREATE TABLE rm_lm_reporter (
+              ENTERPRISE_ID numeric NOT NULL,
+              REPORTER_ID numeric NOT NULL,
+              CENTER_ID numeric,
+              PREFIX varchar(50),
+              FIRST_NAME varchar(35),
+              LAST_NAME varchar(50),
+              OCCUPATION_ID numeric,
+              CUST_RPT_ID varchar(20),
+              ADDRESS varchar(120),
+              CITY varchar(35),
+              STATE varchar(40),
+              ZIP varchar(15),
+              COUNTRY varchar(50),
+              PHONE varchar(20),
+              ALT_PHONE varchar(20),
+              FAX varchar(50),
+              EMAIL varchar(100),
+              HEALTHCARE_PROF numeric,
+              RPTR_TYPE_ID numeric,
+              SUFFIX varchar(15),
+              RECIPIENT numeric(1),
+              PREFERRED numeric(1),
+              ADDRESS_J varchar(120),
+              SUFFIX_J varchar(15),
+              DELETED timestamp,
+              DEPARTMENT varchar(60),
+              DEPARTMENT_J varchar(60),
+              COUNTRY_ID numeric,
+              CITY_J varchar(35),
+              FIRST_NAME_J varchar(35),
+              LAST_NAME_J varchar(50),
+              PREFIX_J varchar(50),
+              STATE_J varchar(40),
+              PRIMARY KEY (ENTERPRISE_ID,REPORTER_ID)
+          ); " }
+
+    { "rm_lm_reporter_institution"
+          "CREATE TABLE rm_lm_reporter_institution (
+              ENTERPRISE_ID numeric NOT NULL,
+              SEQ_NUM numeric NOT NULL,
+              INST_ID numeric NOT NULL,
+              REPORTER_ID numeric NOT NULL,
+              SORT_ID numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,SEQ_NUM)
+          ); " }
+
+    { "rm_lm_reporter_type"
+          "CREATE TABLE rm_lm_reporter_type (
+              ENTERPRISE_ID numeric NOT NULL,
+              RPTR_TYPE_ID numeric NOT NULL,
+              REPORTER_TYPE varchar(30) NOT NULL,
+              PROTECTED numeric,
+              DISPLAY numeric,
+              E2B_CODE numeric,
+              REPORTER_TYPE_J varchar(30),
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,RPTR_TYPE_ID)
+          ); " }
+
+    { "rm_lm_report_build_status"
+          "CREATE TABLE rm_lm_report_build_status (
+              STATUS_ID numeric NOT NULL,
+              STATUS_NAME varchar(100) NOT NULL,
+              REPORT_TYPE numeric NOT NULL,
+              STATUS_NAME_J varchar(100),
+              PRIMARY KEY (STATUS_ID,REPORT_TYPE)
+          ); " }
+
+    { "rm_lm_report_forms"
+          "CREATE TABLE rm_lm_report_forms (
+              ENTERPRISE_ID numeric NOT NULL,
+              REPORT_FORM_ID numeric NOT NULL,
+              FORM_DESC varchar(200) NOT NULL,
+              AGENCY_ID numeric,
+              RPT_TYPE numeric,
+              HIDDEN numeric,
+              FORM_CATEGORY numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,REPORT_FORM_ID)
+          ); " }
+
+    { "rm_lm_report_media"
+          "CREATE TABLE rm_lm_report_media (
+              ENTERPRISE_ID numeric NOT NULL,
+              MEDIA_ID numeric NOT NULL,
+              MEDIA varchar(30) NOT NULL,
+              PROTECTED numeric,
+              DISPLAY numeric,
+              MEDIA_J varchar(30),
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,MEDIA_ID)
+          ); " }
+
+    { "rm_lm_report_type"
+          "CREATE TABLE rm_lm_report_type (
+              ENTERPRISE_ID numeric NOT NULL,
+              RPT_TYPE_ID numeric NOT NULL,
+              REPORT_TYPE varchar(30) NOT NULL,
+              PROTECTED numeric,
+              DISPLAY numeric,
+              INCL_LIT numeric,
+              INCL_TRIAL numeric,
+              E2B_CODE numeric,
+              ABRV varchar(3),
+              INVESTIGATIONAL numeric,
+              REPORT_TYPE_J varchar(30),
+              DELETED timestamp,
+              INCL_RESEARCH numeric NOT NULL,
+              PRIMARY KEY (ENTERPRISE_ID,RPT_TYPE_ID)
+          ); " }
+
+    { "rm_lm_rpt_category"
+          "CREATE TABLE rm_lm_rpt_category (
+              ENTERPRISE_ID numeric NOT NULL,
+              RPT_CATEGORY_ID numeric NOT NULL,
+              RPT_CATEGORY varchar(3),
+              REPORT_FORM_ID numeric,
+              DESCRIPTION_J varchar(200),
+              E2B_CODE numeric,
+              DISPLAY numeric,
+              DESCRIPTION varchar(200),
+              PROTECTED numeric,
+              CATEGORY_FILTER numeric,
+              DELETED timestamp,
+              PRIMARY KEY (ENTERPRISE_ID,RPT_CATEGORY_ID)
+          ); " }
+
+    { "rm_lm_severity"
+          "CREATE TABLE rm_lm_severity (
+              SEVERITY_ID numeric NOT NULL,
+              SEVERITY varchar(30) NOT NULL,
+              PROTECTED numeric,
+              DISPLAY numeric,
+              DELETED timestamp,
+              PRIMARY KEY (SEVERITY_ID)
+          ); " }
+
+    { "rm_lm_sites"
+          "CREATE TABLE rm_lm_sites (
+              ENTERPRISE_ID numeric NOT NULL,
+              SITE_ID numeric NOT NULL,
+              SITE_DESC varchar(40),
+              SITE_ABRV varchar(4),
+              DELETED timestamp,
+              LAM_SITE numeric,
+              PROTECT_PATIENT numeric,
+              PROTECT_REPORTER numeric,
+              APPROVED_REPORTS numeric(1),
+              PROCESS_LAM_ASSESS numeric NOT NULL,
+              INTAKE_FOLDER_ID numeric,
+              PRIMARY KEY (ENTERPRISE_ID,SITE_ID)
+          ); " }
+
   ] ))

 (def dummy


alts! takes a collection, whoops

alts! takes a collection, whoops

--- src/lazubot/docker.clj
+++ src/lazubot/docker.clj
@@ -66,7 +66,7 @@
         worker-doc (get current-workers (first (keys current-workers)))
         result-channel (chan)]
     (go (>! (:in worker-doc) form)
-        (let [[response channel] (alts! (:out worker-doc) (timeout 10000))]
+        (let [[response channel] (alts! [(:out worker-doc) (timeout 10000)])]
           (if (= channel (:out worker-doc))
             (>! result-channel response)
             (replace-worker! worker-doc))))


Add :sh-opts arg to 'git to allow :in and other c.j.s/sh args.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -123,13 +123,13 @@
     -1))

 (defn git
-  [{:keys [^File gitdir ok-statuses]
+  [{:keys [^File gitdir ok-statuses sh-opts]
     :or {ok-statuses #{0}}} & subcmd]
   ;; We won't handle bare repos or displaced worktrees
   (let [cmd-args (if (nil? gitdir)
                    []
                    [:dir gitdir])
-        all-args (concat subcmd cmd-args)
+        all-args (concat subcmd cmd-args sh-opts)
         ;; _ (prn :calling (doall (cons 'git all-args)))
         {:keys [exit] :as rtn} (apply sh "git" all-args)
         rtn (assoc rtn :bool (if (zero? (:exit rtn))


Add functions for 'newest-voom-ver-by-spec using voom tags

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -346,17 +346,101 @@
       xs))
    (lazy-seq (println "done"))))

-(defn update-ver-cache
+(defn parse-sha-refs
+  [s]
+  (let [[sha refstr] (vec (.split #":" s 2))
+        refs (when refstr
+               (when-let [[_ x] (re-find #"\((.*)\)" refstr)]
+                 (vec (.split #",\s+" x))))]
+    {:sha sha, :refs refs}))
+
+(defn project-change-shas
   [gitdir]
-  (let [prj-changes (likely-project-shas gitdir)
-        sha-info (map
-                  (fn [{:keys [sha file]}]
-                    (when-let [p (robust-read-project gitdir sha file)]
-                      {:proj (symbol (:group p) (:name p))
-                       :v (:version p)
-                       :sha sha}))
-                  (report-progress gitdir prj-changes))]
-    (remove nil? sha-info)))
+  (->> (git {:gitdir gitdir} "log" "--all" "--pretty=format:%H:%d"
+            "--name-status" "--" "project.clj" "**/project.clj")
+       :lines
+       (keep #(if-let [[_ op path] (re-matches #"(.)\t(.*)" %)]
+                {:op op :path path}
+                (when (seq %)
+                  (parse-sha-refs %))))
+       (#(concat % [{:sha "end sigil"}]))
+       (reductions (fn [[partial complete] entry]
+                     (if (:sha entry)
+                       [entry partial]
+                       [(update-in partial [:ops] (fnil conj []) entry) nil]))
+                   [nil nil])
+       (keep second)))
+
+(defn tag-projects
+  [gitdir]
+  (let [proj-shas (project-change-shas gitdir)]
+    (doseq [{:keys [sha refs ops]} (report-progress gitdir proj-shas)
+            :while (not-any? #(.startsWith ^String % "tag: voom-") refs)
+            {:keys [op path]} ops]
+      (when-let [p (and (not= "D" op)
+                        (robust-read-project gitdir sha path))]
+        (let [tag (s/join "--" ["voom"
+                                (str (:group p) "%" (:name p))
+                                (:version p)
+                                (s/replace (:root p) #"/" "%")
+                                (subs sha 0 7)])]
+          (git {:gitdir gitdir} "tag" tag sha))))))
+
+(defn clear-voom-tags
+  [gitdir]
+  (let [tags (->> (git {:gitdir gitdir} "tag" "--list" "voom-*")
+                  :lines
+                  (remove empty?))]
+    (when (seq tags)
+      (apply git {:gitdir gitdir} "tag" "--delete" tags)
+      nil)))
+
+(defn parse-tag
+  [tag]
+  (->
+   (zipmap [:prefix :proj :ver :path :sha] (s/split tag #"--"))
+   (update-in [:path] (fnil s/replace "") #"%" "/")))
+
+(defn newest-voom-ver-by-spec
+  [proj-name ver-spec {:keys [repo ref path]}]
+
+  (for [gitdir (all-repos-dirs)]
+    (let [ptn (s/join "--" ["voom"
+                       (str (namespace proj-name) "%" (name proj-name))
+                       (str ver-spec "*")])
+          tags (:lines (git {:gitdir gitdir} "tag" "--list" ptn))
+          ;;_ (prn :tags tags)
+          tspecs (if (= tags [""])
+                   []
+                   (map parse-tag tags))
+          paths (set (map :path tspecs))]
+
+      (doall
+       (for [path paths
+             branch (map #(re-find #"[^/]*/+[^/]*$" (str %))
+                         (glob (str gitdir "/refs/remotes/*/*")))
+             :let [commits
+                   , (map
+                      parse-sha-refs
+                      (:lines (apply git {:gitdir gitdir} "log"
+                                     "--pretty=format:%H:%d" "--decorate" "--reverse"
+                                     (concat (map #(str "^" % "^") tags)
+                                             [branch "--" path]))))]
+             :when (seq commits)]
+         (some (fn [[current next-commit]]
+                 #_(prn :refs path (:refs next-commit))
+                 (when (or (= :end next-commit)
+                           (some #(= path (:path (parse-tag %)))
+                                 (:refs next-commit)))
+                   {:sha (:sha current)
+                    :path path
+                    :gitdir gitdir
+                    :branch branch}))
+               (partition 2 1 (concat commits [:end]))))))))
+
+
+
+

 ;; Add metadata pinning (how big to bump? all? minor? sha?) -- warn about not updating
 ;; Opt-in autobump  -- default to no major auto


Fix bug introduced while splitting out 'git-commits.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -960,7 +960,7 @@

 (defn git-commits
   [gitdir branch]
-  (->
+  (->>
    (git {:gitdir gitdir} "log" "--full-history" "--reverse" "--pretty=%H:%ct:%T:%P" branch)
    :lines
    (map #(let [[sha ctime tree parents] (s/split % #":")


Fix missing reader conditional on builtin-spec tests file.

--- test/cats/builtin_spec.cljc
+++ test/cats/builtin_spec.cljc
@@ -1,8 +1,11 @@
 (ns cats.builtin-spec
-  (:require [cljs.test :as t]
-            [cats.builtin :as b]
+  (:require [cats.builtin :as b]
             [cats.protocols :as p]
             [cats.monad.maybe :as maybe]
+
+            #?(:cljs [cljs.test :as t]
+               :clj [clojure.test :as t])
+
             #?(:cljs [cats.core :as m :include-macros true]
                :clj [cats.core :as m])))


Move a test

Move a test

--- test/picard/test/client.clj
+++ test/picard/test/client.clj
@@ -144,6 +144,40 @@
     ;; 2 is to account for the connection test-helper makes
     (is (= 2 (count (netty-connect-evts))))))

+(defcoretest issuing-pause-resume
+  [ch1 ch2]
+  (fn [resp req]
+    (resp :response [200 {"transfer-encoding" "chunked"} :chunked])
+    (resp :body "Hello")
+    (resp :body "World")
+    (resp :done nil)
+    (fn [_ _] true))
+
+  (let [upstream
+        (client/request
+         ["Localhost" 4040]
+         [{:path-info      "/"
+           :request-method "GET"
+           "connection"    "close"}]
+         (fn [upstream evt val]
+           (enqueue ch1 [evt val])
+           (when (= evt :response)
+             (upstream :pause nil))))]
+    (receive ch2 (fn [_] (upstream :resume nil))))
+
+  (is (next-msgs-for
+       ch1
+       :response :dont-care))
+
+  (Thread/sleep 30)
+  (enqueue ch2 true)
+
+  (is (next-msgs-for
+       ch1
+       :body "Hello"
+       :body "World"
+       :done nil)))
+
 (defcoretest telling-the-application-to-chill-out
   [ch ch2]
   (fn [resp req]
@@ -201,40 +235,6 @@
      "connection"    "close"}]
    (fn [_ _ _] true)))

-(defcoretest issuing-pause-resume
-  [ch1 ch2]
-  (fn [resp req]
-    (resp :response [200 {"transfer-encoding" "chunked"} :chunked])
-    (resp :body "Hello")
-    (resp :body "World")
-    (resp :done nil)
-    (fn [_ _] true))
-
-  (let [upstream
-        (client/request
-         ["Localhost" 4040]
-         [{:path-info      "/"
-           :request-method "GET"
-           "connection"    "close"}]
-         (fn [upstream evt val]
-           (enqueue ch1 [evt val])
-           (when (= evt :response)
-             (upstream :pause nil))))]
-    (receive ch2 (fn [_] (upstream :resume nil))))
-
-  (is (next-msgs-for
-       ch1
-       :response :dont-care))
-
-  (Thread/sleep 30)
-  (enqueue ch2 true)
-
-  (is (next-msgs-for
-       ch1
-       :body "Hello"
-       :body "World"
-       :done nil)))
-
 (defcoretest connecting-to-an-invalid-server
   [_ ch2]
   :hello-world


improved string-centered-* functions - renamed string-centered-rect -> string-centered-bounds - added string-centered-glyphbounds - changed signature of draw-string-centered

--- src/mastersign/drawing.clj
+++ src/mastersign/drawing.clj
@@ -8,7 +8,7 @@

 (defn draw-dot
   ([g p & {color :color
-            :or {color Color/RED}}]
+           :or {color Color/RED}}]
   (doto g
     (.setColor color)
     (.fill (ellipse (- (.x p) 2) (- (.y p) 2) 4 4)))))
@@ -63,27 +63,53 @@
         c (rect-center r)]
      (point (- (.x c)) (- (.y c)))))

-(defn string-centered-rect
+(defn string-centered-bounds
   ([g font text]
+   (string-centered-bounds g font text 0 0))
+  ([g font text p]
+   (string-centered-bounds g font text (.x p) (.y p)))
+  ([g font text x y]
    (let [gv (.createGlyphVector font (.getFontRenderContext g) text)
          r (.getVisualBounds gv)
          c (rect-center r)]
-     (rectangle (- (.x r) (.x c)) (- (.y r) (.y c)) (.width r) (.height r))))
+     (rectangle (- (+ x (.x r)) (.x c)) (- (+ y (.y r)) (.y c)) (.width r) (.height r)))))
+
+(defn string-centered-glyphbounds
+  ([g font text]
+   (string-centered-glyphbounds g font text 0 0))
+  ([g font text p]
+   (string-centered-glyphbounds g font text (.x p) (.y p)))
   ([g font text x y]
-   (let [r (string-centered-rect g font text)]
-     (set! (.x r) (+ x (.x r)))
-     (set! (.y r) (+ y (.y r)))
-     r)))
+  (let [frc (.getFontRenderContext g)
+        gv (.createGlyphVector font frc text)
+        r (.getVisualBounds gv)
+        c (rect-center r)
+        glyphbounds (map
+                     #(.getBounds2D (.getGlyphOutline gv % (- x (.x c)) (- y (.y c))))
+                     (range (.getNumGlyphs gv)))]
+    (vec glyphbounds))))
+
+(defn string-centered-outline
+  ([g font text]
+   (string-centered-outline g font text 0 0))
+  ([g font text p]
+   (string-centered-outline g font text (.x p) (.y p)))
+  ([g font text x y]
+   (let [frc (.getFontRenderContext g)
+         gv (.createGlyphVector font frc text)
+         r (.getVisualBounds gv)
+         c (rect-center r)]
+     (.getOutline gv (- x (.x c)) (- y (.y c))))))

 (defn draw-string-centered
-  [g text x y & {font :font,
-                 color :color,
-                 :or {font default-font,
-                      color Color/BLACK}}]
+  [g text p & {font :font,
+               color :color,
+               :or {font default-font,
+                    color Color/BLACK}}]
   (let [offset (string-centered-offset g font text)]
     (doto g
         (.setColor color)
         (.setFont font)
         (.drawString text
-                     (float (+ x (.x offset)))
-                     (float (+ y (.y offset)))))))
+                     (float (+ (.x p) (.x offset)))
+                     (float (+ (.y p) (.y offset)))))))


Fix a problem with selection of commercial audio books

--- src/mdr2/abacus/import.clj
+++ src/mdr2/abacus/import.clj
@@ -67,14 +67,14 @@
    (map fix-production)
    (map #(merge (prod/default-meta-data) %))))

-(defn extract-id
-  [line]
-  (parse-int (or (second (re-find #"^\./dam(\d+)" line)) "0")))
+(defn extract-id [regexp s] (parse-int (or (second (re-find regexp s)) "0")))
+(def extract-id-from-file (partial extract-id #"^\./dam(\d+)"))
+(def extract-id-from-db (partial extract-id #"^dam(\d+)"))

 (defn files-by-id
   [f]
   (with-open [r (clojure.java.io/reader f)]
-    (group-by extract-id (line-seq r))))
+    (group-by extract-id-from-file (line-seq r))))

 (defn wav-file? [f] (re-matches #".*\.wav$" f))
 (defn struct-file? [f] (re-matches #".*/struct.html$" f))
@@ -93,6 +93,7 @@
   [m]
   (-> m
       (assoc (keyword (:element m)) (:value m))
+      (assoc :id (extract-id-from-db (:id m)))
       (rename-keys {:idVorstufe :library_number
                     :producedDate :produced_date
                     :sourceDate :source_date
@@ -123,7 +124,7 @@
 (def all-commercial-productions
   (let [statement (string/join
                    "\n"
-                   ["SELECT d.id, d.tm, d.identifier, d.title, d.process_status, m.element, m.value"
+                   ["SELECT d.tm, d.identifier AS id, d.title, d.process_status, m.element, m.value"
                     "FROM madras.document d, madras.meta m"
                     "WHERE d.id IN (SELECT id_document FROM madras.meta WHERE element='idVorstufe' AND value regexp '^PNX [2-9][0-9][0-9][0-9]')"
                     "AND d.id = m.id_document"])]


Remove superfluous decompression.

Remove superfluous decompression.

--- src/onyx/queue/hornetq.clj
+++ src/onyx/queue/hornetq.clj
@@ -311,15 +311,17 @@
           s)))))

 (defn take-segments
-  ([f n] (take-segments f n []))
-  ([f n rets]
+  ;; Set limit of 32 to match HornetQ's byte buffer. If they don't
+  ;; match, hashCode() doesn't work as expected.
+  ([f n] (take-segments f n [] (.limit (fressian/write :done) 32)))
+  ([f n rets ba]
      (if (= n (count rets))
        rets
        (let [segment (f)]
          (if (nil? segment)
            rets
-           (let [decompressed (fressian/read (.toByteBuffer (.getBodyBufferCopy segment)))]
-             (if (= :done decompressed)
+           (let [m (.toByteBuffer (.getBodyBufferCopy segment))]
+             (if (= m ba)
                (conj rets segment)
-               (recur f n (conj rets segment)))))))))
-
+               (recur f n (conj rets segment) ba))))))))
+


Fix scope to allow for the rendering of plain bufs

--- src/overtone/viz/scope.clj
+++ src/overtone/viz/scope.clj
@@ -17,6 +17,7 @@
 (def FPS 10)
 (def scopes* (atom {}))
 (def scope-pool* (atom nil))
+(def scopes-running?* (atom false))
 (def WIDTH 600)
 (def HEIGHT 400)
 (def X-PADDING 5)
@@ -32,7 +33,7 @@
 (defn- update-scope [s]
   (let [{:keys [buf size width height panel y-array x-array panel]} s
         frames (buffer-data buf)
-        step (int (/ (:size buf) width))
+        step (int (/ (buffer-size buf) width))
         y-scale (/ (- height (* 2 Y-PADDING)) -2)
         y-shift (+ (/ height 2) Y-PADDING)]
     (dotimes [x width]
@@ -92,13 +93,18 @@

 (defn scopes-start
   []
-  (create-pool-if-necessary)
-  (start-scopes-runner))
+  (if-not @scopes-running?*
+    (do
+      (create-pool-if-necessary)
+      (start-scopes-runner)
+      (reset! scopes-running?* true))))

 ;;  (.cancel (:runner @scope*) true)
 (defn scopes-stop
   []
-  (stop-and-reset-pool! scope-pool*))
+  (stop-and-reset-pool! scope-pool*)
+  (reset! scopes-running?* false))
+

 (defn- scope-bus
   "Set a bus to view in the scope."
@@ -106,8 +112,6 @@
   (let [buf (buffer SCOPE-BUF-SIZE)
         _ (wait-for-buffer buf)
         bus-synth (bus->buf :target 0 :position :tail (:num s) buf)]
-
-    (apply-at (+ (now) 1000) update-scope [])
     (assoc s
       :size SCOPE-BUF-SIZE
       :bus-synth bus-synth
@@ -117,8 +121,8 @@
   "Set a buffer to view in the scope."
   [s]
   (assoc s
-    :size (:size (buffer-info (:num s)))
-    :buf (:num s)))
+    :size (:n-frames (buffer-info (:num s)))
+    :buf (buffer-info (:num s))))

 (defn- mk-scope
   [num kind keep-on-top width height]


docstring edits

docstring edits

--- src/ontrail/import.clj
+++ src/ontrail/import.clj
@@ -66,7 +66,7 @@
   (int (read-string (html/text (nth exercise 6)))))

 (defn get-tags [exercise]
-  "Current implementation stores either empty string or one tag per ex. Now tag is a list of strings."
+  "Import implementation stores either empty string or one tag per ex. Now tag is a list of strings."
   (let [one-tag (string/trim (html/text (nth exercise 8)))]
     (if (= "" one-tag)
       '()


fixed distance parser bug

fixed distance parser bug

--- src/ontrail/parser.clj
+++ src/ontrail/parser.clj
@@ -62,7 +62,7 @@

 (defn as-double-km [str]
   (let [x (string/replace str #"," ".")]
-    (int (* 1000 (Double. x)))))
+    (Math/round (* 1000 (Double/valueOf x)))))

 (def distance-regexps
   [{:re #"^([0-9]+)$" :conv as-double-km}


Add websocket endpoitn

Add websocket endpoitn

--- src/ruuvi/ring_handler.clj
+++ src/ruuvi/ring_handler.clj
@@ -17,7 +17,7 @@
    [ring.middleware.format]
    [ring.middleware.params]
    [buddy.auth.middleware :refer [wrap-authentication]]
-
+   [ruuvi.resources.websocket :as websocket]
    [ruuvi.swagger :as swagger]
    [ruuvi.middleware :as middleware]
    [ruuvi.security :as sec]
@@ -35,6 +35,7 @@
        {:context ["api"]
         :swagger-options swagger/swagger-options
         :default-middleware sv/wrap-with-schema-validation}
+       ["websocket" 'ruuvi.resources.websocket]
        ["meta" 'ruuvi.resources.meta]
        ["auth" 'ruuvi.resources.auth]
        ["events" 'ruuvi.resources.events]
@@ -75,7 +76,8 @@
   component/Lifecycle
   (start [component]
          (debug "RingHandler starting")
-         (let [component-app (create-handler component development)]
+         (let [component-app (-> (create-handler component development)
+                                 (websocket/websocket-middleware "/api/websocket"))]
            (assoc component :app component-app)))
   (stop [component]
         (debug "RingHandler stopping")


Fixing slow playback by correctly calculating the start time while playing notes one at a time

--- src/pianola/webui.cljs
+++ src/pianola/webui.cljs
@@ -78,7 +78,7 @@
   (let [{:keys [context playing]} @app-state
         {:keys [time duration] :as note} (first notes)
         remainder (rest notes)
-        at (+ time (synth/current-time context))
+        at (synth/current-time context)
         synth-instance (-> note
                            (update :pitch temperament/equal)
                            (dissoc :time)


Updates to render 'cancel' and 'canceled' state of the activity. Show a check-mark, when do-not-wait right menu option is clicked to indicate that the activity has been addressed.

--- src/planviz/state.cljs
+++ src/planviz/state.cljs
@@ -184,6 +184,14 @@

 (defmulti plans-mutate om/dispatch)

+(defmethod plans-mutate :default [a b c]
+  (println "WARN plans-mutate default")
+  ;(println "a keys" (keys a))
+  ;(pprint a)
+  (println "b" b)
+  ;(println "c" c)
+  )
+
 (defmethod plans-mutate 'plans/pan-zoom
   [{:keys [state] :as env} k {:keys [pan-zoom] :as params}]
   {:value {:keys comp/pan-zoom-query}
@@ -299,9 +307,18 @@
             edge-id (if (not (node-id? update-uid))
                       (composite-key plid update-uid))
             edge (if edge-id (get edge-by-plid-id edge-id))
+            prev-state (:edge/state edge)
+            ;; For cancel event, we want to preserve previous state
+            ;; and add a marker
+            cancel-event? (= :cancel state)
+            cancelled-event? (= :cancelled state)
+            new-state (if cancel-event?
+                        prev-state
+                        state)
+            edge (assoc edge :edge/marker-mid state)
             edge-by-plid-id (if edge
                               (assoc edge-by-plid-id edge-id
-                                (assoc edge :edge/state state))
+                                (assoc edge :edge/state new-state))
                               edge-by-plid-id)]
         (recur edge-by-plid-id (first more) (rest more))))))

@@ -340,6 +357,13 @@
    (let [edge-id (edge-key-fn edge)
          ref [:edge/edge-by-plid-id edge-id]]
      #(swap! state update-in ref merge edge))})
+
+(defmethod plans-mutate 'plans/edge-marker-mid
+  [{:keys [state]} _ {:keys [edge]}]
+  {:value {:keys comp/edge-query}
+   :action #(swap! state update-in [:edge/edge-by-plid-id (edge-key-fn edge) :edge/marker-mid]
+                   (fn [_]
+                     (:edge/marker-mid edge)))})

 (defonce plans-parser (om/parser {:read plans-read :mutate plans-mutate}))

@@ -773,3 +797,6 @@
 (defn network-updates [updates]
   (plans-query `[(plans/network-updates {:updates ~updates})])
   true) ;; for deferred
+
+(defn update-edge-marker-mid [edge]
+  (plans-query `[(plans/edge-marker-mid {:edge ~edge})]))


[#2925] If repeatable, generate at least 2 answers

--- backend/specs/akvo/lumen/specs/import.clj
+++ backend/specs/akvo/lumen/specs/import.clj
@@ -142,7 +142,7 @@
                                 (reduce (fn [c [groupId columns]]
                                           (let [r (if (get repeatables groupId)
                                                         (let [x (rand-int (get max-responses groupId))]
-                                                          (if (> x 0) x 1))
+                                                          (if (> x 1) x 2))
                                                         1)]
                                             (assoc c groupId (mapv (fn [_] (sample-column-values columns instance-id))
                                                                    (range r))))


Use redirects for index-files

Use redirects for index-files

--- modules/reitit-ring/src/reitit/ring.cljc
+++ modules/reitit-ring/src/reitit/ring.cljc
@@ -96,26 +96,30 @@
                      (fn
                        ([request] (handler request))
                        ([request respond _] (respond (handler request)))))
-            trim-path (fn [& paths] (str/replace (apply str paths) "//" "/"))
+            join-paths (fn [& paths]
+                         (str/replace (str/replace (str/join "/" paths) #"([/]+)" "/") #"/$" ""))
             resource-response (fn [path]
-                                (if-let [response (or (paths (trim-path "/" path)) (response/resource-response path options))]
+                                (if-let [response (or (paths (join-paths "/" path))
+                                                      (response/resource-response path options))]
                                   (response/content-type response (mime-type/ext-mime-type path))))
             path-or-index-response (fn [path uri]
                                      (or (resource-response path)
                                          (loop [[file & files] index-files]
                                            (if file
-                                             (let [path (trim-path path file)]
-                                               (if (resource-response path)
-                                                 {:status 302 :headers {"Location" (trim-path uri "/" path)}}
-                                                 (recur files)))))))
+                                             (if (resource-response (join-paths path file))
+                                               {:status 302 :headers {"Location" (join-paths uri file)}}
+                                               (recur files))))))
             handler (if path
                       (fn [request]
                         (let [uri (:uri request)]
                           (if-let [path (if (>= (count uri) path-size) (subs uri path-size))]
                             (path-or-index-response path uri))))
                       (fn [request]
-                        (let [path (-> request :path-params parameter)]
-                          (or (path-or-index-response path path) {:status 404}))))]
+                        (let [uri (:uri request)
+                              path (-> request :path-params parameter)]
+                          (or (path-or-index-response path uri)
+                              ;; TODO: use generic not-found handler
+                              {:status 404}))))]
         (create handler)))))

 (defn ring-handler


using systems range

using systems range


Make the error message more helpful

Make the error message more helpful

--- src/midje/error_handling/semi_sweet_validations.clj
+++ src/midje/error_handling/semi_sweet_validations.clj
@@ -27,8 +27,11 @@

         (exposed-testable? (first funcall))
         (validation-error-report-form
-         form
-         "Prerequisites cannot be specified for private functions exposed with expose-testables.")
+          form
+          "A prerequisite cannot be specified on a function exposed via expose-testables."
+          (cl-format nil "Instead, specify it directly on the var: #'~S/~S"
+                     (-> (first funcall) fnref-var-object meta :ns ns-name)
+                     (first funcall)))

         :else
         form))))


finish content and edit

finish content and edit

--- src/pc/views/blog/ideas_are_made_with_precursor.clj
+++ src/pc/views/blog/ideas_are_made_with_precursor.clj
@@ -63,67 +63,73 @@

 (defn ideas-are-made-with-precursor []
   {:title "Ideas are made with Precursor."
-   :blurb ""
+   :blurb "I'm exceedingly curious to see how people use Precursor. Recently we've been using an internal playback tool to learn about this..."
    :author "Danny"
    :image ""
    :body
    (list
     [:article
-     [:p "Precursor is a collaboration web app that makes prototyping effortless. "
-         "Although, lately I've noticed a lot of users ignore that last part. "
-         "There are fascinating things being made with Precursor everyday. "
-         "I even put together a list of my favorites. "]]
+     [:p "As our user base continues to grow, I'm exceedingly curious to see how people use Precursor. "
+         "Recently we've been using an internal playback tool to learn about this. "]
+     [:p "Today I'm excited to announce that we're now making this tool accessible to everyone. "
+         "I've curated the following examples to showcase some of its key uses. "]]

-    [:article [:h3 "Dave was here."]]
+    [:article
+     [:h3 "Keep moving forward."]
+     [:p  "This doc is a unique glimpse at the discipline it takes to be a great designer. "
+          "Eddie is well known for his exceptional work, and rather than waste time with elaborate sketches, he quickly opts for a simple placeholder to get the job done. "]]
     (featured-dribbble "lobanovskiy" "17592197312062?cx=1044&cy=580&z=0.45&replay=true")
-    [:article [:h3 "Why so artsy?"]]
+
+    [:article
+     [:h3 "Why so serious?"]
+     [:p  "I like this illustration because it reminds me that work should be fun. "
+          "I also find it interesting how much detail Damir can achieve with each stroke. "]]
     (featured-dribbble "dhotlo2" "17592197311947?cx=629&cy=376&z=1&replay=true")
-    [:article [:h3 "That poor avatar."]]
+
+    [:article
+     [:h3 "Trim the trash."]
+     [:p  "This is something I'm seeing more people practice with Precursor—prototypes don't need many detail. "
+          "Watch Faith contemplate the value of that avatar, explore the idea, and ultimately remove it. "]]
     (featured-dribbble "fatihturan" "17592197311774?cx=707&cy=502&z=1&replay=true")
-    [:article [:h3 "Would watch again."]]
+
+    [:article
+     [:h3 "Iteration is important."]
+     [:p  "Without watching Justin build this prototype, it's hard to tell how many iterations we through. "
+          "Too many can be just as dangerous as too few, but I think this strikes a good balance. "]]
     (featured-dribbble "jyo208" "17592197310592?cx=584&cy=581&z=0.55&replay=true")
-    [:article [:h3 "Cost of living."]]
+
+    [:article
+     [:h3 "Cost of living."]
+     [:p  "Before Ken tried drawing any components, he got his content and spacing figured out. "
+          "Isolating important areas of your ideas is crucial for expressing them quickly. "]]
     (featured-dribbble "kenseals" "17592197311539?cx=517&cy=392&z=1&replay=true&tx-count=59")
-    [:article [:h3 "Solid spatial awareness."]]
+
+    [:article
+     [:h3 "Solid spatial awareness."]
+     [:p  "Well that was fast. "
+          "Peter made short work of this map by staying focused on his content—a great strategy for diagramming. "
+          "He figured out alignment and connections afterwards. "]]
     (featured-github "peteratticusberg" "17592197310304?cx=687&cy=636&z=0.8&replay=true")
-    [:article [:h3 "Teammate helps out."]]
+
+    [:article
+     [:h3 "Teammate helps out."]
+     [:p  "Mathieu used duplication to skip over the tedious areas of his idea. "
+          "He prioritized the unique aspects of his prototype by automating the others. "]]
     (featured-dribbble "tooks_" "17592197311539?cx=517&cy=392&z=1&replay=true&tx-count=59")

+    ; [:article
+    ;  [:h3 "Lastly, for Reddit."]
+    ;  [:p  "And just for fun I went ahead and made a little playback of my own for Alexis Ohanian. "
+    ;       "It features everyone's favorite alien mascot, Snoo. "
+    ;       "*tips fedora* "]]
+    ; (featured-dribbble "lobanovskiy" "17592197311539?cx=517&cy=392&z=1&replay=true&tx-count=59")
+
     [:article
-     [:h3 "What's with the anonymity?"]
-     [:p "Precursor is free for everyone to use. "
-         "That even includes users who don't sign up, so we get a lot of anonymous illustrations. "
-         "If one of these belongs to you send me an email. "
-         "The attribution will get updated and I'll even send you a custom t-shirt to say thanks. "]]
+     [:h3 "I'd wear that."]
+     [:p  "To thank these users for letting me use their work, I'm sending them all custom t-shirts displaying their prototypes. "
+          "I want to do this again soon, so if you make something cool, let me know. "
+          "Email danny@precursorapp.com with a link and if I feature it, you'll get a one-of-a-kind t-shirt! "]]

     [:figure [:img {:src (cdn-path "/blog/ideas-are-made-with-precursor/eddie-shirt.png")}]]

-    [:article
-     [:p "And by \"custom\" I mean the t-shirt will have your design on it. "
-         "I plan on doing more features like this in the future. "
-         "If you make something cool with Precursor email "
-         [:a {:href "#"} "danny@precursorapp.com"]
-         " with your mailing address and a link to the doc. "
-         "If it gets featured in the next post I'll ship you a one-of-a-kind t-shirt!"]]
-
-    [:article
-     [:h3 "I tried making one of my own."]
-     [:p "We implemented a new feature recently that lets users play back interactions that happened in their doc. "
-         "The main utility in this feature will come later, but in the meantime we thought it would be fun to play with in groups. "
-         "And if we're trying to show it off to a group, why not target a huge group? "
-         "Like Reddit, perhaps? "]]
-
-    [:figure [:img {:src "https://placehold.it/800x600"}]]
-
-    [:article
-     [:h3 "That's it for now."]
-     [:p "I had a lot of fun finding all of this cool stuff, and I didn't even get to showcase everything."
-         "I'm hoping to do this again soon, but it does take a considerable amount of time to sort through thousands of these. "
-         "You can help by sending me tips for amazing docs to take a look at. "
-         "So if you or your teammate make a really cool looking wireframe, illustration, etc. this week, tell me about it! "]]
-
-    ; [:figure
-    ;  [:a.img {:data-caption-black "I pile icons on top of each other, and then I toggle their visibility to compare."}
-    ;   [:img {:src (cdn-path "/blog/clojurescript-is-a-design-tool/illustrator-onoff.gif")}]]]
-
     )})


Try setting Driver explicitly

Try setting Driver explicitly

--- src/swartz/models/core.clj
+++ src/swartz/models/core.clj
@@ -1,4 +1,5 @@
 (ns swartz.models.core
   (:require [environ.core :refer [env]]))

-(def db {:connection-uri (env :database-url)})
+(def db {:connection-uri (env :database-url)
+         :classname "org.postgresql.Driver"})


updated airswap dapp url

updated airswap dapp url

Signed-off-by: Andrey Shovkoplyas <b713972e59b8e606e23253c4a13e948139fea4d1@gmail.com>

--- src/status_im/ui/screens/browser/default_dapps.cljs
+++ src/status_im/ui/screens/browser/default_dapps.cljs
@@ -5,7 +5,7 @@
 (def all
   [{:title (i18n/label :t/default-dapps-exchanges)
     :data  [{:name        "Airswap"
-             :dapp-url    "https://www.airswap.io/trade"
+             :dapp-url    "https://instant.airswap.io/"
              :photo-path  "contacts://airswap"
              :description "Meet the future of trading."}
             {:name        "Bancor"


Vacuum tables in performance test to exclude database performance

--- src/test/clojure/pdok/featured/performance_test.clj
+++ src/test/clojure/pdok/featured/performance_test.clj
@@ -14,6 +14,11 @@
 (defn clean-db []
   (j/execute! test-db ["DROP SCHEMA IF EXISTS \"featured_performance_performance-set\" CASCADE"])
   (j/execute! test-db ["DROP SCHEMA IF EXISTS \"performance-set\" CASCADE"]))
+
+(defn vacuum-tables []
+  (j/execute! test-db ["VACUUM ANALYZE \"featured_performance_performance-set\".feature"] :transaction? false)
+  (j/execute! test-db ["VACUUM ANALYZE \"featured_performance_performance-set\".feature_stream"] :transaction? false)
+  (j/execute! test-db ["VACUUM ANALYZE \"featured_performance_performance-set\".timeline_col1"] :transaction? false))

 (defn generate-new-features [ids difficult?]
   (with-bindings {#'generator/*difficult-geometry?* difficult?}
@@ -47,7 +52,9 @@
                       (merge {:check-validity-on-delete false} cfg)
                       "performance-set" persistence [timeline])]
       (dorun (processor/consume processor features))
-      (:statistics (processor/shutdown processor)))))
+      (let [statistics (processor/shutdown processor)
+            _ (vacuum-tables)]
+      (:statistics statistics)))))

 (deftest double-file-test
   (clean-db)


Replace Add Projects buttons

Replace Add Projects buttons

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -3,6 +3,7 @@
             [frontend.async :refer [navigate! raise!]]
             [frontend.components.common :as common]
             [frontend.components.forms :refer [managed-button]]
+            [frontend.components.pieces.button :as button]
             [frontend.components.pieces.card :as card]
             [frontend.components.pieces.org-picker :as org-picker]
             [frontend.components.pieces.tabs :as tabs]
@@ -53,10 +54,9 @@
   (reify
     om/IRender
     (render [_]
-      (html
-       [:button.btn.btn-primary
-        {:on-click #(raise! owner [:refreshed-user-orgs {}])} ;; TODO: spinner while working?
-        "Reload Organizations"]))))
+      (button/button {:on-click #(raise! owner [:refreshed-user-orgs {}])
+                      :primary? true}
+                     "Reload Organizations"))))

 (defn- repo-title [repo link?]
   (let [repo-name (vcs-url/repo-name (:vcs_url repo))
@@ -155,32 +155,29 @@
   (reify
     om/IRender
     (render [_]
-      (html
-       [:a.btn.btn-primary.plan {:href (routes/v1-org-settings-path {:org login
-                                                                     :vcs_type vcs_type
-                                                                     :_fragment "osx-pricing"})
-                                 :on-click #((om/get-shared owner :track-event)
-                                             {:event-type :select-plan-clicked
-                                              :properties {:org login
-                                                           :vcs-type vcs_type
-                                                           :plan-type pm/osx-plan-type}})}
-        "Select Plan"]))))
+      (button/link {:href (routes/v1-org-settings-path {:org login
+                                                        :vcs_type vcs_type
+                                                        :_fragment "osx-pricing"})
+                    :on-click #((om/get-shared owner :track-event)
+                                {:event-type :select-plan-clicked
+                                 :properties {:org login
+                                              :vcs-type vcs_type
+                                              :plan-type pm/osx-plan-type}})
+                    :primary? true}
+                   "Select Plan"))))

 (defn free-trial-button [{{:keys [login vcs_type]} :selected-org} owner]
   (reify
     om/IRender
     (render [_]
-      (html
-       (managed-button
-        (let [plan-type :osx
-              template "osx-trial"]
-          [:a.btn.trial {:on-click #(do
-                                      (raise! owner [:activate-plan-trial {:plan-type plan-type
-                                                                           :template template
-                                                                           :org {:name login
-                                                                                :vcs_type vcs_type}}]))
-                         :data-spinner true}
-           "Start 2 Week Trial"]))))))
+      (button/managed-button
+       {:on-click #(do
+                    (raise! owner
+                            [:activate-plan-trial {:plan-type :osx
+                                                   :template "osx-trial"
+                                                   :org {:name login
+                                                         :vcs_type vcs_type}}]))}
+       "Start 2 Week Trial"))))

 (defn no-plan-empty-state [{{:keys [login vcs_type] :as selected-org} :selected-org} owner]
   (reify
@@ -201,6 +198,7 @@
          "Select a plan to build your OS X projects now."]
         [:div.buttons
          (om/build select-plan-button {:selected-org selected-org})
+         " "
          (om/build free-trial-button {:selected-org selected-org})]]))))

 (defmulti repo-list (fn [{:keys [type]}] type))
@@ -395,30 +393,32 @@
                                 github-authorized? "github"
                                 :else "bitbucket")
             tab-content (html
-                         [:div
-                          (when (= "github" selected-vcs-type)
-                            (if github-authorized?
-                              (missing-org-info owner)
-                              [:div
-                               [:p "GitHub is not connected to your account yet. To connect it, click the button below:"]
-                               [:a.btn.btn-primary {:href (gh-utils/auth-url)
-                                                    :on-click #((om/get-shared owner :track-event) {:event-type :authorize-vcs-clicked
-                                                                                :properties {:vcs-type selected-vcs-type}})}
-                                "Authorize with GitHub"]]))
-                          (when (and (= "bitbucket" selected-vcs-type)
-                                     (not bitbucket-authorized?))
-                            [:div
-                             [:p "Bitbucket is not connected to your account yet. To connect it, click the button below:"]
-                             [:a.btn.btn-primary {:href (bitbucket/auth-url)
-                                                  :on-click #((om/get-shared owner :track-event) {:event-type :authorize-vcs-clicked
-                                                                                :properties {:vcs-type selected-vcs-type}})}
-                              "Authorize with Bitbucket"]])
-                          (om/build org-picker/picker {:orgs (filter (partial select-vcs-type selected-vcs-type) orgs)
-                                                       :selected-org selected-org
-                                                       :on-org-click #(raise! owner [:selected-add-projects-org %])})
-                          (when (get-in user [:repos-loading (keyword selected-vcs-type)])
-                            [:div.orgs-loading
-                             [:div.loading-spinner common/spinner]])])]
+                          [:div
+                           (when (= "github" selected-vcs-type)
+                             (if github-authorized?
+                               (missing-org-info owner)
+                               [:div
+                                [:p "GitHub is not connected to your account yet. To connect it, click the button below:"]
+                                (button/link {:href (gh-utils/auth-url)
+                                              :on-click #((om/get-shared owner :track-event) {:event-type :authorize-vcs-clicked
+                                                                                :properties {:vcs-type selected-vcs-type}})
+                                              :primary? true}
+                                             "Authorize GitHub")]))
+                           (when (and (= "bitbucket" selected-vcs-type)
+                                      (not bitbucket-authorized?))
+                             [:div
+                              [:p "Bitbucket is not connected to your account yet. To connect it, click the button below:"]
+                              (button/link {:href (bitbucket/auth-url)
+                                            :on-click #((om/get-shared owner :track-event) {:event-type :authorize-vcs-clicked
+                                                                                :properties {:vcs-type selected-vcs-type}})
+                                            :primary? true}
+                                           "Authorize Bitbucket")])
+                           (om/build org-picker/picker {:orgs (filter (partial select-vcs-type selected-vcs-type) orgs)
+                                                        :selected-org selected-org
+                                                        :on-org-click #(raise! owner [:selected-add-projects-org %])})
+                           (when (get-in user [:repos-loading (keyword selected-vcs-type)])
+                             [:div.orgs-loading
+                              [:div.loading-spinner common/spinner]])])]
         (if bitbucket-possible?
           (let [tabs [{:name "github"
                        :icon (html [:i.octicon.octicon-mark-github])


refactor: remove duplicate binding

refactor: remove duplicate binding

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -275,14 +275,15 @@
         show-forks (true? (get-in settings [:add-projects :show-forks]))]
     (html
      [:div.proj-wrapper
-      (if-let [selected-login (get-in settings [:add-projects :selected-org :login])]
+      (if selected-org-login
         (let [;; we display a repo if it belongs to this org, matches the filter string,
               ;; and matches the fork settings.
               display? (fn [repo]
                          (and
                           (or show-forks (not (:fork repo)))
-                          (select-vcs-type (:vcs-type selected-org) repo)
-                          (= (:username repo) selected-login)
+                          (select-vcs-type (or (:vcs-type selected-org)
+                                               "github") repo)
+                          (= (:username repo) selected-org-login)
                           (gstring/caseInsensitiveContains (:name repo) repo-filter-string)))
               filtered-repos (->> repos (filter display?) (sort-by :pushed_at) (reverse))]
           [:div (om/build repo-filter settings)


Fix syntax error.

Fix syntax error.

Not sure how the tests ran with this problem -- I must have run the wrong.

Sorry about that.

--- src/riemann/common.clj
+++ src/riemann/common.clj
@@ -12,7 +12,7 @@
   (:use clojure.math.numeric-tower))

 ; Don't mangle underscores into dashes. <sigh>
-(.setUseUnderscores protobuf.core.PersistentProtocolBufferMap true)
+(protobuf.core.PersistentProtocolBufferMap/setUseUnderscores true)

 ; Protobufs
 (def Msg (protodef com.aphyr.riemann.Proto$Msg))


don't transduce request part

don't transduce request part

--- src/s7p/slave/core.clj
+++ src/s7p/slave/core.clj
@@ -128,8 +128,8 @@

 (defn work [test req result]
   (->> @dsps
+       (map (fn [dsp] {:dsp dsp :response (http/post (:url dsp) (json-request-option req))}))
        (sequence (comp
-                  (map (fn [dsp] {:dsp dsp :response (http/post (:url dsp) (json-request-option req))}))
                   (map destruct)
                   (map #(validate req %))
                   (map #(log-validated test %))


Removing unused require statement

Removing unused require statement

--- src/satellite/util.clj
+++ src/satellite/util.clj
@@ -1,5 +1,4 @@
-(ns satellite.util
-  (require [clj-http.client :as client]))
+(ns satellite.util)

 (defonce thread-counter (java.util.concurrent.atomic.AtomicLong.))
 (defmacro thread


Removed inane debugging prints.

Removed inane debugging prints.

--- src/shale/sessions.clj
+++ src/shale/sessions.clj
@@ -119,23 +119,22 @@
                             reserve-after-create nil
                             current-url nil}
                        :as requirements}]
-  (prn-tee "create requirements" requirements)
   (s/validate (s/maybe Node ) node)
   (let [merged-reqs
-        (prn-tee "create merged reqs" (merge {:node (select-keys (nodes/get-node {}) [:url :id])
+        (merge {:node (select-keys (nodes/get-node {}) [:url :id])
                 :tags tags}
                (select-keys requirements
                             [:browser-name
                              :tags
                              :current-url
                              :reserved
-                             :reserve-after-create])))
+                             :reserve-after-create]))
         resolved-node-reqs
-        (prn-tee "create resolved reqs" (if (get-in merged-reqs [:node :url])
+        (if (get-in merged-reqs [:node :url])
           (assoc-in-fn merged-reqs
                        [:node :url]
                        (comp str host-resolved-url))
-          merged-reqs))
+          merged-reqs)
         defaulted-reqs
         (assoc-fn resolved-node-reqs
                   :reserved
@@ -149,7 +148,7 @@
         (merge {"browserName" browser-name}
                extra-desired-capabilities)
         wd
-        (new-webdriver (prn-tee "new webdriver node url" (get-in defaulted-reqs [:node :url]))  capabilities)
+        (new-webdriver (get-in defaulted-reqs [:node :url]) capabilities)
         session-id
         (remote-webdriver/session-id wd)]
     (last


fix date pattern

fix date pattern

--- utils/src/samsara/utils.clj
+++ utils/src/samsara/utils.clj
@@ -26,7 +26,7 @@
   (if-not data
     ""
     (-> data
-        (json/generate-string {:pretty pretty :date-format "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"})
+        (json/generate-string {:pretty pretty :date-format "yyyy-MM-dd'T'HH:mm:ss.SSSX"})
         ((fn [s] (if pretty (str s \newline) s))))))


Make more consistent connection creation from datasource.

--- src/suricatta/impl.clj
+++ src/suricatta/impl.clj
@@ -66,11 +66,7 @@
 (extend-protocol proto/IContextBuilder
   APersistentMap
   (make-context [^clojure.lang.APersistentMap dbspec]
-    (let [^DataSource datasource (:datasource dbspec)
-          ^Connection connection (if datasource
-                                   (.getConnection datasource)
-                                   (-> (jdbc/make-connection dbspec)
-                                       (:connection)))
+    (let [^Connection connection (:connection (jdbc/make-connection dbspec))
           ^SQLDialect dialect (if (:dialect dbspec)
                                 (translate-dialect (:dialect dbspec))
                                 (JDBCUtils/dialect connection))


ignore case in species term

ignore case in species term

--- src/wb_es/web/core.clj
+++ src/wb_es/web/core.clj
@@ -7,7 +7,8 @@
   (->> []
        (cons (when-let [type-value (:type options)]
                {:type {:value (clojure.string/replace type-value #"_" "-")}}))
-       (cons (when-let [species-value (:species options)]
+       (cons (when-let [species-value (some->> (:species options)
+                                               (clojure.string/lower-case))]
                {:term {:species species-value}}))
        (filter identity)))


refactor by isolating skipTestPerfixIfPresent

--- agiledox.clj
+++ agiledox.clj
@@ -16,8 +16,11 @@
 (defn as-header [filename]
   (str (.replaceFirst (.replaceFirst filename "\\.java" "") "Test" "") ":"))

+(defn skipTestPerfixIfPresent [feature]
+	(.replaceFirst feature "- test" "-"))
+
 (defn as-feature [line]
-  (.replaceFirst (.toLowerCase (.replaceAll line "([A-Z])" " $1")) "- test" "-"))
+  (skipTestPerfixIfPresent (.toLowerCase (.replaceAll line "([A-Z])" " $1"))))

 (def empty-line "")


autofocus search + remove cruft from freebase app

--- src/bolt/core.cljs
+++ src/bolt/core.cljs
@@ -23,39 +23,8 @@
   (om/component
    (dom/form #js {:onSubmit #(submit-search chan %)
                   :className "jumbotron"}
-            (dom/input #js {:type "text" :id "search_term"})
+            (dom/input #js {:type "text" :id "search_term" :autoFocus "autofocus"})
             (dom/input #js {:type "submit" :value "Search"}))))
-
-;; TODO: give each element a :key
-(defn render-table [headers rows]
-  (apply dom/table
-         #js {:className "table table-striped"}
-         nil
-         (dom/caption nil (str "Found " (count rows) " results"))
-         (apply dom/tr nil
-                  (map
-                   (fn [value] (dom/th nil value))
-                   headers))
-         (map #(apply dom/tr
-                       nil
-                       (map
-                        (fn [value] (dom/td nil value))
-                        %))
-               rows)))
-
-(defn click-id-link [chan id e]
-  (.log js/console e)
-  (put! chan [:service.id id])
-  false)
-
-(defn search-results [app owner {:keys [chan]}]
-  (om/component
-   (dom/div
-    #js {:id "search_results"}
-    (if-let [result (:search-result app)]
-      (do (.log js/console "DATA" result)
-          (render-table ["h1" "h2"] [["c1" "c2"] ["d1" "d2"]]))
-      ""))))

 (defn process-search
   "For now this is just a local config lookup but this could interact


Adding entity-component-types so I can track what types an entity knows about.

--- src/brute/core.clj
+++ src/brute/core.clj
@@ -4,19 +4,23 @@

 (def ^{:private true} all-entities (ref []))
 (def ^{:private true} entity-components (ref {}))
+(def ^{:private true} entity-component-types (ref {}))

 (defn reset-all!
     "Resets the state of this entity component system. Good for tests"
     []
     (alter-var-root #'all-entities (constantly (ref [])))
-    (alter-var-root #'entity-components (constantly (ref {}))))
+    (alter-var-root #'entity-components (constantly (ref {})))
+    (alter-var-root #'entity-component-types (constantly (ref {}))))
+

 (defn create-entity!
     "Creates an entity and stores it"
     []
     (let [entity (java.util.UUID/randomUUID)]
         (dosync
-            (alter all-entities conj entity))
+            (alter all-entities conj entity)
+            (alter entity-component-types assoc entity #{}))
         entity))

 (defn get-all-entities
@@ -37,7 +41,9 @@
     "Add a component instance to a given entity"
     [entity instance]
     (dosync
-        (alter entity-components assoc-in [(get-component-type instance) entity] instance)))
+        (let [type (get-component-type instance)]
+            (alter entity-components assoc-in [type entity] instance)
+            (alter entity-component-types assoc entity (conj (get @entity-component-types entity) type)))))

 (defn get-component
     "Get the component data for a specific component type"
@@ -55,7 +61,11 @@
     "Remove a component instance from an entity"
     [entity instance]
     (let [type (get-component-type instance)]
-        (dosync (alter entity-components assoc type (dissoc (get @entity-components type) entity)))))
+        (dosync
+            (alter entity-components assoc type (dissoc (get @entity-components type) entity))
+            (alter entity-component-types assoc entity (disj (get @entity-component-types entity) type)))))
+
+

 ;; TODO: kill-entity
 ;; TODO: get-all-components-on-entity


Add {left,right}-map to cats.core

Add {left,right}-map to cats.core

--- src/cats/core.cljc
+++ src/cats/core.cljc
@@ -35,7 +35,7 @@
      (:require [cats.protocols :as p]
                [clojure.set]
                [cats.context :as ctx]))
-  (:refer-clojure :exclude [when unless filter sequence]))
+  (:refer-clojure :exclude [filter sequence unless when]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Context-aware functions
@@ -141,6 +141,22 @@
    (let [ctx (ctx/get-current bv)]
      (ctx/with-context ctx
        (p/-bimap ctx f g bv)))))
+
+(defn left-map
+  "Map covariantly over the first argument."
+  ([f]
+   (fn [bv]
+     (left-map f bv)))
+  ([f bv]
+   (bimap f identity bv)))
+
+(defn right-map
+  "Map covariantly over the second argument."
+  ([g]
+   (fn [bv]
+     (right-map g bv)))
+  ([g bv]
+   (bimap identity g bv)))

 (defn fapply
   "Given a function wrapped in a monadic context `af`,


Renamed to w-actx.

Renamed to w-actx.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -39,11 +39,11 @@
       (>! tick-ch t)
       (set-el-innerHTML "tot-ticks" t)
       (recur (inc t)))
-    (ago world w
+    (ago w-actx w
          (while true
-           (<! clicks)
+           (.log js/console (<! clicks))
            (set-el-innerHTML "output" (get-el-value "input"))
-           (let [res (string/join "\n" (atake world (cbfg.fence/test world)))]
+           (let [res (string/join "\n" (atake w-actx (cbfg.fence/test w-actx)))]
              (set-el-innerHTML "output" (str "<pre>" res "</pre>"))
              (println res))))
     tick-delay))


Set duration to 120s.

Set duration to 120s.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -136,5 +136,5 @@
                                (thread-info-fn) (println)
                                )
                   1000)
-      (run-once (executor) (fn [] (System/exit 0)) 60000))))
+      (run-once (executor) (fn [] (System/exit 0)) 120000))))


fix in defimplicit expansion

fix in defimplicit expansion

--- src/latte/core.clj
+++ src/latte/core.clj
@@ -587,7 +587,7 @@
                          :body (s/* any?)))

-(s/def ::iparam (s/tuple symbol? symbol?))
+(s/def ::iparam any?) ;; (s/tuple symbol? symbol?))

 (defn ^:no-doc mk-impl-doc [name params explanation]
   (str "\n```\n"
@@ -605,7 +605,9 @@
             {def-env :def-env ctx :ctx params :params} header]
         (when (defenv/registered-definition? def-name)
           (println "[Warning] redefinition as implicit"))
-        (let [metadata (merge (meta &form) {:doc (mk-impl-doc def-name (mapv first params) doc)})]
+        (let [metadata (merge (meta &form) {:doc (mk-impl-doc def-name (mapv #(if (vector? %)
+                                                                                (first %)
+                                                                                %) params) doc)})]
           `(do
              (def ~def-name (defenv/->Implicit '~def-name (fn [~def-env ~ctx ~@params] ~@body)))
              (alter-meta! (var ~def-name) #(merge % (quote ~metadata)))


Update transit-java; fix up handler method naming; add docstrings

--- src/transit.clj
+++ src/transit.clj
@@ -47,10 +47,10 @@
      (make-handler tag-fn rep-fn str-rep-fn nil))
   ([tag-fn rep-fn str-rep-fn verbose-handler-fn]
      (reify Handler
-       (tag [_ o] (tag-fn o))
-       (rep [_ o] (rep-fn o))
-       (stringRep [_ o] (when str-rep-fn (str-rep-fn o)))
-       (verboseHandler [_] (when verbose-handler-fn (verbose-handler-fn))))))
+       (getTag [_ o] (tag-fn o))
+       (getRep [_ o] (rep-fn o))
+       (getStringRep [_ o] (when str-rep-fn (str-rep-fn o)))
+       (getVerboseHandler [_] (when verbose-handler-fn (verbose-handler-fn))))))

 (defn default-handlers
   "Returns a map of default Handlers for
@@ -61,38 +61,38 @@
   {
    java.util.List
    (reify Handler
-     (tag [_ l] (if (seq? l) "list" "array"))
-     (rep [_ l] (if (seq? l) (TransitFactory/taggedValue "array" l ) l))
-     (stringRep [_ _] nil)
-     (verboseHandler [_] nil))
+     (getTag [_ l] (if (seq? l) "list" "array"))
+     (getRep [_ l] (if (seq? l) (TransitFactory/taggedValue "array" l ) l))
+     (getStringRep [_ _] nil)
+     (getVerboseHandler [_] nil))

    clojure.lang.BigInt
    (reify Handler
-     (tag [_ _] "n")
-     (rep [_ bi] (str (biginteger bi)))
-     (stringRep [this bi] (.rep this bi))
-     (verboseHandler [_] nil))
+     (getTag [_ _] "n")
+     (getRep [_ bi] (str (biginteger bi)))
+     (getStringRep [this bi] (.getRep this bi))
+     (getVerboseHandler [_] nil))

    clojure.lang.Keyword
    (reify Handler
-     (tag [_ _] ":")
-     (rep [_ kw] (nsed-name kw))
-     (stringRep [_ kw] (nsed-name kw))
-     (verboseHandler [_] nil))
+     (getTag [_ _] ":")
+     (getRep [_ kw] (nsed-name kw))
+     (getStringRep [_ kw] (nsed-name kw))
+     (getVerboseHandler [_] nil))

    clojure.lang.Ratio
    (reify Handler
-     (tag [_ _] "ratio")
-     (rep [_ r] (TransitFactory/taggedValue "array" [(numerator r) (denominator r)]))
-     (stringRep [_ _] nil)
-     (verboseHandler [_] nil))
+     (getTag [_ _] "ratio")
+     (getRep [_ r] (TransitFactory/taggedValue "array" [(numerator r) (denominator r)]))
+     (getStringRep [_ _] nil)
+     (getVerboseHandler [_] nil))

    clojure.lang.Symbol
    (reify Handler
-     (tag [_ _] "$")
-     (rep [_ sym] (nsed-name sym))
-     (stringRep [_ sym] (nsed-name sym))
-     (verboseHandler [_] nil))
+     (getTag [_ _] "$")
+     (getRep [_ sym] (nsed-name sym))
+     (getStringRep [_ sym] (nsed-name sym))
+     (getVerboseHandler [_] nil))
    })

 (deftype Writer [w])


:bug: Dont return duplicated files on dashboard.

--- backend/src/uxbox/services/queries/project_files.clj
+++ backend/src/uxbox/services/queries/project_files.clj
@@ -26,7 +26,8 @@
 (s/def ::user ::us/uuid)

 (su/defstr sql:generic-project-files
-  "select pf.*,
+  "select distinct on (pf.id, pf.created_at)
+          pf.*,
           p.name as project_name,
           array_agg(pp.id) over pages_w as pages
      from project_files as pf


added :. as a path option, useful for 'cat :.' to view the current directory as a map

--- src/mapfs/core.clj
+++ src/mapfs/core.clj
@@ -53,14 +53,22 @@
 (defn- resolve-path
   [parts]
   (let [p (if (keyword? parts) [parts] parts)]
-  (reduce #(if (= :.. %2) (pop %1) (conj %1 %2))
+  (reduce #(case %2
+            :.. (pop %1)
+            :. %1
+            (conj %1 %2))
           @CURRENT_DIR p)))
+
+;(defn split-path-regex
+;  [parts]
+
+;  )

 (defn ls
   "List keys in current directory of filesystem, or given path."
-  [& path-keys]
+  [& key-path]
   (->>
-    (sort (keys (get-in @FS_ROOT (resolve-path path-keys))))
+    (sort (keys (get-in @FS_ROOT (resolve-path key-path))))
     (map
       #(let [path (conj @CURRENT_DIR %)
              v (get-in @FS_ROOT path)]


memoize the state names

memoize the state names

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -26,43 +26,44 @@
      [:table.table.table-striped
       [:thead [:tr [:th "Title"] [:th "State"] [:th "Action"]]]
       [:tbody
-       (for [{:keys [id title state] :as production} (prod/find-all)]
-         (let [realized-state (first (db/find-state {:id state}))]
-          [:tr
-           [:td (link-to (str "/production/" id) title)]
-           [:td (:name realized-state)]
-           [:td
-            (layout/button-group
-             (remove
-              nil?
-              [(layout/button (str "/production/" id ".xml")
-                              (layout/glyphicon "download"))
-               (layout/button (str "/production/" id "/upload")
-                              (layout/glyphicon "upload"))
-               (when-let [next-state (:next_state realized-state)]
-                 (form/form-to
-                  {:class "btn-group"}
-                  [:post (str "/production/" id "/state")]
-                  (form/hidden-field :state next-state)
-                  (anti-forgery-field)
-                  [:button.btn.btn-default
-                   ;; only allow setting the state to recorded if there is a DAISY export
-                   ;; and the production has been imported from the library, i.e. is not
-                   ;; handled via ABACUS
-                   (when-not
-                       (and (= next-state "recorded")
-                            (:library_number production) ; is the product not managed by
+       (let [cached-state (memoize db/find-state)]
+         (for [{:keys [id title state] :as production} (prod/find-all)]
+           (let [realized-state (first (cached-state {:id state}))]
+             [:tr
+              [:td (link-to (str "/production/" id) title)]
+              [:td (:name realized-state)]
+              [:td
+               (layout/button-group
+                (remove
+                 nil?
+                 [(layout/button (str "/production/" id ".xml")
+                                 (layout/glyphicon "download"))
+                  (layout/button (str "/production/" id "/upload")
+                                 (layout/glyphicon "upload"))
+                  (when-let [next-state (:next_state realized-state)]
+                    (form/form-to
+                     {:class "btn-group"}
+                     [:post (str "/production/" id "/state")]
+                     (form/hidden-field :state next-state)
+                     (anti-forgery-field)
+                     [:button.btn.btn-default
+                      ;; only allow setting the state to recorded if there is a DAISY export
+                      ;; and the production has been imported from the library, i.e. is not
+                      ;; handled via ABACUS
+                      (when-not
+                          (and (= next-state "recorded")
+                               (:library_number production) ; is the product not managed by
                                         ; ABACUS
-                            (prod/manifest? production)) ; is there a DAISY export?
-                     {:disabled "disabled"})
-                   (layout/glyphicon "transfer") " "
-                   (:name (first (db/find-state {:id next-state})))]))
-               ;; (layout/dropdown (for [next (state/next-states state)]
-               ;;                    (layout/menu-item "#" (state/to-str next)))
-               ;;                  (layout/glyphicon "transfer"))
-               (when (friend/authorized? #{:admin} identity)
-                 (layout/button (str "/production/" id "/delete")
-                                (layout/glyphicon "trash")))]))]]))]])))
+                               (prod/manifest? production)) ; is there a DAISY export?
+                        {:disabled "disabled"})
+                      (layout/glyphicon "transfer") " "
+                      (:name (first (cached-state {:id next-state})))]))
+                  ;; (layout/dropdown (for [next (state/next-states state)]
+                  ;;                    (layout/menu-item "#" (state/to-str next)))
+                  ;;                  (layout/glyphicon "transfer"))
+                  (when (friend/authorized? #{:admin} identity)
+                    (layout/button (str "/production/" id "/delete")
+                                   (layout/glyphicon "trash")))]))]])))]])))

 (defn production [request id]
   (let [p (prod/find id)


capture avoidance check

capture avoidance check

--- test/java_time/dev/gen.clj
+++ test/java_time/dev/gen.clj
@@ -2,9 +2,12 @@
   (:require [clojure.string :as str]
             [clojure.set :as set]))

+(def impl-local-sym '+impl+)
+
 (defn normalize-argv [argv]
   {:post [(or (empty? %)
-              (apply distinct? %))]}
+              (apply distinct? %))
+          (not-any? #{impl-local-sym} %)]}
   (into [] (map-indexed (fn [i arg]
                           (if (symbol? arg)
                             (do (assert (not (namespace arg)))
@@ -29,13 +32,13 @@
         forward-meta (into (sorted-map) (select-keys m [:doc :tag :deprecated]))
         forward-meta (cond-> forward-meta
                        (nil? (:tag forward-meta)) (dissoc :tag))
-        impl '+impl+]
+        _ (assert (not= n impl-local-sym))]
     (when (:macro m)
       (throw (IllegalArgumentException.
                (str "Calling import-fn on a macro: " sym))))
-    (list 'let [impl (list 'delay
-                            (list 'load-java-time)
-                            (list 'deref (list 'resolve (list 'quote sym))))]
+    (list 'let [impl-local-sym (list 'delay
+                                     (list 'load-java-time)
+                                     (list 'deref (list 'resolve (list 'quote sym))))]
                (list* 'defn n
                       (concat
                         (some-> (not-empty forward-meta) list)
@@ -44,8 +47,8 @@
                                  (let [argv (normalize-argv argv)]
                                    (list argv
                                          (if (some #{'&} argv)
-                                           (list* 'apply (list 'deref impl) (remove #{'&} argv))
-                                           (list* (list 'deref impl) argv)))))
+                                           (list* 'apply (list 'deref impl-local-sym) (remove #{'&} argv))
+                                           (list* (list 'deref impl-local-sym) argv)))))
                                arglists)))))))

 (defn import-macro [sym]


State event specs.

State event specs.

--- src/onyx/spec.cljc
+++ src/onyx/spec.cljc
@@ -681,3 +681,45 @@
                 :onyx.core/windows-state
                 :onyx.core/filter-state
                 :onyx.core/batch]))
+
+(s/def :onyx.state-event/event-type keyword?)
+
+(s/def :onyx.state-event/task-event
+  (s/get-spec :onyx.core/event-map))
+
+(s/def :onyx.state-event/segment any?)
+
+(s/def :onyx.state-event/group-key any?)
+
+(s/def :onyx.state-event/window
+  (s/multi-spec window-type :window/type))
+
+(s/def :onyx.state-event/grouped? boolean?)
+
+(s/def :onyx.state-event/lower-bound integer?)
+
+(s/def :onyx.state-event/upper-bound integer?)
+
+(s/def :onyx.state-event/log-type #{:trigger :aggregation})
+
+(s/def :onyx.state-event/trigger-update
+  (s/coll-of any? :kind vector?))
+
+(s/def :onyx.state-event/aggregation-update
+  (s/coll-of any? :kind vector?))
+
+(s/def :onyx.state-event/next-state any?)
+
+(s/def :onyx.core/state-event
+  (s/keys :req-un [:onyx.state-event/event-type
+                   :onyx.state-event/task-event
+                   :onyx.state-event/segment
+                   :onyx.state-event/group-key
+                   :onyx.state-event/window]
+          :opt-un [:onyx.state-event/grouped?
+                   :onyx.state-event/lower-bound
+                   :onyx.state-event/upper-bound
+                   :onyx.state-event/log-type
+                   :onyx.state-event/trigger-update
+                   :onyx.state-event/aggregation-update
+                   :onyx.state-event/next-state]))


Whitespace for code readability

Whitespace for code readability

--- src/pamela/htn.clj
+++ src/pamela/htn.clj
@@ -1756,7 +1756,8 @@
                   :irks irks-i})

                 (#{:parallel :sequence :choose} type)
-                (log/error (str mpclass "." mname ":") "\nEmbedding a" type "is not supported within a defpmethod when used for HTN generation")
+                (log/error (str mpclass "." mname ":")
+                           "\nEmbedding a" type "is not supported within a defpmethod when used for HTN generation")

                 :else
                 (log/error "Unexpected type:" type))]


more open css transition fn

more open css transition fn

--- src/show/core.cljs
+++ src/show/core.cljs
@@ -20,9 +20,9 @@
 (defn css-transition-group
   "Create dom entrance and exit animations. Ensure that you have a unique :key
   property set on each component/dom-element that you pass as a body"
-  [transition-name body]
+  [opts body]
   (let [group (.. js/React -addons -CSSTransitionGroup)]
-    (group #js {:transitionName transition-name} (clj->js body))))
+    (group (clj->js opts) (clj->js body))))

 ;; Getters and setters
 (defn get-node


stuff

stuff

--- src/tabby/core.clj
+++ src/tabby/core.clj
@@ -2,49 +2,35 @@
   (:require [tabby.cluster :as cluster]
             [tabby.local-net :as local-net]
             [clojure.tools.logging :refer [warn info]]
+            [clojure.tools.cli :as cli]
             [tabby.net :as net]
             [tabby.server :as server]
             [tabby.utils :as u])
   (:gen-class))

-(def test-args
-  ["-port" "1337" "-peers" "foo:1,foo:2,foo:3"])
+(defn- parse-peers [s]
+  (map (fn [x]
+         (let [[_ host port id] (re-matches #"(.*):(\d+)=(\d+)" x)]
+           {:host host :port (Integer/parseInt port) :id id}))
+       (.split s ",")))

-(def expected
-  {:port 1337
-   :peers [{:hostname "foo" :port 1}
-           {:hostname "foo" :port 2}
-           {:hostname "foo" :port 3}]})
-
-(defn- parse-int [x]
-  (Integer/parseInt x))
-
-(defn- parse-peers [^String s]
-  (map (fn [^String x]
-         (let [[hostname port] (.split x ":")]
-           {:hostname hostname
-            :id x
-            :port (parse-int port)})) (.split s ",")))
-
-(defn- convert [options]
-  (-> options
-      (update :port parse-int)
-      (update :peers parse-peers)))
+(def cli-options
+  [["-p" "--port PORT" "Port number"
+   :default 8080
+    :parse-fn #(Integer/parseInt %)
+    :validate-fn [#(and (> % 1024) (<  % 65535 ))]]
+   ["-i" "--id ID" "Unique ID"]
+   ["-P" "--peers PEERLIST"
+    :parse-fn parse-peers]])

 (defn- parse-args [args]
-  (loop [args args
-         opts {}]
-    (if (empty? args)
-      opts
-      (let [^String a (first args)]
-        (if (= (first a) \-)
-          (recur (rest (rest args))
-                 (assoc opts (keyword (.substring a 1)) (second args))))))))
+  (let [opts (cli/parse-opts args cli-options)]
+    (:options opts)))

 (defn -main [& args]
   (try
     (let [options (parse-args args)]
-     (-> (server/create-server (str (:hostname options) ":" (:port options)))
+     (-> (server/create-server (:id options))
          (net/start-server! (:port options))
          (server/set-peers (:peers options))))
     (catch Exception e


fix getters

fix getters

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -156,7 +156,7 @@
   "Return the current zone, which can be overridden by the *clock* dynamic var"
   []
   (if-let [clk *clock*]
-    (.getZone clk)
+    (t.i/getter zone clk)
     (. ZoneId systemDefault)))

 (extend-protocol IConversion
@@ -636,9 +636,9 @@
   (days [d] (.toDays d))

   Period
-  (days [p] (.getDays p))
-  (months [p] (.getMonths p))
-  (years [p] (.getYears p)))
+  (days [p] (t.i/getter days p))
+  (months [p] (t.i/getter months p))
+  (years [p] (t.i/getter years p)))

 (defn new-duration [n u]
   (let [unit (unit-map u)]


fixed html-tree when passed "".

fixed html-tree when passed "".

It should return a VText("") node, but it returns "".

--- src/vdom/core.cljs
+++ src/vdom/core.cljs
@@ -26,12 +26,17 @@

 (declare svg-tree)

+(defn virtual-node? [arg]
+  ;; use javascript notion of true/false,
+  ;; otherwise, this will return true for "" and cause issues
+  (js/Boolean (js/VDOM.isVirtualNode arg)))
+
 (defn html-tree [arg]
   (cond
     (nil? arg)
     (text-node "")

-    (js/VDOM.isVirtualNode arg)
+    (virtual-node? arg)
     arg

     (seq? arg)
@@ -55,7 +60,7 @@
     (nil? arg)
     (text-node "")

-    (js/VDOM.isVirtualNode arg)
+    (virtual-node? arg)
     arg

     (string? arg)


FIX remove unused require of piggieback from user.clj

--- env/dev/clj/user.clj
+++ env/dev/clj/user.clj
@@ -12,7 +12,6 @@
    [clojure.test :as test]
    [clojure.tools.namespace.repl :refer (refresh refresh-all)]
    [ring.server.standalone :refer [serve]]
-   [cemerick.piggieback]
    [cljs.repl :as repl]
    [cljs.repl.browser :as browser]
    [datomic.api :as d]


Move favorite star

Move favorite star

--- frontend/src/cruncher/views.cljs
+++ frontend/src/cruncher/views.cljs
@@ -63,9 +63,9 @@
                                           (dom/input #js {:className "poketable-checkbox"
                                                           :type      "checkbox"
                                                           :value     (:id pokemon)}))))
+              (dom/td nil (if (:favorite pokemon) (vlib/fa-icon "fa-star") (vlib/fa-icon "fa-star-o")))
               (dom/td nil (:pokemon_id pokemon))
               (dom/td nil (:name pokemon))
-              (dom/td nil (if (:favorite pokemon) (vlib/fa-icon "fa-star") (vlib/fa-icon "fa-star-o")))
               (dom/td nil (:nickname pokemon))
               (dom/td nil (:cp pokemon))
               (dom/td nil (:health pokemon))


Move components

Move components

--- src/airhead_frontend/components.cljs
+++ src/airhead_frontend/components.cljs
@@ -2,6 +2,9 @@
   (:require [reagent.core :as r]
             [airhead-frontend.state :refer [app-state update-state!]]
             [airhead-frontend.requests :as req]))
+
+;; -------------------------
+;; Header

 (defn header []
   (let [cursor  (r/cursor app-state [:info])
@@ -10,6 +13,9 @@
     [:header
      [:h1 title]
      [:p message]]))
+
+;; -------------------------
+;; Player

 (defn now-playing []
   (let [track (@app-state :now-playing)]
@@ -35,6 +41,9 @@
          [now-playing]
          [:a {:href url} "↗"]]))))

+;; -------------------------
+;; Upload
+
 (defn progress-bar []
   (let [percentage (@app-state :upload-percentage)]
     (if (< 0 percentage 100)
@@ -56,6 +65,9 @@

        [:p (@app-state :upload-status)]])))

+;; -------------------------
+;; Tracks
+
 (defn playlist-add-button [track]
   [:button.add
    {:on-click #(req/playlist-add! (:uuid track))}
@@ -73,12 +85,38 @@
       [action-button track])]
    [:td (track :title)] [:td (track :artist)] [:td (track :album)]])

-(defn tracks-table [tracks action-button]
-  [:table.tracks
-   [:thead
-    [:tr [:th] [:th  "Title"] [:th "Artist"] [:th "Album"]]]
-   [:tbody (for [track tracks]
-             ^{:key track} [track-tr track action-button])]])
+;; -------------------------
+;; Playlist
+
+(defn playlist-section []
+  [:section#playlist
+   [:h2 "Playlist"]
+   (if-let [tracks (not-empty (@app-state :playlist))]
+     [:table.tracks
+      [:thead
+       [:tr [:th] [:th  "Title"] [:th "Artist"] [:th "Album"]]]
+      [:tbody (for [track tracks]
+                ^{:key track} [track-tr track playlist-remove-button])]]
+     "The playlist is empty")])
+
+;; -------------------------
+;; Search
+
+(defn on-query-change [e]
+  (update-state! :query (-> e .-target .-value))
+  (req/get-library!))
+
+(defn search-form []
+  [:section#search
+   [:form
+    [:label {:for "query"} "Search:"]
+    [:input {:type "text"
+             :id "query"
+             :value (@app-state :query)
+             :on-change on-query-change}]]])
+
+;; -------------------------
+;; Library

 (defn update-sort-field! [new-field]
   (if (= new-field (:sort-field @app-state))
@@ -100,41 +138,22 @@
                             " ▲"
                             " ▼"))]])

-(defn sorted-tracks-table [tracks action-button]
-  [:table.tracks
-   [:thead
-    [:tr [:th]
-     [sorting-th :title "Title"]
-     [sorting-th :artist "Artist"]
-     [sorting-th :album "Album"]]]
-   [:tbody (for [track (sort-tracks tracks)]
-             ^{:key track} [track-tr track action-button])]])
+(defn library-section []
+  (let [tracks (@app-state :library)]
+    [:section#library
+     [:h2 "Library"]
+     [search-form]
+     [:table.tracks
+      [:thead
+       [:tr [:th]
+        [sorting-th :title "Title"]
+        [sorting-th :artist "Artist"]
+        [sorting-th :album "Album"]]]
+      [:tbody (for [track (sort-tracks tracks)]
+                ^{:key track} [track-tr track playlist-add-button])]]]))

-(defn playlist-section []
-  [:section#playlist
-   [:h2 "Playlist"]
-   (if-let [tracks (not-empty (@app-state :playlist))]
-     [tracks-table tracks playlist-remove-button]
-     "The playlist is empty")])
-
-(defn on-query-change [e]
-  ;(get-library!)
-  (update-state! :query (-> e .-target .-value)))
-
-(defn search-form []
-  [:section#search
-   [:form
-    [:label {:for "query"} "Search:"]
-    [:input {:type "text"
-             :id "query"
-             :value (@app-state :query)
-             :on-change on-query-change}]]])
-
-(defn library-section []
-  [:section#library
-   [:h2 "Library"]
-   [search-form]
-   [sorted-tracks-table (@app-state :library) playlist-add-button]])
+;; -------------------------
+;; Main

 (defn page-component []
   [:main


saving.

saving.

--- src/clj/forma/hadoop/jobs/update.clj
+++ src/clj/forma/hadoop/jobs/update.clj
@@ -59,91 +59,90 @@
      start-workflow
      ([] (println "Starting workflow."))

-     ;; preprocess-modis
-     ;; ([]
-     ;;  (println "Preprocessing MODIS data")
-     ;;  (p/PreprocessModis (path :staging "MOD13A1/")
-     ;;                     (:pailpath storage)
-     ;;                     "{20}*"
-     ;;                     (:tiles conf)
-     ;;                     (:modis-layers conf)))
-
-     ;; pre-rain
-     ;; ([:tmp-dirs rain-output
-     ;;   :deps start-workflow]
-     ;;  (println "Preprocessing rain")
-     ;;  (p/PreprocessRain (path :archive "PRECL")
-     ;;                    rain-output
-     ;;                    (:spatial-res conf)
-     ;;                    (:temporal-res conf)))
-
-     ;; rain->modis
-     ;; ([:tmp-dirs exploded-rain-output
-     ;;   :deps pre-rain]
-     ;;  (println "Exploding rain into MODIS pixels")
-     ;;  (p/ExplodeRain rain-output
-     ;;                 exploded-rain-output
-     ;;                 (:spatial-res conf)
-     ;;                 (:tiles conf)))
-
-     ;; ndvi-timeseries
-     ;; ([:tmp-dirs ndvi-series-output
-     ;;   :deps start-workflow]
-     ;;  (println "NDVI timeseries")
-     ;;  (ts/ModisTimeseries (:pailpath storage)
-     ;;                      ndvi-series-output
-     ;;                      (:spatial-res conf)
-     ;;                      (:temporal-res conf)
-     ;;                      "ndvi"))
-
-     ;; ndvi-filter
-     ;; ([:tmp-dirs filtered-ndvi-output
-     ;;   :deps ndvi-timeseries]
-     ;;  (println "Filtering NDVI")
-     ;;  (r/TimeseriesFilter (:spatial-res conf)
-     ;;                      (:temporal-res conf)
-     ;;                      ndvi-series-output
-     ;;                      (:static storage)
-     ;;                      filtered-ndvi-output))
-
-     ;; adjust-series
-     ;; ([:deps [rain->modis ndvi-filter]]
-     ;;  (println "Joining NDVI and rain series, adjusting length")
-     ;;  (r/AdjustSeries (:spatial-res conf)
-     ;;                  (:temporal-res conf)
-     ;;                  filtered-ndvi-output
-     ;;                  exploded-rain-output
-     ;;                  adjusted-s3))
-
-     ;; trends
-     ;; ([:tmp-dirs trends-output
-     ;;   ;; :deps adjust-series
-     ;;   ]
-     ;;  (println "Calculating trends stats")
-     ;;  (r/Trends (:spatial-res conf)
-     ;;            (:temporal-res conf)
-     ;;            est-end
-     ;;            adjusted-s3
-     ;;            trends-output
-     ;;            est-start))
-
-     ;; trends->pail
-     ;; ([:deps trends]
-     ;;  (println "Adding trends series to pail")
-     ;;  (r/TrendsPail (:spatial-res conf)
-     ;;                (:temporal-res conf)
-     ;;                est-end
-     ;;                trends-output
-     ;;                (:pailpath storage)))
-
-     ;; merge-trends
-     ;; ([:deps trends->pail]
-     ;;  (println "Merging trends time series stored in pail")
-     ;;  (r/MergeTrends (:spatial-res conf)
-     ;;                 (:temporal-res conf)
-     ;;                 est-end
-     ;;                 (:pailpath storage)
-     ;;                 merged-trends-s3))
+     preprocess-modis
+     ([]
+      (println "Preprocessing MODIS data")
+      (p/PreprocessModis (path :staging "MOD13A1/")
+                         (:pailpath storage)
+                         "{20}*"
+                         (:tiles conf)
+                         (:modis-layers conf)))
+
+     pre-rain
+     ([:tmp-dirs rain-output
+       :deps start-workflow]
+      (println "Preprocessing rain")
+      (p/PreprocessRain (path :archive "PRECL")
+                        rain-output
+                        (:spatial-res conf)
+                        (:temporal-res conf)))
+
+     rain->modis
+     ([:tmp-dirs exploded-rain-output
+       :deps pre-rain]
+      (println "Exploding rain into MODIS pixels")
+      (p/ExplodeRain rain-output
+                     exploded-rain-output
+                     (:spatial-res conf)
+                     (:tiles conf)))
+
+     ndvi-timeseries
+     ([:tmp-dirs ndvi-series-output
+       :deps start-workflow]
+      (println "NDVI timeseries")
+      (ts/ModisTimeseries (:pailpath storage)
+                          ndvi-series-output
+                          (:spatial-res conf)
+                          (:temporal-res conf)
+                          "ndvi"))
+
+     ndvi-filter
+     ([:tmp-dirs filtered-ndvi-output
+       :deps ndvi-timeseries]
+      (println "Filtering NDVI")
+      (r/TimeseriesFilter (:spatial-res conf)
+                          (:temporal-res conf)
+                          ndvi-series-output
+                          (:static storage)
+                          filtered-ndvi-output))
+
+     adjust-series
+     ([:deps [rain->modis ndvi-filter]]
+      (println "Joining NDVI and rain series, adjusting length")
+      (r/AdjustSeries (:spatial-res conf)
+                      (:temporal-res conf)
+                      filtered-ndvi-output
+                      exploded-rain-output
+                      adjusted-s3))
+
+     trends
+     ([:tmp-dirs trends-output
+       :deps adjust-series]
+      (println "Calculating trends stats")
+      (r/Trends (:spatial-res conf)
+                (:temporal-res conf)
+                est-end
+                adjusted-s3
+                trends-output
+                est-start))
+
+     trends->pail
+     ([:deps trends]
+      (println "Adding trends series to pail")
+      (r/TrendsPail (:spatial-res conf)
+                    (:temporal-res conf)
+                    est-end
+                    trends-output
+                    (:pailpath storage)))
+
+     merge-trends
+     ([:deps trends->pail]
+      (println "Merging trends time series stored in pail")
+      (r/MergeTrends (:spatial-res conf)
+                     (:temporal-res conf)
+                     est-end
+                     (:pailpath storage)
+                     merged-trends-s3))

      preprocess-fires
      ([:tmp-dirs fire-output
@@ -276,6 +275,4 @@
       (r/FormaDavid (:nodata conf)
                     (:gadm2eco storage)
                     (:static storage)
-                    david-s3))
-
-     )))
+                    david-s3)))))


Refactoring clean-probs.

Refactoring clean-probs.

--- src/clj/forma/postprocess/output.clj
+++ src/clj/forma/postprocess/output.clj
@@ -36,11 +36,17 @@
   (vector (vec series)))

 (defn backward-looking-mavg
-  "Moving average calculated up to a given element (i.e. looking backwards), rather than starting with a given element. Ensures that only information up to and including given element is incorporated in the moving average.
+  "Moving average calculated up to a given element (i.e. looking backwards),
+   rather than starting with a given element. Ensures that only information up
+   to and including given element is incorporated in the moving average.

-Expanded timeseries includes pre-pended nils. So moving average is actually forward looking, but starting with non-existing (and filtered out) 'prior' nil values.
+   Expanded timeseries includes pre-pended nils. So moving average is actually
+   forward looking, but starting with non-existing (and filtered out) 'prior'
+   nil values.

-Ex. (backward-looking-mavg 3 [1 2 3 4]) expands to [nil nil 1 2 3 4]. Nils are filtered out, so the output is effectively [(average [1]) (average [1 2]) (average [1 2 3]) (average 2 3 4)]"
+   Ex. (backward-looking-mavg 3 [1 2 3 4]) expands to [nil nil 1 2 3 4]. Nils are
+   filtered out, so the output is effectively:
+    [(average [1]) (average [1 2]) (average [1 2 3]) (average 2 3 4)]"
   [window series]
   (let [expanded-ts (concat (repeat (dec window) nil) (flatten series))]
     (map (comp float average (partial filter not-nil?))


revert: user must specify gae java sdk since it's versioned

--- tasklib/build.boot
+++ tasklib/build.boot
@@ -9,11 +9,10 @@
                 #_["maven-central" "http://mvnrepository.com"]
                 "central" "http://repo1.maven.org/maven2/"}
  :dependencies   '[[org.clojure/clojure "1.8.0" :scope "provided"]
-                   [boot/core "2.5.5" :scope "provided"]
+                   [boot/core "2.6.0-SNAPSHOT" :scope "provided"]
+                   [boot/pod "2.6.0-SNAPSHOT" :scope "provided"]
                    [stencil "0.5.0"]
                    [adzerk/boot-test "1.0.7" :scope "test"]
-                   ;; this is for the GAE runtime (NB: scope provided):
-                   [com.google.appengine/appengine-java-sdk LATEST :scope "provided" :extension "zip"]
                    ;; ;; we need this so we can import KickStart for the run task:
                    [com.google.appengine/appengine-tools-sdk RELEASE]
                    ])