fix bad preamble warning

fix bad preamble warning

fixes #561

--- sidecar/src/figwheel_sidecar/schemas/cljs_options.clj
+++ sidecar/src/figwheel_sidecar/schemas/cljs_options.clj
@@ -803,10 +803,10 @@
    ;; **** TODO add in the cljs.compiler unknown/similar-key warning here

    ;; these next warnings probably be elevated to an errors attach-reason
-   (attach-warning ":preamble has no effect when :optimizations is not :none"
+   (attach-warning ":preamble has no effect when :optimizations is :none"
                    (fn [{:keys [optimizations] :as cmpl}]
                      (not (and (contains? cmpl :preamble)
-                               (not (opt-none? optimizations))))))
+                               (opt-none? optimizations)))))

    (attach-warning ":hashbang has no effect when :target is not :nodejs"
                    (fn [{:keys [target] :as cmpl}]


Lets get the right dir for the pre/post inst scripts

--- src/fatty/core.clj
+++ src/fatty/core.clj
@@ -90,7 +90,7 @@
 (defn build-deb
   "Builds a deb"
   [project-name version os-data]
-  (let [status (sh "fpm" "-s" "dir" "-t" "deb" "-v" version "-n" project-name "/opt/opscode" "-m" "Opscode, Inc." "--post-install" "./debian/postinst" "--post-uninstall" "./debian/postrm" "--description" "The full stack install of Opscode Chef" "--url" "http://www.opscode.com" :dir "./pkg") ]
+  (let [status (sh "fpm" "-s" "dir" "-t" "deb" "-v" version "-n" project-name "/opt/opscode" "-m" "Opscode, Inc." "--post-install" "../debian/postinst" "--post-uninstall" "../debian/postrm" "--description" "The full stack install of Opscode Chef" "--url" "http://www.opscode.com" :dir "./pkg") ]
     (log-sh-result status
                    (str "Created debian package")
                    (str "Failed to create debian package"))))
@@ -98,7 +98,7 @@
 (defn build-rpm
   "Builds a rpm"
   [project-name version os-data]
-  (let [status (sh "fpm" "-s" "dir" "-t" "rpm" "-v" version "-n" project-name "/opt/opscode" "-m" "Opscode, Inc." "--post-install" "./debian/postinst" "--post-uninstall" "./debian/postrm" "--description" "The full stack install of Opscode Chef" "--url" "http://www.opscode.com" :dir "./pkg")]
+  (let [status (sh "fpm" "-s" "dir" "-t" "rpm" "-v" version "-n" project-name "/opt/opscode" "-m" "Opscode, Inc." "--post-install" "../debian/postinst" "--post-uninstall" "../debian/postrm" "--description" "The full stack install of Opscode Chef" "--url" "http://www.opscode.com" :dir "./pkg")]
     (log-sh-result status
                    (str "Created rpm package")
                    (str "Failed to create rpm package"))))


[#114] Fix misplaced arg, :db conn option not working

--- src/taoensso/carmine/connections.clj
+++ src/taoensso/carmine/connections.clj
@@ -67,7 +67,7 @@
                (-> (.getOutputStream socket)
                    (BufferedOutputStream. buff-size)))

-        db (when (and db (not (zero? db)) db))]
+        db (when (and db (not (zero? db))) db)]

     (when (or password db conn-setup-fn)
       (protocol/with-context conn


Show collaborators in the add-projects organization listing.

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -61,33 +61,41 @@
       (utils/tooltip "#collaborators-tooltip-hack" {:placement "right"}))
     om/IRender
     (render [_]
-      (let [{:keys [user settings]} data
+      (let [{:keys [user settings repos]} data
             show-fork-accounts? (get-in settings [:add-projects :show-fork-accounts])]
         (html
-          [:div
-           [:div.overview
-            [:span.big-number "1"]
-            [:div.instruction "Choose a GitHub account that you are a member of or have access to."]]
-           [:div.organizations
-            [:h4 "Your accounts"]
-            [:ul.organizations
-             (map (fn [org] (organization org settings owner))
-                  (:organizations user))
-             (organization user settings owner)]
-            (missing-org-info owner)]
-           [:div.organizations
-            [:h4
-             [:a
-              {:on-click #(raise! owner [:toggled-input {:path [:settings :add-projects :show-fork-accounts]}])}
-              "Users & organizations who have made pull requests to your repos "
-              (if show-fork-accounts?
-                [:i.fa.fa-chevron-down ""]
-                [:i.fa.fa-chevron-up ""])]]
-            (if show-fork-accounts?
-              [:ul.organizations
-               (->> (:collaborators user)
-                    (remove (fn [org] (= (:login user) (:login org))))
-                    (map (fn [org] (organization org settings owner))))])]])))))
+         [:div
+          [:div.overview
+           [:span.big-number "1"]
+           [:div.instruction "Choose a GitHub account that you are a member of or have access to."]]
+          [:div.organizations
+           [:h4 "Your accounts"]
+           [:ul.organizations
+            (map (fn [org] (organization org settings owner))
+                 ;; here we display you, then all of your organizations, then all of the owners of
+                 ;; repos that aren't organizations and aren't you. We do it this way because the
+                 ;; organizations route is much faster than the repos route. We show them
+                 ;; in this order (rather than e.g. putting the whole thing into a set)
+                 ;; so that new ones don't jump up in the middle as they're loaded.
+                 (concat [user]
+                         (:organizations user)
+                         (let [org-names (->> user :organizations (cons user) (map :login) set)
+                               in-orgs? (comp org-names :login)]
+                           (->> repos (map :owner) (remove in-orgs?) (set)))))]
+           (missing-org-info owner)]
+          [:div.organizations
+           [:h4
+            [:a
+             {:on-click #(raise! owner [:toggled-input {:path [:settings :add-projects :show-fork-accounts]}])}
+             "Users & organizations who have made pull requests to your repos "
+             (if show-fork-accounts?
+               [:i.fa.fa-chevron-down ""]
+               [:i.fa.fa-chevron-up ""])]]
+           (if show-fork-accounts?
+             [:ul.organizations
+              (->> (:collaborators user)
+                   (remove (fn [org] (= (:login user) (:login org))))
+                   (map (fn [org] (organization org settings owner))))])]])))))

 (def repos-explanation
   [:div.add-repos
@@ -325,7 +333,8 @@
         [:hr]
         [:div.org-listing
          (om/build organization-listing {:user user
-                                         :settings settings})]
+                                         :settings settings
+                                         :repos repos})]
         [:hr]
         [:div#project-listing.project-listing
          [:div.overview


Three tests for get-port function

Three tests for get-port function

--- test/zg/core_test.clj
+++ test/zg/core_test.clj
@@ -32,18 +32,55 @@
     (testing "if the zg.core/start-server definition exists."
         (is (callable? 'zg.core/start-server))))

+
 (deftest test-get-and-check-port-existence
     "Check that the zg.core/get-and-check-port definition exists."
     (testing "if the zg.core/get-and-check-port definition exists."
         (is (callable? 'zg.core/get-and-check-port))))
+

 (deftest test-get-port-existence
     "Check that the zg.core/get-port definition exists."
     (testing "if the zg.core/get-port definition exists."
         (is (callable? 'zg.core/get-port))))

+
 (deftest test--main-existence
     "Check that the zg.core/-main definition exists."
     (testing "if the zg.core/-main definition exists."
         (is (callable? 'zg.core/-main))))

+;
+; Tests for function behaviours
+;
+
+(deftest test-get-port
+    "Check the function zg.core/get-port."
+    (testing "the function zg.core/get-port."
+        (is (= (get-port "1")     "1"))
+        (is (= (get-port "2")     "2"))
+        (is (= (get-port "3000")  "3000"))
+        (is (= (get-port "65534") "65534"))
+        (is (= (get-port "65535") "65535"))))
+
+(deftest test-get-port-special-cases
+    "Check the function zg.core/get-port."
+    (testing "the function zg.core/get-port."
+        (is (= (get-port nil)     "3000"))
+        (is (= (get-port "")      "3000"))
+        (is (= (get-port 0)       "3000"))
+        (is (= (get-port 1)       "3000"))
+        (is (= (get-port 65535)   "3000"))
+        (is (= (get-port 65536)   "3000"))))
+
+(deftest test-get-port-negative
+    "Check the function zg.core/get-port."
+    (testing "the function zg.core/get-port."
+        (is (thrown? AssertionError (get-port "0")))
+        (is (thrown? AssertionError (get-port "-1")))
+        (is (thrown? AssertionError (get-port "-2")))
+        (is (thrown? AssertionError (get-port "65536")))
+        (is (thrown? AssertionError (get-port "65537")))
+        (is (thrown? AssertionError (get-port "1000000")))))
+
+


Load manifest in function

Load manifest in function

--- lein-template/src/leiningen/new/modular.clj
+++ lein-template/src/leiningen/new/modular.clj
@@ -68,6 +68,14 @@
            []
            (group-by first seq)))

+(defn load-manifest [f name]
+  (load-edn-string
+   (stencil/render-string
+    (slurp f)
+    {:name name
+     :dev-password (format "\"%s\"" (generate-password))
+     :sanitized (name-to-path name)})))
+
 (defn modular
   "Create a new modular project - TODO documentation show go here which
   will be shown on 'lein new :show modular' , but will only appear when
@@ -89,12 +97,7 @@
                          (map (partial apply keyword))
                          set)

-        manifest (load-edn-string
-                  (stencil/render-string
-                   (slurp (io/resource "manifest.edn"))
-                   {:name name
-                    :dev-password (format "\"%s\"" (generate-password))
-                    :sanitized (name-to-path name)}))
+        manifest (load-manifest (io/resource "manifest.edn") name)

         select-module?
         (fn [{:keys [module]}]


Add blackrain metadata.

Add blackrain metadata.

--- src/overtone/sc/machinery/ugen/metadata/extras/blackrain.clj
+++ src/overtone/sc/machinery/ugen/metadata/extras/blackrain.clj
@@ -24,4 +24,82 @@
           modulated once the UGen has been instantiated. There is a tiny
           overhead associated to this."}

-   ])
+   {:name "BMoog"
+    :summary "24db/oct Rolloff - 4nd Order Resonant Low/High/Band Pass Filter"
+    :args [{:name "in"
+            :default :none
+            :doc "Input signal to be processed"}
+
+           {:name "freq"
+            :default 440.0
+            :doc "Cutoff frequency"}
+
+           {:name "q"
+            :default 0.2
+            :doc "Bandwidth/cutoff frequency. 0 < q > 1"}
+
+           {:name "mode"
+            :default 0.0
+            :doc "Filter mode:
+                < 1 - low pass filter.
+                < 2 - high pass filter.
+                < 3 - bandpass filter.
+                Defaults to lowpass"}]
+   :rates #{:ar}
+   :doc "BlackRain's yet 'nother moog impersonation.  Oh yes.  See also: SOS RLPF RHPF BLowPass BLowPass4 BHiPass BHiPass4 BLowShelf BHiShelf BBandPass BBandStop BAllPass IIRFilter"}
+
+   {:name "IIRFilter"
+    :summary "24db/oct Rolloff, 4nd Order Resonant Low Pass Filter"
+    :args [{:name "in"
+            :default :none
+            :doc "Input signal to be processed"}
+
+           {:name "freq"
+            :default 440.0
+            :doc "Cutoff frequency"}
+
+           {:name "rq"
+            :default 1.0
+            :doc  "The reciprocal of Q.  Bandwidth / cutoffFreq"}]
+    :rates #{:ar}
+    :doc "See also: SOS BLowPass BLowPass4 BHiPass BHiPass4 BLowShelf BHiShelf BBandPass BBandStop BAllPass BMoog"}
+
+   {:name "SVF"
+    :summary "12db/Oct State Variable Filter"
+    :args [{:name "in"
+            :default :none
+            :doc "Audio in"}
+
+           {:name "cutoff"
+            :default 2200.0
+            :doc "Cutoff frequency"}
+
+           {:name "res"
+            :default 0.1
+            :doc "Resonance 0.0 - 1.0"}
+
+           {:name "low"
+            :default 1.0
+            :doc "Lowpass filter output level 0.0 - 1.0"}
+
+           {:name "band"
+            :default 0.0
+            :doc "Bandpass filter output level 0.0 - 1.0"}
+
+           {:name "high"
+            :default 0.0
+            :doc "Highpass filter output level 0.0 - 1.0"}
+
+           {:name "notch"
+            :default 0.0
+            :doc "Notch filter output level 0.0 - 1.0"}
+
+           {:name "peak"
+            :default 0.0
+            :doc "Notch filter output level 0.0 - 1.0"}]
+    :rates #{:ar :kr}
+    :doc "Total, 100% Plastic..."
+   }
+
+
+])


Remove printlns & separate new dependency tests

--- src/test/clojure/clojure/tools/namespace/dependency_test.clj
+++ src/test/clojure/clojure/tools/namespace/dependency_test.clj
@@ -177,15 +177,15 @@
             (depend :level26 :level25a)
             (depend :level26 :level25b)
             (depend :level26 :level25c)
-            (depend :level26 :level25d)
-            ))
+            (depend :level26 :level25d)))

 (deftest t-transitive-dependencies
   (is (= #{:a :c :b}
          (transitive-dependencies g1 :d)))
   (is (= '#{two four six one five three}
-         (transitive-dependencies g2 'seven)))
-  (println "dbx: " (System/currentTimeMillis) "before t-transitive-dependencies g3 :level24")
+         (transitive-dependencies g2 'seven))))
+
+(deftest t-transitive-dependencies-deep
   (is (= #{:level0
            :level1a :level1b :level1c :level1d
            :level2
@@ -209,10 +209,8 @@
            :level20
            :level21a :level21b :level21c :level21d
            :level22
-           :level23a :level23b :level23c :level23d
-           }
+           :level23a :level23b :level23c :level23d}
          (transitive-dependencies g3 :level24)))
-  (println "dbx: " (System/currentTimeMillis) "after t-transitive-dependencies g3 :level24 -- took ~30 sec on my machine")
   (is (= #{:level0
            :level1a :level1b :level1c :level1d
            :level2
@@ -238,11 +236,9 @@
            :level22
            :level23a :level23b :level23c :level23d
            :level24
-           :level25a :level25b :level25c :level25d
-           }
-         (transitive-dependencies g3 :level26)))
-  (println "dbx: " (System/currentTimeMillis) "after t-transitive-dependencies g3 :level26 -- took ~2 min on my machine (4 times longer than previous test)")
-  )
+           :level25a :level25b :level25c :level25d}
+         (transitive-dependencies g3 :level26))))
+

 (deftest t-transitive-dependents
   (is (= '#{four seven}


Test that the mlet macro body runs in an implicit do

--- tests/tests_cats.cljx
+++ tests/tests_cats.cljx
@@ -27,7 +27,13 @@
     (is (= [3 4 5]
            (mlet [i [1 2 3 4 5]
                  :when (> i 2)]
-                 (m/return i)))))
+                 (m/return i))))
+  (testing "The body runs in an implicit do"
+    (is (= (t/just 3)
+           (mlet [i (t/just 2)
+                  :let [x (inc i)]]
+                 (assert (= x 3))
+                 (m/return x))))))

 (deftest test-sequence-m
   (testing "It works with Maybe values"


Add get_elem

Add get_elem

--- mern_utils/src/mern_utils/frontend_lib.cljs
+++ mern_utils/src/mern_utils/frontend_lib.cljs
@@ -21,6 +21,9 @@
 (defn get-elems-by-tag-name [tag]
   (dom/getElementsByTagNameAndClass tag))

+(defn get-elem [id]
+  (dom/getElement id))
+
 (defn get-js-var
   "Get global JS variables"
   [var-name]


Improve input placeholder for repair

Improve input placeholder for repair

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -312,7 +312,7 @@
       [:div.form-group
        (form/label "identifier" "Search term")
        (form/text-field {:class "form-control"
-                         :placeholder "DAM number, DS number, DY number, Title or Author"}
+                         :placeholder "damxxxxx, dsxxxxx, DYxxxxx, Title or Author"}
                         "identifier")]
       (form/submit-button {:class "btn btn-default"} "Repair")))))


ignore uppercase series because chromedrivers behave differently

--- test/clj/conference_rating/functional_test.clj
+++ test/clj/conference_rating/functional_test.clj
@@ -1,7 +1,8 @@
 (ns conference-rating.functional-test
   (:require [clj-webdriver.taxi :as taxi]
             [clojure.test :refer [deftest is testing use-fixtures]]
-            [conference-rating.server :as server]))
+            [conference-rating.server :as server]
+            [clojure.string :as s]))

 (taxi/set-driver! {:browser :chrome})

@@ -64,6 +65,6 @@

     ; conference detail page
     (wait-for "page-conference-detail")
-    (is (= "SOME SERIES" (text "text-conference-series")))
+    (is (= "some series" (s/lower-case (text "text-conference-series")))) ; different chromedrivers treat css transform differently
     (is (= "some conference name" (text "text-conference-name")))
     (is (= "www.some-link.org" (text "text-conference-link")))))


Expanded explanation on challenge 4-3

Expanded explanation on challenge 4-3

--- test/workshop/jobs/challenge_4_3_test.clj
+++ test/workshop/jobs/challenge_4_3_test.clj
@@ -6,13 +6,15 @@
             [onyx.api]))

 ;; Time to compose what we've learned about state and lifecycles
-;; with function parameters. One way to add parameters to a function
-;; is with :onyx/params. Another way is by using lifecycles. You
-;; can add non-serializable parameters to a function by using the
+;; with function parameters. One way is by using lifecycles, as
+;; we have seen. The other is to add parameters to a function
+;; with :onyx/params.
+;;
+;; You can add non-serializable parameters to a function by using the
 ;; :before-task-start and/or :before-batch lifecycles. Return a map
 ;; with key :onyx.core/params. The value of this key should be a vector
 ;; of values. This vector is applied to the *beginning* of the function
-;; signature.
+;; signature, so you'll get them before the segment.
 ;;
 ;; In this challenge, you'll create an atom using lifecycles to sum
 ;; up the :n values of a segment. Maintain the state through the function,


prepare-batch is defined already in the misc ns

--- src/kixi/hecuba/api/measurements.clj
+++ src/kixi/hecuba/api/measurements.clj
@@ -132,10 +132,6 @@
      :month            (util/get-month-partition-key t)
      :reading_metadata {}}))

-(defn prepare-batch [measurements]
-  (hayt/batch
-   (apply hayt/queries (map #(hayt/insert :partitioned_measurements (hayt/values %)) measurements))))
-
 (defn index-post! [store ctx]
   (let [request       (:request ctx)
         route-params  (:route-params request)
@@ -151,7 +147,7 @@
               {:keys [min-date max-date]} (m/min-max-dates validated-measurements)]
           (db/execute session (m/prepare-batch validated-measurements))
           (v/update-sensor-metadata store sensor min-date max-date)
-          {:response {:status 202 :body "Accepted"}})
+          {:response {:status 202 :body "Accepted"}})
         {:response {:status 400 :body "Provide valid device_id and type."}}))))

 (defn index-handle-created [ctx]


Added tag sorting in recent articles template.

--- src/lambda_blog/templates/recent.clj
+++ src/lambda_blog/templates/recent.clj
@@ -27,7 +27,7 @@
                                                  :href (path path-to-root
                                                              (format "/tags/%s.html" (url-encode t)))}
                                                 t)))
-                                     tags))))))
+                                     (sort tags)))))))
            (div {:class :article-content}
                 summary
                 (p (a {:href url}


CLJS: typos

CLJS: typos

--- src/main/cljs/cljs/tools/reader.cljs
+++ src/main/cljs/cljs/tools/reader.cljs
@@ -109,36 +109,36 @@
   ([token offset length base]
      (let [l (+ offset length)]
        (when-not (== (count token) l)
-         (throw (ex-info. (str "Invalid unicode character: \\" token)
-                          {:type :illegal-argument})))
+         (throw (ex-info (str "Invalid unicode character: \\" token)
+                         {:type :illegal-argument})))
        (loop [i offset uc 0]
          (if (== i l)
            (js/String.fromCharCode uc)
            (let [d (char-code (nth token i) base)]
              (if (== d -1)
-               (throw (ex-info. (str "Invalid digit: " (nth token i))
-                                {:type :illegal-argument}))
+               (throw (ex-info (str "Invalid digit: " (nth token i))
+                               {:type :illegal-argument}))
                (recur (inc i) (+ d (* uc base)))))))))

   ([^not-native rdr initch base length exact?]
      (loop [i 1 uc (char-code initch base)]
        (if (== uc -1)
-         (throw (ex-info. (str "Invalid digit: " initch)
-                          {:type :illegal-argument}))
+         (throw (ex-info (str "Invalid digit: " initch)
+                         {:type :illegal-argument}))
          (if-not (== i length)
            (let [ch (peek-char rdr)]
              (if (or (whitespace? ch)
                      (macros ch)
                      (nil? ch))
                (if exact?
-                 (throw (ex-info. (str "Invalid character length: " i ", should be: " length)
-                                  {:type :illegal-argument}))
+                 (throw (ex-info (str "Invalid character length: " i ", should be: " length)
+                                 {:type :illegal-argument}))
                  (js/String.fromCharCode uc))
                (let [d (char-code ch base)]
                  (read-char rdr)
                  (if (== d -1)
-                   (throw (ex-info. (str "Invalid digit: " ch)
-                                    {:type :illegal-argument}))
+                   (throw (ex-info (str "Invalid digit: " ch)
+                                   {:type :illegal-argument}))
                    (recur (inc i) (+ d (* uc base)))))))
            (js/String.fromCharCode uc))))))

@@ -364,7 +364,7 @@
   nil)

 (defn- resolve-ns [sym]
-  (or (get *alias-map* sym sym)
+  (or (get *alias-map* sym)
       (when-let [ns (find-ns sym)]
         (symbol (ns-name ns)))))

@@ -776,7 +776,7 @@
     \( read-fn
     \{ read-set
     \< (throwing-reader "Unreadable form")
-    \=(throwing-reader "read-eval not supported")
+    \= (throwing-reader "read-eval not supported")
     \" read-regex
     \! read-comment
     \_ read-discard


Reactivate all tests

Reactivate all tests

--- src/test/discuss/tests.cljs
+++ src/test/discuss/tests.cljs
@@ -8,7 +8,7 @@

 (enable-console-print!)

-(doo-tests ;;'discuss.components.clipboard-test
-           ;;'discuss.references.lib-test
-           ;;'discuss.utils.common-test
+(doo-tests 'discuss.components.clipboard-test
+           'discuss.references.lib-test
+           'discuss.utils.common-test
            'discuss.translations-test)


implemented conducts and different realms

--- src/demogorgon/nh.clj
+++ src/demogorgon/nh.clj
@@ -76,6 +76,20 @@
       "obtained the sokoban prize"
       "defeated Medusa"])

+(def conducts
+     ["foodless"
+      "vegan"
+      "vegetarian"
+      "atheist"
+      "weaponless"
+      "pacifist"
+      "illiterate"
+      "polyless"
+      "polyselfless"
+      "wishless"
+      "artifact wishless"
+      "genocideless"])
+
 (defn zone [zonenum]
   (let [i (if (isa? (class zonenum) String)
             (Integer/parseInt zonenum)
@@ -118,8 +132,8 @@
                                 ""))) props)]
     (zipmap keys values)))

-(defn insert-xlogfile-line-db [line]
-  (let [data (parse-line line)]
+(defn insert-xlogfile-line-db [region line]
+  (let [data (assoc (parse-line line) :region region)]
     (let [record (assoc data :death_uniq (.replaceAll (:death data) ", while .*$", ""))]
       (sql/insert-records :xlogfile
                         record))))
@@ -222,11 +236,11 @@
     (.substring str 0 max)
     str))

-(defn handle-xlogfile-line [irc line]
+(defn handle-xlogfile-line [irc file line]
   (sql/with-connection db
     (sql/transaction
-     (insert-xlogfile-line-db line)))
-  (let [data (parse-line line)]
+     (insert-xlogfile-line-db (region-from-fn file) line)))
+  (let [data (assoc (parse-line line) :region (region-from-fn file))]
     (if (and (or (< (Integer/parseInt (:turns data)) 10)
                  (< (Integer/parseInt (:points data)) 10))
              (or (= (:death data) "quit")
@@ -268,25 +282,40 @@
          (catch Exception e
            (.error logger "tweet failed" e)))))))

+(condp = "euas"
+  "us" "american"
+  "eu" "european"
+  "us")
+
+(defn friendly-region [rgn]
+  (condp = rgn
+    "us" "american"
+    "eu" "european"
+    rgn))
+
 (defn make-game-action-out [data]
   (condp = (:game_action data)
     "started" (if (:character data)
-                (format "%s enters the dungeon as a%s."
+                (format "%s enters the %s dungeon as a%s."
                         (:player data)
+                        (friendly-region (:region data))
                         (:character data))
-                (format "%s enters the dungeon as a%s %s %s."
+                (format "%s enters the %s dungeon as a%s %s %s."
                         (:player data)
+                        (friendly-region (:region data))
                         (:alignment data)
                         (race (:race data))
                         (role (:role data))))
     "resumed" (if (:character data)
-                (format "%s the%s resumes the adventure."
+                (format "%s the%s resumes the adventure in the %s realm."
                         (:player data)
-                        (:character data))
-                (format "%s the %s %s resumes the adventure."
+                        (:character data)
+                        (friendly-region (:region data)))
+                (format "%s the %s %s resumes the adventure in the %s realm."
                         (:player data)
                         (race (:race data))
-                        (role (:role data))))
+                        (role (:role data))
+                        (friendly-region (:region data))))

     "saved" (format "%s is taking a break from the hard life as an adventurer."
                     (:player data))
@@ -307,12 +336,12 @@
   (let [bitfield (if (integer? bitfield)
                    bitfield
                    (bitfield-to-int bitfield))]
-    (first (filter string?
-                   (map (fn [idx]
-                          (if (bit-test bitfield idx)
-                            (nth values idx)
-                            nil))
-                        (range (count values)))))))
+    (filter string?
+            (map (fn [idx]
+                   (if (bit-test bitfield idx)
+                     (nth values idx)
+                     nil))
+                 (range (count values))))))

 (defn make-livelog-out [data]
   (condp #(contains? %2 %1) data
@@ -368,12 +397,20 @@
                     (if (not (or (= achieve-diff 0)
                                  (= achieve-diff 0x200)
                                  (= achieve-diff 0x400)))
-                      (parse-bitfield achievements achieve-diff)))
+                      (format "%s %s after %s turns."
+                              (:player data)
+                              (first (parse-bitfield achievements achieve-diff))
+                              (:turns data))))

     (str "unhandled line: " data)))

-(defn handle-livelog-line [irc line]
-  (let [data (parse-line line)]
+(defn region-from-fn [fn]
+  (if (.endsWith fn "-us")
+    "us"
+    "eu"))
+
+(defn handle-livelog-line [irc file line]
+  (let [data (assoc (parse-line line) :region (region-from-fn file))]
     (if (not (is-scum (:player data)))
       (let [out (make-livelog-out data)]
         (if out
@@ -398,7 +435,11 @@
 (defn run-watcher [watcher]
   (with-local-vars [files {"livelog"   {:length (.length (File. (str (:un-dir config) "livelog")))
                                         :callback #'handle-livelog-line}
+                           "livelog-us"   {:length (.length (File. (str (:un-dir config) "livelog-us")))
+                                        :callback #'handle-livelog-line}
                            "xlogfile"  {:length (.length (File. (str (:un-dir config) "xlogfile")))
+                                        :callback #'handle-xlogfile-line}
+                           "xlogfile-us"  {:length (.length (File. (str (:un-dir config) "xlogfile-us")))
                                         :callback #'handle-xlogfile-line}}]
     (while
      (not (Thread/interrupted))
@@ -416,7 +457,7 @@
                  (loop [line (read-line-ra ra)]
                    (if line
                      (do
-                       ((:callback file) (:irc @watcher) line)
+                       ((:callback file) (:irc @watcher) fn line)
                        (var-set files (assoc (var-get files)
                                         fn
                                         (assoc (get (var-get files) fn) :length (.getFilePointer ra))))
@@ -485,12 +526,19 @@
       [:endtime "TIMESTAMP"]
       [:gender0 "TEXT"]
       [:align0 "TEXT"]
-      [:flags "TEXT"])
+      [:flags "TEXT"]
+      [:region "TEXT"])
      (let [lines (read-lines (str (:un-dir config) "xlogfile"))]
        (doseq [line lines]
-         (insert-xlogfile-line-db line)))))
+         (insert-xlogfile-line-db "eu" line)))
+     (let [lines (read-lines (str (:un-dir config) "us/" "xlogfile-us"))]
+       (doseq [line lines]
+         (insert-xlogfile-line-db "us" line)))))
   (.info logger "database initialized"))

 (defn nh-start [watcher]
   (nh-init-db)
   (.start (:thread @watcher)))
+
+(defn nh-run [watcher]
+  (.start (:thread @watcher)))


service function suitable to be used on gce/gae

--- datastore/src/clojure/gclouj/datastore.clj
+++ datastore/src/clojure/gclouj/datastore.clj
@@ -13,8 +13,12 @@
 (defn test-options [project-id port]
   (DatastoreOptionsFactory/createTestOptions project-id port))

-(defn service [options]
-  (.service options))
+(defn service
+  "Creates the Datastore service to be used with other functions. Use
+  options when connecting outside of the Google Cloud Platform, if
+  you're running on GCE/GAE you can use the no-args version."
+  ([] (.service (DatastoreOptions/defaultInstance)))
+  ([options] (.service options)))

 (defmulti complete-key (fn [project-id kind name-or-id] (cond (string? name-or-id) :name
                                                              (number? name-or-id) :id)))


New tests: test-verbore-show-configuration, test-include-jenkins-reply and test-get-credentials-id

--- test/emender_jenkins/config_test.clj
+++ test/emender_jenkins/config_test.clj
@@ -92,6 +92,25 @@
     "Check that the emender-jenkins.config/pretty-print? definition exists."
     (testing "if the emender-jenkins.config/pretty-print? definition exists."
         (is (callable? 'emender-jenkins.config/pretty-print?))))
+
+
+(deftest test-verbose-show-configuration?-existence
+    "Check that the emender-jenkins.config/verbose-show-configuration? definition exists."
+    (testing "if the emender-jenkins.config/verbose-show-configuration? definition exists."
+        (is (callable? 'emender-jenkins.config/verbose-show-configuration?))))
+
+
+(deftest test-include-jenkins-reply?-existence
+    "Check that the emender-jenkins.config/include-jenkins-reply? definition exists."
+    (testing "if the emender-jenkins.config/include-jenkins-reply? definition exists."
+        (is (callable? 'emender-jenkins.config/include-jenkins-reply?))))
+
+
+(deftest test-get-credentials-id-existence
+    "Check that the emender-jenkins.config/get-credentials-id definition exists."
+    (testing "if the emender-jenkins.config/get-credentials-id definition exists."
+        (is (callable? 'emender-jenkins.config/get-credentials-id))))
+

 ;
 ; Test for function behaviours


Shorter test input to reduce clutter.

Shorter test input to reduce clutter.


test - don't use async setTimeout and instead call (done) direct from handlers). Add failure handler.

--- test/re_frame_http_fx/core_test.cljs
+++ test/re_frame_http_fx/core_test.cljs
@@ -2,7 +2,6 @@
   (:require
     [ajax.core     :as ajax]
     [cljs.test     :refer-macros [is deftest async]]
-    [clojure.set   :as set]
     [cljs.spec     :as s]
     [re-frame.core :as re-frame]
     [re-frame-http-fx.core]))
@@ -14,38 +13,43 @@
 ;; ---- TESTS ------------------------------------------------------------------

-(deftest ^:async test-get
-  (let [seen-events     (atom #{})
-        forwarder       (re-frame/add-post-event-callback
-                          (fn [source_event _]
-                            (swap! seen-events #(->> source_event first (conj %)))))]
-    ;; setup effects handler
-    (re-frame/def-event-fx
-      ::http-test
-      (fn [_context _event-v]
-        {:http {:method          :get
-                :uri             "https://api.github.com/orgs/day8"
-                :response-format (ajax/json-response-format {:keywords? true})
-                :on-success      [::good-http-result "test-token1"]
-                :on-failure      [::bad-http-result "test-token1"]}}))
-    ;; setup success handler
-    (re-frame/def-event
-      ::good-http-result
-      (fn [db [_ token result]]
-        (is (= "test-token1" token) "expected: token to passed through")
-        (is (map? result) "expected: result should be a map")
-        (is (every? keyword? (keys result)) "all keys should be keywords as per :response-format")
-        ;; check shape of result using loose Spec
-        (is (not= (s/conform ::api-result result) :cljs.spec/invalid)
-            (s/explain-str ::api-result result))
-        db))
-    ;; kick things off
-    (re-frame/dispatch [::http-test])
-    ;; give re-frame and http time to process
+(deftest ajax-get
+  ;; Setup handler which returns a :http effect specifying an ajax-request.
+  ;; Note we specify optional :response-format to make sure our json result
+  ;; has keywords for keys, and :timeout see the ajax-request API
+  ;; for more details https://github.com/JulianBirch/cljs-ajax#ajax-request
+  ;; We specify an :on-failure for completenes but we don't expect the request
+  ;; to fail unless there is something wrong with your internet or github.
+  (re-frame/def-event-fx
+    ::http-test
+    (fn [_context _event-v]
+      {:http {:method          :get
+              :uri             "https://api.github.com/orgs/day8"
+              :timeout         5000
+              :response-format (ajax/json-response-format {:keywords? true})
+              :on-success      [::good-http-result "test-token1"]
+              :on-failure      [::bad-http-result "test-token1"]}}))
     (async done
-       (js/setTimeout
-         (fn []
-           (is (@seen-events ::good-http-result) "::good-http-result should have been fired")
-           (done)
-           (re-frame/remove-post-event-callback forwarder))
-         3000))))
+
+      ;; setup success handler
+      (re-frame/def-event
+        ::good-http-result
+        (fn [db [_ token result]]
+          (is (= "test-token1" token) "expected: token passed through")
+          ;; check shape of result using loose Spec
+          (is (not= (s/conform ::api-result result) :cljs.spec/invalid)
+              (s/explain-str ::api-result result))
+          (is (every? keyword? (keys result)) "keys should be keywords")
+          (done)
+          db))
+
+      ;; setup failure handler
+      (re-frame/def-event
+        ::bad-http-result
+        (fn [db [_ _token error]]
+          (re-frame/console :error "Unexpected HTTP error, something wrong with your internet? " error)
+          (done)
+          db))
+
+      ;; kick things off
+      (re-frame/dispatch [::http-test])))


Escape all the htmls

Escape all the htmls

--- src/greenyet/view.clj
+++ src/greenyet/view.clj
@@ -1,7 +1,6 @@
 (ns greenyet.view
   (:require [clojure.string :as str]
-            [hiccup.util :refer [escape-html]]
-            [hiccup.core :refer [html]]))
+            [hiccup.core :refer [h html]]))

 (defn- index-of [list item]
   (count (take-while (partial not= item) list)))
@@ -33,19 +32,21 @@
 (defn- host-as-html [host]
   [:td {:class (str/join " " ["host" (some-> host
                                              :color
-                                             name)])}
-   (escape-html (:hostname host))
+                                             name
+                                             h)])}
+   (h (:hostname host))
    (when (:message host)
-     [:span.message (escape-html (:message host))])
+     [:span.message (h (:message host))])
    (when (:components host)
      [:ol.components
       (for [comp (prefer-order-of color-by-importance (:components host) :color)]
         [:li {:class (str/join " " ["component" (some-> comp
                                                         :color
-                                                        name)])
-              :title (:message comp)
-              :data-name (:name comp)}
-         (:name comp)])
+                                                        name
+                                                        h)])
+              :title (h (:message comp))
+              :data-name (h (:name comp))}
+         (h (:name comp))])
       [:li.more]])])

 (defn- environment-table-as-html [environments rows]
@@ -56,14 +57,14 @@
           [:tr
            [:td]
            (for [env environments]
-             [:td (escape-html env)])]]
+             [:td (h env)])]]
          [:tbody
           (for [row rows]
             [:tr
              [:td
-              (let [system-name (escape-html (some :system row))]
-                [:a {:href (str/join ["?systems=" system-name])}
-                 system-name])]
+              (let [system-name (h (some :system row))]
+                [:a {:href (str/join ["?systems=" (h system-name)])}
+                 (h system-name)])]
              (for [host row]
                (host-as-html host))])]]))


Disable validations when switchin mode in user-auth module

--- src/braid/client/gateway/user_auth/events.cljs
+++ src/braid/client/gateway/user_auth/events.cljs
@@ -53,6 +53,7 @@
   (fn [{state :db} [_ mode]]
     {:db (-> state
              clear-error
+             (assoc-in [:user-auth :should-validate?] false)
              (assoc-in [:user-auth :mode] mode))}))

 (reg-event-fx


Cosmetic.

Cosmetic.

--- src/onyx/coordinator/log/datomic.clj
+++ src/onyx/coordinator/log/datomic.clj
@@ -68,18 +68,22 @@
     (filter (fn [t] (not (contains? active-tasks (:db/id t)))) sorted-tasks)))

 (defn all-active-jobs-ids [db]
-  (let [query '[:find ?job ?tx :where
-                [?job :job/task ?task ?tx]
-                [?task :task/complete? false]]]
-    (map first (sort-by second (d/q query db)))))
+  (->> db
+       (d/q '[:find ?job ?tx :where
+              [?job :job/task ?task ?tx]
+              [?task :task/complete? false]])
+       (sort-by second)
+       (map first)))

 (defn last-offered-job [db]
-  (let [query '[:find ?job ?tx :where
-                [?job :job/task ?task ?tx]
-                [?peer :peer/task ?task]
-                [?peer :peer/status :acking]]
-        result (d/q query (d/history db))]
-    (first (last (sort-by second result)))))
+  (->> (d/history db)
+       (d/q '[:find ?job ?tx :where
+              [?job :job/task ?task ?tx]
+              [?peer :peer/task ?task]
+              [?peer :peer/status :acking]])
+       (sort-by second)
+       (last)
+       (first)))

 (defn job-candidate-seq [job-seq last-offered]
   (->> (cycle job-seq)


edit links & completeness indication

edit links & completeness indication

--- src/io/perun/site.clj
+++ src/io/perun/site.clj
@@ -146,19 +146,31 @@
      [:div.mt2 (nav)]]
     [:div.ph3.mt5 contents]]))

+(defn edit-link [post]
+  (str "https://github.com/hashobject/perun.io/edit/new/guides/" (:path post)))
+
 (defn guide-page [{global-meta :meta post :entry}]
   (with-top-nav
     [:div
      [:h1.dib.ma0.pr2 (:title post)]
-     [:a.no-underline {:href "/"} "edit"]]
+     [:a.no-underline {:href (edit-link post)} "edit"]]
     [:div.md (:content post)]))

 (defn guides [{global-meta :meta guides :entries}]
   (with-top-nav
     (for [g (sort-by :index guides)]
-      [:a.dt.pv3.mv3.no-underline
-       {:href (str "/" (:permalink g))}
-       [:div.dtc.pv1 (icon (:icon g))]
-       [:div.dtc.pl4.black.v-top
-        [:h2.ma0 (:title g)]
-        [:p (:description g)]]])))+      (if (:complete g)
+        [:a.dt.pv3.mv3.no-underline
+         {:href (str "/" (:permalink g))}
+         [:div.dtc.pv1 (icon (:icon g))]
+         [:div.dtc.pl4.black.v-top
+          [:h2.ma0 (:title g)]
+          [:p (:description g)]]]
+        [:div.dt.pv3.mv3
+         {:style "opacity:0.5"}
+         [:div.dtc.pv1 (icon (:icon g))]
+         [:div.dtc.pl4.v-top
+          [:div
+           [:h2.dib.mv0.mr3 (:title g)]
+           [:span "TBD"]]
+          [:p (:description g)]]]))))


Fix Wrong arguments

Fix Wrong arguments

--- src/puppeteer/app/slackbot/alice.clj
+++ src/puppeteer/app/slackbot/alice.clj
@@ -40,7 +40,7 @@
         (do (message-usecase/send-build-succeed-message message-usecase $) $)
         (do (message-usecase/send-deploy-start-message message-usecase $) $)
         (do (apply deploy-usecase $))
-        (do (message-usecase/send-deploy-succeed-message $) $)))))
+        (do (message-usecase/send-deploy-succeed-message message-usecase $) $)))))

 (defn- build-failure
   [{:keys [message-usecase build-usecase conf-usecase job-usecase]}


Fix demo texts

Fix demo texts

--- test/com/wsscode/pathom/connect/planner_readers_test.cljc
+++ test/com/wsscode/pathom/connect/planner_readers_test.cljc
@@ -249,7 +249,7 @@
                                                             :great-video-service.video/like-count
                                                             :great-video-service.video/channel-title]}
                                               (fn [_ _]
-                                                {:great-video-service.video/title         "Youtube Title"
+                                                {:great-video-service.video/title         "Great Video Title"
                                                  :great-video-service.video/duration      420
                                                  :great-video-service.video/like-count    42
                                                  :great-video-service.video/channel-title "Channel"}))]}
@@ -261,7 +261,7 @@
                                                             :other-video-thing.video/like-count
                                                             :other-video-thing.video/channel-title]}
                                               (fn [_ _]
-                                                {:other-video-thing.video/title         "Vimeo Title"
+                                                {:other-video-thing.video/title         "Other Video Thing Title"
                                                  :other-video-thing.video/duration      860
                                                  :other-video-thing.video/like-count    88
                                                  :other-video-thing.video/channel-title "VChannel"}))]}]
@@ -272,10 +272,10 @@
                                :other-video-thing.video/title]}

                              ::foreign-calls]})
-             '{[:video/id 123] {:great-video-service.video/title    "Youtube Title"
+             '{[:video/id 123] {:great-video-service.video/title    "Great Video Title"
                                 :other-video-thing.video/like-count 88
                                 :great-video-service.video/duration 420
-                                :other-video-thing.video/title      "Vimeo Title"}
+                                :other-video-thing.video/title      "Other Video Thing Title"}
                ::foreign-calls {other-video-thing   [[{([:other-video-thing.video/id 123] {:pathom/context {}})
                                                        [:other-video-thing.video/title
                                                         :other-video-thing.video/like-count]}]]


Testing some nested foreign queries

Testing some nested foreign queries

--- test/com/wsscode/pathom/connect/planner_readers_test.cljc
+++ test/com/wsscode/pathom/connect/planner_readers_test.cljc
@@ -7,7 +7,7 @@
             [com.wsscode.pathom.sugar :as ps]
             [com.wsscode.pathom.test-helpers :as th]))

-(defn run-parser [{::keys [resolvers query entity foreign]}]
+(defn run-parser [{::keys [resolvers query entity foreign error-stack?]}]
   (let [parser (ps/connect-serial-parser
                  (cond-> {::ps/connect-reader pc/reader3}
                    foreign
@@ -18,7 +18,8 @@
                        foreign)))
                  resolvers)]
     (parser (cond-> {}
-              entity (assoc ::p/entity (atom entity)))
+              entity (assoc ::p/entity (atom entity))
+              error-stack? (assoc ::p/process-error (fn [_ e] (.printStackTrace e))))
       query)))

 (deftest test-runner3
@@ -159,7 +160,29 @@
                {::resolvers [(pc/single-attr-resolver :b :c #(str % "-C"))]
                 ::foreign   [{::resolvers [(pc/constantly-resolver :b "boo")]}]
                 ::query     [:c]})
-             {:c "boo-C"})))))
+             {:c "boo-C"})))
+
+    (testing "nested queries"
+      (is (= (run-parser
+               {::resolvers [(pc/single-attr-resolver :user/id :user/name str)]
+                ;::error-stack? true
+                ::foreign   [{::resolvers [(pc/resolver 'users
+                                             {::pc/output [{:users [:user/id]}]}
+                                             (fn [_ _] {:users {:user/id 1}}))]}]
+                ::query     [{:users [:user/name]}]})
+             {:users {:user/name "1"}}))
+
+      (is (= (run-parser
+               {::resolvers [(pc/single-attr-resolver :user/id :user/name str)]
+                ::foreign   [{::resolvers [(pc/resolver 'users
+                                             {::pc/output [{:users [:user/id]}]}
+                                             (fn [_ _] {:users [{:user/id 1}
+                                                                {:user/id 2}
+                                                                {:user/id 3}]}))]}]
+                ::query     [{:users [:user/name]}]})
+             {:users [{:user/name "1"}
+                      {:user/name "2"}
+                      {:user/name "3"}]})))))

 (deftest test-compute-foreign-query
   (testing "no inputs"


improve get peers number

improve get peers number

--- src/lib_onyx/peer.clj
+++ src/lib_onyx/peer.clj
@@ -2,7 +2,9 @@
   (:require [onyx.api]))

 (defn start-peer [n peer-config env-config]
-  (let [n-peers (or (try (Integer/parseInt 1) (catch Exception e)) n)
+  (let [n-peers (if-some [n-peers n]
+                         (Integer/parseInt (.toString n-peers))
+                         1)
         _ (println "Starting peer-group")
         peer-group (onyx.api/start-peer-group peer-config)
         _ (println "Starting env")


CMR-1863 Undocumenting XML generation shorthand using keywords.

--- umm-spec-lib/src/cmr/umm_spec/umm_to_xml_mappings/dsl.clj
+++ umm-spec-lib/src/cmr/umm_spec/umm_to_xml_mappings/dsl.clj
@@ -12,14 +12,6 @@
   A vector specifies that an element should be created. The first element of the vector is the tag
   name of the element. The rest of the contents of the vector are treated as a list of content
   generators that specify the content of the element.
-
-  Keywords may be used as a shorthand for a child element whose contents are to be taken from the
-  corresponding path in the current context, as a convenience for formats which map closely to the
-  UMM model itself. e.g.:
-
-      [:foo :bar bat]
-      ;; is equivalent to
-      [:foo [:bar (xpath \"bar\")] [:bat (xpath \"bat\")]]

   A map immediately following the tag name (without a ::type) will be treated as attributes for the
   element. The attributes map is treated as a map of attribute names to content generators for each


typos

typos

--- src/meta/promise.cljs
+++ src/meta/promise.cljs
@@ -11,7 +11,7 @@
   (reject  [_ value]    "Rejects the promise with value as the reason.")
   (log     [_]          "Output the result of the previous promise to the console.")
   (err     [_]          "Catch and output the error of a promise.")
-  (map     [_ f]  "Map a function to the result of the previous promise."))
+  (map     [_ f]        "Map a function to the result of the previous promise."))

 (extend-protocol IPromise
   js/Promise


Make todo example easier to understand

Make todo example easier to understand

Put simpler SQL information in the UI to make it clearer

--- src/webapp/framework/client/components/main_view.cljs
+++ src/webapp/framework/client/components/main_view.cljs
@@ -45,16 +45,17 @@
                                                         ))))

                               })
-                                (realtime select  id, item  from  coils_todo_items
-                                          {}
-                                        (container
-                                            (inline  "10%" (str (<-- :id)))
-                                            (inline  "90%" (str (<-- :item)))))
+                                  (div {:style {:fontWeight "bold"}} "realtime select  id, item  from  coils_todo_items")
+                                  (realtime select  id, item  from  coils_todo_items
+                                            {}
+                                            (container
+                                             (inline  "10%" (str (<-- :id)))
+                                             (inline  "90%" (str (<-- :item)))))

                                   (div {:style {:padding "20px" :backgoundColor "white"}})

-                                  ( select-debug  id, item  from  coils_todo_items
+                                  (comment select-debug  id, item  from  coils_todo_items  order by id
                                           {}
                                           (container
                                             (inline  "10%" (str (<-- :id)))
@@ -62,6 +63,15 @@

                                   (div {:style {:padding "20px" :backgoundColor "white"}})

+
+
+
+
+
+
+
+
+                                  (div {:style {:fontWeight "bold"}} "select  id,item  from  coils_todo_items  where id > 0")
                                   ( select  id,item  from  coils_todo_items  where id > 0
                                                   {}
                                                   (container
@@ -72,6 +82,16 @@
                                   (div {:style {:padding "20px" :backgoundColor "white"}})

+
+
+
+
+
+
+
+
+
+                                  (div {:style {:fontWeight "bold"}} "(realtime select id,user_name from coils_users")
                                   (realtime select id,user_name from coils_users
                                                   {}
                                                   (container
@@ -80,7 +100,7 @@

                                   (div {:style {:padding "20px" :backgoundColor "white"}})

-                                  ( realtime-debug select id, item from coils_todo_items where id < 43
+                                  (comment realtime-debug select id, item from coils_todo_items where id < 43
                                           {}
                                           (container
                                             (inline  "10%" (str (<-- :id)))


fix deref mistake

fix deref mistake

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10498 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- plugins/SlideExplorer2/src/slide_explorer/flatfield.clj
+++ plugins/SlideExplorer2/src/slide_explorer/flatfield.clj
@@ -1,6 +1,7 @@
 (ns slide-explorer.flatfield
   (:require [slide-explorer.tile-cache :as tile-cache]
-            [slide-explorer.image :as image]))
+            [slide-explorer.image :as image]
+            [slide-explorer.store :as store]))

 (defn map-vals [f m]
@@ -22,25 +23,23 @@
       (image/gaussian-blur 50)
       image/normalize-to-max))

-(defn flat-field-by-channel [cache-value]
-  (->> cache-value
+(defn flat-field-by-channel [cache]
+  (->> @cache
        (unzoomed-indices-by-channel)
        (map-vals (partial images-in-cache cache))
        (map-vals flat-field)))

-;(defn run-correction [
+; TODO: (defn re-flatten [in-cache])
+

 ;; testing

 (defn test-generate []
-  (->> @slide-explorer.view/mt
+  (->> slide-explorer.view/mt
        flat-field-by-channel
        (map-vals image/show)))

-(defn test-select []
-  (images-in-cache-for-flatfielding slide-explorer.view/mt))
-

@@ -84,4 +83,4 @@
           (slide-explorer.disk/write-tile dir {:i i} (first images0)))
         (when-let [more (next images0)]
           (recur more (inc i)))))))
-  )+)


ask db about permission every time

ask db about permission every time

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -83,16 +83,19 @@
 (defn ws-handler-dispatch-fn [req]
   (-> req :event first))

+(defn has-document-access? [doc-id req scope]
+  (let [doc (doc-model/find-by-id (:db req) doc-id)]
+    (auth/has-document-permission? (:db req) doc (-> req :ring-req :auth) scope)))
+
 (defn check-document-access-from-auth [doc-id req scope]
-  (let [doc (doc-model/find-by-id (:db req) doc-id)]
-    (when-not (auth/has-document-permission? (:db req) doc (-> req :ring-req :auth) scope)
-      (if (auth/logged-in? (:ring-req req))
-        (throw+ {:status 403
-                 :error-msg "This document is private. Please request access."
-                 :error-key :document-requires-invite})
-        (throw+ {:status 401
-                 :error-msg "This document is private. Please log in to access it."
-                 :error-key :document-requires-login})))))
+  (time (when-not (has-document-access? doc-id req scope)
+          (if (auth/logged-in? (:ring-req req))
+            (throw+ {:status 403
+                     :error-msg "This document is private. Please request access."
+                     :error-key :document-requires-invite})
+            (throw+ {:status 401
+                     :error-msg "This document is private. Please log in to access it."
+                     :error-key :document-requires-login})))))

 ;; TODO: make sure to kick the user out of subscribed if he loses access
 (defn check-subscribed [doc-id req scope]
@@ -101,11 +104,9 @@
   (when (= scope :admin)
     (get-in @document-subs [doc-id (-> req :client-id)])))

-;; TODO: this should take an access level at some point
 (defn check-document-access [doc-id req scope]
   {:pre [doc-id]}
-  (or (check-subscribed doc-id req scope)
-      (check-document-access-from-auth doc-id req scope)))
+  (check-document-access-from-auth doc-id req scope))

 (defn check-team-subscribed [team-uuid req scope]
   (when (= scope :admin)


Improve plane

Improve plane

--- src/play_clj/math.clj
+++ src/play_clj/math.clj
@@ -314,13 +314,15 @@

 (defn plane*
   "The function version of `plane`"
-  [^Vector3 normal ^double d]
-  (Plane. normal d))
+  ([arg1 arg2]
+    (Plane. arg1 arg2))
+  ([^Vector3 p1 ^Vector3 p2 ^Vector3 p3]
+    (Plane. p1 p2 p3)))

 (defmacro plane
   "Returns a [Plane](http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/math/Plane.html)"
-  [normal d & options]
-  `(u/calls! ^Plane (plane* ~normal ~d) ~@options))
+  [args & options]
+  `(u/calls! ^Plane (apply plane* ~args) ~@options))

 (defmacro plane!
   "Calls a single method on a `plane`"


Don't play keys when scrolling [in progress]

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -3,7 +3,7 @@
   (:require [goog.dom :as dom]
             [goog.events :as events]
             [cljs.core.async :as async :refer [<! >! put! chan timeout sliding-buffer close!
-                                               map<]]
+                                               mapcat< onto-chan closed?]]
             [playmary.util :as util]
             [playmary.scales :as scales]))

@@ -97,7 +97,7 @@
   (draw-notes draw-ctx instrument)
   (.restore draw-ctx))

-(defn touch->note
+(defn touch->piano-key
   [x instrument]
   (let [note-index (.floor js/Math (/ x (piano-key-width instrument)))]
     (nth (-> instrument :piano-keys keys) note-index)))
@@ -116,7 +116,7 @@
      :notes ()
      :w 0 :h 0 :sound-ready false
      :px-per-ms 0.1
-     :cur-touches {}
+     ;; :cur-touches {}
      :scrolling? false
      :start start
      :playhead start}))
@@ -154,8 +154,8 @@

 (defn touch->freq
   [instrument touch]
-  (touch->note (get-in touch [:position :x])
-               instrument))
+  (touch->piano-key (get-in touch [:position :x])
+                    instrument))

 (defn maybe-init-synths
   [instrument]
@@ -171,96 +171,90 @@
   [f coll val]
   (reduce f val coll))

-(defn touches->notes
-  [{playhead :playhead :as instrument} touches]
-  (->> touches
-       (map (fn [t] (assoc t :freq (touch->freq instrument t))))
-       (remove (fn [t] (get-in instrument [:piano-keys (t :freq) :on?])))
-       (map (fn [t] {:freq (t :freq)
-                     :on playhead
-                     :off nil
-                     :touch-id (t :touch-id)}))))
-
-(defn start-notes
-  [touches {notes :notes :as instrument}]
-  (let [new-notes (touches->notes instrument (filter-type "touchstart" touches))]
-    (reduce play-piano-key
-            (assoc instrument :notes (concat new-notes notes))
-            (map :freq new-notes))))
+(defn touch->note
+  [{playhead :playhead :as instrument} touch]
+  (let [freq (touch->freq instrument touch)]
+    (if (not (get-in instrument [:piano-keys freq :on?]))
+      {:freq freq
+       :on playhead
+       :off nil
+       :touch-id (touch :touch-id)})))
+
+(defn start-note
+  [touch {notes :notes :as instrument}]
+  (if-let [new-note (touch->note instrument touch)]
+    (-> instrument
+        (maybe-init-synths)
+        (play-piano-key (new-note :freq))
+        (assoc :notes (conj notes new-note)))
+    instrument))

 (defn end-notes
-  [touches {notes :notes playhead :playhead :as instrument}]
-  (let [off-touch-ids (->> (filter-type "touchend" touches)
-                           (map :touch-id)
-                           set)
-        note-off? (fn [n] (contains? off-touch-ids (n :touch-id)))]
+  [touch {notes :notes playhead :playhead :as instrument}]
+  (let [note-off? (fn [n] (= (touch :touch-id) (n :touch-id)))]
     (-> instrument
         (assoc :notes (map (fn [n] (if (note-off? n) (assoc n :off playhead) n)) notes))
         (->> (reduce-val->> stop-piano-key (->> notes (filter note-off?) (map :freq)))))))

-(defn x-distance
-  [{{end-x :x} :position :as t} instrument]
-  (- (get-in instrument [:cur-touches (t :touch-id) :position :x]) end-x))
-
-(defn y-distance
-  [{{end-y :y} :position :as t} instrument]
-  (- (get-in instrument [:cur-touches (t :touch-id) :position :y]) end-y))
+;; (defn x-distance
+;;   [{{end-x :x} :position :as t} instrument]
+;;   (- (get-in instrument [:cur-touches (t :touch-id) :position :x]) end-x))
+
+;; (defn y-distance
+;;   [{{end-y :y} :position :as t} instrument]
+;;   (- (get-in instrument [:cur-touches (t :touch-id) :position :y]) end-y))

 (defn distance
-  [t instrument]
-  (.sqrt js/Math (+ (.pow js/Math (x-distance t instrument) 2)
-                    (.pow js/Math (y-distance t instrument) 2))))
-
-(defn filter-scroll-touches
-  [touches instrument]
-  (filter (fn [t] (> (.abs js/Math (distance t instrument)) 10))
-          (filter-type "touchmove" touches)))
-
-(defn record-touches
-  [touches instrument]
-  (let [starts (filter-type "touchstart" touches)
-        moves (filter-type "touchmove" touches)
-        ends (filter-type "touchend" touches)]
-    (-> instrument
-        (update-in [:cur-touches] into (map vector (map :touch-id starts) starts))
-        (update-in [:cur-touches] into (map vector (map :touch-id moves) moves))
-        (update-in [:cur-touches] (fn [c] (apply dissoc c (map :touch-id ends)))))))
+  [{x1 :x y1 :y} {x2 :x y2 :y}]
+  (.sqrt js/Math (+ (.pow js/Math (- x2 x1) 2) (.pow js/Math (- y2 y1) 2))))
+
+;; (defn filter-scroll-touches
+;;   [touches instrument]
+;;   (filter (fn [t] (> (.abs js/Math (distance t instrument)) 10))
+;;           (filter-type "touchmove" touches)))
+
+;; (defn record-touches
+;;   [touches instrument]
+;;   (let [starts (filter-type "touchstart" touches)
+;;         moves (filter-type "touchmove" touches)
+;;         ends (filter-type "touchend" touches)]
+;;     (-> instrument
+;;         (update-in [:cur-touches] into (map vector (map :touch-id starts) starts))
+;;         (update-in [:cur-touches] into (map vector (map :touch-id moves) moves))
+;;         (update-in [:cur-touches] (fn [c] (apply dissoc c (map :touch-id ends)))))))

 (defn scroll
-  [scroll-touches {playhead :playhead px-per-ms :px-per-ms :as instrument}]
-  (if-let [scroll-touch (first (sort (fn [a b] (max (.abs js/Math (y-distance a instrument))
-                                                    (.abs js/Math (y-distance b instrument))))
-                                     scroll-touches))]
-    (-> instrument
-        (assoc :scrolling? true)
-        (assoc :playhead (+ playhead (/ (y-distance scroll-touch instrument) px-per-ms))))
-    (assoc instrument :scrolling? false)))
-
-(defn delete-scrolled-notes
-  [scroll-touches {notes :notes :as instrument}]
-  (let [scroll-touch-ids (set (map :touch-id scroll-touches))
-        delete-notes (group-by (fn [t] (and (nil? (t :off))
-                                            (contains? scroll-touch-ids (t :touch-id))))
-                               notes)]
-    (-> instrument
-        (assoc :notes (get delete-notes false))
-        (->> (reduce-val->> stop-piano-key (map :freq (get delete-notes true)))))))
-
-(defn handle-scrolling
-  [touches instrument]
-  (let [scroll-touches (filter-scroll-touches touches instrument)]
-    (->> instrument
-         (scroll scroll-touches)
-         (delete-scrolled-notes scroll-touches)
-         (record-touches touches))))
-
-(defn fire-touches-on-instrument
-  [instrument touches]
-  (->> instrument
-       maybe-init-synths
-       (start-notes touches)
-       (end-notes touches)
-       (handle-scrolling touches)))
+  [touch {playhead :playhead px-per-ms :px-per-ms :as instrument}]
+  ;; #_(-> instrument
+  ;;     ;; (assoc :scrolling? true)
+  ;;   (assoc :playhead (+ playhead (/ (touch :y-distance) px-per-ms))))
+  ;; (assoc instrument :scrolling? false)
+  (assoc instrument :playhead (+ playhead (/ (touch :y-distance) px-per-ms))))
+
+;; (defn delete-scrolled-notes
+;;   [scroll-touches {notes :notes :as instrument}]
+;;   (let [scroll-touch-ids (set (map :touch-id scroll-touches))
+;;         delete-notes (group-by (fn [t] (and (nil? (t :off))
+;;                                             (contains? scroll-touch-ids (t :touch-id))))
+;;                                notes)]
+;;     (-> instrument
+;;         (assoc :notes (get delete-notes false))
+;;         (->> (reduce-val->> stop-piano-key (map :freq (get delete-notes true)))))))
+
+;; (defn handle-scrolling
+;;   [touches instrument]
+;;   (let [scroll-touches (filter-scroll-touches touches instrument)]
+;;     (->> instrument
+;;          (scroll scroll-touches)
+;;          (delete-scrolled-notes scroll-touches)
+;;          (record-touches touches))))
+
+(defn fire-touch-on-instrument
+  [touch instrument]
+  (condp = (touch :type)
+    "touchstart" (start-note touch instrument)
+    "touchmove" (scroll touch instrument)
+    "touchend" (end-notes touch instrument)))

 (defn update-size [instrument canvas-id]
   (let [{w :w h :h :as window-size} (util/get-window-size)]
@@ -270,13 +264,95 @@

 (defn touches
   [canvas-id type]
-  (map< touch-data->touches (util/listen (dom/getElement canvas-id) type)))
-
-(defn create-touch-input-channel
-  [canvas-id]
-  (async/merge [(touches canvas-id :touchstart)
-                (touches canvas-id :touchend)
-                (touches canvas-id :touchmove)]))
+  (mapcat< touch-data->touches (util/listen (dom/getElement canvas-id) type)))
+
+;; (defn create-touch-input-channel
+;;   [canvas-id]
+;;   (async/merge [(touches canvas-id :touchstart)
+;;                 (touches canvas-id :touchend)
+;;                 (touches canvas-id :touchmove)]))
+
+(defn scroll?
+  [scroll-state cur-t]
+  (let [prev-t (get scroll-state (cur-t :touch-id))]
+    (and prev-t
+         (= (cur-t :type) "touchmove")
+         (or (= (prev-t :type) "touchmove")
+             (and (= (prev-t :type) "touchstart")
+                  (> (distance (cur-t :position) (prev-t :position)) 3))))))
+
+(defn emit-hold?
+  [t]
+  (> (t :age) 0))
+
+(def emit-scroll? (constantly true))
+
+(def emit-end? emit-hold?)
+
+(defmulti handle-touch (fn [t touch-state] (:type t)))
+
+(defmethod handle-touch "touchstart"
+  [{touch-id :touch-id :as t} {holds :holds scroll-states :scroll-states :as touch-state}]
+  (-> touch-state
+      (assoc :holds (assoc holds touch-id (assoc t :age 0)))
+      (assoc :scroll-states (assoc scroll-states touch-id t))))
+
+(defmethod handle-touch "touchmove"
+  [{touch-id :touch-id :as t}
+   {holds :holds scrolls :scrolls ends :ends scroll-states :scroll-states :as touch-state}]
+  (-> touch-state
+      (assoc :holds (if (scroll? scroll-states t) (dissoc holds touch-id) holds))
+      (assoc :scrolls (if (scroll? scroll-states t)
+                        (let [{{x1 :x y1 :y} :position} (get scroll-states touch-id)
+                              {{x2 :x y2 :y} :position} t]
+                          (assoc scrolls touch-id (-> t (assoc :x-distance (- x1 x2))
+                                                        (assoc :y-distance (- y1 y2)))))
+                        scrolls))
+      (assoc :scroll-states (if (scroll? scroll-states t)
+                              (assoc scroll-states touch-id t)
+                              (dissoc scroll-states touch-id)))))
+
+(defmethod handle-touch "touchend"
+  [{touch-id :touch-id :as t} {ends :ends scroll-states :scroll-states :as touch-state}]
+  (-> touch-state
+      (assoc :ends (assoc ends touch-id (assoc t :age 0)))
+      (assoc :scroll-states (dissoc scroll-states touch-id))))
+
+(defn emit-or-return
+  [hash-map emit? c]
+  (let [{emit true keep false} (group-by emit? (vals hash-map))]
+    (onto-chan c (or (vals (select-keys hash-map (map :touch-id emit))) '()) false)
+    (select-keys hash-map (map :touch-id keep))))
+
+(defn age
+  [touch-map]
+  (reduce (fn [m k] (update-in m [k :age] inc)) touch-map (keys touch-map)))
+
+(defn emit-events
+  [out-c {holds :holds scrolls :scrolls ends :ends :as touch-state}]
+  (-> touch-state
+      (assoc :holds (age (emit-or-return holds emit-hold? out-c)))
+      (assoc :scrolls (emit-or-return scrolls emit-scroll? out-c))
+      (assoc :ends (age (emit-or-return ends emit-end? out-c)))))
+
+(defn touch-chan
+  [canvas-id wait]
+  (let [out-c (chan)
+        c-touchstart (touches canvas-id :touchstart)
+        c-touchmove (touches canvas-id :touchmove)
+        c-touchend (touches canvas-id :touchend)]
+    (go (loop [touch-state {:holds (sorted-map) :scrolls (sorted-map) :ends (sorted-map)
+                            :scroll-states {}}]
+          (let [[v _] (alts! [c-touchstart c-touchmove c-touchend (timeout wait)])]
+            (if (nil? v)
+              (recur (emit-events out-c touch-state))
+              (recur (handle-touch v touch-state))))))
+    out-c))
+
+;; (defn scroll-touches-chan
+;;   [canvas-id]
+;;   (touches canvas-id :touchmove))
+

 (defn step-time
   [instrument delta]
@@ -292,10 +368,10 @@
 (set-up-web-audio-on-first-touch)

 (let [canvas-id "canvas"
+      frame-delay 16
       c-instrument (chan (sliding-buffer 1))
       c-orientation-change (util/listen js/window :orientation-change)
-      c-touch (create-touch-input-channel canvas-id)
-      frame-delay 16]
+      c-touch (touch-chan canvas-id frame-delay)]

   (go
    (let [draw-ctx (util/get-ctx canvas-id)]
@@ -311,8 +387,8 @@
   (go
    (loop [instrument (update-size (create-instrument (scales/c-minor)) canvas-id)]
      (>! c-instrument instrument)
-     (let [[data c] (alts! [c-touch c-orientation-change (timeout frame-delay)])]
+     (let [[data c] (alts! [c-orientation-change c-touch (timeout frame-delay)])]
        (condp = c
          c-orientation-change (recur (update-size instrument canvas-id))
-         c-touch (recur (fire-touches-on-instrument instrument data))
+         c-touch (recur (fire-touch-on-instrument data instrument))
          (recur (tick instrument frame-delay)))))))


Change colours so black bars don't bleed into iPhone frame


Use *options* instead of default-opts.

Use *options* instead of default-opts.

--- src/puget/printer.clj
+++ src/puget/printer.clj
@@ -244,22 +244,20 @@

 ;; PRINT FUNCTIONS

-(def ^:private default-opts
-  "Default Puget printing options."
-  {:width 80})
-
-
 (defn pprint
   ([value]
-   (pprint value default-opts))
-  ([value opts]
-   (fipp/pprint-document (canonize value) opts)))
+   (pprint value *options*))
+  ([value opts]
+   (let [doc (if-let [m (and (:print-meta opts) (meta value))]
+               [:align [:span "^" (canonize m)] :line (canonize value)]
+               (canonize value))]
+     (fipp/pprint-document doc {:width (:width opts)}))))

 (defn pprint-str
   "Pretty-print a value to a string."
   ([value]
-   (pprint-str value default-opts))
+   (pprint-str value *options*))
   ([value opts]
    (-> value
        (pprint opts)
@@ -270,7 +268,7 @@
 (defn cprint
   "Like pprint, but turns on colored output."
   ([value]
-   (cprint value default-opts))
+   (cprint value *options*))
   ([value opts]
    (with-color (pprint value opts))))

@@ -278,7 +276,7 @@
 (defn cprint-str
   "Pretty-prints a value to a colored string."
   ([value]
-   (cprint-str value default-opts))
+   (cprint-str value *options*))
   ([value opts]
    (-> value
        (cprint opts)


Cast HTTP connection to interface rather than implementation class

--- test/clj_http/test/core.clj
+++ test/clj_http/test/core.clj
@@ -13,9 +13,9 @@
            (org.apache.http.message BasicHeader BasicHeaderIterator)
            (org.apache.http.client.methods HttpPost)
            (org.apache.http.client.params CookiePolicy ClientPNames)
-           (org.apache.http HttpResponse HttpConnection HttpVersion)
+           (org.apache.http HttpResponse HttpConnection HttpInetConnection
+                            HttpVersion)
            (org.apache.http.protocol HttpContext ExecutionContext)
-           (org.apache.http.impl SocketHttpClientConnection)
            (org.apache.http.impl.client DefaultHttpClient)
            (org.apache.http.cookie CookieSpecFactory)
            (org.apache.http.impl.cookie BrowserCompatSpec)
@@ -415,7 +415,7 @@
          (localhost "/redirect-to-get")
          {:response-interceptor
           (fn [^HttpResponse resp ^HttpContext ctx]
-            (let [^SocketHttpClientConnection conn (.getAttribute ctx
+            (let [^HttpInetConnection conn (.getAttribute ctx
                                         ExecutionContext/HTTP_CONNECTION)]
               (swap! saved-ctx conj {:remote-port (.getRemotePort conn)
                                      :http-conn conn})))})]


more testing

more testing

--- test/cortex/module_test.clj
+++ test/cortex/module_test.clj
@@ -9,12 +9,15 @@
             [clojure.test.check.generators :as gen]
             [clojure.test.check.properties :as prop]))

+(declare MODULE-GENS)

 (def MODULE-GENS [(gen/return (layers/linear [[1 2] [3 4]] [0 10]))
                   (gen/return (layers/logistic [3]))])

-(defspec test-module-parameters
+(defspec test-module-parameter-lengths
          100
          (prop/for-all [m (gen/one-of MODULE-GENS)]
-           (= (m/ecount (parameters m)) (m/ecount (gradient m)))))+           (let [params (parameters m)
+                 grad (gradient m)]
+             (= (m/ecount params) (m/ecount grad) (parameter-count m)))))


use update instead of  assoc in `update-some`

--- frameworks/keyed/helix/src/demo/state.cljs
+++ frameworks/keyed/helix/src/demo/state.cljs
@@ -32,8 +32,7 @@

 (defn update-some [data]
   (reduce (fn [data index]
-            (let [row (get data index)]
-              (assoc data index (assoc row :label (str (:label row) " !!!")))))
+            (update data index update :label str " !!!"))
           data
           (range 0 (count data) 10)))


[#233] FormInstance form version

[#233] FormInstance form version

--- api/src/clojure/org/akvo/flow_api/datastore/form_instance.clj
+++ api/src/clojure/org/akvo/flow_api/datastore/form_instance.clj
@@ -251,6 +251,7 @@
    :data-point-id (str (.getProperty form-instance "surveyedLocaleId"))
    :identifier (.getProperty form-instance "surveyedLocaleIdentifier")
    :display-name (.getProperty form-instance "surveyedLocaleDisplayName")
+   :form-version (.getProperty form-instance "formVersion")
    :created-at (ds/created-at form-instance)
    :modified-at (ds/modified-at form-instance)})


support ASF, barf meaningfully if encoding unknown

--- src/sledge/server.clj
+++ src/sledge/server.clj
@@ -40,10 +40,14 @@
 (def encoding-types
   {"mp3" {:mime "audio/mpeg" :suffix "mp3" :transcode []}
    "FLAC 16 bits" {:mime "audio/flac" :suffix "flac" :transcode ["mp3"]}
+   "ASF (audio): 0x0161 (Windows Media Audio (ver 7,8,9))"
+   {:mime "audio/x-ms-asf" :suffix "asf" :transcode []}
    })

 (defn media-links [r]
-  (let [enc (get encoding-types (:encoding-type r))
+  (let [e-t (:encoding-type r)
+        enc (or (get encoding-types e-t)
+                (throw (Exception. (str "unsupported encoding-type " e-t))))
         basename (base64 (:pathname r))]
     (reduce (fn [h fmt]
               (assoc h fmt { "href" (str "/bits/" basename "."  fmt)}))


ended Refs & validation functions

ended Refs & validation functions

--- src/mark-volkmann-tutorial/reference-types.clj
+++ src/mark-volkmann-tutorial/reference-types.clj
@@ -134,4 +134,67 @@
     (withdraw from-account amount)
     (deposit to-account amount)))

-
+(defn- report-1 ; a private function
+  "prints information about a single account"
+  [account]
+  ; This assumes it is being called from within
+  ; the transaction started in reporrt/
+  (let [balance-ref (account :balance-ref)]
+    (println "balance for" (account :owner) "is" @balance-ref)))
+
+(defn report
+  "prints information about any number of accounts"
+  [& accounts]
+  (dosync
+    (doseq [account accounts]
+      (report-1 account))))
+
+; set a default uncaught exception handler
+; to handle exceptions not caught in other threads.
+(Thread/setDefaultUncaughtExceptionHandler
+  (proxy [Thread$UncaughtExceptionHandler] []
+    (uncaughtException [thread throwable]
+                       ; Just print the exception
+                       (println (.. throwable .getCause .getMessage)))))
+
+(let [a1 (open-account "Mark")
+      a2 (open-account "Tami")
+      thread (Thread. #(transfer a1 a2 50))]
+  (try
+    (deposit a1 100)
+    (deposit a2 200)
+
+    ; There are sufficient fund in Mark's account at this point
+    ; to transfer $50 to Tami's account.
+    (.start thread) ; will sleep in deposit function twice!
+
+    ; Unfortunately, due to the time it takes to complete the transfer
+    ; (simulated with sleep calls), the next call will complete first.
+    (withdraw a1 75)
+
+    ; Now there ara insufficient fund in Mark's account
+    ; to complete the transfer.
+
+    (.join thread)   ; wait for thread to finish
+    (report a1 a2)
+    (catch IllegalAccessException e
+      (println (.getMessage e) "in main thread"))))
+
+
+;; Validation functions
+; Note the use of the :validator directive when creating the Ref
+; to assign a validation function which is integer? in this case.
+(def my-ref (ref 0 :validator integer?))
+
+(try
+  (dosync
+    (ref-set my-ref 1) ; works
+
+    ; The next line doesn't work, so the transaction is rolled back
+    ; and the previous change isn't commited.
+    (ref-set my-ref "foo"))
+  (catch IllegalStateException e
+    ; do nothing
+    ))
+
+(println "my-ref =" @my-ref) ; due to validation failure -> 0


don't rely on the presence of midi-out

don't rely on the presence of midi-out

--- src/overtone/examples/compositions/rotater.clj
+++ src/overtone/examples/compositions/rotater.clj
@@ -10,7 +10,7 @@

 ;; Specify output device
-(def synth-out (midi-out "Bus 1"))
+(def synth-out (first (connected-midi-receivers)))

 ;; Rotate between these notes
 (def rotate (ref '(-10 -7 -14 -5)) )


:sparkles: Set proper equality check for ref used in group.

This avoids rerender groups when only siblings changes.

--- frontend/src/uxbox/main/refs.cljs
+++ frontend/src/uxbox/main/refs.cljs
@@ -70,7 +70,7 @@
                        (map #(get objects %))
                        (filter identity)
                        (vec)))))
-      (l/derive st/state)))
+      (l/derive st/state {:equals? =})))

 (defn is-child-selected?
   [id]


CMR-3233 Add missing function comments

CMR-3233 Add missing function comments

--- umm-spec-lib/src/cmr/umm_spec/version_migration.clj
+++ umm-spec-lib/src/cmr/umm_spec/version_migration.clj
@@ -122,10 +122,13 @@
   c)

 (defn first-contact-info
+  "Update the array of contact infos to be a single instance using the first contact info in the list"
   [c]
   (update-in c [:ContactInformation] first))

 (defn update-data-center-contact-info
+  "Update data center contact infos to be a single instance - this includes the contact info on the
+   data center, the contact info inside each contact person and each contact group"
   [data-center]
   (-> data-center
       (first-contact-info)
@@ -140,12 +143,15 @@
     (update-in [:ContactGroups] #(mapv first-contact-info %))))

 (defn contact-info-to-array
+  "Update the contact info field to be an array. If contact info is nil, leave it as nil."
   [c]
   (if (some? (:ContactInformation c))
    (assoc c :ContactInformation [(:ContactInformation c)])
    c))

 (defn update-data-center-contact-info-to-array
+  "Update data center contact infos to be arrays - this includes the contact info on the
+   data center, the contact info inside each contact person and each contact group"
   [data-center]
   (-> data-center
       (contact-info-to-array)


whitespace

whitespace

--- sidecar/src/figwheel_sidecar/config.clj
+++ sidecar/src/figwheel_sidecar/config.clj
@@ -267,8 +267,7 @@
    { :id "hey" :figwheel {:on-jsload 'heyhey.there :hey 5}})
   ((comp prep-build-for-figwheel-client forward-devcard-option)
    { :id "hey" :figwheel {:on-jsload 'heyhey.there :hey 5 :devcards true} :build-options {:fun false}})
-
-)
+ )

 (defn prep-builds [builds]
   (-> builds


Filtered additional packages in COM06

Filtered additional packages in COM06

--- src/alfresco_technical_validation/binary_validation.clj
+++ src/alfresco_technical_validation/binary_validation.clj
@@ -203,10 +203,28 @@
                          START n=NODE(*)
                          WHERE HAS(n.name)
                            AND HAS(n.package)
-                           AND NOT(n.package =~ 'org.apache..*')
-                           AND NOT(n.package =~ 'com.google..*')
-                           AND NOT(n.package =~ 'com.sap..*')
-                           AND NOT(n.package =~ 'com.sun..*')
+                           AND NOT(n.package =~ 'java.*')
+                           AND NOT(n.package =~ 'sun.*')
+                           AND NOT(n.package =~ 'com.sun.*')
+                           AND NOT(n.package =~ 'org.w3c.*')
+                           AND NOT(n.package =~ 'org.apache.*')
+                           AND NOT(n.package =~ 'org.alfresco.*')
+                           AND NOT(n.package =~ 'org.json.*')
+                           AND NOT(n.package =~ 'org.xml.*')
+                           AND NOT(n.package =~ 'org.springframework.*')
+                           AND NOT(n.package =~ 'org.hibernate.*')
+                           AND NOT(n.package =~ 'org.mybatis.*')
+                           AND NOT(n.package =~ 'net.sf.ehcache.*')
+                           AND NOT(n.package =~ 'org.quartz.*')
+                           AND NOT(n.package =~ 'org.mozilla.*')
+                           AND NOT(n.package =~ 'com.google.*')
+                           AND NOT(n.package =~ 'com.sap.*')
+                           AND NOT(n.package =~ 'com.license4j.*')
+                           AND NOT(n.package =~ 'com.aspose.*')
+                           AND NOT(n.package =~ 'asposewobfuscated.*')
+                           AND NOT(n.package =~ 'groovy.*')
+                           AND NOT(n.package =~ 'org.gradle.*')
+                           AND NOT(n.package =~ 'proguard.*')
                            AND HAS(n.`class-version`)
                            AND n.`class-version` < 50
                         RETURN n.name AS ClassName, n.`class-version-str` AS ClassVersion


Tidied up filenames - removed source directory prefix.

--- src/alfresco_technical_validation/source_validation.clj
+++ src/alfresco_technical_validation/source_validation.clj
@@ -54,7 +54,7 @@
                        }
     :ant               { :ivy #"antlib:org\.apache\.ivy\.ant" }
     :java              {
-                         :synchronized #"\ssynchronized\s"
+                         :synchronized #"(^|\s)synchronized(\s|$)"
                        }
   })

@@ -104,9 +104,12 @@
     { "AlfrescoVersionMax" (if (empty? message) "Not specified" message) }))

 (defn- stb08-stb09-use-of-synchronized
-  [content-index]
+  [source content-index]
   (let [uses-of-synchronized (filter #(= :synchronized (:regex-id %)) content-index)
-        message              (str "Uses of synchronized:\n" (s/join "\n" (map #(str (:file %) " line " (:line-number %)) uses-of-synchronized)))]
+        message              (str "Uses of synchronized:\n"
+                                  (s/join "\n"
+                                          (map #(str (subs (str (:file %)) (.length ^String source)) " line " (:line-number %))
+                                               uses-of-synchronized)))]
     (merge
       (build-bookmark-map "STB08"
                           (empty? uses-of-synchronized)
@@ -128,6 +131,6 @@
       (module-versions                 content-index)
       (alfresco-min-versions           content-index)
       (alfresco-max-versions           content-index)
-      (stb08-stb09-use-of-synchronized content-index)
+      (stb08-stb09-use-of-synchronized source content-index)
     )))


fix outdated title on anchor in side menu

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -147,7 +147,7 @@
                 [:span (or (get-in app [:cust :name]) "You")])])
            (for [[id {:keys [show-mouse? color cust-name]}] (dissoc (:subscribers app) client-id)
                  :let [id-str (or cust-name (apply str (take 6 id)))]]
-             [:a {:title "An anonymous user is viewing this document. Click to toggle showing their mouse position."
+             [:a {:title "Ping this person in chat."
                   :role "button"
                   :key id
                   :on-click #(cast! :aside-user-clicked {:id-str id-str})}


Proper use of time series chart.

Proper use of time series chart.

--- src-cljs/kixi/hecuba/widgets/chart.cljs
+++ src-cljs/kixi/hecuba/widgets/chart.cljs
@@ -1,5 +1,7 @@
 (ns kixi.hecuba.widgets.chart
   (:require
+   [cljs-time.core :as t]
+   [cljs-time.format :as tf]
    [mrhyde.core :as mrhyde]
    [om.core :as om :include-macros true]
    [om.dom :as dom :include-macros true]
@@ -11,19 +13,7 @@
 (mrhyde/bootstrap)
 (enable-console-print!)

-;; Should be called after the draw function
-(defn clean-axis [axis interval]
-  (if (> (.-length (.-shapes axis)) 0)
-    (let [del (atom 0)]
-      (when (> interval 1)
-        (let [text (.selectAll (.-shapes axis) "text")]
-          (.each text (fn [d]
-                        (when (not= (mod @del interval) 0)
-                          (.remove (js* "this"))
-                          (.each (.selectAll (.-shapes axis) "line") (fn [d2]
-                                                                       (if (= d d2)
-                                                                         (.remove (js* "this"))))))
-                        (swap! del inc))))))))
+(def amon-date (tf/formatter "yyyy-MM-ddTHH:mm:ssZ"))

 (defn- draw-chart [cursor measurements]
   (let [Chart            (.-chart dimple)
@@ -31,17 +21,18 @@
         [type device_id] (-> (get-in cursor [:sensor])
                              str
                              (str/split #"-"))
-        data             (into [] (map #(assoc % :id device_id) measurements))
+        data             (into [] (->> measurements
+                                       (map #(assoc % :id device_id))
+                                       (map #(assoc % :timestamp (tf/parse amon-date (:timestamp %))))))
         unit             (get-in cursor [:unit])
         dimple-chart     (.setBounds (Chart. svg) "5%" "15%" "80%" "50%")
-        x                (.addCategoryAxis dimple-chart "x" "timestamp")
+        x                (.addTimeAxis dimple-chart "x" "timestamp")
         y                (.addMeasureAxis dimple-chart "y" "value")
         s                (.addSeries dimple-chart type js/dimple.plot.line (clj->js [x y]))]
     (aset s "data" (clj->js data))
     (.addLegend dimple-chart "5%" "10%" "20%" "10%" "right")
     (.draw dimple-chart)
     (.text (.-titleShape y) unit)
-    (let [n (count data)] (clean-axis x (Math/round (+ (/ n 50) 0.5))))
     (.attr (.selectAll (.-shapes x) "text") "transform" (fn [d]
                                                           (let [transform (.attr (.select d3 (js* "this")) "transform")]
                                                             (when-not (empty?


added serializer to use.

added serializer to use.

--- src/carbonite/JavaBridge.clj
+++ src/carbonite/JavaBridge.clj
@@ -1,5 +1,5 @@
 (ns carbonite.JavaBridge
-  (:use carbonite.api)
+  (:use [carbonite api serializer])
   (:gen-class :main false
               :methods
               [^{:static true} [defaultRegistry


correct interpret function return

correct interpret function return

--- src/clj_money/validation.clj
+++ src/clj_money/validation.clj
@@ -61,7 +61,7 @@
   (when (and (seq? pred)
              (or (= (first pred) '<=)
                  (= (first pred) 'clojure.core/<=)))
-    [(first path)
+    [path
      (format "Count must be greater than or equal to %s" (second pred))]))

 (defn- interpret-unknown-failure


correct function reference

correct function reference

--- src/clj_money/web/server.clj
+++ src/clj_money/web/server.clj
@@ -29,7 +29,7 @@
   (GET "/signup" []
        (users/new-user))
   (POST "/users" req
-        (users/create (:params req)))
+        (users/create-user (:params req)))
   (friend/logout (POST "/logout" [] (redirect "/")))
   (friend/wrap-authorize protected-routes #{:user})
   (ANY "*" []


Change discard pile abbreviation from disc to pile.

--- src/cljs-blackjack/core.cljs
+++ src/cljs-blackjack/core.cljs
@@ -119,11 +119,11 @@
   win."
   [event]
   (let [{:keys [deck discard-pile dealer-hand player-hand current-bet]} @game
-        [player1 disc0] (discard [player-hand discard-pile])
-        [dealer1 disc1] (discard [dealer-hand disc0])
-        [deck2 dealer2 disc2] (deal (deal [deck dealer1 disc1] :up) :down)
-        [deck3 player2 disc3] (deal (deal [deck2 player1 disc2] :up) :up)]
-    (swap! game assoc :playing true :discard-pile disc3 :player-hand player2
+        [player1 pile0] (discard [player-hand discard-pile])
+        [dealer1 pile1] (discard [dealer-hand pile0])
+        [deck2 dealer2 pile2] (deal (deal [deck dealer1 pile1] :up) :down)
+        [deck3 player2 pile3] (deal (deal [deck2 player1 pile2] :up) :up)]
+    (swap! game assoc :playing true :discard-pile pile3 :player-hand player2
            :dealer-hand dealer2 :deck deck3 :player-feedback "" :feedback-color :black)
     (if (immediate-win dealer2 player2)
       (do


Basic idea validation

Basic idea validation

--- src/cljs/geoforms/forms.cljs
+++ src/cljs/geoforms/forms.cljs
@@ -41,16 +41,42 @@
       (assoc :email "Email is empty")

       (when-let [email (:email person)]
-        (nil? (re-find email-regex email)))
+        (and (seq email)
+             (nil? (re-find email-regex email))))
       (assoc :email "Email is not valid")

       (nil? (:age person))
       (assoc :age "Age is not set"))))

+(defn validate-idea
+  "Build map of {key error} pairs, where each {error} relates to idea.{key}"
+  [idea]
+  (cond-> {}
+    ;; TODO: user has signed
+
+    (empty? (:title idea))
+    (assoc :title "Title cannot be blank.")
+
+    (when-let [title (:title idea)]
+      (and (seq title)
+           (some (comp #{title} :title) @db/ideas)))
+    (assoc :title "Title must be unique")
+
+    (empty? (:category idea))
+    (assoc :category "Category must be set.")))
+
 (defn validate-user!
   "Update errors atom, and return true if there were any errors."
   [doc]
   (let [errors (validate-user @doc)]
+    (swap! doc assoc :errors errors)
+    (empty? errors)))
+
+(defn validate-idea!
+  "Update errors atom, and return true if there were any errors."
+  [doc]
+  (let [errors (validate-idea @doc)]
+    (prn errors)
     (swap! doc assoc :errors errors)
     (empty? errors)))

@@ -67,7 +93,6 @@

 (defn submit-idea!
   [doc]
-  (prn doc)
   (db/create-idea! doc))

 ;; forms
@@ -110,6 +135,13 @@
   [:div.row
    [:div.col
     [:input.form-control {:field type :id id :placeholder label}]]])
+
+(defn error-field [key]
+  [:div.row
+   [:div.col-md-2]
+   [:div.col-md-5
+    [:div.alert.alert-danger
+     {:field :alert :id (str ":errors." (name key))}]]])

 ;;; COMPONENTS

@@ -134,7 +166,7 @@
      :on-change #(swap! idea-doc assoc-in [:category]
                         (-> % .-target .-value))}
     [:option
-     {:value "" :disabled true :selected true}
+     {:value "", :disabled true, :selected true}
      "Pick a category..."]
     (for [c @db/categories]
       [:option {:value c :key (symbol c)} c])]])
@@ -161,13 +193,18 @@
 (def idea-template
   [:div
    (input "Idea title" :text :title)
+   (error-field :title)
+
    [select-cat-component]
+   (error-field :category)
+
    [:p
     [:textarea.form-control
      {:rows        "4"
       :placeholder "If necessary, add a description"
       :field       :textarea
       :id          :desc}]]
+
    (for [i (range 3)]
      [:div {:key i}
       (input "URL" :text (str ":urls." i))])])
@@ -179,37 +216,30 @@
     idea-doc
     #_ (fn [k v _] (prn k v _))]
    [:button.btn.btn-default
-    {:on-click #(-> @idea-doc normalize-idea submit-idea!)}
+    {:on-click #(when (validate-idea! idea-doc)
+                  (-> @idea-doc normalize-idea submit-idea!))}
     "Add your idea"]])

 (defn signature-component []
   [:div.well
    (input "first name" :text :person.first-name)
-   [:div.row
-    [:div.col-md-2]
-    [:div.col-md-5
-     [:div.alert.alert-danger
-      {:field :alert :id :errors.first-name}]]]
+   (error-field :first-name)

    (input "last name" :text :person.last-name)
-   [:div.row
-    [:div.col-md-2]
-    [:div.col-md-5
-     [:div.alert.alert-danger
-      {:field :alert :id :errors.last-name}]]]
+   (error-field :last-name)

    (input "email" :email :person.email)
-   [:div.row
-    [:div.col-md-2]
-    [:div.col-md-5
-     [:div.alert.alert-danger
-      {:field :alert :id :errors.email}]]]
+   (error-field :email)

    [:div.form-group
     (row "age"
          [:select.form-control {:field :list :id :person.age}
-          (for [a db/age-groups]
-            [:option {:value a :key a} (name a)])])]
+          (cons
+           [:option {:value "", :disabled true, :selected true, :key "disabled"}
+            "Pick an age..."]
+           (for [a db/age-groups]
+             [:option {:value a :key a} (name a)]))])]
+   (error-field :age)

    (radios-yes-no
     "I want to get noticed about my supported ideas progress."


day 17

day 17

--- src/adventofcode/day17.clj
+++ src/adventofcode/day17.clj
@@ -1,66 +1,7 @@
 (ns adventofcode.day17
   (:require [clojure.java.io :as io]
-            [clojure.string :as str]))
-
-(defmacro combinations [sizes liters]
-  (let [sizes# sizes
-        symbols# (map #(symbol (str "n" %)) sizes#)
-        ranges# (map #(list range 0 (inc (quot liters %))) sizes#)
-        bindings# (-> (vec (interleave symbols# ranges#))
-                      (conj :when (list '= liters
-                                        (list 'apply '+ (conj symbols# 'list)))))]
-    `(for ~bindings# (vec ~@symbols#))))
-
-(combinations test-vec 10)
-
-(defmacro combinations-2 [sizes liters]
-  (let [sizes# sizes
-        liters# liters]
-    `(let [symbols# (map #(symbol (str "n" %)) ~sizes#)
-           ranges# (map #(list range 0 (inc (quot ~liters# %))) ~sizes#)
-           bindings# (-> (vec (interleave symbols# ranges#))
-                         (conj :when (list '= ~liters#
-                                           (list 'apply '+ (conj symbols# 'list)))))]
-       (foor bindings# (vec symbols#)))))
-
-(defmacro combinations-3 [sizes liters]
-  `(for
-    [~@(concat (interleave
-                (map #(symbol (str "n" %)) sizes)
-                (map #(list range 0 (inc (quot liters %))) sizes))
-               (list :when (list '= liters
-                                 (list 'apply '+ (conj (map #(symbol (str "n" %)) sizes) 'list)))))]
-     [~@(map #(symbol (str "n" %)) sizes)]))
-
-(defmacro for' [bindings body]
-  (let [bindings# bindings
-        body# body]
-    `(for [~@bindings] [~@body])))
-
-(foor [n (range 2)] n)
-
-(def c (combinations-2 test-vec 10))
-(count (eval c))
-(foor (first (combinations-2 test-vec 10)) (second (combinations-2 test-vec 10)))
-(macroexpand-1 '(combinations-2 test-vec 10))
-
-(combinations-3 test-vec 10)
-(clojure.pprint/pprint (macroexpand-1 '(combinations-3 test-vec 10)))
-
-(def test-vec [1 2])
-(combinations test-vec 10)
-
-(defn gen-bind-body [sizes liters]
-  (let [symbols (map #(gensym (str "n" %)) sizes)
-        ranges (map #(list 'range 0 (inc (quot liters %))) sizes)
-        bindings (concat (interleave symbols ranges)
-                         (list :when (list '= liters
-                                           (list 'apply '+ (conj symbols 'list)))))]
-    [bindings symbols]))
-
-(clojure.pprint/pprint (let [[binds body] (gen-bind-body (list 1 2) 10)]
-                         (eval (list 'for' binds body))))
-(eval (deref test-vec))
+            [clojure.string :as str]
+            [clojure.math.combinatorics :as combo :refer [subsets]]))

 (def containers (->> "day17.txt"
                      io/resource
@@ -68,6 +9,21 @@
                      slurp
                      str/split-lines
                      (mapv read-string)))
-(require '[clojure.pprint :refer [pprint]])
-(def part-one (let [[binds body] (pprint (gen-bind-body containers 150))]
-                (count (eval (list 'for' binds body)))))
+
+(defn fit? [indexes]
+  (= 150
+     (->> indexes
+          (map #(get containers %))
+          (apply +))))
+
+(def fit-subsets (->> (subsets (range (count containers)))
+                      (filter fit?)))
+
+(def part-one (count fit-subsets))
+
+(def part-two (let [min-subset-count (->> fit-subsets
+                                          (map count)
+                                          (apply min))]
+                (->> fit-subsets
+                     (filter #(= (count %) min-subset-count))
+                     count)))