Complete to cast list parse.

Complete to cast list parse.

--- src/uk/co/anthonycampbell/imdb/cast_parser.clj
+++ src/uk/co/anthonycampbell/imdb/cast_parser.clj
@@ -76,11 +76,11 @@
     (if (not-empty page-content)
         (let [cast-table (search-for-cast (parse-cast-page page-content))]
             ; Parse cast list
-            (loop [cast-string ""
+            (loop [cast-list []
                    cast-rows (html/select cast-table [:tr])]
                 (if (not-empty cast-rows)
-                    ; Recurrsively compile cast string
-                    (recur (str cast-string
+                    ; Recurrsively compile cast list
+                    (recur (concat cast-list
                         (let [cast-name (html/select (first cast-rows) [:td.nm])
                               cast-character (html/select (first cast-rows) [:td.char])]

@@ -90,23 +90,31 @@
                                       cast-character-value (:tag (first (:content (first cast-character))))]
                                     (if (= (str cast-character-value) ":a")
                                         (if (not-empty cast-name-value)
-                                            (str ", " (first (:content cast-name-value)))))))))
+                                            [(first (:content cast-name-value))]))))))
                         ; Next row
                         (let [cast-character (html/select (first cast-rows) [:td.char])]
                             (if (not-empty cast-character)
                                 (let [cast-character-value (:tag (first (:content (first cast-character))))]

                                     ; We don't want too many cast entries
-                                    (if (true)
+                                    (if (<= (count cast-list) 20)

                                         ; Lets only continue if we're still dealing with 'real' characters
                                         (if (= (str cast-character-value) ":a")
-                                            (rest cast-rows)
-
-                                            )))))
+                                            (rest cast-rows)))))))

-                    ; Final clean up
-                    (ccstring/trim (subs cast-string 2)))))))
+                ; Convert list to string
+                (loop [cast-string ""
+                       cast-list-temp cast-list]
+                    (if (not-empty cast-list-temp)
+                        ; Recurrsively compile cast string
+                        (recur (str cast-string (str ", " (first cast-list-temp)))
+                            ; Next element
+                            (rest cast-list-temp))
+
+                        ; Finaly clean up
+                        (if (not-empty cast-string)
+                            (ccstring/trim (subs cast-string 2))))))))))

 (defn construct-directors
     "Construct a directors string based on the provided parsed page content"
@@ -121,7 +129,8 @@
                     (rest director-list))

                 ; Final clean up
-                (ccstring/trim (subs director-string 2))))))
+                (if (not-empty director-string)
+                    (ccstring/trim (subs director-string 2)))))))

 (defn construct-producers
     "Construct a producers string based on the provided parsed page content"
@@ -154,7 +163,8 @@
                     (rest producer-list))

                 ; Final clean up
-                (ccstring/trim (subs producer-string 2))))))
+                (if (not-empty producer-string)
+                    (ccstring/trim (subs producer-string 2)))))))

 (defn construct-screen-writers
     "Construct a screen-writers string based on the provided parsed page content"
@@ -178,4 +188,5 @@
                             (rest screen-writer-set))

                         ; Final clean up
-                        (ccstring/trim (subs screen-writer-string 2))))))))
+                        (if (not-empty screen-writer-string)
+                            (ccstring/trim (subs screen-writer-string 2)))))))))


Continue to parse cast list.

Continue to parse cast list.

--- src/uk/co/anthonycampbell/imdb/cast_parser.clj
+++ src/uk/co/anthonycampbell/imdb/cast_parser.clj
@@ -12,6 +12,15 @@
     (html/select page-content
         [:html :body :div#wrapper :div#root :div#pagecontent :div#tn15 :div#tn15main :div#tn15content
          :table]))
+
+(defn search-for-cast
+    "Searches through all of the provided cast tables until we find the
+     cast sub section."
+    [cast-tables]
+    (if (not-empty cast-tables)
+        (let [cast-table (html/select cast-tables [:table.cast])]
+            (if (not-empty cast-table)
+                cast-table))))

 (defn search-for-directors
     "Searches through all of the provided cast tables until we find the
@@ -49,8 +58,6 @@
     "Searches through all of the provided cast tables until we find the
      writing credits sub section."
     [cast-tables]
-    ;(println cast-tables)
-
     (if (not-empty cast-tables)
         (let [table-links (html/select (first cast-tables) [:a])]
             (if (not-empty table-links)
@@ -67,7 +74,39 @@
     "Construct a cast string based on the provided parsed page content"
     [page-content]
     (if (not-empty page-content)
-        nil))
+        (let [cast-table (search-for-cast (parse-cast-page page-content))]
+            ; Parse cast list
+            (loop [cast-string ""
+                   cast-rows (html/select cast-table [:tr])]
+                (if (not-empty cast-rows)
+                    ; Recurrsively compile cast string
+                    (recur (str cast-string
+                        (let [cast-name (html/select (first cast-rows) [:td.nm])
+                              cast-character (html/select (first cast-rows) [:td.char])]
+
+                            ; Only persist if we're dealing with a 'real' character
+                            (if (not-empty cast-character)
+                                (let [cast-name-value (first (:content (first cast-name)))
+                                      cast-character-value (:tag (first (:content (first cast-character))))]
+                                    (if (= (str cast-character-value) ":a")
+                                        (if (not-empty cast-name-value)
+                                            (str ", " (first (:content cast-name-value)))))))))
+                        ; Next row
+                        (let [cast-character (html/select (first cast-rows) [:td.char])]
+                            (if (not-empty cast-character)
+                                (let [cast-character-value (:tag (first (:content (first cast-character))))]
+
+                                    ; We don't want too many cast entries
+                                    (if (true)
+
+                                        ; Lets only continue if we're still dealing with 'real' characters
+                                        (if (= (str cast-character-value) ":a")
+                                            (rest cast-rows)
+
+                                            )))))
+
+                    ; Final clean up
+                    (ccstring/trim (subs cast-string 2)))))))

 (defn construct-directors
     "Construct a directors string based on the provided parsed page content"
@@ -87,8 +126,6 @@
 (defn construct-producers
     "Construct a producers string based on the provided parsed page content"
     [page-content]
-    (println (search-for-producers (parse-cast-page page-content)))
-
     (if (not-empty page-content)
         ; Parse list of producers
         (loop [producer-string ""


Tests for #7

Tests for #7

--- test/freecoin/test/handlers/participant_query.clj
+++ test/freecoin/test/handlers/participant_query.clj
@@ -31,8 +31,20 @@
                                                       (assoc :params {:uid (:uid wallet)})
                                                       (assoc :session {:signed-in-uid (:uid wallet)})))]
                (:status response) => 200
-               (:body response) => (contains (t/locale [:wallet :balance]))
-               )))
+               (:body response) => (contains (t/locale [:wallet :balance]))))
+       (fact "displays the balance of the participant wallet with the given uid"
+             (let [wallet-store (fm/create-memory-store)
+                   blockchain (fb/create-in-memory-blockchain :bk)
+                   my-wallet (:wallet (w/new-empty-wallet! wallet-store blockchain uuid/uuid
+                                                           "stonecutter-user-id" "name" "test@email.com"))
+                   her-wallet (:wallet (w/new-empty-wallet! wallet-store blockchain uuid/uuid
+                                                            "stonecutter-user-id" "alice" "alice@email.com"))
+                   account-page-handler (fp/account wallet-store blockchain)
+                   response (account-page-handler (-> (rmr/request :get "/account/")
+                                                      (assoc :params {:uid (:uid her-wallet)})
+                                                      (assoc :session {:signed-in-uid (:uid my-wallet)})))]
+               (:status response) => 200
+               (:body response) => (contains (t/locale [:wallet :balance])))))

 ;;        (fact "can not be accessed when user is not signed in"))


CMR-5238: Updated tests for recent changes in metadata.

--- test/cmr/opendap/tests/system/app/ous/core.clj
+++ test/cmr/opendap/tests/system/app/ous/core.clj
@@ -75,7 +75,7 @@
         (is (= 200 (:status response)))
         (is (= "cmr-service-bridge.v2.1; format=json"
                (get-in response [:headers :cmr-media-type])))
-        (is (= ["https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user/FS2/AIRS/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"]
+        (is (= ["https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user/FS2/AIRS/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A,Latitude,Longitude"]
                (util/parse-response response)))))
     (testing "GET without subset ..."
       (let [response @(httpc/get
@@ -91,7 +91,7 @@
         (is (= 200 (:status response)))
         (is (= "cmr-service-bridge.v2.1; format=json"
                (get-in response [:headers :cmr-media-type])))
-        (is (= ["https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user/FS2/AIRS/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc"]
+        (is (= ["https://f5eil01.edn.ecs.nasa.gov/opendap/DEV01/user/FS2/AIRS/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A,Latitude,Longitude"]
                (util/parse-response response)))))))

 (deftest gridded-with-ummvar-1-1-api-v2-1-bounds


Add 1ms sleep to allow time for the last item to be processed in sink-test

--- test/asystant/pipe_test.clj
+++ test/asystant/pipe_test.clj
@@ -32,12 +32,13 @@

 (defspec sink-test
   (prop/for-all [messages events/gen-events]
-                (let [output (atom [])
+                (let [output  (atom [])
                       sink-fn (fn [m] (swap! output conj m))
                       in-ch   (async/chan)
                       sdc     ((sink sink-fn) in-ch nil)]
                   (async/<!! (async/onto-chan in-ch messages))
                   (sdc)
+                  (Thread/sleep 1)
                   (is (= messages @output)))))

 (defspec transform-test


minor fixes in German translation

minor fixes in German translation

--- src/status_im/translations/de.cljs
+++ src/status_im/translations/de.cljs
@@ -85,12 +85,13 @@
    :incorrect-code                        (str "Tut uns leid, der Code war nicht korrekt, bitte erneut eingeben")
    :generate-passphrase                   (str "Ich werde eine Passphrase für Sie generieren, damit Sie Ihren"
                                                "Zugriff wiederherstellen oder sich von einem anderen Gerät aus einloggen können")
-   :phew-here-is-your-passphrase          "*Puh* das war schwer, hier ist Ihr Passphrase, *bitte aufschreiben und sicher aufbewahren!*Sie benötigen dies, um Ihren Account wiederherzustellen."
+   :phew-here-is-your-passphrase          "*Puh* das war schwer, hier ist Ihr Passphrase, *bitte aufschreiben und sicher aufbewahren!* Sie benötigen dies, um Ihren Account wiederherzustellen."
    :here-is-your-passphrase               "Hier ist Ihr Passphrase, *bitte aufschreiben und sicher verwahren!*Sie benötigen dies, um Ihren Account wiederherzustellen."
    :written-down                          "Stellen Sie sicher, dass Sie es sicher aufgeschrieben haben"
    :phone-number-required                 "Tippen Sie hier, um Ihre Telefonnummer einzugeben & ich werde Ihre Freunde finden"
+   :shake-your-phone                      "Bug gefunden oder Verbesserungsvorschlag? Einfach das Telefon ~schütteln~!"
    :intro-status                          "Chatten Sie mit mir, um Ihren Account einzurichten und Ihre Einstellungen zu ändern!"
-   :intro-message1                        "Willkommen beim Status\nTippen Sie auf diese nachricht, um Ihr Passwort einzurichten und loszulegen!"
+   :intro-message1                        "Willkommen bei Status\nTippen Sie auf diese Nachricht, um Ihr Passwort einzurichten und loszulegen!"
    :account-generation-message            "Eine Sekunde, ich muss wahnsinnig schwere Mathematik machen, um Ihr Konto zu generieren!"

    ;chats


A few more fixes for swedish translation

--- src/status_im/translations/sv.cljs
+++ src/status_im/translations/sv.cljs
@@ -91,7 +91,7 @@
    :remove-from-contacts                  "Ta bort från kontakter"
    :start-conversation                    "Börja en konversation"
    :send-transaction                      "Sänd en transaktion"
-   :testnet-text                          "Du är på {{testnet}} Testnet. Sänd inte äkta ETH eller SNT till din address"
+   :testnet-text                          "Du är på {{testnet}} Testnet. Sänd inte riktiga ETH eller SNT till din address"
    :mainnet-text                          "Du är på Mainnet. Äkta ETH kommer att sändas"

    ;;make_photo
@@ -113,9 +113,9 @@
    :confirmation-code                     (str "Tack! Vi har skickat dig ett textmeddelande med en bekräftelse "
                                                "kod. Var god ange den koden för att bekräfta ditt telefonnummer")
    :incorrect-code                        (str "Tyvärr var koden felaktig, var god ange den igen")
-   :phew-here-is-your-passphrase          "*Pust* det var svårt, här är din lösenordsfras, *skriv ner det här och förvara det säkert!* Du kommer att behöva det för att återställa ditt konto."
-   :here-is-your-passphrase               "Här är din lösenordsfras, *skriv ner det här och förvara det säkert!* Du kommer att behöva det för att återställa ditt konto."
-   :here-is-your-signing-phrase           "Här är din underskriftsfras. Du kommer att använde den för att verifiera dina transaktioner. *Skriv ner det här och förvara det säkert!*"
+   :phew-here-is-your-passphrase          "*Pust* det var svårt, här är din lösenordsfras, *skriv ner den och förvara den säkert!* Du kommer att behöva den för att återställa ditt konto."
+   :here-is-your-passphrase               "Här är din lösenordsfras, *skriv ner den och förvara den säkert!* Du kommer att behöva den för att återställa ditt konto."
+   :here-is-your-signing-phrase           "Här är din underskriftsfras. Du kommer att använde den för att verifiera dina transaktioner. *Skriv ner den och förvara den säkert!*"
    :phone-number-required                 "Tryck här för att ange ditt telefonnummer så jag kommer att hitta dina vänner"
    :shake-your-phone                      "Hittade du ett fel eller har du ett förbättringsförslag? ~Skaka~ bara din telefon!"
    :intro-status                          "Chatta med mig för att konfigurera ditt konto och ändra dina inställningar!"
@@ -183,7 +183,7 @@
    :save                                  "Spara"
    :delete                                "Ta bort"
    :clear-history                         "Rensa historik"
-   :mute-notifications                    "Tysta anmälningar"
+   :mute-notifications                    "Tysta aviseringar"
    :leave-chat                            "Lämna chatt"
    :chat-settings                         "Chattinställningar"
    :edit                                  "Redigera"
@@ -321,7 +321,7 @@
    :transactions-sign-transaction         "Skriv under transaktionen"
    :transactions-sign-later               "Skriv under senare"
    :transactions-delete                   "Ta bort transaktion"
-   :transactions-delete-content           "Transaktionen tas bort från listan 'Ounderskrivna'"
+   :transactions-delete-content           "Transaktionen tas bort från listan 'Ej underskrivna'"
    :transactions-history                  "Historik"
    :transactions-unsigned                 "Ej underskrivna"
    :transactions-history-empty            "Inga transaktioner i din historik ännu"


increase request timeout

increase request timeout

- give more time for requests to complete
- change mailserver everytime a request time out

Signed-off-by: yenda <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@status.im>

--- src/status_im/transport/inbox.cljs
+++ src/status_im/transport/inbox.cljs
@@ -28,11 +28,12 @@

 (def one-day (* 24 3600))
 (def seven-days (* 7 one-day))
-(def maximum-number-of-attemps 3)
+(def maximum-number-of-attemps 2)
+(def request-timeout 30)

 (def connection-timeout
   "Time after which mailserver connection is considered to have failed"
-  5000)
+  10000)

 (defn- parse-json
   ;; NOTE(dmitryn) Expects JSON response like:
@@ -178,6 +179,7 @@
                     (clj->js {:topic          topic
                               :mailServerPeer address
                               :symKeyID       sym-key-id
+                              :timeout        request-timeout
                               :from           from
                               :to             to})
                     (fn [error request-id]
@@ -370,8 +372,8 @@

 (fx/defn resend-request
   [{:keys [db] :as cofx} {:keys [request-id]}]
-  (if (>= maximum-number-of-attemps
-          (get-in [:transport.inbox/current-request :attemps] db))
+  (if (<= maximum-number-of-attemps
+          (get-in db [:transport.inbox/current-request :attemps]))
     (fx/merge cofx
               {:db (update db :transport.inbox/current-request dissoc :attemps)}
               (change-mailserver))


Completed 05_maps.clj clojure

Completed 05_maps.clj clojure

--- hackerrank/functional_programming/clojure/clojure-koans/src/koans/05_maps.clj
+++ hackerrank/functional_programming/clojure/clojure-koans/src/koans/05_maps.clj
@@ -3,48 +3,48 @@

 (meditations
   "Don't get lost when creating a map"
-  (= {:a 1 :b 2} (hash-map :a 1 __ __))
+  (= {:a 1 :b 2} (hash-map :a 1 :b 2 ))

   "A value must be supplied for each key"
-  (= {:a 1} (hash-map :a __))
+  (= {:a 1} (hash-map :a 1))

   "The size is the number of entries"
-  (= __ (count {:a 1 :b 2}))
+  (= 2 (count {:a 1 :b 2}))

   "You can look up the value for a given key"
-  (= __ (get {:a 1 :b 2} :b))
+  (= 2 (get {:a 1 :b 2} :b))

   "Maps can be used as functions to do lookups"
-  (= __ ({:a 1 :b 2} :a))
+  (= 1 ({:a 1 :b 2} :a))

   "And so can keywords"
-  (= __ (:a {:a 1 :b 2}))
+  (= 1 (:a {:a 1 :b 2}))

   "But map keys need not be keywords"
-  (= __ ({2006 "Torino" 2010 "Vancouver" 2014 "Sochi"} 2010))
+  (= "Vancouver" ({2006 "Torino" 2010 "Vancouver" 2014 "Sochi"} 2010))

   "You may not be able to find an entry for a key"
-  (= __ (get {:a 1 :b 2} :c))
+  (= nil (get {:a 1 :b 2} :c))

   "But you can provide your own default"
-  (= __ (get {:a 1 :b 2} :c :key-not-found))
+  (= :key-not-found (get {:a 1 :b 2} :c :key-not-found))

   "You can find out if a key is present"
-  (= __ (contains? {:a nil :b nil} :b))
+  (= true  (contains? {:a nil :b nil} :b))

   "Or if it is missing"
-  (= __ (contains? {:a nil :b nil} :c))
+  (= false (contains? {:a nil :b nil} :c))

   "Maps are immutable, but you can create a new and improved version"
-  (= {1 "January" 2 __} (assoc {1 "January"} 2 "February"))
+  (= {1 "January" 2 "February"} (assoc {1 "January"} 2 "February"))

   "You can also create a new version with an entry removed"
-  (= {__ __} (dissoc {1 "January" 2 "February"} 2))
+  (= {1 "January"} (dissoc {1 "January" 2 "February"} 2))

   "Often you will need to get the keys, but the order is undependable"
-  (= (list __ __ __)
+  (= (list 2006 2010 2014)
      (sort (keys {2010 "Vancouver" 2014 "Sochi" 2006 "Torino"})))

   "You can get the values in a similar way"
-  (= (list __ __ __)
+  (= (list "Sochi" "Torino" "Vancouver")
      (sort (vals {2006 "Torino" 2010 "Vancouver" 2014 "Sochi"}))))


n-peers should come first

n-peers should come first

--- test/desdemona/cli_test.clj
+++ test/desdemona/cli_test.clj
@@ -124,8 +124,8 @@
          NumberFormatException #"BOGUS"
          (peers/-main "BOGUS"))))
   (testing "happy case"
-    (let [group (gensym)
-          n-peers 6
+    (let [n-peers 6
+          group (gensym)
           peers (for [_ (range n-peers)] (gensym))
           events (atom [])
           redef-pairs (for [sym ['onyx.api/start-peer-group


Reset streak after asking for a hint

Reset streak after asking for a hint

--- src/cljs/daveconservatoire/site/ui/exercises.cljs
+++ src/cljs/daveconservatoire/site/ui/exercises.cljs
@@ -96,7 +96,8 @@
   [{:keys [state ref]} _ _]
   {:action
    (fn []
-     (swap! state update-in (conj ref ::hints-used) inc))})
+     (swap! state #(-> (update-in % (conj ref ::hints-used) inc)
+                       (assoc-in (conj ref ::streak-count) 0))))})

 (defmethod um/mutate 'dcex/check-answer
   [{:keys [state ref]} _ _]


Remove RequiresPayment from event create

--- src/cljs/elevent_client/pages/events/id/edit.cljs
+++ src/cljs/elevent_client/pages/events/id/edit.cljs
@@ -62,7 +62,7 @@
                              ""))
                          :EventId))))))
     (fn []
-      (let [{:keys [Name OrganizationId Venue StartDate EndDate RequiresPayment
+      (let [{:keys [Name OrganizationId Venue StartDate EndDate
                     TicketPrice Description]}
             @form

@@ -158,29 +158,11 @@
                [input/component :text {}
                 (r/wrap TicketPrice swap! form assoc :TicketPrice)]]]]
             [:div.field
-             [:div.field
-              ; TODO: someday make UI checkboxes work
-              #_[:div.field
-              [(with-meta identity
-                          {:component-did-mount
-                           #(.checkbox (js/$ ".ui.checkbox"))})
-               [:div#requires-payment.ui.checkbox
-                [:input {:type "checkbox"}]
-                [:label "Ticket required"]]]]
-               [:label
-                [:input#requires-payment
-                 {:type "checkbox"
-                  :on-change #(swap! form assoc :RequiresPayment
-                                     (if (nil? (:RequiresPayment @form))
-                                       true
-                                       (not (:RequiresPayment @form))))}]
-                " Ticket required"]]]
-            [:div.field
              [:label "Description"]
              [input/component :textarea {}
               (r/wrap Description swap! form assoc :Description)]]
             [action-button/component
-             {:class [:primary (when (seq errors) :disabled)]}
+             {:class (str "primary" (when (seq errors) " disabled"))}
              (if event-id "Edit" "Add")
              (create-event @form)]]]]]))))


Re-layout Terra banner to make text wrap instead of being clipped. (#1542)

* Re-layout Terra banner to make text wrap instead of being clipped.

* Apply suggestions from code review

Co-Authored-By: Isaac Zarsky <638db5d5d5fc8ac22caf9d70be31c97a4d530fb9@broadinstitute.org>

--- src/cljs/main/broadfcui/common/notifications.cljs
+++ src/cljs/main/broadfcui/common/notifications.cljs
@@ -270,7 +270,7 @@

 (defn terra-link-text [terra-redirect-url]
   (let [final-terra-url (or terra-redirect-url (config/firecloud-terra-url))]
-    [:span {}
+    [:div {}
       "You are using the classic FireCloud interface. "
       "As of August 2019, FireCloud will permanently migrate to our new experience, powered by Terra. Click "
       [:a {:href final-terra-url
@@ -285,37 +285,26 @@
      (let [{:keys [dismissed?]} @state
            {:keys [terra-redirect-url]} props]
        (when (not dismissed?)
-         [:div {}
-          [:div {:style {:height "66px"
-                         :line-height "66px"
-                         :width "100%"
-                         :position "relative"
-                         :overflow "hidden"
-                         :white-space "nowrap"
-                         :border-bottom "2px solid rgb(176, 210, 57)"
-                         :box-shadow "rgba(0, 0, 0, 0.12) 0px 3px 2px 0px"
-                         :background "81px url('assets/header-left-hexes.svg') no-repeat,
+         [:div {:style {:display "flex"
+                        :align-items "center"
+                        :height 66
+                        :width "100%"
+                        :border-bottom "2px solid rgb(176, 210, 57)"
+                        :box-shadow "rgba(0, 0, 0, 0.12) 0px 3px 2px 0px"
+                        :background "81px url('assets/header-left-hexes.svg') no-repeat,
                                        right url('assets/header-right-hexes.svg') no-repeat, rgb(116, 174, 67)"}}
-           [:img {:src "assets/terra-logo.svg"
+          [:img {:src "assets/terra-logo.svg"
                   :style {:height "56px"
                           :width "60px"
-                          :float "left"
                           :margin "4px 10px"}}]
-           [:span {:style {:color "white"
-                           :height "66px"
-                           :display "inline-block"
-                           :vertical-align "middle"
-                           :margin-left "112px"
-                           :text-align "center"
-                           :font-weight "500"}}
+          [:div {:style {:color "white"
+                         :flexGrow 1
+                         :text-align "center"
+                         :font-weight "500"}}
             (if (and (common/has-return?) (config/terra-redirects-enabled))
               "This page is displaying in our legacy application. Please bear with us as we migrate these features fully into Terra."
-              (terra-link-text terra-redirect-url))]]
-          [:div {:style {:alignSelf "center"
-                         :padding "1rem"
-                         :position "absolute"
-                         :top "0px"
-                         :right "0px"}}
+              (terra-link-text terra-redirect-url))]
+          [:div {:style {:margin "1rem"}}
            [FoundationTooltip
             {:tooltip "Hide for now"
              :style {:borderBottom "none"}


Remove counting rubbish from the solver

Remove counting rubbish from the solver

--- src/aurora/btree.cljs
+++ src/aurora/btree.cljs
@@ -426,8 +426,6 @@
   (reset [this key]
          (set! node (.-root tree))
          (set! ix 0))
-  (val [this]
-       (aget (.-vals node) ix))
   (seek-gt [this key]
            (loop []
              (if (and (instance? Node (.-parent node))
@@ -483,22 +481,16 @@
 ;; los and his are inclusive

 ;; propagate updates the current lo/hi for each var and may set the solver to failed
-;;   returns the val of the current key (only has to be correct when all its vars are fixed)
 ;; split-left either:
 ;;   breaks the solutions into two branches, sets the left branch, returns true
 ;;   has only one possible solution, does nothing, returns false
 ;; split-right:
 ;;   breaks the solutions into two branches, sets the right branch
-;; val returns the number of solutions with this key (assumes all vars are fixed)

 (deftype Contains [iterator vars scratch-key]
   Object
   (reset [this solver constraint]
          (.reset iterator))
-  (val [this solver constraints]
-       ;; TODO somewhat uncomfortable with the fact that this is stateful
-       ;; could store current key and check key= instead
-       (.val iterator))
   (propagate [this solver constraint]
              (let [los (.-los solver)
                    his (.-his solver)]
@@ -576,8 +568,6 @@
 (deftype Constant [c var]
   Object
   (reset [this solver constraint])
-  (val [this solver constraint]
-       1)
   (split-left [this solver constraint]
               false)
   (split-right [this solver constraint])
@@ -592,8 +582,6 @@
   (reset [this solver constraint]
          (dotimes [i (alength vars)]
            (.set-watch solver (aget vars i) constraint true)))
-  (val [this solver constraint]
-       1)
   (split-left [this solver constraint]
               false)
   (split-right [this solver constraint])
@@ -616,8 +604,6 @@
   (reset [this solver constraint]
          (dotimes [i (alength vars)]
            (.set-watch solver (aget vars i) constraint true)))
-  (val [this solver constraint]
-       1)
   (split-left [this solver constraint]
               false)
   (split-right [this solver constraint])
@@ -641,8 +627,6 @@
   (reset [this solver constraint]
          (dotimes [i (alength vars)]
            (.set-watch solver (aget vars i) constraint true)))
-  (val [this solver constraint]
-       1)
   (split-left [this solver constraint]
               false)
   (split-right [this solver constraint])
@@ -666,8 +650,6 @@
   (reset [this solver constraint]
          (.set-watch solver lo-var constraint true)
          (.set-watch solver hi-var constraint true))
-  (val [this solver constraint]
-       1)
   (split-left [this solver constraint]
               (let [los (.-los solver)
                     his (.-his solver)
@@ -800,23 +782,17 @@
                 (do
                   (.split this)
                   (recur 0)))))))
-  (val [this]
-       (let [result 1]
-         (dotimes [constraint (alength constraints)]
-           (set!! result (* result (.val (aget constraints constraint) this constraint))))
-         result))
-  (elems [this]
-         (let [results #js []]
-           (loop []
-             (let [result (.next this)]
-               (when-not (nil? result)
-                 (apush results result)
-                 (apush results (.val this))
-                 (recur))))
-         results))
+  (keys [this]
+        (let [results #js []]
+          (loop []
+            (let [result (.next this)]
+              (when-not (nil? result)
+                (apush results result)
+                (recur))))
+          results))
   ISeqable
   (-seq [this]
-        (seq (map vec (partition 2 (.elems this))))))
+        (seq (.keys this))))

 (defn solver [num-vars constraints]
   (let [los (least-key num-vars)
@@ -986,12 +962,8 @@
                 key-len
                 #js [(contains (iterator tree) (into-array (range key-len)))
                      (contains (iterator tree) (into-array (range key-len)))])
-        tree-elems (.elems tree)]
-    (dotimes [i (alength tree-elems)]
-      (let [elem (aget tree-elems i)]
-        (when (number? elem)
-          (aset tree-elems i (* elem elem)))))
-    (prim= tree-elems (.elems solver))))
+        tree-keys (.keys tree)]
+    (prim= tree-keys (.keys solver))))

 (defn self-join-prop [key-len]
   (prop/for-all [min-keys gen/s-pos-int
@@ -1001,16 +973,15 @@
 (defn run-product-join-prop [min-keys key-len updates]
   (let [product-tree (tree min-keys key-len)
         [tree _] (apply-to-tree (tree min-keys key-len) updates)
-        elems (.elems tree)
-        _ (dotimes [i (alength elems)]
-            (dotimes [j (alength elems)]
-              (when (and (== 0 (mod i 2)) (== 0 (mod j 2)))
-                (.update product-tree (.concat (aget elems i) (aget elems j)) (* (aget elems (+ i 1)) (aget elems (+ j 1)))))))
+        keys (.keys tree)
+        _ (dotimes [i (alength keys)]
+            (dotimes [j (alength keys)]
+              (.add product-tree (.concat (aget keys i) (aget keys j)))))
         solver (solver
                 (* 2 key-len)
                 #js [(contains (iterator tree) (into-array (range 0 key-len)))
                      (contains (iterator tree) (into-array (range key-len (* 2 key-len))))])]
-    (prim= (.elems product-tree) (.elems solver))))
+    (prim= (.keys product-tree) (.keys solver))))

 (defn product-join-prop [key-len]
   (prop/for-all [min-keys gen/s-pos-int


fix typo

fix typo

--- src/babel/forest.cljc
+++ src/babel/forest.cljc
@@ -280,7 +280,7 @@
                                 (str ".. and "
                                      (- (count complement-candidate-lexemes) 5) " more."))))]
                 (log/warn message)
-;                (throw (exception message)))
+;                (exception message)
 )
               (do (log/debug (str "add-complement after adding complement: "
                                   (morph (first return-val)) ",.."))


Reactivated old tests

Reactivated old tests

--- test/photon/stream_test.clj
+++ test/photon/stream_test.clj
@@ -4,21 +4,22 @@
             [ring.mock.request :as mock]
             [clojure.tools.logging :as log]
             [muon-clojure.client :as cl]
-            [photon.riak :as riak]
+            [photon.filedb :as filedb]
             [photon.streams :as streams]
             [photon.muon :as m])
   (:use midje.sweet))

 (def amazon-url "amqp://localhost")
+(def db (filedb/->DBFile "/tmp/temporalphoton.log"))

 (defn prepare! []
-  (let [ms (m/start-server! "bucket-test-1")]
+  (let [ms (m/start-server! "photon-test" db)]
     (streams/clean! (:stm ms))
     ms))

 (defn test-cold []
   (let [b (cl/muon-client amazon-url "monitor-client" "monitor" "client")
-        c (cl/with-muon b (cl/stream-subscription "muon://photon/stream"
+        c (cl/with-muon b (cl/stream-subscription "muon://photon-test/stream"
                                                   :stream-name "dummy"
                                                   :stream-type :cold
                                                   :from 0))]
@@ -33,7 +34,7 @@

 (defn test-hot-cold []
   (let [b (cl/muon-client amazon-url "1monitor-client" "2monitor" "3lient")
-        c (cl/with-muon b (cl/stream-subscription "muon://photon/stream"
+        c (cl/with-muon b (cl/stream-subscription "muon://photon-test/stream"
                                                   :stream-name "dummy"
                                                   :stream-type :hot-cold
                                                   :from 0))]
@@ -49,28 +50,28 @@
     (Thread/sleep 10000)
     (close! c)))

-#_(let [ms (prepare!)
+(let [ms (prepare!)
       n1 (test-cold)
       n2 (test-cold)]
   (fact "Consistent behaviour in cold streaming" n1 => n2))

-#_(let [ms (prepare!)
+(let [ms (prepare!)
       a (cl/muon-client amazon-url "asap-client" "asap" "client")]
-  (cl/with-muon a (cl/post-event "muon://photon/events" "dummy" {:test :ok}))
-  (cl/with-muon a (cl/post-event "muon://photon/events" "dummy" {:test :ok}))
-  (cl/with-muon a (cl/post-event "muon://photon/events" "dummy" {:test :ok}))
-  (cl/with-muon a (cl/post-event "muon://photon/events" "dummy" {:test :ok}))
+  (cl/with-muon a (cl/post-event "muon://photon-test/events"
+                                 {:test :ok
+                                  :stream-name "dummy"}))
+  (cl/with-muon a (cl/post-event "muon://photon-test/events"
+                                 {:test :ok
+                                  :stream-name "dummy"}))
+  (cl/with-muon a (cl/post-event "muon://photon-test/events"
+                                 {:test :ok
+                                  :stream-name "dummy"}))
+  (cl/with-muon a (cl/post-event "muon://photon-test/events"
+                                 {:test :ok
+                                  :stream-name "dummy"}))
   (fact "Correct count" (test-cold) => 4))

-#_(Thread/sleep 20000)
+(let [n1 (test-cold)
+      n2 (test-cold)]
+  (fact "Consistent behaviour in cold streaming after posts" n1 => n2))

-#_(let [n1 (test-cold)
-      n2 (test-cold)]
-  (fact "Consistent behaviour in cold streaming" n1 => n2))
-
-#_(let [ms (m/start-server! "rxriak-events-v1")]
-  (streams/clean! (:stm ms)))
-
-
-
-


use a test fixture instead of trying to do it manually

--- test/greybear/model_test.clj
+++ test/greybear/model_test.clj
@@ -10,13 +10,17 @@
                 :user "greybear-test"
                 :password "greybear-test"})

-(defn clear-database []
+(defn database-fixture [f]
   (jdbc/with-connection test-conn
-    (teardown)
-    (setup)))
+    (try
+      (setup)
+      (f)
+      (finally
+        (teardown)))))
+
+(use-fixtures :each database-fixture)

 (deftest user-create
-  (clear-database)
   (create-user "foo" "bar")
   (is (= (select players
                  (fields :name)
@@ -24,20 +28,19 @@
          [{:name "foo"}])))

 (deftest user-create-already-exists
-  (user-create)
+  (create-user "foo" "bar")
   (is (nil? (create-user "foo" "bar")))
   (is (= {:cnt 1}
          (first (select players
                         (aggregate (count :*) :cnt))))))

 (deftest verify-user-password-test
-  (user-create)
+  (create-user "foo" "bar")
   (is (true? (verify-user-password "foo" "bar"))))

 (deftest verify-user-password-no-user
-  (clear-database)
   (is (nil? (verify-user-password "foo" "bar"))))

 (deftest verify-user-password-wrong-password
-  (user-create)
+  (create-user "foo" "bar")
   (is (false? (verify-user-password "foo" "qux"))))


Equality should be symmetrical

Equality should be symmetrical

--- test/protobuf/core_test.clj
+++ test/protobuf/core_test.clj
@@ -72,6 +72,7 @@
         p (protobuf Foo :id 5 :tags ["fast" "shiny"] :label "nice")
         q (protobuf Foo :id 5 :tags ["fast" "shiny"] :label "nice")]
     (is (= m p))
+    (is (= p m))
     (is (= q p))))

 (deftest test-meta


Add RNIB to the producer-raw to producer mapping

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -120,7 +120,8 @@
    25 "CAB, Landschlacht"
    40 "BIT, München"
    50 "BSVÖ, Wien"
-   103 "Paderborn"})
+   103 "Paderborn"
+   111 "RNIB, London"})

 (def genre-code-to-genre
   "Mapping between genre-code and genre. Used for movies"


Determine accompanying-material based on some preconditions

at least for braille books

--- src/catalog/vubis.clj
+++ src/catalog/vubis.clj
@@ -248,14 +248,26 @@
                                               (parse-int series-volume))
                      double-spaced? (boolean
                                       (and double-spaced?
-                                           (re-find #"^Weitzeilig" double-spaced?)))]
+                                           (re-find #"^Weitzeilig" double-spaced?)))
+                     braille-grade (braille-grade-raw-to-braille-grade braille-grade)
+                     ;; apparently the data in the library re accompanying-material for
+                     ;; braille books is not to be trusted, hence we figure out if there
+                     ;; is some accompanying material based on an elaborate set of
+                     ;; preconditions
+                     accompanying-material (when (and
+                                                  rucksackbuch-number
+                                                  (= (:sub-genre item) :kinderbücher-ab-6)
+                                                  (= braille-grade :vollschrift)
+                                                  (not double-spaced?))
+                                             "inkl. Schwarzschriftbeilage")]
                  (-> item
                      (assoc-some
                       :rucksackbuch-number rucksackbuch-number
                       :rucksackbuch? (boolean rucksackbuch-number)
-                      :braille-grade (braille-grade-raw-to-braille-grade braille-grade)
+                      :braille-grade braille-grade
                       :double-spaced? double-spaced?
-                      :volumes (parse-int volumes))))
+                      :volumes (parse-int volumes)
+                      :accompanying-material accompanying-material)))
       :grossdruck (-> item
                       (assoc-some
                        :volumes (parse-int volumes)))


Fixed bug with first child element not rendering.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -719,17 +719,21 @@
                (.createElementNS js/document xmlns tag-name)
                (.createElement js/document tag-name))
         attrs? (first tail)
-        attrs (when (map? attrs?) attrs?)
+        have-attrs (map? attrs?)
+        attrs (when have-attrs attrs?)
         attrs (cond-> attrs
-                      (and id (not (:id attrs)))
-                      (assoc :id id)
-                      class
-                      (update :class
-                              (fn [cls]
-                                (let [class (.replace class re-dot " ")]
-                                  (if cls (str class " " cls) class)))))
+
+                (and id (not (:id attrs)))
+                (assoc :id id)
+
+                class
+                (update :class
+                        (fn [cls]
+                          (let [class (.replace class re-dot " ")]
+                            (if cls (str class " " cls) class)))))
+
         state (init-element-state! node tag)
-        children (if attrs (rest tail) tail)]
+        children (if have-attrs (rest tail) tail)]
     (bind-attrs! node attrs state)
     (when children
       (append-children! node children))


ugh. conj*

ugh. conj*

--- src/com/billpiel/mem_tracer/util/tree_query.clj
+++ src/com/billpiel/mem_tracer/util/tree_query.clj
@@ -56,6 +56,12 @@
   ((or *get-tags-mz* get-tags)
    node
    pred-map))
+
+(defn conj*
+  [& r]
+  (if (= (count r) 1)
+    (first r)
+    (apply conj r)))

 (defn insert-tags-into-summary
   [& [tags summary]]
@@ -70,7 +76,7 @@
           (-<> summary
                :set
                (or #{})
-               (apply conj <> tags))
+               (apply conj* <> tags))
           #{})})

 (defn merge-children-tag-summary
@@ -93,7 +99,7 @@
    :set (-<> ch-tags
              :set
              (or #{})
-             (apply conj <> tag))})
+             (apply conj* <> tag))})

 (defn get-children-tag-summary*
   [zipr pred-map]


Fixed some errors in the test case for munch (now passes two tests!)

--- test/minijava/test_munch.clj
+++ test/minijava/test_munch.clj
@@ -13,10 +13,11 @@
 				(let [
 				   t1 (Temp (minijava.ir.temp.Temp.))
 				   t2 (Temp (minijava.ir.temp.Temp.))
-					tree (Move (t1 Mem (BinaryOp :+ (Const 2))) t2)]
+					tree (Move t1 (Mem (BinaryOp :+ (Const 2)  t2)))]

 				 (is (= (select tree)
-           '(Movl (MEMORY t1 (CONST 2))t2))
+          (list(movl (MEMORY t1 2)t2)))
 				)))

+


Blacklist env vars from ciderex startup

Blacklist env vars from ciderex startup

  instead of whitelisting  everything else

--- src/cider_ci/exec.clj
+++ src/cider_ci/exec.clj
@@ -58,12 +58,19 @@

 (defn commons-exec-sh [command env-variables working-dir timeout]
   (commons-exec/sh command
-                   ; add (System/getenv) to see inherited env vars ; either is bad:
-                   ;   without: we loose job control
-                   ;   with: wee see a bunch vars from starting the executor
+                   ; try to blacklist some vars which are set during executor startup
+                   ; and visible through (System/getenv)
                    {:env (conj
-                           {}
-                           (select-keys (System/getenv) ["HOME" "USER"])
+                           (dissoc (conj {} (System/getenv))
+                                   "CLASSPATH"
+                                   "JAVA_CMD"
+                                   "JVM_OPTS"
+                                   "LEIN_HOME"
+                                   "LEIN_JAVA_CMD"
+                                   "LEIN_JVM_OPTS"
+                                   "LEIN_VERSION"
+                                   "TRAMPOLINE_FILE"
+                                   )
                            env-variables)
                     :dir working-dir
                     :watchdog (* 1000 timeout)}))
@@ -75,7 +82,8 @@
   (try
     (let [started {:started_at (time/now)}
           working-dir (:working_dir params)
-          env-variables (prepare-env-variables (conj {:cider-ci_working_dir working-dir}
+          env-variables (prepare-env-variables (conj {}
+                                                     {:cider-ci_working_dir working-dir}
                                                      (or (:ports params) {})
                                                      (:environment_variables params)))
           timeout (or (:timeout params) 200)


CLJS-303: fix case so it only evaluates its first argument once

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -713,10 +713,12 @@
                         (if (seq? test)
                           (reduce #(assoc-test %1 %2 expr) m test)
                           (assoc-test m test expr)))
-                      {} (partition 2 clauses))]
-   `(cond
-     ~@(mapcat (fn [[m c]] `((cljs.core/= ~m ~e) ~c)) pairs)
-     :else ~default)))
+                      {} (partition 2 clauses))
+        esym (gensym)]
+   `(let [~esym ~e]
+      (cond
+        ~@(mapcat (fn [[m c]] `((cljs.core/= ~m ~esym) ~c)) pairs)
+        :else ~default))))

 (defmacro try
   "(try expr* catch-clause* finally-clause?)


* src/clj/cljs/core.clj: all tests pass

* src/clj/cljs/core.clj: all tests pass

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -255,12 +255,18 @@
                                                      meths (if ifn?
                                                              (map adapt-params meths)
                                                              meths)]
-                                                 (if (or ifn? (vector? (first meths))) ;; deal w/ ifn later
-                                                   [`(set! ~(symbol pf) (fn ~@meths))]
-                                                   (map (fn [[sig & body :as meth]]
-                                                          `(set! ~(symbol (str pf "__" (count sig)))
-                                                                 (fn ~meth)))
-                                                        meths))))
+                                                 (cond
+                                                  ifn?
+                                                  [`(set! ~(symbol pf) (fn ~@meths))]
+
+                                                  (vector? (first meths))
+                                                  [`(set! ~(symbol (str pf "__" (count (first meths)))) (fn ~@meths))]
+
+                                                  :else
+                                                  (map (fn [[sig & body :as meth]]
+                                                         `(set! ~(symbol (str pf "__" (count sig)))
+                                                                (fn ~meth)))
+                                                       meths))))
                                              sigs)))))]
         `(do ~@(mapcat assign-impls impl-map))))))


map clojure.core/in-ns to REPL in-ns special for existing tools

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -594,20 +594,22 @@
           ([repl-env env form]
             (self repl-env env form nil))
           ([repl-env env [_ file :as form] opts]
-            (load-file repl-env file opts)))]
-    {'in-ns
-     (fn self
-       ([repl-env env form]
-        (self repl-env env form nil))
-       ([repl-env env [_ [quote ns-name] :as form] _]
-         ;; guard against craziness like '5 which wreaks havoc
-        (when-not (and (= quote 'quote) (symbol? ns-name))
-          (throw (IllegalArgumentException. "Argument to in-ns must be a symbol.")))
-        (when-not (ana/get-namespace ns-name)
-          (swap! env/*compiler* assoc-in [::ana/namespaces ns-name] {:name ns-name})
-          (-evaluate repl-env "<cljs repl>" 1
-            (str "goog.provide('" (comp/munge ns-name) "');")))
-        (set! ana/*cljs-ns* ns-name)))
+            (load-file repl-env file opts)))
+        in-ns-fn
+        (fn self
+          ([repl-env env form]
+           (self repl-env env form nil))
+          ([repl-env env [_ [quote ns-name] :as form] _]
+            ;; guard against craziness like '5 which wreaks havoc
+           (when-not (and (= quote 'quote) (symbol? ns-name))
+             (throw (IllegalArgumentException. "Argument to in-ns must be a symbol.")))
+           (when-not (ana/get-namespace ns-name)
+             (swap! env/*compiler* assoc-in [::ana/namespaces ns-name] {:name ns-name})
+             (-evaluate repl-env "<cljs repl>" 1
+               (str "goog.provide('" (comp/munge ns-name) "');")))
+           (set! ana/*cljs-ns* ns-name)))]
+    {'in-ns in-ns-fn
+     'clojure.core/in-ns in-ns-fn
      'require
      (fn self
        ([repl-env env form]


clarify permitted values for :file in canonical stacktrace

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -137,7 +137,9 @@
        :line <integer>
        :column <integer>}*]

-     :file must be a URL path (without protocol) relative to :output-dir."))
+     :file must be a URL path (without protocol) relative to :output-dir. If
+     no source file can be supplied (such as REPL defs), :file may be a custom
+     identifier string surrounded by angle brackets, i.e. \"<cljs repl>\"."))

 (defprotocol IPrintStacktrace
   (-print-stacktrace [repl-env stacktrace error build-options]


`cljs.test/assert-expr 'instance?` case bug, change `class` to `type`

--- src/clj/cljs/test.clj
+++ src/clj/cljs/test.clj
@@ -90,10 +90,10 @@
            env'# (if result#
                    (cljs.test/do-report ~env
                      {:type :pass, :message ~msg,
-                      :expected '~form, :actual (class object#)})
+                      :expected '~form, :actual (type object#)})
                    (cljs.test/do-report ~env
                      {:type :fail, :message ~msg,
-                      :expected '~form, :actual (class object#)}))]
+                      :expected '~form, :actual (type object#)}))]
        (if (:return env'#)
          (assoc env'# :last-value result#)
          result#))))


Only call :ice-strength-changed if the strength actually did change.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -417,7 +417,8 @@
       (swap! state update-in [:bonus] dissoc :ice-strength)
       (trigger-event state side :pre-ice-strength ice)
       (update! state side (assoc ice :current-strength (ice-strength state side ice)))
-      (trigger-event state side :ice-strength-changed (get-card state ice) oldstren))))
+      (when (not= oldstren (:current-strength (get-card state ice)))
+        (trigger-event state side :ice-strength-changed (get-card state ice) oldstren)))))

 (defn update-ice-in-server [state side server]
   (doseq [ice (:ices server)] (update-ice-strength state side ice) ))


Cleanup.

Cleanup.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -416,7 +416,6 @@
       (swap! state update-in [:bonus] dissoc :ice-strength)
       (trigger-event state side :pre-ice-strength ice)
       (update! state side (assoc ice :current-strength (ice-strength state side ice)))
-      ;(when (not= (:current-strength (get-card state ice)) oldstren)
       (trigger-event state side :ice-strength-changed (get-card state ice) oldstren))))

 (defn update-ice-in-server [state side server]


Don't send :turn-events to client, as with :events.

--- src/clj/game/main.clj
+++ src/clj/game/main.clj
@@ -63,7 +63,7 @@
                            (swap! state update-in [:log] #(conj % {:user "__system__" :text text})))
           "quit" (system-msg state (keyword side) "left the game"))
         (if-let [state (@game-states gameid)]
-          (.send socket (generate-string (assoc (dissoc @state :events) :action action)))
+          (.send socket (generate-string (assoc (dissoc @state :events :turn-events) :action action)))
           (.send socket (generate-string "ok")))
         (catch Exception e
           (println "Error " action command (get-in args [:card :title]) e "\nStack trace:"


Added a short-test

Added a short-test


Added code that allows one to save a simulation every so many steps when running plans.

--- src/main/clojure/brainardlab/nben/retina/util.clj
+++ src/main/clojure/brainardlab/nben/retina/util.clj
@@ -26,7 +26,8 @@
                  :sizes [20]
                  :S-cone-flags [:human]
                  :samples [2500000]
-                 :runs [1 2]}
+                 :runs [1 2]
+                 :save-every 100000}
       :standard {:surrounds [[0.25 3.0] nil]
                  :L-to-Ms [[16 1] [8 1] [4 1] [2 1] [1 1] [1 2] [1 4] [1 8] [1 16]]
                  :M-lambda-maxs [530.3 535 540 545 550 555]
@@ -35,7 +36,18 @@
                  :sizes [20 15 10 5]
                  :S-cone-flags [:human]
                  :samples [2500000]
-                 :runs [0]}
+                 :runs [0]
+                 :save-every 100000}
+      :savetest {:surrounds [[0.25 3.0]]
+                 :L-to-Ms [[4 1]]
+                 :M-lambda-maxs [535 540]
+                 :L-lambda-maxs [558.9]
+                 :S-lambda-maxs [420.7]
+                 :sizes [10 5]
+                 :S-cone-flags [:human]
+                 :samples [100]
+                 :save-every 20
+                 :runs [3]}
       :test     {:surrounds [[0.25 3.0] nil]
                  :L-to-Ms [[16 1] [8 1] [4 1]]
                  :M-lambda-maxs [535 540]
@@ -113,11 +125,46 @@
                  :else ""))
          "].bin")))

+;; used when setting up retina simulations automatically by simulate-some-retinas
+(defn- analysis-print-every [[analfn finfn every-k iter dat] sig]
+  (if (= 0 (mod iter every-k))
+    (println (format "Iteration %8d..." iter)))
+  [analfn finfn every-k (inc iter) (analfn dat sig)])
+(defn- finish-print-every [[analfn finfn every-k iter dat]]
+  (println "Simulation finished after " iter " iterations.")
+  (finfn dat))
+(defn- analysis-save-every [[analfn finfn R run embed every-k iter dat] sig]
+  (if (and (> iter 0) (= 0 (mod iter every-k)))
+    (write-simulation (simulation-filename R iter run :embed embed) R (finfn dat)))
+  [analfn finfn R run every-k (inc iter) (analfn dat sig)])
+(defn- finish-save-every [[analfn finfn R run embed every-k iter dat]]
+  (finfn dat))
+(defn- init-print-every [analfn finfn every-k start-dat]
+  [analfn finfn every-k 0 start-dat])
+(defn- init-save-every [analfn finfn R run embed every-k start-dat]
+  [analfn finfn R run every-k 0 start-dat])
+(defn- make-analysis [save-every print-every Rs run embed]
+  (let [n (count Rs)
+        [init1 anal1 fin1]
+        (if save-every
+          [(map #(init-save-every correlation-analysis correlation-analysis
+                                  %1 run embed save-every nil)
+                Rs)
+           (repeat n analysis-save-every)
+           (repeat n finish-save-every)]
+          [(repeat n nil) (repeat n correlation-analysis) (repeat n correlation-analysis)])]
+    (if print-every
+      [(cons (init-print-every (first anal1) (first fin1) print-every (first init1))
+             (next init1))
+       (cons analysis-print-every (next anal1))
+       (cons finish-print-every (next fin1))]
+      [init1 anal1 fin1])))
+
 ;; a function for simulating some of the retinas; given the total number of jobs and
 ;; a a job id, this will simulate and write out the results for the appropriate chunk
 ;; of simulations from the given set. The plan should be :basic or :standard.
 (defn simulate-some-retinas [plan-id hs-cache-filename output-dir total-nodes node-id
-                             &{:keys [verbose]}]
+                             &{:keys [verbose print-every] :or {print-every 10000}}]
   (let [plan (get simulation-plans plan-id)
         plan-retinas (retinas-from-plan plan)
         my-retinas (if (coll? node-id)
@@ -128,27 +175,23 @@
         runs (get plan :runs [0])
         cache (read-hyperspectral-cache hs-cache-filename)
         samples (get plan :samples [2500000])
-        embed (get plan :embed true)]
+        embed (get plan :embed true)
+        save-every (get plan :save-every)]
     (doseq [image-count samples
             run runs]
       (if verbose
         (println (format "Simulating %d retinas with %d samples from cache %s (run = %d)..."
                          (count my-retinas) image-count hs-cache-filename run)))
-      (let [corr-mtcs (if verbose
-                        (simulate-retinas
-                         my-retinas cache
-                         :image-count image-count
-                         :init-reduce (cons [0 nil] (repeat (dec (count my-retinas)) nil))
-                         :analysis (cons (fn [[iter dat] sig]
-                                           (if (= 0 (mod iter 1000))
-                                             (println "Iteration " iter "..."))
-                                           [(inc iter) (correlation-analysis dat sig)])
-                                         (repeat (dec (count my-retinas)) correlation-analysis))
-                         :finish (cons (fn [[iter dat]]
-                                         (println "Simulation complete after " iter " iterations.")
-                                         (correlation-analysis dat))
-                                       (repeat (dec (count my-retinas)) correlation-analysis)))
-                        (simulate-retinas my-retinas (val cache) :image-count image-count))
+      (let [[inits analfns finfns] (make-analysis save-every
+                                                  (when verbose print-every)
+                                                  my-retinas
+                                                  run
+                                                  embed)
+            corr-mtcs (simulate-retinas my-retinas cache
+                                        :image-count image-count
+                                        :init-reduce inits
+                                        :analysis analfns
+                                        :finish finfns)
             flnms (map #(str output-dir "/" (simulation-filename % image-count run)) my-retinas)]
         (doall
          (map #(write-simulation %1 %2 %3 :embed embed)


Added spectral-spacing plan for testing evenly-spaced lambda-max values.


Ordering tests need to allow for same timestamps

--- test/kixi/integration/search/ordering_test.clj
+++ test/kixi/integration/search/ordering_test.clj
@@ -50,8 +50,8 @@
       (success desc-resp)
       (let [ts-asc (map timestamp (get-in asc-resp [:body :items]))
             ts-desc (map timestamp (get-in desc-resp [:body :items]))]
-        (is (apply < (map tc/to-long (map t/from-str ts-asc))))
-        (is (apply > (map tc/to-long (map t/from-str ts-desc))))
+        (is (apply <= (map tc/to-long (map t/from-str ts-asc))))
+        (is (apply >= (map tc/to-long (map t/from-str ts-desc))))
         (is (= ts-asc
                (reverse ts-desc)))))))


(PDB-3952) Fix wait in test-stop-with-periodic-gc-running

Don't wait when we're testing the case where we intentionally block
the gc.  Otherwise the test takes much longer than it should.

--- test/puppetlabs/puppetdb/cli/services_test.clj
+++ test/puppetlabs/puppetdb/cli/services_test.clj
@@ -264,12 +264,14 @@
 ;; we wait on it if it doesn't take too long, and we proceed anyway
 ;; if it does.

-(defn test-stop-with-periodic-gc-running [infinite-delay? expected-msg-rx]
+(defn test-stop-with-periodic-gc-running [slow-gc? expected-msg-rx]
   (with-log-output log-output
     (let [gc-blocked (promise)
           gc-proceed (promise)
           gc svcs/collect-garbage]
-      (with-redefs [svcs/stop-gc-wait-ms (constantly default-timeout-ms)
+      (with-redefs [svcs/stop-gc-wait-ms (constantly (if slow-gc?
+                                                       0 ;; no point in waiting
+                                                       default-timeout-ms))
                     svcs/collect-garbage (fn [& args]
                                            (deliver gc-blocked true)
                                            @gc-proceed
@@ -285,7 +287,7 @@
                                                stop-status))
             @gc-blocked
             (is #{:collecting-garbage} @stop-status)
-            (when-not infinite-delay?
+            (when-not slow-gc?
               (deliver gc-proceed true))))))
     (is (= 1 (->> @log-output
                   (logs-matching expected-msg-rx)


Update genartlib dep in project template

--- project-template/project.clj
+++ project-template/project.clj
@@ -1,9 +1,7 @@
 (defproject sketch "0.1.0-SNAPSHOT"
   :description "A template for a sketch with Quil/Processing"
   :dependencies [[org.clojure/clojure "1.10.0"]
-                 [org.apache.commons/commons-math3 "3.3"]
-                 [quil "2.7.1"]
-                 [genartlib "0.1.17"] ; utility functions
+                 [genartlib/genartlib "0.1.18"] ; utility functions
                  [com.seisw/gpcj "2.2.0"]] ; polygon clipping
   :jvm-opts ["-Xms4000m" "-Xmx4000M" "-server"] ; 4GB heap size
   :source-paths ["src/clj"]


Make function private

Make function private

--- minicraft/desktop/src-common/minicraft/utils.clj
+++ minicraft/desktop/src-common/minicraft/utils.clj
@@ -79,7 +79,7 @@
          first
          nil?)))

-(defn tiled-map-layer-names
+(defn ^:private tiled-map-layer-names
   [screen]
   (for [layer (tiled-map-layers screen)]
     (tiled-map-layer! layer :get-name)))


added the missing e2e data attribute for testing

--- src/cljs/conference_rating/view_utils/conference.cljs
+++ src/cljs/conference_rating/view_utils/conference.cljs
@@ -24,7 +24,7 @@
 (defn add-rating-button [conference styles label]
   (if (not (is-future-conference? conference))
     [:div {:class "text-lg-right"}
-     [:a {:class (str "btn btn-orange voice-btn " styles) :href (str "#/conferences/" (:_id conference) "/add-rating")}
+     [:a {:class (str "btn btn-orange voice-btn " styles) :data-e2e "button-add-new-rating" :href (str "#/conferences/" (:_id conference) "/add-rating")}
       [:span {:class "glyphicon glyphicon-bullhorn hidden-sm"}]
       label]]))


Fix the order for the insert query parts

--- src/clojure/clojurewerkz/cassaforte/new_query_api.clj
+++ src/clojure/clojurewerkz/cassaforte/new_query_api.clj
@@ -98,10 +98,11 @@
        :what-columns 1
        :what-column  1
        :from         2
-       :where        3
-       :order        4
-       :limit        4
-       :filtering    5}
+       :filtering    3
+       :where        4
+       :order        5
+       :limit        6
+       }
       renderers
       {:what-count   (fn count-all-query [query-builder _]
                        (.countAll query-builder))


tidy up grain ugen metadata

tidy up grain ugen metadata

--- src/overtone/sc/machinery/ugen/metadata/grain.clj
+++ src/overtone/sc/machinery/ugen/metadata/grain.clj
@@ -2,72 +2,170 @@
   (:use [overtone.sc.machinery.ugen common check]))

 (def specs
-     [
+  [

-      {:name "GrainSin"
-       :args [{:name "num-channels" :mode :num-outs :default 1 :doc "the number of channels to output. If 1, mono is returned and pan is ignored."}
-              {:name "trigger" :default 0 :doc "a kr or ar trigger to start a new grain. If ar, grains after the start of the synth are sample accurate."}
-              {:name "dur" :default 1 :doc "size of the grain."}
-              {:name "freq" :default 440.0 :doc "the input to granulate"}
-              {:name "pan" :default 0 :doc "Determines where to pan the output. If numChannels = 1, no panning is done; if numChannels = 2, panning is similar to Pan2; if numChannels > 2, pannins is the same as PanAz."}
-              {:name "envbufnum" :default -1 :doc "the buffer number containing a singal to use for the grain envelope. -1 uses a built-in Hanning envelope."}
-              {:name "max-grains" :default 512 :doc " the maximum number of overlapping grains that can be used at a given time. This value is set at the UGens init time and can't be modified. This can be set lower for more	efficient use of memory."}]
-       :rates #{:ar}
-       :doc "Granular synthesis with sine tones"}
+   {:name "GrainSin"
+    :args [{:name "num-channels"
+            :mode :num-outs
+            :default 1
+            :doc "the number of channels to output. If 1, mono is
+                  returned and pan is ignored." }

-      ;; GrainFM : MultiOutUGen {
-      ;;  *ar { arg numChannels = 1, trigger = 0, dur = 1, carfreq = 440, modfreq = 200, index = 1,
-      ;;      pan = 0, envbufnum = -1, mul = 1, add = 0;
-      ;;    ^this.multiNew('audio', numChannels, trigger, dur, carfreq, modfreq, index, pan, envbufnum)
-      ;;      .madd(mul, add);
-      ;;    }
+           {:name "trigger"
+            :default 0
+            :doc "a kr or ar trigger to start a new grain. If ar, grains
+                  after the start of the synth are sample accurate." }

-      ;;  init { arg argNumChannels ... theInputs;
-      ;;    inputs = theInputs;
-      ;;    ^this.initOutputs(argNumChannels, rate);
-      ;;  }
+           {:name "dur"
+            :default 1
+            :doc "size of the grain."}

-      ;;  argNamesInputsOffset { ^2 }
-      ;;  }
+           {:name "freq"
+            :default 440.0
+            :doc "the input to granulate"}

-      ;; GrainBuf : MultiOutUGen {
-      ;;  *ar { arg numChannels = 1, trigger = 0, dur = 1, sndbuf, rate = 1, pos = 0, interp = 2,
-      ;;      pan = 0, envbufnum = -1, mul = 1, add = 0;
-      ;;    ^this.multiNew('audio', numChannels, trigger, dur, sndbuf, rate, pos, interp, pan,
-      ;;      envbufnum).madd(mul, add);
-      ;;    }
+           {:name "pan"
+            :default 0
+            :doc "Determines where to pan the output. If num-channels =
+                  1, no panning is done; if num-channels = 2, panning is
+                  similar to Pan2; if numChannels > 2, pannins is the
+                  same as PanAz." }

-      ;;  init { arg argNumChannels ... theInputs;
-      ;;    inputs = theInputs;
-      ;;    ^this.initOutputs(argNumChannels, rate);
-      ;;  }
-      ;;  argNamesInputsOffset { ^2 }
-      ;;  }
+           {:name "envbufnum"
+            :default -1
+            :doc "the buffer number containing a singal to use for the
+                  grain envelope. -1 uses a built-in Hanning envelope."}

-      {:name "GrainIn"
-       :args [{:name "num-channels" :mode :num-outs :default 1 :doc "the number of channels to output. If 1, mono is returned and pan is ignored."}
-              {:name "trigger" :default 0 :doc "a kr or ar trigger to start a new grain. If ar, grains after the start of the synth are sample accurate."}
-              {:name "dur" :default 1 :doc "size of the grain."}
-              {:name "in" :default :none :doc "the input to granulate"}
-              {:name "pan" :default 0 :doc "Determines where to pan the output. If numChannels = 1, no panning is done; if numChannels = 2, panning is similar to Pan2; if numChannels > 2, pannins is the same as PanAz."}
-              {:name "envbufnum" :default -1 :doc "the buffer number containing a singal to use for the grain envelope. -1 uses a built-in Hanning envelope."}
-              {:name "max-grains" :default 512 :doc " the maximum number of overlapping grains that can be used at a given time. This value is set at the UGens init time and can't be modified. This can be set lower for more	efficient use of memory."}]
-       :rates #{:ar}
-       :check (nth-input-stream? 3)
-       :doc "Granulate an input signal"}
+           {:name "max-grains"
+            :default 512
+            :doc " the maximum number of overlapping grains that can be
+                   used at a given time. This value is set at the UGens
+                   init time and can't be modified. This can be set
+                   lower for more efficient use of memory." }]
+    :rates #{:ar}
+    :doc "Granular synthesis with sine tones"}
+
+   ;; GrainFM : MultiOutUGen {
+   ;;  *ar { arg numChannels = 1, trigger = 0, dur = 1, carfreq = 440, modfreq = 200, index = 1,
+   ;;      pan = 0, envbufnum = -1, mul = 1, add = 0;
+   ;;    ^this.multiNew('audio', numChannels, trigger, dur, carfreq, modfreq, index, pan, envbufnum)
+   ;;      .madd(mul, add);
+   ;;    }
+
+   ;;  init { arg argNumChannels ... theInputs;
+   ;;    inputs = theInputs;
+   ;;    ^this.initOutputs(argNumChannels, rate);
+   ;;  }
+
+   ;;  argNamesInputsOffset { ^2 }
+   ;;  }
+
+   ;; GrainBuf : MultiOutUGen {
+   ;;  *ar { arg numChannels = 1, trigger = 0, dur = 1, sndbuf, rate = 1, pos = 0, interp = 2,
+   ;;      pan = 0, envbufnum = -1, mul = 1, add = 0;
+   ;;    ^this.multiNew('audio', numChannels, trigger, dur, sndbuf, rate, pos, interp, pan,
+   ;;      envbufnum).madd(mul, add);
+   ;;    }
+
+   ;;  init { arg argNumChannels ... theInputs;
+   ;;    inputs = theInputs;
+   ;;    ^this.initOutputs(argNumChannels, rate);
+   ;;  }
+   ;;  argNamesInputsOffset { ^2 }
+   ;;  }
+
+   {:name "GrainIn"
+    :args [{:name "num-channels"
+            :mode :num-outs
+            :default 1
+            :doc "the number of channels to output. If 1, mono is
+                  returned and pan is ignored." }
+
+           {:name "trigger"
+            :default 0
+            :doc "a kr or ar trigger to start a new grain. If ar, grains
+                  after the start of the synth are sample accurate." }
+
+           {:name "dur"
+            :default 1
+            :doc "size of the grain."}
+
+           {:name "in"
+            :default :none
+            :doc "the input to granulate"}
+
+           {:name "pan"
+            :default 0
+            :doc "Determines where to pan the output. If num-channels =
+                  1, no panning is done; if num-channels = 2, panning is
+                  similar to Pan2; if num-channels > 2, pannins is the
+                  same as PanAz." }
+
+           {:name "envbufnum"
+            :default -1
+            :doc "the buffer number containing a singal to use for the
+                  grain envelope. -1 uses a built-in Hanning envelope."                  }
+
+           {:name "max-grains"
+            :default 512
+            :doc "the maximum number of overlapping grains that can be
+                  used at a given time. This value is set at the UGens
+                  init time and can't be modified. This can be set lower
+                  for more efficient use of memory." }]
+    :rates #{:ar}
+    :check (nth-input-stream? 3)
+    :doc "Granulate an input signal"}

-      {:name "Warp1"
-       :args [{:name "num-channels" :mode :num-outs :default 1 :doc "the number of channels in the soundfile used in bufnum."}
-              {:name "bufnum" :default 0 :doc "the buffer number of a mono soundfile."}
-              {:name "pointer" :default 0 :doc "the position in the buffer.  The value should be between 0 and 1, with 0 being the begining of the buffer, and 1 the end."}
-              {:name "freq-scale" :default 1 :doc "the amount of frequency shift. 1.0 is normal, 0.5 is one octave down, 2.0 is one octave up. Negative values play the soundfile backwards."}
-              {:name "window-size" :default 0.1 :doc "the size of each grain window."}
-              {:name "envbufnum" :default -1 :doc "the buffer number containing a singal to use for the grain envelope. -1 uses a built-in Hanning envelope."}
-              {:name "overlaps" :default 8 :doc "the number of overlaping windows."}
-              {:name "window-rand-ratio" :default 0.0 :doc "the amount of randomness to the windowing function.  Must be between 0 (no randomness) to 1.0 (probably to random actually)"}
-              {:name "interp" :default 1 :doc "the interpolation method used for pitchshifting grains. 1 = no interpolation. 2 = linear. 4 = cubic interpolation (more computationally intensive)."}]
-       :rates #{:ar}
-       :doc "A granular time stretcher and pitchshifter.
+   {:name "Warp1"
+    :args [{:name "num-channels"
+            :mode :num-outs
+            :default 1
+            :doc "the number of channels in the soundfile used in
+                  bufnum." }

-Inspired by Chad Kirby's SuperCollider2 Warp1 class, which was inspired by Richard Karpen's sndwarp for CSound. "}])
+           {:name "bufnum"
+            :default 0
+            :doc "the buffer number of a mono soundfile."}
+
+           {:name "pointer"
+            :default 0
+            :doc "the position in the buffer.  The value should be
+                  between 0 and 1, with 0 being the begining of the
+                  buffer, and 1 the end." }
+
+           {:name "freq-scale"
+            :default 1
+            :doc "the amount of frequency shift. 1.0 is normal, 0.5 is
+                  one octave down, 2.0 is one octave up. Negative values
+                  play the soundfile backwards." }
+
+           {:name "window-size"
+            :default 0.1
+            :doc "the size of each grain window."}
+
+           {:name "envbufnum"
+            :default -1
+            :doc "the buffer number containing a singal to use for the
+                  grain envelope. -1 uses a built-in Hanning envelope." }
+
+           {:name "overlaps"
+            :default 8
+            :doc "the number of overlaping windows."}
+
+           {:name "window-rand-ratio"
+            :default 0.0
+            :doc "the amount of randomness to the windowing function.
+                  Must be between 0 (no randomness) to 1.0 (probably to
+                  random actually)"}
+
+           {:name "interp"
+            :default 1
+            :doc "the interpolation method used for pitchshifting
+                  grains. 1 = no interpolation. 2 = linear. 4 = cubic
+                  interpolation (more computationally intensive)." }]
+    :rates #{:ar}
+    :doc "A granular time stretcher and pitchshifter.
+
+          Inspired by Chad Kirby's SuperCollider2 Warp1 class, which was
+          inspired by Richard Karpen's sndwarp for CSound."}])


Remove scan result for ver3.3 of react-native-ble-manager

--- src/re_natal_esp32control_app/android/core.cljs
+++ src/re_natal_esp32control_app/android/core.cljs
@@ -32,8 +32,8 @@

 (defn ble-scan []
   (-> (.scan BleManager (clj->js []) 30 true)
-      (.then (fn [results]
-               (prn :finished-scan results)))))
+      (.then (fn []
+               (prn :finished-scan)))))

 (defn device-button [device]
   [touchable-highlight


Add a comment on "formatted" vs "extended".

--- src/drake/fs/hive.clj
+++ src/drake/fs/hive.clj
@@ -81,6 +81,8 @@
 (defn table-info [table-path]
   (when (table-exists? table-path)
     (let [{:keys [datasource database table normalized]} (hive-path table-path)
+          ;; note: it has to be "describe formatted" because
+          ;; "describe extended" omits the "transient_lastDdlTime" field.
           sql (format "describe formatted %s.%s" database table)
           meta (jdbc/query datasource [sql])
           [ctime mtime] (parse-metadata meta)]


Adding apple logo to repos we think are osx.

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -116,11 +116,13 @@
             should-build? (repo-model/should-do-first-follower-build? repo)]
         (html
          (cond (repo-model/can-follow? repo)
-               [:li.repo-follow {:class (when (repo-model/likely-osx-repo? repo) "osx")}
+               [:li.repo-follow
                 [:div.proj-name
                  [:span {:title (str (vcs-url/project-name (:vcs_url repo))
                                      (when (:fork repo) " (forked)"))}
-                  (:name repo)]]
+                  (:name repo)]
+                 (when (repo-model/likely-osx-repo? repo)
+                   [:i.fa.fa-apple])]
                 (when building?
                   [:div.building "Starting first build..."])
                 (managed-button
@@ -140,7 +142,9 @@
                 [:div.proj-name
                  [:span {:title (str (vcs-url/project-name (:vcs_url repo))
                                      (when (:fork repo) " (forked)"))}
-                  (:name repo)]
+                  (:name repo)
+                  (when (repo-model/likely-osx-repo? repo)
+                    [:i.fa.fa-apple])]
                  [:a {:id tooltip-id
                       :data-placement "right"
                       :title (str "View " (:name repo) (when (:fork repo) " (forked)") " project")


Definition of groups in ebc.directoy corrected

--- src/ebc/directory.clj
+++ src/ebc/directory.clj
@@ -19,26 +19,26 @@
 #_(set! *warn-on-reflection* true)

 ;; Checking file names
-(defn do-check
-  "Checks the filenames in the ebooks collection in basedir and
-   reports result on stdout."
-  [basedir report-fn]
-  (report-fn (:ver c/ebc-rev))
-  (report-fn (str "Analyzing " basedir " ..."))
-  (loop [books-seq (books basedir), i 1, result ()]
-    (if (empty? books-seq)
-      (do
-        (report-fn (str "Checked " i " eBooks."))
-        (if (empty? result)
-          (report-fn "No errors found.")
-          (do
-            (report-fn "Please check the following files")
-            (doseq [error result]
-              (report-fn "-" error)))))
-      (let [name (:name (first books-seq))]
-        (if (= 0 (rem i 100))
-          (report-fn (str "Analyzing ... "  i " ...")))
-        (recur (rest books-seq) (inc i) (if (ebc-name? name) result (conj result name)))))))
+(defn do-check
+  "Checks the filenames in the ebooks collection in basedir and
+   reports result on stdout."
+  [basedir report-fn]
+  (report-fn (:ver c/ebc-rev))
+  (report-fn (str "Analyzing " basedir " ..."))
+  (loop [books-seq (books basedir), i 1, result ()]
+    (if (empty? books-seq)
+      (do
+        (report-fn (str "Checked " i " eBooks."))
+        (if (empty? result)
+          (report-fn "No errors found.")
+          (do
+            (report-fn "Please check the following files")
+            (doseq [error result]
+              (report-fn "-" error)))))
+      (let [name (:name (first books-seq))]
+        (if (= 0 (rem i 100))
+          (report-fn (str "Analyzing ... "  i " ...")))
+        (recur (rest books-seq) (inc i) (if (ebc-name? name) result (conj result name)))))))

 ;; The following function is used to define the groups for
@@ -56,16 +56,16 @@
   ^{:doc "Groups for the directory of books ordered by authors"}
   author-grps
   [{:caption "Authors, A-E", :flt (make-filter :sort-author (sort-key "0") (sort-key "F")) :html "ebc-a1.html"}
-   {:caption "Authors, F-L", :flt (make-filter :sort-author (sort-key "F") (sort-key "L")) :html "ebc-a2.html"}
-   {:caption "Authors, M-R", :flt (make-filter :sort-author (sort-key "M") (sort-key "R")) :html "ebc-a3.html"}
+   {:caption "Authors, F-L", :flt (make-filter :sort-author (sort-key "F") (sort-key "M")) :html "ebc-a2.html"}
+   {:caption "Authors, M-R", :flt (make-filter :sort-author (sort-key "M") (sort-key "S")) :html "ebc-a3.html"}
    {:caption "Authors, S-Z", :flt (make-filter :sort-author (sort-key "S") (sort-key "ZZ")) :html "ebc-a4.html"}])

 (def
   ^{:doc "Groups for the directory of books ordered by titles"}
   title-grps
   [{:caption "Titles, A-E", :flt (make-filter :sort-title (sort-key "0") (sort-key "F")) :html "ebc-t1.html"}
-   {:caption "Titles, F-L", :flt (make-filter :sort-title (sort-key "F") (sort-key "L")) :html "ebc-t2.html"}
-   {:caption "Titles, M-R", :flt (make-filter :sort-title (sort-key "M") (sort-key "R")) :html "ebc-t3.html"}
+   {:caption "Titles, F-L", :flt (make-filter :sort-title (sort-key "F") (sort-key "M")) :html "ebc-t2.html"}
+   {:caption "Titles, M-R", :flt (make-filter :sort-title (sort-key "M") (sort-key "S")) :html "ebc-t3.html"}
    {:caption "Titles, S-Z", :flt (make-filter :sort-title (sort-key "S") (sort-key "ZZ")) :html "ebc-t4.html"}])

 (def


Tests: updated the param name in a test, it changed upstream.

--- test/clj_http/test/core.clj
+++ test/clj_http/test/core.clj
@@ -426,7 +426,7 @@

 (deftest t-add-client-params
   (testing "Using add-client-params!"
-    (let [ps {"http.connection-manager.timeout" 100
+    (let [ps {"http.conn-manager.timeout" 100
               "http.socket.timeout" 250
               "http.protocol.allow-circular-redirects" false
               "http.protocol.version" HttpVersion/HTTP_1_0


added description for third session

added description for third session

--- src/cljs/work_sessions/components/headers.cljs
+++ src/cljs/work_sessions/components/headers.cljs
@@ -23,8 +23,11 @@
     "This is a digital union of non-material workers, the virtual space of multi-user processing, so try not to distract each other, you can watch someone doing her cognitive work."]
    [:p
     "You can be present with an image of you, you can also share your screen with your current work (On the left side of the screen, click Share screen – a button with a green computer). The sound stays on."]
-   [:p
-    "In this very session we are focusing on improving the infrastructure for work: clean the desktop, install a photoshop that has not been installed for a long time, add a plug-in that has always been lacking, clean e-mail to avoid paying for it, unsubscribe from mailouts that are so many that nothing can be found in the Inbox."]
+   ;;
+   ;; session description
+   ;;
+   [:p
+    "In the third session we are concentrating on back-ups, or rather on what is lost irrevocably, if a computer or a tablet suddenly breaks or a phone is stolen. To get an idea of what exactly you should do, spend a few minutes remembering the data that you have irretrievably lost. These can be texts that once disappeared from the desktop, and their copies were not found. The editing of the video that you have been doing for the whole day was lost when the editing program collapsed one evening, and the file hasn’t been saved. Formatted flash drive with photos from the shooting that you haven’t copied anywhere. Or a broken site due to lost data during a hosting crash."]
    [:p
     (unescapeEntities "The session length is 1 hour, 13.30 — 14.30 Helsinki and Moscow time.")]
    [:p
@@ -73,12 +76,15 @@
    [:p
     "Можешь присутствовать на сессии своим изображением, можешь расшаривать экран со своей работой (кнопка «Показать экран» в меню слева, там изображен зеленый компьютер). Звук оставляешь включенным.
 "]
-   [:p
-    (unescapeEntities "Во второй серии мы фокусируемся на улучшении инфраструктуры для работы: почистить десктоп, установить фотошоп, который давно не получалось установить, добавить плагин, которого всегда не хватало, почистить почту, чтобы не платить за нее, отписаться от навязчивых рассылок, из-за которых ничего не возможно найти в папке "входящие" в почте.")]
-   [:p
-    "Продолжительность сессии – 1 час, с 13.30 до 14.30 по Хельсинки и Москве."]
-   [:p
-    "Следующая сессия будет через неделю – 9 июня в это же время."]
+   ;;
+   ;; session description
+   ;;
+   [:p
+    (unescapeEntities "В третьей сессии мы концентрируемся на бэкапах, точнее на том, что потеряется безвозвратно, если вдруг сломается компьютер или планшет или украдут телефон. Чтобы понять, чем именно вам заняться, проведите несколько минут, вспоминая те данные, которые вы безвозвратно потеряли. Это могут быть тексты, которые однажды пропали с рабочего стола,  а их копий не было. Монтаж видео, который вы делали целый день и который потерялся, когда монтажная программа рухнула под вечер, а файл вы не сохраняли. Отформатированная флешка с фотографиями со съемки, которые вы никуда не скопировали. Или неработающий сайт из-за потерявшихся данных во время сбоя на хостинге.")]
+   [:p
+    (unescapeEntities "Продолжительность сессии — 1 час, с 13.30 до 14.30 по Хельсинки и Москве.")]
+   [:p
+    (unescapeEntities "Следующая сессия будет через неделю — 9 июня в это же время.")]
    [:p
     "Если ты присоединяешься к сессии при помощи компьютера. Открываешь в "
     [:a {:href "https://www.google.com/chrome/"


Add possibility to specify keyspace while building cluster

--- src/clojure/clojurewerkz/cassaforte/client.clj
+++ src/clojure/clojurewerkz/cassaforte/client.clj
@@ -189,15 +189,19 @@

 (defn ^Session connect
   "Connects to a Cassandra cluster"
-  [cluster]
-  (.connect ^Cluster cluster))
+  ([^Cluster cluster]
+     (.connect cluster))
+  ([^Cluster cluster keyspace]
+     (.connect cluster (name keyspace))))

 (defn connect!
   "Connects and sets *default-cluster* and *default-session* for default cluster and session, that
    cql/execute is going to use."
-  [hosts & {:keys [] :as options}]
+  [hosts & {:keys [keyspace] :as options}]
   (let [cluster (build-cluster (assoc options :contact-points hosts))
-        session (connect cluster)]
+        session (if keyspace
+                  (connect cluster keyspace)
+                  (connect cluster))]
     (alter-var-root (var *default-cluster*) (constantly cluster))
     (alter-var-root (var *default-session*) (constantly session))
     session))


CMR-5351: Support instances when log level may be a string.

--- src/cmr/exchange/common/components/logging.clj
+++ src/cmr/exchange/common/components/logging.clj
@@ -14,7 +14,7 @@
 (defn start
   [this]
   (log/info "Starting logging component ...")
-  (let [log-level (config/log-level this)
+  (let [log-level (keyword (config/log-level this))
         log-nss (config/log-nss this)]
     (log/debug "Setting up logging with level" log-level)
     (log/trace "Log config:" (get-in this [:config :data :logging]))


cjl - Read command line args correctly and printing bogus solutions

--- src/icfp2015/core.clj
+++ src/icfp2015/core.clj
@@ -1,13 +1,39 @@
 (ns icfp2015.core
-  (:require [clojure.data.json :as json])
+  (:require [clojure.data.json :as json]
+            [clojure.tools.cli :refer [parse-opts]]
+            [icfp2015.problem :refer [get-games]])
   (:gen-class))

-(defn load-json
-  "Parse JSON problems"
-  [json]
-  (json/read-str json :key-fn keyword))
+(defn get-solution [problem]
+  (let [games (get-games problem)
+        solve (fn [game]
+                { :problemId (:problemId game)
+                  :seed (:seed game)
+                  :solution [""] })]
+    (map solve games)))
+
+(defn read-games-from-file [f]
+  (-> f
+      (slurp)
+      (json/read-str :key-fn keyword)
+      (get-games)))
+
+(defn solve-game [game]
+  { :problemId (:problemId game)
+    :seed (:seed game)
+    :solution [""] })
+
+(def cli-options
+  [["-f" "--file FILE" "Input filename"
+    :id :input-files
+    :default []
+    :assoc-fn (fn [m k v] (update-in m [k] conj v))]])

 (defn -main
   "I don't do a whole lot ... yet."
   [& args]
-  (load-json (last args)))
+  (let [args (parse-opts args cli-options)
+        input-files (get-in args [:options :input-files])
+        games (mapcat read-games-from-file input-files)
+        solutions (map solve-game games)]
+    (println (json/write-str solutions))))


Slight refactoring

Slight refactoring

--- src/joiner/design.clj
+++ src/joiner/design.clj
@@ -3,13 +3,13 @@
   (:use joiner.core)
   (:use joiner.resource))

-(defn- load-view [path]
+(defn- load-files [path files]
   (let [loader-fn (fn[sum value]
 		    (let [file-content (load-resource (str path value ".js"))]
 		      (if (nil? file-content)
 			    sum
 			    (assoc sum (keyword value) file-content))))]
-    (reduce loader-fn {} ["map" "reduce"])))
+    (reduce loader-fn {} files)))

 (defn- remove-view [database design-doc view-name]
   (with-db database
@@ -20,7 +20,8 @@
 (defn update-view [database design-doc view-name]
   "Create or update a new view based on the resources found at
    design-doc/view-name/[map.js reduce.js]"
-  (let [mapreduce (load-view (str design-doc "/views/" view-name "/"))]
+  (let [mapreduce (load-files (str design-doc "/views/" view-name "/")
+			      ["map" "reduce"])]
     (if (empty? mapreduce)
       (remove-view database design-doc view-name)
       (with-db database database


start handling js deps

start handling js deps

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -31,8 +31,10 @@
              [analyze-host-expr :refer [analyze-host-expr]]]
             [clojure.tools.analyzer.js.utils
              :refer [desugar-ns-specs validate-ns-specs ns-resource source-path res-path]]
+            [cljs
+             [tagged-literals :as tags]
+             [js-deps :as deps]]
             [clojure.java.io :as io]
-            [cljs.tagged-literals :as tags]
             [clojure.tools.reader :as reader]
             [clojure.tools.reader.reader-types :as readers])
   (:import cljs.tagged_literals.JSValue)
@@ -54,16 +56,12 @@

 ;; TODO: seed cljs.core/cljs.user
 (defn global-env []
-  (atom '{:namespaces {cljs.user {:mappings       {}
-                                  :aliases        {}
-                                  :macro-mappings {}
-                                  :macro-aliases  {}
-                                  :ns             cljs.user}
-                       cljs.core {:mappings       {}
-                                  :aliases        {}
-                                  :macro-mappings {}
-                                  :macro-aliases  {}
-                                  :ns             cljs.core}}}))
+  (atom {:namespaces          '{cljs.core {:mappings       {}
+                                           :aliases        {}
+                                           :macro-mappings {}
+                                           :macro-aliases  {}
+                                           :ns             cljs.core}}
+         :js-dependency-index (deps/js-dependency-index {})}))

 (defn empty-env
   "Returns an empty env map"
@@ -263,6 +261,7 @@
 (declare analyze-ns)
 (defn ensure-loaded [ns env]
   (or (-> (env/deref-env) :namespaces ns)
+      (-> (env/deref-env) :js-dependency-index (get (name ns)))
       (analyze-ns ns)))

 (defn core-macros []
@@ -282,6 +281,7 @@
                                     m)) {} require)
         require-mappings (reduce (fn [m [ns {:keys [refer]}]]
                                    (ensure-loaded ns env)
+                                   ;; TODO: handle (:require [goog.lib :refer [things]]) ?
                                    (reduce #(assoc %1 %2 (get-in (env/deref-env)
                                                                  [:namespaces ns :mappings %2])) m refer))
                                  {} require)


add case*

add case*

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -42,7 +42,7 @@

 (def specials
   "Set of the special forms for clojurescript"
-  (into ana/specials '#{ns deftype* defrecord* js*}))
+  (into ana/specials '#{ns deftype* defrecord* js* case*}))

 (defmulti parse
   "Extension to tools.analyzer/-parse for CLJS special forms"
@@ -257,6 +257,37 @@
      (when args
        {:args     exprs
         :children [:args]}))))
+
+(defmethod parse 'case*
+  [[_ test tests thens default :as form] env]
+  (assert (symbol? test) "case* must switch on symbol")
+  (assert (every? vector? tests) "case* tests must be grouped in vectors")
+  (let [expr-env (ctx env :expr)
+        test-expr (-analyze test expr-env)
+        nodes (mapv (fn [tests then]
+                      {:op       :case-node
+                       :tests    (mapv (fn [test]
+                                         {:op       :case-test
+                                          :test     (-analyze test expr-env)
+                                          :children [:test]})
+                                       tests)
+                       :then     {:op   :case-then
+                                  :then (-analyze then env)
+                                  :children [:then]}
+                       :children [:tests :then]})
+                    tests thens)
+        default-expr (-analyze default env)]
+    (assert (every? (fn [t] (and (= :const (-> t :test :op))
+                           ((some-fn number? string?) (:form t))))
+               (mapcat :tests nodes))
+            "case* tests must be numbers or strings")
+    {:op       :case
+     :form     form
+     :env      env
+     :test     (assoc test-expr :case-test true)
+     :nodes    nodes
+     :default  default-expr
+     :children [:test :nodes :default]}))

 (declare analyze-ns)
 (defn ensure-loaded [ns env]


remove all sugar in desugar-host-expr

remove all sugar in desugar-host-expr

--- src/main/clojure/clojure/tools/analyzer/js.clj
+++ src/main/clojure/clojure/tools/analyzer/js.clj
@@ -95,48 +95,49 @@
     (when (:macro (meta var))
       var)))

-;; should js/foo and (js/foo) be handled in a separate op?
 (defn desugar-host-expr [form env]
-  (cond
-   (symbol? form)
-   (let [ns (namespace form)]
-     (if (and ns (not= "js" ns) (not (resolve-ns (symbol ns) env)))
-       (with-meta (list '. (symbol ns) (symbol (str "-" (symbol (name form)))))
-         (meta form))
-       form))
-
-   (seq? form)
-   (let [[op & expr] form]
-     (if (symbol? op)
-       (let [opname (name op)
-             opns   (namespace op)
-             op-s   (str op)]
-         (cond
-
-          (= (first opname) \.)
-          (let [[target & args] expr
-                args (list* (symbol (subs opname 1)) args)]
-            (with-meta (list '. target (if (= 1 (count args))
-                                         (first args) args))
-              (meta form)))
-
-          (and opns (not= "js" opns) (not (resolve-ns (symbol opns) env)))
-          (let [target (symbol opns)
-                op (symbol opname)]
-            (with-meta (list '. target (if (zero? (count expr))
-                                         op
-                                         (list* op expr)))
-              (meta form)))
-
-
-          (= (last opname) \.)
-          (with-meta (list* 'new (symbol (subs op-s 0 (dec (count op-s)))) expr)
-            (meta form))
-
-          :else form))
-       form))
-
-   :else form))
+  (-> (cond
+      (symbol? form)
+      (let [ns (namespace form)]
+        (cond
+         (= "js" ns)
+         (list 'js* (name form))
+
+         (and ns (not (resolve-ns (symbol ns) env)))
+         (list '. (symbol ns) (symbol (str "-" (symbol (name form)))))
+
+         :else form))
+
+      (and (seq? form)
+           (symbol? (first form)))
+      (let [[op & expr] form
+            opname (name op)
+            opns   (namespace op)
+            op-s   (str op)]
+        (cond
+
+         (= (first opname) \.)
+         (let [[target & args] expr
+               args (list* (symbol (subs opname 1)) args)]
+           (list '. target (if (= 1 (count args))
+                             (first args) args)))
+
+         (= (last opname) \.)
+         (list* 'new (symbol (subs op-s 0 (dec (count op-s)))) expr)
+
+         (= "js" opns) ;; (js/foo ..) -> ((js* "foo") ..)
+         (list* (list 'js* opname) expr)
+
+         (and opns (not (resolve-ns (symbol opns) env)))
+         (let [target (symbol opns)
+               op (symbol opname)]
+           (list '. target (if (zero? (count expr))
+                             op
+                             (list* op expr))))
+
+         :else form))
+      :else form)
+    (with-meta (meta form))))

 (defn macroexpand-1 [form env]
   (env/ensure (global-env)
@@ -322,7 +323,6 @@
                                     m)) {} require)
         require-mappings (reduce (fn [m [ns {:keys [refer] :as spec}]]
                                    (ensure-loaded ns spec env)
-                                   ;; TODO: handle (:require [goog.lib :refer [things]]) ?
                                    (reduce #(assoc %1 %2 (get-in (env/deref-env)
                                                                  [:namespaces ns :mappings %2])) m refer))
                                  {} require)


No longer fire watermarks on timer tick

No longer fire watermarks on timer tick

--- src/onyx/triggers.clj
+++ src/onyx/triggers.clj
@@ -18,8 +18,6 @@
   {:fire-time s/Int :fire? s/Bool})

 (defn exceeds-watermark? [window upper-extent-bound segment]
-  (prn window)
-  (prn (:window/window-key window) "::" segment)
   (let [watermark (get segment (:window/window-key window))]
     (>= (coerce-key watermark :milliseconds) upper-extent-bound)))

@@ -107,26 +105,20 @@
   (:fire? trigger-state))

 (s/defn watermark-fire?
-  [trigger :- Trigger trigger-state {:keys [upper-bound segment extent window] :as trigger-event}]
-  (prn (keys trigger-event))
-  (prn (:window trigger-event))
-  (prn "--")
+  [trigger :- Trigger trigger-state {:keys [upper-bound event-type segment window] :as trigger-event}]
   ;; If this was stimulated by a new segment, check if it should fire.
   ;; Otherwise if this was a completed task, always fire.
-  (if segment
-    (exceeds-watermark? window upper-bound segment)
-    true))
+  (or (and segment (exceeds-watermark? window upper-bound segment))
+      (= event-type :task-lifecycle-stopped)))

 (s/defn percentile-watermark-fire?
-  [trigger :- Trigger trigger-state {:keys [lower-bound upper-bound segment extent window]} :- StateEvent]
+  [trigger :- Trigger trigger-state {:keys [lower-bound upper-bound event-type segment window]} :- StateEvent]
   ;; If this was stimulated by a new segment, check if it should fire.
   ;; Otherwise if this was a completed task, always fire.
-  (if segment
-    (exceeds-percentile-watermark? window trigger lower-bound upper-bound segment)
-    true))
+  (or (and segment (exceeds-percentile-watermark? window trigger lower-bound upper-bound segment))
+      (= event-type :task-lifecycle-stopped)))

 ;;; Top level vars to bundle the functions together
-
 (def segment
   {:trigger/init-state segment-init-state
    :trigger/next-state segment-next-state


remove log2 fn

remove log2 fn

--- src/overtone/util.clj
+++ src/overtone/util.clj
@@ -322,7 +322,3 @@
    (consecutive-ints? [1 2 3 5 4]) ;=> false"
   [s]
   (apply = (map - (rest s) (seq s))))
-
-(defn log2 [x]
-  (/ (Math/log x)
-     (Math/log 2)))


Add more adaptations to cats 1.0.0 breaking changes.

--- src/promesa/core.cljs
+++ src/promesa/core.cljs
@@ -37,7 +37,7 @@
 (declare promise-context)

 (extend-type js/Promise
-  mp/Context
+  mp/Contextual
   (-get-context [_] promise-context)

   mp/Extract
@@ -205,7 +205,7 @@
 (def ^{:no-doc true}
   promise-context
   (reify
-    mp/ContextClass
+    mp/Context
     (-get-level [_] mc/+level-default+)

     mp/Functor