Error handling and don't process directories with dumb names

--- src/atom_finder/core.clj
+++ src/atom_finder/core.clj
@@ -172,14 +172,24 @@
         exts #{"c" "cc" "cpp" "c++" "h" "hh" "hpp" "h++"}]

     (filter
-     #(exts (nth (re-find #".*\.([^.]+)" (.getName %)) 1 nil))
+     (fn [file]
+       (and
+        (exts (nth (re-find #".*\.([^.]+)" (.getName file)) 1 nil))
+        (.isFile file))
+       )
      files)))

 (comment
+
 (time
- (prn (count (for [filename (map #(.getPath %) (c-files "/Users/dgopstein/opt/src/mono"))]
-     (let [root (translation-unit filename)]
-       (prn [(count (atom-finder.find-atom/macros-in-contexts root)) filename]))))))
+ ; (prn (count (for [filename (map #(.getPath %) (c-files "/Users/dgopstein/opt/src/mono"))]
+ (prn (count (for [filename (map #(.getPath %) (c-files "/Users/dgopstein/opt/src/gcc"))]
+               (try
+                 (let [root (translation-unit filename)]
+                   (prn [(count (atom-finder.find-atom/macros-in-contexts root)) filename]))
+                 (catch Exception e
+                   (printf "-- error parsing file: \"%s\"\n" filename)
+                     ))))))

 )


variable renaming

variable renaming

--- src/babel/morphology.clj
+++ src/babel/morphology.clj
@@ -81,13 +81,13 @@
      (group-by-two (rest (rest remaining))))))

 (defn expand-replace-patterns [unify-with patterns]
-  (mapcat (fn [x]
+  (mapcat (fn [pattern]
             (map (fn [pair]
                    {:u (unify unify-with
-                              (:agr x))
+                              (:agr pattern))
                     :p (:p pair)})
                  (map (fn [p]
                         {:agr :top
                          :p p})
-                      (group-by-two (:p x)))))
+                      (group-by-two (:p pattern)))))
           patterns))


Delete the newly created security group, if any of the configuration requests fail.

--- src/shuppet/securitygroups.clj
+++ src/shuppet/securitygroups.clj
@@ -3,7 +3,8 @@
    [shuppet.aws :refer [ec2-request]]
    [shuppet.util :refer :all]
    [clojure.tools.logging :as log]
-   [clojure.data.zip.xml :refer [xml1-> text xml->]]))
+   [clojure.data.zip.xml :refer [xml1-> text xml->]]
+   [slingshot.slingshot :refer [try+ throw+]]))

 (defn- create-params [opts]
   (without-nils {"GroupName" (:GroupName opts)
@@ -37,7 +38,7 @@

 (defn- build-network-params
   [index opts]
-  (into {} (map #(network-query-params index %1) opts)))
+  (into {} (map #(network-query-params index %) opts)))

 (defn- network-action
   [sg-id opts action]
@@ -61,7 +62,7 @@
   (let [egress (check-default-egress opts)]
     (when-not (empty? egress)
       (network-action sg-id egress :AuthorizeSecurityGroupEgress)
-      (network-action sg-id {:IpRanges "0.0.0.0/0" :IpProtocol "-1"} :RevokeSecurityGroupEgress))))
+      (network-action sg-id (list {:IpRanges "0.0.0.0/0" :IpProtocol "-1"}) :RevokeSecurityGroupEgress))))

 (defn- network-config
   [params]
@@ -114,11 +115,15 @@

 (defn- build-sg
   [opts]
-  (delete-sg (get opts :GroupName))
+  (delete-sg (:GroupName opts))
   (if-let [sg-id (create opts)]
-    (do
-      (configure-network sg-id opts)
-      (log/info "Succesfully created and configured a security group with the config " opts))
+    (try+
+     (do
+       (configure-network sg-id opts)
+       (log/info "Succesfully created and configured a security group with the config " opts))
+     (catch map? error
+       (delete-sg (:GroupName opts))
+       (throw+ error)))
     (log/error "Security group already exists for the config " opts)))

 (defn- filter-params
@@ -138,7 +143,6 @@
   (let [opts (-> opts
                  (assoc :Ingress (flatten (:Ingress opts)))
                  (assoc :Egress (flatten (:Egress opts))))
-        opts (merge {:VpcId @vpc-id} opts)
         response (process :DescribeSecurityGroups (filter-params opts))]
     (if-let [sg-id (xml1-> response :securityGroupInfo :item :groupId text) ]
       (compare-sg sg-id response opts)


remove temporary range array with forloop

20ms -> 10ms for generation at size 325

--- src/sierpinski_sieve/core.cljs
+++ src/sierpinski_sieve/core.cljs
@@ -14,7 +14,7 @@
         next (make-array size)]
     (aset next 0 1)
     (aset next (dec size) 1)
-    (doseq [x (range 1 (dec size))]
+    (forloop [(x 1) (< x (dec size)) (inc x)]
       (let [before (aget row (dec x))
             above (aget row x)]
         (aset next x (mod (+ before above) modulus))))


Failed BookKeeper writes now reboot the peer #390

Also closes #500 by improving performance of write-take-batch

--- src/onyx/state/log/bookkeeper.clj
+++ src/onyx/state/log/bookkeeper.clj
@@ -2,7 +2,8 @@
   (:require [onyx.log.curator :as curator]
             [taoensso.timbre :refer [info error warn trace fatal] :as timbre]
             [com.stuartsierra.component :as component]
-            [clojure.core.async :refer  [chan timeout thread go >! <! <!! >!! alts!! close!]]
+            [clojure.core.async :refer [chan timeout thread go >! <! <!! >!! alts!! close! poll!]]
+            [clojure.core.async.impl.protocols :refer [closed?]]
             [onyx.compression.nippy :as nippy]
             [onyx.extensions :as extensions]
             [onyx.monitoring.measurements :refer [emit-latency-value emit-latency]]
@@ -63,11 +64,11 @@

 (def HandleWriteCallback
   (reify AsyncCallback$AddCallback
-    (addComplete [this rc lh entry-id ack-fn]
+    (addComplete [this rc lh entry-id [success-fn fail-fn]]
       (if (= rc (BKException$Code/OK))
-        (ack-fn)
-        ;; TODO: should restart peer, see https://github.com/onyx-platform/onyx/issues/390
-        (warn "Unable to complete async write to bookkeeper. BookKeeper exception code:" rc)))))
+        (success-fn)
+        (do (warn "Unable to complete async write to bookkeeper. BookKeeper exception code:" rc)
+            (fail-fn))))))

 (defn compaction-transition
   "Transitions to a new compacted ledger, plus a newly created ledger created
@@ -107,56 +108,51 @@
           (.asyncAddEntry compacted-ledger
                           compacted-serialized
                           HandleWriteCallback
-                          (fn []
-                            (close-handle previous-handle)
-                            (emit-latency-value :window-log-compaction monitoring (- (System/currentTimeMillis) start-time))
-                            (>!! outbox-ch
-                                 {:fn :compact-bookkeeper-log-ids
-                                  :args {:job-id job-id
-                                         :task-id task-id
-                                         :slot-id slot-id
-                                         :peer-id id
-                                         :prev-ledger-ids (vec (butlast current-ids))
-                                         :new-ledger-ids [compacted-ledger-id]}}))))))))
-
-(defn ch->type [ch batch-ch timeout-ch kill-ch task-kill-ch]
-  (cond (= ch timeout-ch)
-        :timeout
-        (or (= ch kill-ch) (= ch task-kill-ch))
-        :shutdown
-        :else
-        :read))
-
-(defn take-write-batch [peer-opts batch-ch kill-ch task-kill-ch]
-  (let [batch-size (arg-or-default :onyx.bookkeeper/write-batch-size peer-opts)
-        timeout-ms (arg-or-default :onyx.bookkeeper/write-batch-timeout peer-opts)
-        timeout-ch (timeout timeout-ms)]
-    (loop [entries [] ack-fns [] i 0]
-      (if (< i batch-size)
-        (let [[[entry ack-fn] ch] (alts!! [kill-ch task-kill-ch batch-ch timeout-ch] :priority true)]
-          (if entry
-            (recur (conj entries entry)
-                   (conj ack-fns ack-fn)
-                   (inc i))
-            (let [msg-type (ch->type ch batch-ch timeout-ch kill-ch task-kill-ch)]
-              [msg-type entries ack-fns])))
-        [:read entries ack-fns]))))
-
-(defn process-batches [{:keys [ledger-handle next-ledger-handle batch-ch] :as log}
+                          (list (fn []
+                                  (close-handle previous-handle)
+                                  (emit-latency-value :window-log-compaction monitoring (- (System/currentTimeMillis) start-time))
+                                  (>!! outbox-ch
+                                       {:fn :compact-bookkeeper-log-ids
+                                        :args {:job-id job-id
+                                               :task-id task-id
+                                               :slot-id slot-id
+                                               :peer-id id
+                                               :prev-ledger-ids (vec (butlast current-ids))
+                                               :new-ledger-ids [compacted-ledger-id]}}))
+                                (fn []
+                                  (close! (:onyx.core/restart-ch event))))))))))
+
+(defn take-write-batch [batch-size batch-ch]
+  (loop [entries [] ack-fns [] i 0]
+    (if (< i batch-size)
+      (let [[entry ack-fn] (poll! batch-ch)]
+        (if entry
+          (recur (conj entries entry)
+                 (conj ack-fns ack-fn)
+                 (inc i))
+          [entries ack-fns]))
+      [entries ack-fns])))
+
+(defn process-batches [{:keys [ledger-handle next-ledger-handle batch-ch] :as log}
                        {:keys [onyx.core/kill-ch onyx.core/task-kill-ch onyx.core/peer-opts] :as event}]
-  (thread
-    (loop [[result batch ack-fns] (take-write-batch peer-opts batch-ch kill-ch task-kill-ch)]
-      ;; Safe point to transition to the next ledger handle
-      (when @next-ledger-handle
-        (compaction-transition log event))
-      (when-not (empty? batch)
-        (.asyncAddEntry ^LedgerHandle @ledger-handle
-                        ^bytes (nippy/window-log-compress batch)
-                        HandleWriteCallback
-                        (fn [] (run! (fn [f] (f)) ack-fns))))
-      (if-not (= :shutdown result)
-        (recur (take-write-batch peer-opts batch-ch kill-ch task-kill-ch))))
-    (info "BookKeeper: shutting down batch processing")))
+  (thread
+    (let [batch-size (arg-or-default :onyx.bookkeeper/write-batch-size peer-opts)
+          batch-backoff (arg-or-default :onyx.bookkeeper/write-batch-backoff peer-opts)]
+      (loop [[batch ack-fns] (take-write-batch batch-size batch-ch)]
+        ;; Safe point to transition to the next ledger handle
+        (when @next-ledger-handle
+          (compaction-transition log event))
+        (if (empty? batch)
+          (Thread/sleep batch-backoff)
+          (.asyncAddEntry ^LedgerHandle @ledger-handle
+                          ^bytes (nippy/window-log-compress batch)
+                          HandleWriteCallback
+                          (list (fn [] (run! (fn [f] (f)) ack-fns))
+                                (fn [] (close! (:onyx.core/restart-ch event))))))
+        (if (and (not (closed? kill-ch))
+                 (not (closed? task-kill-ch)))
+          (recur (take-write-batch batch-size batch-ch)))))
+          (info "BookKeeper: shutting down batch processing")))

 (defn assign-bookkeeper-log-id-spin [{:keys [onyx.core/peer-opts
                                              onyx.core/job-id onyx.core/task-id
@@ -170,10 +166,16 @@
                  :task-id task-id
                  :slot-id slot-id
                  :ledger-id new-ledger-id}})
-    (while (and (first (alts!! [kill-ch task-kill-ch] :default true))
-                (not= new-ledger-id (last (event->ledger-ids event))))
-      (info "New ledger id has not been published yet. Backing off.")
-      (Thread/sleep (arg-or-default :onyx.bookkeeper/ledger-id-written-back-off peer-opts)))))
+    (loop []
+      (let [exit? (nil? (first (alts!! [kill-ch task-kill-ch] :default true)))
+            not-added? (not= new-ledger-id (last (event->ledger-ids event)))]
+        (cond exit?
+              (info "Exiting assign-bookkeeper-log-id-spin early as peer has been reassigned.")
+              not-added?
+              (do
+                (info "New ledger id has not been published yet. Backing off.")
+                (Thread/sleep (arg-or-default :onyx.bookkeeper/ledger-id-written-back-off peer-opts))
+                (recur)))))))

 (defmethod state-extensions/initialize-log :bookkeeper [log-type {:keys [onyx.core/peer-opts] :as event}]
   (let [bk-client (bookkeeper peer-opts)
@@ -268,7 +270,8 @@
 (defmethod state-extensions/close-log onyx.state.log.bookkeeper.BookKeeperLog
   [{:keys [client ledger-handle next-ledger-handle]} event]
   (try
-    (close-handle @ledger-handle)
+    (when @ledger-handle
+      (close-handle @ledger-handle))
     (when @next-ledger-handle
       (close-handle @next-ledger-handle))
     (catch Throwable t


[#11173] Open profile on tapping self mention

--- src/status_im/chat/models.cljs
+++ src/status_im/chat/models.cljs
@@ -289,7 +289,7 @@
   [{:keys [db] :as cofx} identity]
   (let [my-public-key (get-in db [:multiaccount :public-key])]
     (if (= my-public-key identity)
-      (navigation/navigate-to-cofx cofx :my-profile nil)
+      (navigation/navigate-to-cofx cofx :profile-stack {:screen :my-profile})
       (fx/merge
        cofx
        {:db (assoc db :contacts/identity identity)}


Fix check task to work with multiple source directories

--- src/cake/tasks/check.clj
+++ src/cake/tasks/check.clj
@@ -13,7 +13,9 @@
                                            read-file-ns-decl]]
               [bake.nsdeps :only [deps-from-ns-decl]]) []
               (binding [*warn-on-reflection* true]
-                (doseq [src-file (find-clojure-sources-in-dir (:source-path *project*))]
+                (doseq [src-file (mapcat #(find-clojure-sources-in-dir
+                                           (java.io.File. %))
+                                         (:source-path *project*))]
                   (let [depends-on-cake-core?
                         (fn [ns-decl]
                           (contains? (deps-from-ns-decl ns-decl) 'cake.core))


Permit (:builds (:cljsbuild project)) to be a list.

When the builds collection is part of a composite profile[1], it may be
a list instead of a vector. This is probably a bug in Leiningen, and I
have reported it[2], but this commit provides a trivial workaround:
apply `mapv` to the builds collection whether it is a vector or a seq.
The result becomes a vector.

[1] https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#composite-profiles
[2] https://github.com/technomancy/leiningen/issues/2119

--- plugin/src/leiningen/doo.clj
+++ plugin/src/leiningen/doo.clj
@@ -77,7 +77,8 @@
                   (update-in [:compiler] correct-main)))
           builds)

-        (vector? builds) (mapv #(update-in % [:compiler] correct-main) builds)
+        (or (vector? builds) (seq? builds))
+        (mapv #(update-in % [:compiler] correct-main) builds)

         :else (throw (Exception. ":cljsbuild :builds needs to be either a vector or a map"))))))


fix arity

fix arity

--- src/clj/bulldog/core.clj
+++ src/clj/bulldog/core.clj
@@ -98,7 +98,7 @@
     state))

 (defn -main [& args]
-  (start-all-services (or (Integer/parseInt (System/getenv "PORT")) 8080))
+  (start-all-services (or (Integer/parseInt (System/getenv "PORT")) 8080) "bamboozle")
   (println "Server startet at localhost:8080"))

 (comment


better describe for s/+

better describe for s/+

--- src/clj/clojure/spec.clj
+++ src/clj/clojure/spec.clj
@@ -1001,7 +1001,7 @@
 (defn- accept? [{:keys [::op]}]
   (= ::accept op))

-(defn- pcat* [{[p1 & pr :as ps] :ps,  [k1 & kr :as ks] :ks, [f1 & fr :as forms] :forms, ret :ret}]
+(defn- pcat* [{[p1 & pr :as ps] :ps,  [k1 & kr :as ks] :ks, [f1 & fr :as forms] :forms, ret :ret, rep+ :rep+}]
   (when (every? identity ps)
     (if (accept? p1)
       (let [rp (:ret p1)
@@ -1009,7 +1009,7 @@
         (if pr
           (pcat* {:ps pr :ks kr :forms fr :ret ret})
           (accept ret)))
-      {::op ::pcat, :ps ps, :ret ret, :ks ks, :forms forms})))
+      {::op ::pcat, :ps ps, :ret ret, :ks ks, :forms forms :rep+ rep+})))

 (defn- pcat [& ps] (pcat* {:ps ps :ret []}))

@@ -1032,7 +1032,7 @@
 (defn ^:skip-wiki rep+impl
   "Do not call this directly, use '+'"
   [form p]
-  (pcat* {:ps [p (rep* p p [] true form)] :forms `[~form (* ~form)] :ret []}))
+  (pcat* {:ps [p (rep* p p [] true form)] :forms `[~form (* ~form)] :ret [] :rep+ form}))

 (defn ^:skip-wiki amp-impl
   "Do not call this directly, use '&'"
@@ -1139,15 +1139,17 @@
             ::alt (alt* (map #(deriv % x) ps) ks forms)
             ::rep (rep* (deriv p1 x) p2 ret splice forms)))))

-(defn- op-describe [p]
-  ;;(prn {:op op :ks ks :forms forms})
-  (let [{:keys [::op ps ks forms splice p1] :as p} (reg-resolve p)]
+(defn- op-describe [p]
+  (let [{:keys [::op ps ks forms splice p1 rep+] :as p} (reg-resolve p)]
+    ;;(prn {:op op :ks ks :forms forms :p p})
     (when p
       (case op
             ::accept nil
             nil p
             ::amp (list* 'clojure.spec/& (op-describe p1) forms)
-            ::pcat (cons `cat (mapcat vector ks forms))
+            ::pcat (if rep+
+                     (list `+ rep+)
+                     (cons `cat (mapcat vector ks forms)))
             ::alt (cons `alt (mapcat vector ks forms))
             ::rep (list (if splice `+ `*) forms)))))


Remove commented line and rename function

--- src/clj/notes/server.clj
+++ src/clj/notes/server.clj
@@ -24,11 +24,10 @@
   (resources "/react" {:root "react"})
   (files "/" {:root "resources/public"}))

-(defn logging [chain] (fn [req] (do (println (str "REQUEST: " req)) (chain req))))
+(defn logging-middleware [chain] (fn [req] (do (println (str "REQUEST: " req)) (chain req))))

 (def http-handler
   (if is-dev?
-    ;(reload/wrap-reload (api #'routes))
     (-> routes wrap-edn-params)
     (api routes)))


Add viewport

Add viewport

--- src/cljs/gtfve/core.cljs
+++ src/cljs/gtfve/core.cljs
@@ -8,11 +8,37 @@
     (:import goog.History))

 ;; -------------------------
+;; Maps
+
+(defonce Maps google.maps)
+
+(defonce map-types (js->clj Maps.MapTypeId :keywordize-keys true))
+
+(defonce default-opts {:center {:lat 14.653386
+                            :lng 121.032520}
+                   :mapTypeId (:ROADMAP map-types)
+                   :zoom 15})
+
+(defonce gmap (atom nil))
+
+;; -------------------------
 ;; Views

+(defn viewport
+  "Component to show google map"
+  []
+  (reagent/create-class
+   {:component-did-mount (fn [this]
+                           (let [opts default-opts
+                                 node (.getDOMNode this)]
+                             (reset! gmap (Maps.Map. node (clj->js opts)))))
+    :component-function (fn [] [:div {:id :map-canvas
+                                      :style {:height "100%"
+                                              :margin 0
+                                              :padding 0}}])}))
+
 (defn home-page []
-  [:div [:h2 "Welcome to gtfve"]
-   [:div [:a {:href "#/about"} "go to about page"]]])
+  [:div [viewport]])

 (defn about-page []
   [:div [:h2 "About gtfve"]


allow creating a timbre logger with an existing client

--- src/yeller_timbre_appender.clj
+++ src/yeller_timbre_appender.clj
@@ -1,5 +1,10 @@
 (ns yeller-timbre-appender
   (:require [yeller-clojure-client :as yeller-client]))
+
+(defn create-client [options]
+  (if-let [client (:yeller/client options)]
+    client
+    (yeller-client/client options)))

 (defn extract-data [throwable]
   (if-let [data (ex-data throwable)]
@@ -10,7 +15,12 @@
   "Create a Yeller timbre appender.
    (make-yeller-appender {:token \"YOUR API TOKEN HERE\"})
    Required options:
+     either:
      :token \"your api token here\"
+     OR
+     :yeller/client an-existing-yeller-client
+   The second option is for when you already use yeller somewhere else and
+   only want one client in the codebase.
    Optional:
      :environment \"production\" ; the name of the environment the app runs in
   (note that exceptions reported in \"development\" or \"test\" environments
@@ -21,10 +31,10 @@
     {:token \"your token here\"})"
   ([options] (make-yeller-appender {} options))
   ([timbre-options options]
-   (assert (string? (:token options)) "make-yeller-appender requires a token")
+   (assert (or (string? (:token options))
+               (:yeller/client options)) "make-yeller-appender requires a :token or a :yeller/client")
    (let [with-default (merge {:environment "production"} options)
-         client (yeller-client/client options)]
-
+         client (create-client with-default)]
      (merge
        {:doc "A timbre appender that sends errors to yellerapp.com"
         :min-level :warn


more eval-str tests

more eval-str tests

--- src/test/cljs/self_host/test.cljs
+++ src/test/cljs/self_host/test.cljs
@@ -69,7 +69,7 @@

 (deftest test-eval-str
   (async done
-    (let [l (latch 4 done)]
+    (let [l (latch 6 done)]
       (cljs/eval-str st "(+ 1 1)" nil
         {:eval node-eval}
         (fn [{:keys [error value]}]
@@ -99,9 +99,28 @@
         (fn [{:keys [error value]}]
           (is (nil? error))
           (is (== 3))
+          (inc! l)))
+      (cljs/eval-str st "(ns foo.bar)" nil
+        {:eval node-eval
+         :context :expr
+         :def-emits-var true}
+        (fn [{:keys [error value]}]
+          (is (nil? error))
+          (is (not (nil? js/foo.bar)))
+          (inc! l)))
+      (cljs/eval-str st "(defn foo [a b] (+ a b))" nil
+        {:eval node-eval
+         :context :expr
+         :def-emits-var true}
+        (fn [{:keys [error value]}]
+          (is (nil? error))
+          (is (== (js/cljs.user.foo 1 2) 3))
           (inc! l))))))

 (defn -main [& args]
   (run-tests))

 (set! *main-cli-fn* -main)
+
+(comment
+  )


DRYing up test assertions

DRYing up test assertions

--- test/aeolian/composer_test.clj
+++ test/aeolian/composer_test.clj
@@ -37,11 +37,13 @@
              (notes-in-measure "Foo.java#1 LL=30 CC=5") => (contains t/prefix)
              (notes-in-measure "Foo.java#1 LL=30 CC=3") => (contains t/prefix))

+       (defn- measure-for [metrics key] (c/metrics-to-measure [metrics] key "" "" 1))
+
        (fact "method-length is mapped to accompanying chord"
-             (str/index-of (c/metrics-to-measure ["Foo.java#1 LL=30 ML=1"] k/major "" "" 1) "\"C\"") => truthy
-             (str/index-of (c/metrics-to-measure ["Foo.java#1 LL=30 ML=10"] k/major "" "" 1) "\"Dm\"") => truthy
-             (str/index-of (c/metrics-to-measure ["Foo.java#1 LL=30 ML=5"] k/minor "" "" 1) "\"Cm\"") => truthy
-             (str/index-of (c/metrics-to-measure ["Foo.java#1 LL=30 ML=11"] k/minor "" "" 1) "\"_E\"") => truthy))
+             (measure-for "Foo.java#1 LL=30 ML=1" k/major) => (contains "\"C\"")
+             (measure-for "Foo.java#1 LL=30 ML=10" k/major) => (contains "\"Dm\"")
+             (measure-for "Foo.java#1 LL=30 ML=5" k/minor) => (contains "\"Cm\"")
+             (measure-for "Foo.java#1 LL=30 ML=11" k/minor) => (contains "\"_E\"")))

 (facts "when opening metrics files"
        (fact "all lines are used in composition"


fix imports

fix imports

--- test/bifurcan/durable_test.clj
+++ test/bifurcan/durable_test.clj
@@ -24,6 +24,8 @@
    [io.lacuna.bifurcan.encodings
     SelfDescribing]
    [io.lacuna.bifurcan.durable.blocks
+    HashMap
+    HashMap$MapEntry
     HashTable
     HashTable$Entry
     HashTable$Writer
@@ -32,9 +34,6 @@
     SkipTable$Reader
     SkipTable$Writer
     SkipTable$Entry]
-   [io.lacuna.bifurcan.durable.collections
-    HashMap
-    HashMap$MapEntry]
    [io.lacuna.bifurcan.durable
     Util
     BlockPrefix


Add other test case for authorization middleware.

--- test/buddy/test_buddy_auth.clj
+++ test/buddy/test_buddy_auth.clj
@@ -48,4 +48,13 @@
           handler (wrap-authorization handler backend)
           req     (make-request "user" "pass")
           resp    (handler req)]
-      (is (= (:status resp) 401)))))
+      (is (= (:status resp) 401)))
+    (let [backend (http-basic-backend :realm "Foo" :authfn auth-fn)
+          handler (fn [req] (if (nil? (:identity req))
+                              (throw-notauthorized {:msg "FooMsg"})
+                              req))
+          handler (wrap-authentication handler backend)
+          handler (wrap-authorization handler backend)
+          req     (make-request "foo" "pass")
+          resp    (handler req)]
+      (is (= (:identity resp) :foo)))))


Create LeanMap dissoc tests

Create LeanMap dissoc tests

--- test/clojure/lean_map/test.clj
+++ test/clojure/lean_map/test.clj
@@ -22,6 +22,13 @@
   (t/is (= :bar1 (-> lmu/empty transient (assoc! :key70327 :bar1 :key101439 :bar2) persistent! (get :key70327))))
   (t/is (= :bar2 (-> lmu/empty transient (assoc! :key70327 :bar1 :key101439 :bar2) persistent! (get :key101439)))))

+(t/deftest dissoc-operations
+  (t/is (= [:foo1] (-> lmu/empty (assoc :foo :bar :foo1 :bar1) (dissoc :foo) keys vec))))
+
+(t/deftest dissoc-operations-with-hash-collisions
+  (t/is (= [:key101439] (-> lmu/empty (assoc :key70327 :bar1 :key101439 :bar2) (dissoc :key70327) keys vec)))
+  (t/is (= :bar2 (-> lmu/empty (assoc :key70327 :bar1 :key101439 :bar2) (dissoc :key70327) (get :key101439 :bar0)))))
+
 (t/deftest hash-map-operations
   (t/is (= (lmu/hash-map :foo :bar) (-> lmu/empty (assoc :foo :bar))))
   (t/is (= :bar (-> (lmu/hash-map :foo :bar) (get :foo)))))


Code cleanup

Code cleanup

--- test/integration/system_itest.clj
+++ test/integration/system_itest.clj
@@ -1,40 +1,35 @@
 (ns integration.system-itest
   (:require [midje.sweet :refer :all]
-            [ruuvi.test-util :as test-util :refer :all]
-            )
-  )
-
+            [ruuvi.test-util :as test-util :refer :all]))

 (fact "System can start and stop."
       (init-system "test/data/system-config.edn")

       (fact "Before starting contains components"
-            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler] :gaps-ok :in-any-order)
-            )
+            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler]
+                                                 :gaps-ok :in-any-order))

       (start-system)
       (fact "Started system contains components"
-            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler] :gaps-ok :in-any-order)
-            )
+            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler]
+                                                 :gaps-ok :in-any-order))
       (fact "Started server responds to PING"
             (get-url "/meta/ping") => (contains {:server "RuuviServer", :version "0.0.1"}))

       (stop-system)
       (fact "Stopped system contains components"
-            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler] :gaps-ok :in-any-order)
-            )
+            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler]
+                                                 :gaps-ok :in-any-order))

       (start-system)
       (fact "System can start after stopping"
-            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler] :gaps-ok :in-any-order)
-            )
+            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler]
+                                                 :gaps-ok :in-any-order))
       (fact "Re-started server responds to PING"
             (get-url "/meta/ping") => (contains {:server "RuuviServer", :version "0.0.1"}))

       (stop-system)
       (fact "Re started system can stop"
-            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler] :gaps-ok :in-any-order)
-            )
-
+            (keys test-util/system) => (contains [:db :http-server :nrepl-server :ring-handler]
+                                                 :gaps-ok :in-any-order))
       )
-


Fix partition from-records test references.

--- test/merkle_db/partition_test.clj
+++ test/merkle_db/partition_test.clj
@@ -62,14 +62,14 @@
         k2 (key/create [2 3 4])
         k3 (key/create [3 4 5])
         k4 (key/create [4 5 6])
-        [part] (part/from-records
-                 store
-                 {::record/families {:ab #{:a :b}, :cd #{:c :d}}}
-                 {k0 {:x 0, :y 0, :a 0, :c 0}
-                  k1 {:x 1, :c 1, :d 1, }
-                  k2 {:b 2, :c 2}
-                  k3 {:x 3, :y 3, :a 3, :b 3}
-                  k4 {:z 4, :d 4}})]
+        part (part/from-records
+               store
+               {::record/families {:ab #{:a :b}, :cd #{:c :d}}}
+               {k0 {:x 0, :y 0, :a 0, :c 0}
+                k1 {:x 1, :c 1, :d 1, }
+                k2 {:b 2, :c 2}
+                k3 {:x 3, :y 3, :a 3, :b 3}
+                k4 {:z 4, :d 4}})]
     (testing "partition construction"
       (is (= 5 (::record/count part)))
       (is (= k0 (::record/first-key part)))
@@ -94,7 +94,7 @@
     [[field-keys families records] mdgen/data-context]
     (is (valid? ::record/families families))
     (let [store (mdag/init-store :types record/codec-types)
-          [part] (part/from-records store {::record/families families} records)
+          part (part/from-records store {::record/families families} records)
           tablets (into {}
                         (map (juxt key #(mdag/get-data store (val %))))
                         (::part/tablets part))]


Add real linear regression tests

Add real linear regression tests

These should be a 1:1 Python->Clojure translation of the lin reg
examples at https://www.tensorflow.org/get_started/get_started

--- test/tensorflow_clj/core_test.clj
+++ test/tensorflow_clj/core_test.clj
@@ -70,3 +70,40 @@
                             :b [[1. 2.] [3. 4.]]}
                   :mul)]
         (is (= v [[1. -2.] [6. -8.]]))))))
+
+(def x-train [1.  2.  3.  4.])
+(def y-train [0. -1. -2. -3.])
+
+(deftest linreg-one-pass
+  (testing "Linear regression (one pass)"
+    (with-graph-file "misc/linreg.pb"
+      (run-graph {:init nil})
+      (let [[[a b c d]] (run-graph {:x x-train} :linear_model)]
+        (is (approx= 0.0 a))
+        (is (approx= 0.3 b))
+        (is (approx= 0.6 c))
+        (is (approx= 0.9 d))))))
+
+(deftest linreg-one-loss
+  (testing "Linear regression (one loss)"
+    (with-graph-file "misc/linreg.pb"
+      (run-graph {:init nil})
+      (let [[loss] (run-graph {:x x-train :y y-train} :loss)]
+        (is (approx= 23.66 loss))))))
+
+(deftest linreg-fixed-vars
+  (testing "Linear regression (fixed variables)"
+    (with-graph-file "misc/linreg.pb"
+      (run-graph {:fixW nil :fixb nil})
+      (let [[loss] (run-graph {:x x-train :y y-train} :loss)]
+        (is (approx= 0.0 loss))))))
+
+(deftest linreg-graph-iterations
+  (testing "Linear regression (1000 iterations)"
+    (with-graph-file "misc/linreg.pb"
+      (run-graph {:init nil})
+      (dotimes [i 1000]
+        (run-graph {:x x-train :y y-train :train nil}))
+      (let [[[W] [b]] (run-graph {} :W :b)]
+        (is (approx= -0.9999 W))
+        (is (approx= 0.99999 b))))))


fill in desc and url

fill in desc and url

--- frontend/project.clj
+++ frontend/project.clj
@@ -1,6 +1,6 @@
 (defproject leftover "0.1.0-SNAPSHOT"
-  :description "FIXME: write this!"
-  :url "http://example.com/FIXME"
+  :description "This is a little app to keep track of how much money is left over."
+  :url "https://github.com/justone/leftovers"

   :license {:name "MIT"
             :url "http://opensource.org/licenses/MIT"}


Add unit test for block wrapping.

Add unit test for block wrapping.

--- test/blocks/block_test.clj
+++ test/blocks/block_test.clj
@@ -65,6 +65,9 @@
         loaded (data/read-block :sha1 content)
         lazy (data/lazy-block
                (:id loaded) (:size loaded)
-               #(bytes/to-input-stream (.getBytes content)))]
+               #(bytes/to-input-stream (.getBytes content)))
+        wrapped (data/wrap-block loaded (constantly ::wrapped))]
     (is (data/loaded? loaded))
-    (is (not (data/loaded? lazy)))))
+    (is (not (data/loaded? lazy)))
+    (is (= loaded wrapped))
+    (is (not (data/loaded? wrapped)))))


[Add] _print-exp-data

[Add] _print-exp-data

--- test/clj_elm/core_test.clj
+++ test/clj_elm/core_test.clj
@@ -154,6 +154,15 @@
     (select-count #(= % 1) (:classes (DataSet. [1 1 -1 -1] [[1 1] [1 1] [1 1] [1 1]])))
     => 2))

+(facts "test-_print-exp-data"
+  (fact "(_print-exp-data exp)"
+    (_print-exp-data {:L 10
+                      :length-train-negative 10 :length-train-positive 10
+                      :length-test-negative 10 :length-test-positive 10
+                      :TP 10 :FP 10 :TN 10 :FN 10
+                      :Accuracy 1/2 :Recall 1/2 :Precision 1/2})
+    => "L:10\n length(train_negative): 10\n length(test_negative): 10\n length(train_positive): 10\n length(test_positive): 10\n TP: 10, FP: 10, TN: 10, FN: 10\n Accuracy: 1/2,Recall: 1/2,Precision: 1/2\n\n"))
+
 (facts "test-+-exp"
   (fact "(+-exp exp1 exp2)"
     (+-exp {:L 500


Update tests

Update tests

--- test/cljam/io/wig_test.clj
+++ test/cljam/io/wig_test.clj
@@ -1,6 +1,7 @@
 (ns cljam.io.wig-test
   (:require [clojure.test :refer :all]
             [clojure.java.io :as cio]
+            [clojure.string :as cstr]
             [cljam.test-common :refer :all]
             [cljam.io.wig :as wig]
             [cljam.util :as util])
@@ -25,21 +26,6 @@
     (.toString bao)))

 (deftest reader
-  (testing "read wig"
-    (is (= (str->wig "variableStep chrom=chr1 span=10\n1 1\n100 2")
-           [{:format :variable-step
-             :chrom "chr1"
-             :span 10
-             :values [{:start 1 :value 1}
-                      {:start 100 :value 2}]}]))
-    (is (= (str->wig "fixedStep chrom=chr1 start=1 step=20 span=10\n1\n2")
-           [{:format :fixed-step
-             :chrom "chr1"
-             :start 1
-             :step 20
-             :span 10
-             :values [1 2]}])))
-
   (testing "make reader instance"
     (with-open [rdr (wig/reader test-wig-file1)]
       (is (instance? cljam.io.wig.WIGReader rdr))))
@@ -47,54 +33,76 @@
   (testing "throw Exception"
     (is (thrown? Exception (wig/reader "test-resources/wig/not-found.wig"))))

-  (testing "read wig with default span value"
-    (is (= (str->wig "variableStep chrom=chr1\n1 0\n100 1")
-           [{:format :variable-step
-             :chrom "chr1"
-             :span 1
-             :values [{:start 1 :value 0}
-                      {:start 100 :value 1}]}]))
-    (is (= (str->wig "fixedStep chrom=chr1 start=1 step=20\n1\n2")
-           [{:format :fixed-step
-             :chrom "chr1"
-             :start 1
-             :step 20
-             :span 1
-             :values [1 2]}])))
+  (testing "read wig"
+    (is (= (str->wig "variableStep chrom=chr1 span=10\n1 1\n101 2")
+           [{:format :variable-step :chrom "chr1" :start 1 :end 10 :value 1}
+            {:format :variable-step :chrom "chr1" :start 101 :end 110 :value 2}]))
+    (is (= (str->wig "fixedStep chrom=chr1 start=1 step=20 span=10\n1\n2")
+           [{:format :fixed-step :chrom "chr1" :start 1 :end 10 :value 1}
+            {:format :fixed-step :chrom "chr1" :start 21 :end 30 :value 2}])))
+
+  (testing "read wig with default span value for variableStep"
+    (is (= (str->wig "variableStep chrom=chr1\n1 1\n101 2")
+           [{:format :variable-step :chrom "chr1" :start 1 :end 1 :value 1}
+            {:format :variable-step :chrom "chr1" :start 101 :end 101 :value 2}])))
+
+  (testing "read wig with default span and step value for fixedStep"
+    (is (= (str->wig "fixedStep chrom=chr1 start=1\n1\n2")
+           [{:format :fixed-step :chrom "chr1" :start 1 :end 1 :value 1}
+            {:format :fixed-step :chrom "chr1" :start 2 :end 2 :value 2}])))
+
+  (testing "read wig with continuous same formats"
+    (let [s (cstr/join \newline ["variableStep chrom=chr19 span=5"
+                                 "1 1"
+                                 "11 10"
+                                 "variableStep chrom=chr19 span=10"
+                                 "101 1"
+                                 "111 10"])]
+      (is (= (str->wig s)
+             [{:format :variable-step :chrom "chr19" :start 1 :end 5 :value 1}
+              {:format :variable-step :chrom "chr19" :start 11 :end 15 :value 10}
+              {:format :variable-step :chrom "chr19" :start 101 :end 110 :value 1}
+              {:format :variable-step :chrom "chr19" :start 111 :end 120 :value 10}])))
+    (let [s (cstr/join \newline ["fixedStep chrom=chr19 start=1 step=10 span=5"
+                                 "1"
+                                 "10"
+                                 "fixedStep chrom=chr19 start=101 step=10 span=10"
+                                 "1"
+                                 "10"])]
+      (is (= (str->wig s)
+             [{:format :fixed-step :chrom "chr19" :start 1 :end 5 :value 1}
+              {:format :fixed-step :chrom "chr19" :start 11 :end 15 :value 10}
+              {:format :fixed-step :chrom "chr19" :start 101 :end 110 :value 1}
+              {:format :fixed-step :chrom "chr19" :start 111 :end 120 :value 10}]))))

   (testing "read wig file"
     (with-open [r (wig/reader test-wig-file1)]
       (is (= (wig/read-fields r)
-             [{:format :variable-step
-               :chrom "chr19"
-               :span 150
-               :values [{:start 49304701 :value 10.0}
-                        {:start 49304901 :value 12.5}
-                        {:start 49305401 :value 15.0}
-                        {:start 49305601 :value 17.5}
-                        {:start 49305901 :value 20.0}
-                        {:start 49306081 :value 17.5}
-                        {:start 49306301 :value 15.0}
-                        {:start 49306691 :value 12.5}
-                        {:start 49307871 :value 10.0}]}
-              {:format :fixed-step
-               :chrom "chr19"
-               :start 49307401
-               :step 300
-               :span 200
-               :values [1000 900 800 700 600 500 400 300 200 100]}])))
+             [{:format :variable-step :chrom "chr19" :start 49304701 :end 49304850 :value 10.0}
+              {:format :variable-step :chrom "chr19" :start 49304901 :end 49305050 :value 12.5}
+              {:format :variable-step :chrom "chr19" :start 49305401 :end 49305550 :value 15.0}
+              {:format :variable-step :chrom "chr19" :start 49305601 :end 49305750 :value 17.5}
+              {:format :variable-step :chrom "chr19" :start 49305901 :end 49306050 :value 20.0}
+              {:format :variable-step :chrom "chr19" :start 49306081 :end 49306230 :value 17.5}
+              {:format :variable-step :chrom "chr19" :start 49306301 :end 49306450 :value 15.0}
+              {:format :variable-step :chrom "chr19" :start 49306691 :end 49306840 :value 12.5}
+              {:format :variable-step :chrom "chr19" :start 49307871 :end 49308020 :value 10.0}
+              {:format :fixed-step :chrom "chr19" :start 49307401 :end 49307600 :value 1000}
+              {:format :fixed-step :chrom "chr19" :start 49307701 :end 49307900 :value 900}
+              {:format :fixed-step :chrom "chr19" :start 49308001 :end 49308200 :value 800}
+              {:format :fixed-step :chrom "chr19" :start 49308301 :end 49308500 :value 700}
+              {:format :fixed-step :chrom "chr19" :start 49308601 :end 49308800 :value 600}
+              {:format :fixed-step :chrom "chr19" :start 49308901 :end 49309100 :value 500}
+              {:format :fixed-step :chrom "chr19" :start 49309201 :end 49309400 :value 400}
+              {:format :fixed-step :chrom "chr19" :start 49309501 :end 49309700 :value 300}
+              {:format :fixed-step :chrom "chr19" :start 49309801 :end 49310000 :value 200}
+              {:format :fixed-step :chrom "chr19" :start 49310101 :end 49310300 :value 100}])))
     (with-open [r (wig/reader test-wig-file2)]
       (is (= (wig/read-fields r)
-             [{:format :variable-step
-               :chrom "chr19"
-               :span 1
-               :values [{:start 49304701 :value 10.0}]}
-              {:format :fixed-step
-               :chrom "chr19"
-               :start 49307401
-               :step 300
-               :span 1
-               :values [1000]}])))))
+             [{:format :variable-step :chrom "chr19" :start 49304701 :end 49304701 :value 10.0}
+              {:format :variable-step :chrom "chr19" :start 49304901 :end 49304901 :value 12.5}
+              {:format :fixed-step :chrom "chr19" :start 49307401 :end 49307401 :value 1000}
+              {:format :fixed-step :chrom "chr19" :start 49307402 :end 49307402 :value 900}])))))

 (deftest writer
   (testing "make writer instance"
@@ -102,16 +110,34 @@
       (is (instance? cljam.io.wig.WIGWriter wtr))))

   (testing "write wig"
-    (is (= (-> "variableStep chrom=chr1 span=10\n1 1\n100 2" str->wig wig->str)
-           "variableStep chrom=chr1 span=10\n1 1\n100 2"))
+    (is (= (-> "variableStep chrom=chr1 span=10\n1 1\n101 2" str->wig wig->str)
+           "variableStep chrom=chr1 span=10\n1 1\n101 2"))
     (is (= (-> "fixedStep chrom=chr1 start=1 step=20 span=10\n1\n2" str->wig wig->str)
            "fixedStep chrom=chr1 start=1 step=20 span=10\n1\n2")))

-  (testing "write wig with default span value"
-    (is (= (-> "variableStep chrom=chr1\n1 1\n100 2" str->wig wig->str)
-           "variableStep chrom=chr1\n1 1\n100 2"))
-    (is (= (-> "fixedStep chrom=chr1 start=1 step=20\n1\n2" str->wig wig->str)
-           "fixedStep chrom=chr1 start=1 step=20\n1\n2"))))
+  (testing "write wig with default span value for variableStep"
+    (is (= (-> "variableStep chrom=chr1\n1 1\n101 2" str->wig wig->str)
+           "variableStep chrom=chr1\n1 1\n101 2")))
+
+  (testing "write wig with default span and step value for fixedStep"
+    (is (= (-> "fixedStep chrom=chr1 start=1\n1\n2" str->wig wig->str)
+           "fixedStep chrom=chr1 start=1\n1\n2")))
+
+  (testing "write wig with continuous same formats"
+    (let [s (cstr/join \newline ["variableStep chrom=chr19 span=5"
+                                 "1 1"
+                                 "11 10"
+                                 "variableStep chrom=chr19 span=10"
+                                 "101 1"
+                                 "111 10"])]
+      (is (= s (-> s str->wig wig->str))))
+    (let [s (cstr/join \newline ["fixedStep chrom=chr19 start=1 step=10 span=5"
+                                 "1"
+                                 "10"
+                                 "fixedStep chrom=chr19 start=101 step=10 span=10"
+                                 "1"
+                                 "10"])]
+      (is (= s (-> s str->wig wig->str))))))

 (deftest source-type-test
   (let [temp-file (str temp-dir "test.wig")]


fix todomvc.utils/guid

fix todomvc.utils/guid

--- labs/architecture-examples/om/src/todomvc/utils.cljs
+++ labs/architecture-examples/om/src/todomvc/utils.cljs
@@ -2,7 +2,7 @@
   (:import [goog.ui IdGenerator]))

 (defn guid []
-  (IdGenerator/getNextUniqueId))
+  (.getNextUniqueId (.getInstance IdGenerator)))

 (defn now []
   (js/Date.))


Fixed formatting.

Fixed formatting.

--- google-maps/src/google_maps/views/home_page.cljs
+++ google-maps/src/google_maps/views/home_page.cljs
@@ -9,7 +9,7 @@
 (defn home-did-mount []
   (let [map-canvas  (.getElementById js/document "map-canvas")
         map-options (clj->js {"center" (google.maps.LatLng. -34.397, 150.644)
-                              "zoom"   8})]
+                              "zoom" 8})]
     (js/google.maps.Map. map-canvas map-options)))

 (defn home-page []


Extend lib

Extend lib

--- frontend/src/crunsher/lib.cljs
+++ frontend/src/crunsher/lib.cljs
@@ -1,13 +1,22 @@
 (ns crunsher.lib
-  (:require [om.next :as om]))
+  (:require [om.next :as om]
+            [clojure.walk :refer [keywordize-keys]]
+            [cognitect.transit :as transit]))

-(defonce app-state
-         (atom
-           {:inventory {:pokemon [{:id   4
-                                   :name "Glumanda"}
-                                  {:id   25
-                                   :name "Pikachu"}
-                                  ]}}))
+(def app-state
+  (atom
+    {:pokemon [{:pokemon_id         4
+                :id                 (rand-int 9999999999999999)
+                :individual_attack  10
+                :individual_defense 10
+                :individual_stamina 10
+                :name               "Glumanda"}
+               {:pokemon_id         25
+                :id                 (rand-int 9999999999999999)
+                :individual_attack  10
+                :individual_defense 10
+                :individual_stamina 10
+                :name               "Pikachu"}]}))

 ;;;; React compatibility
@@ -37,13 +46,13 @@
 (defmulti mutate om/dispatch)

 #_(defmethod mutate 'color/temp
-  [{:keys [state]} _ {:keys [color]}]
-  {:action (fn [] (swap! state update-in [:user :selected-color] (fn [] color)))})
+    [{:keys [state]} _ {:keys [color]}]
+    {:action (fn [] (swap! state update-in [:user :selected-color] (fn [] color)))})

 #_(defmethod mutate 'color/set
-  [{:keys [state]} _ {:keys [name field]}]
-  (let [color (get-selected-color)]
-    {:action (fn [] (swap! state update-in [:scarf field] (fn [] color)))}))
+    [{:keys [state]} _ {:keys [name field]}]
+    (let [color (get-selected-color)]
+      {:action (fn [] (swap! state update-in [:scarf field] (fn [] color)))}))

 (defonce reconciler
          (om/reconciler
@@ -55,4 +64,12 @@
 (defn inventory-pokemon
   "Return all pokemon which are currently stored."
   []
-  (get-in @app-state [:inventory :pokemon]))+  (get-in @app-state [:pokemon]))
+
+
+;;;; Conversions
+(defn json->clj
+  "Use cognitec's transit reader for json to convert it to proper Clojure datastructures."
+  [response]
+  (let [r (transit/reader :json)]
+    (keywordize-keys (transit/read r response))))


Now working better!

Now working better!

--- src/connect5_ai/core.clj
+++ src/connect5_ai/core.clj
@@ -64,6 +64,21 @@
                 (<= 4 (+ prev-right-streak-count prev-right-partial-streak-count))
                     (+ prev-right-direct-streak prev-right-streak-count)
                 :else 1)
+
+              (if (and
+                    (= :min prev-left-streak-type)
+                    (= 3 prev-left-direct-streak)
+                    (< 0 prev-left-partial-streak-count)
+                    (< 0 prev-right-partial-streak-count)
+                    (= 0 prev-right-direct-streak)) 1000000 0)
+
+              (if (and
+                    (= :min prev-right-streak-type)
+                    (= 3 prev-right-direct-streak)
+                    (< 0 prev-right-partial-streak-count)
+                    (< 0 prev-left-partial-streak-count)
+                    (= 0 prev-left-direct-streak)) 1000000 0)
+
             )
         ; Types identiques
           (cond
@@ -133,7 +148,6 @@
           right-streak-count
           right-partial-streak-count
           right-direct-streak)))))
-
 (def compute-path-value (memoize compute-path-value))

@@ -149,7 +163,6 @@
          (< y 0)
          (>= x grid-w)
          (>= y grid-h))))
-(def in-bounds? (memoize in-bounds?))

 (defn gen-map-from-charmat
   "Generates map representation of blabla"
@@ -176,7 +189,6 @@
     (map
       #(map + point %)
       adjacent-transform)))
-(def gen-surrounding-points (memoize gen-surrounding-points))

 (defn gen-children-points
   [parent-state grid-w grid-h]
@@ -209,8 +221,8 @@
   {:v  x
    :h  y
    :d1 (- x y)
-   :d2 (- (dec grid-width) x y)})
-(def line-index-from-point (memoize line-index-from-point))
+   :d2 (- (dec grid-width) x y)}
+  )

 (defn gen-lines
   [points grid-w grid-h]
@@ -234,9 +246,7 @@
             (default-assoc h (indexes :h) x)
             (default-assoc v (indexes :v) y)
             (default-assoc d1 (indexes :d1) x)
-            (default-assoc d2 (indexes :d2) x)))))))
-(def gen-lines (memoize gen-lines))
-
+            (default-assoc d2 (indexes :d2) x)))))))        ; Todo: if it shits bricks, look here closely.

 (defn build-all-lines-from-state
   [state grid-w grid-h is-first-player]
@@ -314,6 +324,39 @@

   (or (= Double/POSITIVE_INFINITY (state :heuristic-result))
       (= Double/NEGATIVE_INFINITY (state :heuristic-result))))
+
+
+(defn- is-it-a-win?
+  ""
+  [grid-w grid-h state]
+  (let [point (state :last-move)
+        max-lines ((state :lines) :max)
+        min-lines ((state :lines) :min)
+        indexes (line-index-from-point point grid-w)
+        paths (map (fn [[linetype-max max-lines-for-type] [linetype-min min-lines-for-type]]
+                     (assert (= linetype-max linetype-min) (str "Map is not mixing the same lines - " linetype-max " with " linetype-min))
+                     (let [line-index (indexes linetype-max)
+                           max-line (or (max-lines-for-type line-index) #{})
+                           min-line (or (min-lines-for-type line-index) #{})
+                           ]
+
+                       (map
+                         (fn [[nx ny :as new-point]]
+                           (let [index-in-line (if (= linetype-max :v) ny nx)]
+                             (cond
+                               (not (in-bounds? grid-w grid-h new-point)) :wall
+                               (contains? max-line index-in-line) :max
+                               (contains? min-line index-in-line) :min
+                               :else :empty)))
+                         (map (partial map + point) (directors linetype-max)))))
+                   max-lines min-lines)]
+    (boolean (some true? (map (fn [path]
+                                (let [parts (partition 5 1 (assoc (into [] path) 5 :max))]
+                                  (reduce #(or %1
+                                               (apply (partial = :max) %2))
+                                          false
+                                          parts)
+                                  )) paths)))))

 (defn- negamax-inner
   ""
@@ -358,9 +401,7 @@
                       (if (> (best :best-value) alpha)
                         (let [alpha (best :best-value)]
                           (if (>= alpha beta)
-                            (do
-                              best
-                              )
+                            best
                             (recur (rest sucessors) best alpha)))
                         (recur (rest sucessors) best alpha)))
                     (recur (rest sucessors) best alpha)))))))))
@@ -368,11 +409,11 @@
 (defn negamax
   ""
   [is-first-player state got-time? grid-width grid-height ret-chan]
+  ;(async/>!! ret-chan {:best-move [0 0]})
   (try
     (loop
-        [deepness 1]
-      (prn "deepness" deepness @got-time?)
-      (if (and @got-time?)
+        [deepness 2]
+      (if @got-time?
         (let [point (negamax-inner state
                                    Double/NEGATIVE_INFINITY
                                    Double/POSITIVE_INFINITY


Forget the previous initial state

Forget the previous initial state

--- src/constraint/core.cljs
+++ src/constraint/core.cljs
@@ -154,7 +154,8 @@

 (defn remember-initial-state
   [world-state]
-  (merge world-state {:initial world-state}))
+  (merge world-state
+         {:initial (dissoc world-state :initial)}))

 (defn parse-state


Adjust ns and main to new AOT compilation

* gorilla.clj (main): renamed to -main

--- src/de/kotka/gorilla.clj
+++ src/de/kotka/gorilla.clj
@@ -21,6 +21,7 @@
 ; THE SOFTWARE.

 (clojure.core/ns de.kotka.gorilla
+  (:gen-class)
   (:use [clojure.contrib.fcase :only (case)])
   (:import
      (clojure.lang RT Compiler Compiler$CompilerException LispReader
@@ -156,7 +157,7 @@
     (handle-connection conn)
     (recur server)))

-(defn main
+(defn -main
   [& _]
   (let [address (InetAddress/getByName "localhost")
         server  (new ServerSocket 10123 0 address)]


Move view into own namespace to keep all files together

--- src/discuss/tooltip.cljs
+++ src/discuss/tooltip.cljs
@@ -1,5 +1,10 @@
 (ns discuss.tooltip
-  (:require [discuss.lib :as lib]))
+  (:require [om.core :as om :include-macros true]
+            [om.dom :as dom :include-macros true]
+            [discuss.clipboard :as clipboard]
+            [discuss.lib :as lib]
+            [discuss.lib.views :as vlib]
+            [discuss.sidebar :as sidebar]))

 (defn show
   "Show tooltip by removing a class."
@@ -47,4 +52,27 @@
         [top left] (calc-position tooltip.offsetWidth tooltip.offsetHeight)]
     (set! (.. tooltip -style -top) (str top "px"))
     (set! (.. tooltip -style -left) (str left "px"))
-    (show)))+    (show)))
+
+
+;;;; Creating the view
+(defn safe-space
+  "Create a safed spacer."
+  []
+  (vlib/safe-html " "))
+
+(defn view [data owner]
+  (reify om/IRender
+    (render [_]
+      (dom/div nil
+               (vlib/logo)
+               (safe-space) " | " (safe-space)
+               (dom/span #js {:className "pointer"
+                              :onClick clipboard/add-selection}
+                         (vlib/fa-icon "fa-bookmark-o")
+                         " Save")
+               (safe-space) "  " (safe-space)
+               (dom/span #js {:className "pointer"
+                              :onClick   sidebar/show}
+                         (vlib/fa-icon "fa-comment")
+                         " Discuss")))))


Log a message for each task which has errored

--- src/exploud/messages.clj
+++ src/exploud/messages.clj
@@ -4,6 +4,7 @@
              [bindings :refer :all]
              [deployments :as deployments]
              [elasticsearch :as es]
+             [log :as log]
              [responses :refer :all]
              [tasks :as tasks]
              [util :as util]]
@@ -149,6 +150,14 @@
     (catch Exception e
       (assoc details :result (error-with e)))))

+(defn- log-error-if-necessary
+  [{:keys [result] :as details}]
+  (if (= (:status result) :error)
+    (if-let [throwable (:throwable result)]
+      (log/write (.getMessage throwable))
+      (log/write "An unspecified error has occurred. It might be worth checking Exploud's logs.")))
+  details)
+
 (defn- determine-next-action
   [{:keys [message] :as details}]
   (let [{:keys [action]} message]
@@ -219,6 +228,7 @@
         (->> details
              ensure-task
              (perform-action action-fn)
+             log-error-if-necessary
              determine-next-action
              update-task
              update-deployment


card improvements

card improvements

--- src/node/game/cards.cljs
+++ src/node/game/cards.cljs
@@ -248,6 +248,11 @@

    "Cyberdex Trial"
    {:effect (effect (purge))}
+
+   "Cyberdex Virus Suite"
+   {:access {:optional {:prompt "Purge viruses with Cyberdex Virus Suite?"
+                        :msg (msg "purge viruses") :effect (effect (purge))}}
+    :abilities [{:msg "purge viruses" :effect (effect (purge) (trash card))}]}

    "Cyberfeeder"
    {:recurring 1}
@@ -446,7 +451,7 @@
                 {:effect (effect (trash card)) :msg "prevent 2 brain damage"}]}

    "Fetal AI"
-   {:access {:req (req (not= (:zone card) :archives)) :msg "do 2 net damages"
+   {:access {:req (req (not= (first (:zone card)) :discard)) :msg "do 2 net damages"
              :effect (effect (damage :net 2))}
     :steal-cost [:credit 2]}

@@ -1608,7 +1613,7 @@
                 {:msg "end the run" :effect (effect (end-run))}]}

    "Cell Portal"
-   {:abilities [{:msg "make the Runner to approach the outermost ICE"
+   {:abilities [{:msg "make the Runner approach the outermost ICE"
                  :effect #(do (swap! %1 assoc-in [:run :position] 0) (derez %1 %2 %3))}]}

    "Changeling"
@@ -1790,7 +1795,8 @@
    {:abilities [{:msg "end the run" :effect (effect (end-run))}]}

    "Orion"
-   {:abilities [{:prompt "Choose a program to trash" :msg "Trash a program" :label "Trash a program"
+   {:abilities [{:prompt "Choose a program to trash" :msg (msg "trash " (:title target))
+                 :label "Trash a program"
                  :choices (req (get-in runner [:rig :program])) :effect (effect (trash target))}
                 {:msg "end the run" :effect (effect (end-run))}]}

@@ -1811,7 +1817,8 @@
    {:abilities [{:msg "end the run" :effect (effect (end-run))}]}

    "Rototurret"
-   {:abilities [{:prompt "Choose a program to trash" :msg "Trash a program" :label "Trash a program"
+   {:abilities [{:prompt "Choose a program to trash" :msg (msg "trash " (:title target))
+                 :label "Trash a program"
                  :choices (req (get-in runner [:rig :program])) :effect (effect (trash target))}
                 {:msg "end the run" :effect (effect (end-run))}]}


Enable function passing of custom request builders and response parsers.

--- src/raven_clj/client.clj
+++ src/raven_clj/client.clj
@@ -30,27 +30,43 @@

 (defn load-documents
   "Loads a collection of documents represented
-  by the given document ids."
-  [endpoint document-ids]
-  {:pre [(is-valid-endpoint endpoint) (not-empty document-ids)]}
-  (let [request (requests/load-documents (:address endpoint) document-ids)
-        response (post-req request)]
-    (res/parse-load-response response)))
+  by the given document ids.
+
+  Optionally takes a request builder fn in order
+  to customize request composition.
+
+  Optionally takes a response parser fn in order
+  to customize response parsing."
+  ([endpoint document-ids]
+   (load-documents endpoint document-ids requests/load-documents res/parse-load-response))
+  ([endpoint document-ids request-builder response-parser]
+   {:pre [(is-valid-endpoint endpoint) (not-empty document-ids)]}
+   (let [request (request-builder (:address endpoint) document-ids)
+         response (post-req request)]
+     (response-parser response))))

 (defn bulk-operations
   "Handles a given set of bulk operations that
-  correspond to RavenDB batch requests."
-  [endpoint operations]
-  {:pre [(is-valid-endpoint endpoint)
-         (not-empty (filter
-                      (comp not nil?)
-                      (map (fn[op]
-                             (cond
-                               (= (:Method op) "PUT") (and (:Document op) (:Metadata op) (:Key op))
-                               (= (:Method op) "DELETE") (:Key op))) operations)))]}
-  (let [request (requests/bulk-operations (:address endpoint) operations)
-        response (post-req request)]
-    (res/parse-cmd-response response)))
+  correspond to RavenDB batch requests.
+
+  Optionally takes a request builder fn in order
+  to customize request composition.
+
+  Optionally takes a response parser fn in order
+  to customize response parsing."
+  ([endpoint operations]
+   (bulk-operations endpoint operations requests/bulk-operations res/parse-cmd-response))
+  ([endpoint operations request-builder response-parser]
+   {:pre [(is-valid-endpoint endpoint)
+          (not-empty (filter
+                       (comp not nil?)
+                       (map (fn[op]
+                              (cond
+                                (= (:Method op) "PUT") (and (:Document op) (:Metadata op) (:Key op))
+                                (= (:Method op) "DELETE") (:Key op))) operations)))]}
+   (let [request (requests/bulk-operations (:address endpoint) operations)
+         response (post-req request)]
+     (res/parse-cmd-response response))))

 (defn put-index
   "Creates or updates an index, where an index takes
@@ -60,22 +76,38 @@
     :alias document-alias
     :where where-clause
     :select projection
-  }"
-  [endpoint index]
-  {:pre [(is-valid-endpoint endpoint)
-         (:name index) (:alias index) (:where index) (:select index)]}
-  (let [request (requests/put-index (:address endpoint) index)
-        response (put-req request)]
-    (res/parse-putidx-response response)))
+  }
+
+  Optionally takes a request builder fn in order
+  to customize request composition.
+
+  Optionally takes a response parser fn in order
+  to customize response parsing."
+  ([endpoint index]
+   (put-index endpoint index requests/put-index res/parse-putidx-response))
+  ([endpoint index request-builder response-parser]
+   {:pre [(is-valid-endpoint endpoint)
+          (:name index) (:alias index) (:where index) (:select index)]}
+   (let [request (requests/put-index (:address endpoint) index)
+         response (put-req request)]
+     (res/parse-putidx-response response))))

 (defn put-document
   "Creates or updates a document by its key. Where 'document'
-  is a map."
-  [endpoint key document]
-  {:pre [(is-valid-endpoint endpoint)]}
-  (let [request (requests/put-document (:address endpoint) key document)
-        response (post-req request)]
-    (res/parse-cmd-response response)))
+  is a map.
+
+  Optionally takes a request builder fn in order
+  to customize request composition.
+
+  Optionally takes a response parser fn in order
+  to customize response parsing."
+  ([endpoint key document]
+   (put-document endpoint key document requests/put-document res/parse-cmd-response))
+  ([endpoint key document request-builder response-parser]
+   {:pre [(is-valid-endpoint endpoint)]}
+   (let [request (request-builder (:address endpoint) key document)
+         response (post-req request)]
+     (response-parser response))))

 (defn query-index
   "Query an index, where the 'query' takes the form:
@@ -83,9 +115,17 @@
     :index index-name
     :x 1
     :y 2
-  }."
-  [endpoint query]
-  {:pre [(is-valid-endpoint endpoint) (:index query)]}
-  (let [request (requests/query-index (:address endpoint) query)
-        response (get-req request)]
-    (res/parse-qryidx-response response)))+  }.
+
+  Optionally takes a request builder fn in order
+  to customize request composition.
+
+  Optionally takes a response parser fn in order
+  to customize response parsing."
+  ([endpoint query]
+   (query-index endpoint query requests/query-index res/parse-qryidx-response))
+  ([endpoint query request-builder response-parser]
+   {:pre [(is-valid-endpoint endpoint) (:index query)]}
+   (let [request (request-builder (:address endpoint) query)
+         response (get-req request)]
+     (response-parser response))))


Add all routes and pasrse request body into JSON

--- src/rsvp_backend/app.clj
+++ src/rsvp_backend/app.clj
@@ -5,19 +5,24 @@
             [ring.adapter.jetty :as jetty]
             [ring.middleware.json :as json]
             [ring.middleware.params :as params]
-            [rsvp-backend.handlers.new-invitee :as new-invitee]
+            [rsvp-backend.handlers.invitee :as invitee]
             [rsvp-backend.util :as util]
             [rsvp-backend.middleware.cors :as cors]
             [rsvp-backend.middleware.logging :as logging]
             [taoensso.timbre :as log]))

-(def routes ["/" [["invitee/new" new-invitee/handler]
+(def routes ["/" [["invitee/new" invitee/new-invitee]
+                  [["invitee/" :code] invitee/get-invitee]
+                  [["invitee/" :code "/metadata"] invitee/update-metadata]
+                  [["invitee/" :code "/rsvp"] invitee/update-rsvp]
+                  [["invitee/" :code "/details"] invitee/update-details]
                   [true (fn [_] (util/error-response 404 "Page not found."))]]
              true (fn [_] (util/error-response 404 "Page not found."))])

 (def main-handler
   (-> (br/make-handler routes)
+      json/wrap-json-body
       json/wrap-json-response
       params/wrap-params
       logging/wrap-log-request-response


We need to run conform in explain

We need to run conform in explain

TODO: is this the way this should be used?

--- src/spec_tools/core.cljc
+++ src/spec_tools/core.cljc
@@ -148,8 +148,8 @@
     x)
   (explain* [this path via in x]
     (let [problems (if (s/spec? pred)
-                     (s/explain* pred path via in x)
-                     (when (= invalid (if (and (fn? pred) (pred x)) x invalid))
+                     (s/explain* pred path via in (s/conform* this x))
+                     (when (= invalid (if (and (fn? pred) (pred (s/conform* this x))) x invalid))
                        [{:path path
                          :pred (s/abbrev (:spec/form this))
                          :val x


Housekeeping

Housekeeping

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -117,10 +117,9 @@
   Special command that takes any value and returns it unchanged as part of
   an enclosing `with-conn` pipeline response."
   [value]
-  (let [vfn (constantly value)
-        parser protocol/*parser*]
+  (let [vfn (constantly value)]
     (swap! (:parser-queue protocol/*context*) conj
-           (with-meta (if parser (comp parser vfn) vfn)
+           (with-meta (if-let [p protocol/*parser*] (comp p vfn) vfn)
              {:dummy-reply? true}))))

 (comment (wc (return :foo) (ping) (return :bar))
@@ -169,10 +168,9 @@
   of a \"NOSCRIPT\" reply, reattempts with `eval`. Returns the final command's
   reply."
   [script numkeys key & args]
-  (let [parser protocol/*parser*
-        [r & _] (->> (apply evalsha* script numkeys key args)
+  (let [[r & _] (->> (apply evalsha* script numkeys key args)
                      (with-replies :as-pipeline))]
-    (with-parser parser
+    (with-parser protocol/*parser*
       (if (and (instance? Exception r)
                (.startsWith (.getMessage ^Exception r) "NOSCRIPT"))
         (apply eval script numkeys key args)


Fix non-expand mode batch write

Fix non-expand mode batch write

Treat incoming batch of updates as a seq rather than a single value.

--- src/taoensso/faraday.clj
+++ src/taoensso/faraday.clj
@@ -1079,10 +1079,9 @@
   (let [expand? *attr-multi-vs?*
         expand? (if (nil? expand?) attr-multi-vs?-default expand?)]

-    (if-not expand?
-      (clj-item->db-item attr-multi-vs-map)
-      (let [;; ensure-coll (fn [x] (if (coll?* x) x [x]))
-            ensure-sequential (fn [x] (if (sequential? x) x [x]))]
+    (let [ensure-sequential (fn [x] (if (sequential? x) x [x]))]
+      (if-not expand?
+        (mapv clj-item->db-item (ensure-sequential attr-multi-vs-map))
         (reduce
           (fn [r attr-multi-vs]
             (let [attrs (keys attr-multi-vs)


Hello world main function

Hello world main function

--- src/try_clojure/core.clj
+++ src/try_clojure/core.clj
@@ -1,6 +1,8 @@
-(ns try-clojure.core)
+(ns try-clojure.core
+  (:require
+    [ring.adapter.jetty :as jetty]))

-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (println x "Hello, World!"))
+(defn -main []
+  (jetty/run-jetty
+    (fn [req] {:status 200 :body "Hello World"})
+    {:port 5000}))


Runs show started-at and duration

Runs show started-at and duration

--- src-cljs/frontend/components/pages/workflow.cljs
+++ src-cljs/frontend/components/pages/workflow.cljs
@@ -1,7 +1,10 @@
 (ns frontend.components.pages.workflow
-  (:require [frontend.components.pieces.card :as card]
+  (:require [frontend.components.common :as common]
+            [frontend.components.pieces.card :as card]
             [frontend.components.pieces.status :as status]
             [frontend.components.templates.main :as main-template]
+            [frontend.datetime :as datetime]
+            [frontend.utils.legacy :refer [build-legacy]]
             [om.next :as om-next :refer-macros [defui]])
   (:require-macros [frontend.utils :refer [component element html]]))

@@ -23,8 +26,11 @@
            (html
             [:div
              [:.status (status/badge :status-class/running (name status))]
-             [:.started-at (str started-at)]
-             [:.stopped-at (str stopped-at)]])))))))
+             [:.started-at {:title (str "Started: " (datetime/full-datetime started-at))}
+              (build-legacy common/updating-duration {:start started-at} {:opts {:formatter datetime/time-ago-abbreviated}})]
+             [:.duration {:title (str "Duration: " (datetime/as-duration (- stopped-at started-at)))}
+              (build-legacy common/updating-duration {:start started-at
+                                                      :stop stopped-at})]])))))))

 (def run (om-next/factory Run))


Remove logs

Remove logs

--- backend/test/akvo/lumen/test_utils.clj
+++ backend/test/akvo/lumen/test_utils.clj
@@ -165,7 +165,6 @@
   "At the moment only support seed of tenants table."
   [config]
   (let [db-uri (-> config :akvo.lumen.component.hikaricp/hikaricp :uri)]
-    (log/error :TT (-> config :akvo.lumen.migrate :seed :tenants))
     (doseq [tenant (-> config :akvo.lumen.migrate :seed :tenants)]
       (seed-tenant {:connection-uri db-uri} tenant))))


:bug: problem with palettes

:bug: problem with palettes

--- frontend/src/uxbox/main/ui/workspace/colorpalette.cljs
+++ frontend/src/uxbox/main/ui/workspace/colorpalette.cljs
@@ -30,8 +30,8 @@

 (defn selected-items-ref
   [library-id]
-  (->> #(get-in % [:library-items :palettes library-id])
-       (l/derived st/state)))
+  (-> #(get-in % [:library-items :palettes library-id])
+      (l/derived st/state)))

 (def selected-library-ref
   (-> #(get-in % [:library-selected :palettes])
@@ -56,75 +56,77 @@
 (mf/defc palette
   [{:keys [libraries left-sidebar?] :as props}]

-  (when (and libraries (-> libraries count (> 0)))
-    (let [current-selection (or (mf/deref selected-library-ref) (-> libraries first :id))
-          state (mf/use-state {:show-menu false })]
-      (mf/use-effect
-       (mf/deps current-selection)
-       #(st/emit! (dlib/retrieve-library-data :palettes current-selection)))
+  (let [current-selection (or (mf/deref selected-library-ref) (-> libraries first :id))
+        state (mf/use-state {:show-menu false })]

-      (let [items (-> current-selection selected-items-ref  mf/deref)
-            doc-width (.. js/document -documentElement -clientWidth)
-            width (:width @state (* doc-width 0.84))
-            offset (:offset @state 0)
-            visible (/ width 86)
-            invisible (- (count items) visible)
-            close #(st/emit! (udw/toggle-layout-flag :colorpalette))
-            container (mf/use-ref nil)
-            container-child (mf/use-ref nil)
+    (mf/use-effect
+     (mf/deps current-selection)
+     #(when current-selection
+        (st/emit! (dlib/retrieve-library-data :palettes current-selection))))

-            on-left-arrow-click
-            (fn [event]
-              (when (> offset 0)
-                (let [element (mf/ref-val container-child)]
-                  (swap! state update :offset dec))))
+    (let [items (or (mf/deref (selected-items-ref current-selection)) [])
+          doc-width (.. js/document -documentElement -clientWidth)
+          width (:width @state (* doc-width 0.84))
+          offset (:offset @state 0)
+          visible (/ width 86)
+          invisible (- (count items) visible)
+          close #(st/emit! (udw/toggle-layout-flag :colorpalette))
+          container (mf/use-ref nil)
+          container-child (mf/use-ref nil)

-            on-right-arrow-click
-            (fn [event]
-              (when (< offset invisible)
-                (let [element (mf/ref-val container-child)]
-                  (swap! state update :offset inc))))
+          on-left-arrow-click
+          (fn [event]
+            (when (> offset 0)
+              (let [element (mf/ref-val container-child)]
+                (swap! state update :offset dec))))

-            on-scroll
-            (fn [event]
-              (if (pos? (.. event -nativeEvent -deltaY))
-                (on-right-arrow-click event)
-                (on-left-arrow-click event)))
+          on-right-arrow-click
+          (fn [event]
+            (when (< offset invisible)
+              (let [element (mf/ref-val container-child)]
+                (swap! state update :offset inc))))

-            after-render
-            (fn []
-              (let [dom (mf/ref-val container)
-                    width (.-clientWidth dom)]
-                (when (not= (:width @state) width)
-                  (swap! state assoc :width width))))
+          on-scroll
+          (fn [event]
+            (if (pos? (.. event -nativeEvent -deltaY))
+              (on-right-arrow-click event)
+              (on-left-arrow-click event)))

-            handle-click
-            (fn [library]
-              (st/emit! (dlib/select-library :palettes (:id library))))]
+          after-render
+          (fn []
+            (let [dom (mf/ref-val container)
+                  width (.-clientWidth dom)]
+              (when (not= (:width @state) width)
+                (swap! state assoc :width width))))

-        (mf/use-effect nil after-render)
+          handle-click
+          (fn [library]
+            (st/emit! (dlib/select-library :palettes (:id library))))]

-        [:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
-         [:& context-menu {:selectable true
-                           :selected (->> libraries (filter #(= (:id %) current-selection)) first :name)
-                           :show (:show-menu @state)
-                           :on-close #(swap! state assoc :show-menu false)
-                           :options (mapv #(vector (:name %) (partial handle-click %)) libraries)} ]
-         [:div.color-palette-actions
-          {:on-click #(swap! state assoc :show-menu true)}
-          [:div.color-palette-actions-button i/actions]]
+      (mf/use-effect nil after-render)

-         [:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]
+      [:div.color-palette {:class (when left-sidebar? "left-sidebar-open")}
+       [:& context-menu {:selectable true
+                         :selected (->> libraries (filter #(= (:id %) current-selection)) first :name)
+                         :show (:show-menu @state)
+                         :on-close #(swap! state assoc :show-menu false)
+                         :options (mapv #(vector (:name %) (partial handle-click %)) libraries)} ]
+       [:div.color-palette-actions
+        {:on-click #(swap! state assoc :show-menu true)}
+        [:div.color-palette-actions-button i/actions]]

-         [:div.color-palette-content {:ref container :on-wheel on-scroll}
-          [:div.color-palette-inside {:ref container-child
-                                      :style {:position "relative"
-                                              :width (str (* 86 (count items)) "px")
-                                              :right (str (* 86 offset) "px")}}
-           (for [item items]
-             [:& palette-item {:color (:content item) :key (:id item)}])]]
+       [:span.left-arrow {:on-click on-left-arrow-click} i/arrow-slide]

-         [:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]]))))
+       [:div.color-palette-content {:ref container :on-wheel on-scroll}
+        [:div.color-palette-inside {:ref container-child
+                                    :style {:position "relative"
+                                            :width (str (* 86 (count items)) "px")
+                                            :right (str (* 86 offset) "px")}}
+         (for [item items]
+           [:& palette-item {:color (:content item) :key (:id item)}])]]
+
+       [:span.right-arrow {:on-click on-right-arrow-click} i/arrow-slide]]))
+  )

 (mf/defc colorpalette
   [{:keys [left-sidebar?]}]


testing for test server started

testing for test server started

--- test/wb_es/core_test.clj
+++ test/wb_es/core_test.clj
@@ -45,6 +45,9 @@
                              :body (->> (assoc-in mappings/index-settings [:settings :number_of_shards] 1)
                                         (json/generate-string))})
         (mount/start)
+        (if test-server-uri
+          (println (format "Testing server is started at %s" test-server-uri))
+          (println "Testing server failed to start"))
         (f)
         (mount/stop))
       )))
@@ -84,9 +87,8 @@

 (deftest server-start-test
   (testing "server started"
-    (try
-      (prn test-server-uri)
-      (prn (http/get test-server-uri)))))
+    (let [response (http/get test-server-uri)]
+      (is (= 200 (:status response))))))

 (deftest anatomy-type-test
   (testing "anatomy type using \"tl\" prefixed terms"


Add build system logos to intro text.

Add build system logos to intro text.

--- src/cljs/clj_templates/pages/templates/page.cljs
+++ src/cljs/clj_templates/pages/templates/page.cljs
@@ -3,6 +3,9 @@
             [clj-templates.util.js :refer [target-value]]
             [re-frame.core :refer [dispatch]]
             [clojure.string :as str]))
+
+(def lein-logo "images/leiningen.jpg")
+(def boot-logo "images/boot-logo.png")

 (defn boot-usage [template-name]
   (str "boot -d boot/new new -t " template-name "-n my-app"))
@@ -20,8 +23,8 @@
     [:div.template-attribute [:div.keyword ":downloads "] [:div.code downloads]]
     [:div.template-icons
      (when (= build-system "lein")
-       [:img {:src "images/leiningen.jpg" :width "20px"}])
-     [:img {:src "images/boot-logo.png" :width "23px"}]]]])
+       [:img {:src lein-logo :width "20px"}])
+     [:img {:src boot-logo :width "23px"}]]]])

 (defn search-input []
   [:input.search-input {:type        "text"
@@ -63,9 +66,11 @@

 (defn intro-text []
   [:div.intro-text "Find Clojure templates for "
-   [:a {:href "https://leiningen.org/" :target "_blank"} "Leiningen"]
+   [:a {:href "https://leiningen.org/" :target "_blank"}
+    "Leiningen" [:img {:src lein-logo :width "20px"}]]
    " and "
-   [:a {:href "http://boot-clj.com/" :target "_blank"} "Boot"]
+   [:a {:href "http://boot-clj.com/" :target "_blank"}
+    "Boot" [:img {:src boot-logo :width "23px"}]]
    ". "])

 (defn templates []


better set context (thawing) mechanics

better set context (thawing) mechanics

--- src/clojure/zensols/model/execute_classifier.clj
+++ src/clojure/zensols/model/execute_classifier.clj
@@ -16,6 +16,7 @@
   (:require [zensols.tabres.display-results :as dr])
   (:require [zensols.actioncli.resource :refer (resource-path)]
             [zensols.util.spreadsheet :as ss]
+            [zensols.util.string :as zs]
             [zensols.model.classifier :as cl]
             [zensols.model.weka :as weka]))

@@ -58,7 +59,9 @@
   * **:set-context-fn** (optional) a function that is called to set the context
   created with **:context-fn** and retrieved from the persisted model; this is
   useful when using/executing the model and the context is needed before
-  **:create-features-fn** is called
+  **:create-features-fn** is called; if this function is provided it replaces
+  the unpersisted context in case there is any *thawing* logic that might be
+  needed for the model

   * **:model-return-keys** what the classifier will return (by default
   `{:label :distributions}`)
@@ -103,10 +106,9 @@
    (create-instances features-set nil))
   ([features-set context]
    (log/infof "generating instances from %d feature sets" (count features-set))
+   (log/debugf "feature sets: <<%s>>" (zs/trunc features-set))
    (log/tracef "feature sets: <<%s>>" (pr-str features-set))
-   (let [{:keys [name set-context-fn]} (model-config)]
-     (if (and set-context-fn context)
-       (set-context-fn context))
+   (let [{:keys [name]} (model-config)]
      (weka/instances
       (format "%s-classify" name)
       features-set
@@ -158,7 +160,12 @@
   [& {:keys [fail-if-not-exists? file]
       :or {fail-if-not-exists? true
            file (:name (model-config))}}]
-  (cl/read-model file :fail-if-not-exists? fail-if-not-exists?))
+  (let [model (cl/read-model file :fail-if-not-exists? fail-if-not-exists?)
+        context (:context model)
+        {:keys [set-context-fn]} (model-config)]
+    (if (and set-context-fn context)
+      (assoc model :context (set-context-fn context))
+      model)))

 (defn prime-model
   "Prime a trained or unpersisted ([[read-model]]) model for classification


Rename function to better describe purpose

--- src/onyx/scheduling/percentage_job_scheduler.clj
+++ src/onyx/scheduling/percentage_job_scheduler.clj
@@ -18,7 +18,7 @@
        (assoc job :capacity n)))
    jobs))

-(defn maximum-jobs-to-use [jobs]
+(defn drop-jobs-overflow [jobs]
   (reduce
    (fn [all {:keys [pct] :as job}]
      (let [sum (apply + (map :pct all))]
@@ -32,7 +32,7 @@
   [replica]
   (let [n-peers (count (:peers replica))
         sorted-jobs (sort-jobs-by-pct replica)
-        jobs-to-use (maximum-jobs-to-use sorted-jobs)
+        jobs-to-use (drop-jobs-overflow sorted-jobs)
         init-allocations (min-allocations jobs-to-use n-peers)]
     (into {} (map (fn [j] {(:job j) (:capacity j)}) init-allocations))))


delaney.clj: some improvements in (traversal) and (protocol)

--- clojure/org/gavrog/clojure/delaney.clj
+++ clojure/org/gavrog/clojure/delaney.clj
@@ -77,18 +77,18 @@
            (seq todo-for-i)
            (let [D (first todo-for-i)
                  Di (s ds i D)
-                 todo (if Di (doall (push-neighbors todo Di)) todo)
+                 todo (if Di (vec (push-neighbors todo Di)) todo)
                  seen (conj seen (as-root Di) [D i] [Di i])]
              (lazy-seq (cons [D i Di] (collect seeds-left todo seen))))
            (seq seeds-left)
            (let [D (first seeds-left)
-                 todo (doall (push-neighbors todo D))
+                 todo (vec (push-neighbors todo D))
                  seen (conj seen (as-root D))]
              (lazy-seq
                (cons (as-root D) (collect (rest seeds-left) todo seen))))
            :else
            ())))
-      (seq seeds) (doall (concat stacks queues)) #{})))
+      (seq seeds) (vec (concat stacks queues)) #{})))

 (defn orbit-reps
   ([ds indices seeds]
@@ -129,17 +129,17 @@
         ipairs (map vector indices (rest indices))
         spins (fn [D] (for [[i j] ipairs] (or (v ds i j D) 0)))
         step (fn step [xs emap n]
-               (when (seq xs)
-                 (let [[[Di i D] & xs] xs]
-                   (if (nil? D)
-                     (recur xs emap n)
-                     (let [[Ei E] (sort [(emap Di) (or (emap D) n)])
-                           new? (= E n)
-                           emap (if new? (assoc emap D n) emap)
-                           n (if new? (inc n) n)
-                           head (if (= i :root) [-1] [(imap i) Ei])
-                           tail (if new? (spins D) [])]
-                       (concat head [E] tail (step xs emap n)))))))]
+               (when-let [[Di i D] (first xs)]
+                 (if (nil? D)
+                   (recur (rest xs) emap n)
+                   (let [[Ei E] (sort [(emap Di) (or (emap D) n)])
+                         new? (= E n)
+                         emap (if new? (assoc emap D n) emap)
+                         n (if new? (inc n) n)
+                         head (if (= i :root) [-1] [(imap i) Ei])
+                         tail (if new? (spins D) [])
+                         prefix (vec (concat head [E] tail))]
+                     (lazy-seq (concat prefix (step (rest xs) emap n)))))))]
     (step trav {} 1)))

 (defn invariant


Don't rely on the kwargs destructing hack.

--- modules/messaging/src/main/clojure/immutant/pipeline.clj
+++ modules/messaging/src/main/clojure/immutant/pipeline.clj
@@ -89,7 +89,7 @@
   functions (\"steps\"), each receiving the result of the previous step."
   [name & args]
   (let [steps (named-steps (take-while fn? args))
-        {:as opts} (seq (drop-while fn? args)) ;; seq is a workaround for CLJ-1140
+        opts (apply hash-map (drop-while fn? args))
         pl (str "queue." (app-name)  ".pipeline-" name)
         pl-fn (pipeline-fn pl (-> steps first meta :step))]
     (if (some #{pl} @pipelines)


PDOK-1599: one feature test

PDOK-1599: one feature test

--- src/test/clojure/pdok/featured/extracts_test.clj
+++ src/test/clojure/pdok/featured/extracts_test.clj
@@ -15,15 +15,14 @@

 (defn one-feature [] (list (test-feature "PDOK" "AAA" "BBB")))

-(deftest test-rendered-feature-gml
-  (time (Thread/sleep 1000))
-  (let [[error features] (features-for-extract "test" "dummy" "gml2extract" (one-feature) "src/test/resources/templates")
-        [tiles feature] (first features)]
-    (is (boolean (re-find #"<geo><gml:Polygon" feature)))
-    (is (boolean (re-find #"<naam>PDOK</naam>" feature)))))

 (defn two-features [] (list (test-feature "name1" "A" "B")
                              (test-feature "name2" "C" "D")))
+
+(deftest test-one-feature
+  (let [[error features] (features-for-extract "test" "dummy" "gml2extract" (one-feature) "src/test/resources/templates")
+        [tiles feature] (first features)]
+    (is (boolean (re-find #"<geo><gml:Polygon" feature)))))

 (deftest test-two-rendered-features
   (let [[error features] (features-for-extract "test" "dummy" "gml2extract" (two-features) "src/test/resources/templates")]
@@ -44,4 +43,13 @@
   (fill-extract "bgt" "bord" "citygml" "33"))

+; (deftest test-rendered-feature-gml
+;  (time (Thread/sleep 1000))
+;  (let [[error features] (features-for-extract "test" "dummy" "gml2extract" (one-feature) "src/test/resources/templates")
+;        [tiles feature] (first features)]
+;    (is (boolean (re-find #"<geo><gml:Polygon" feature)))
+;    (is (boolean (re-find #"<naam>PDOK</naam>" feature)))))
+
+
+
 ;(with-open [s (file-stream ".test-files/new-features-single-collection-100000.json")] (time (last (features-from-package-stream s))))


minor

minor

--- server/src/server/system.clj
+++ server/src/server/system.clj
@@ -40,7 +40,8 @@
                    :auto-reload? true}
         recommender-sparql "http://dbpedia.org/sparql"
         log-config log-config
-        system (new-system db-opts
+        system (new-system
+                  db-opts
                   #'app-fn
                   ring-opts
                   recommender-sparql


Add `testing` docstring support back into deftest

--- modules/lazytest/src/main/clojure/lazytest/deftest.clj
+++ modules/lazytest/src/main/clojure/lazytest/deftest.clj
@@ -2,7 +2,8 @@
   "A drop-in replacement for clojure.test.  Supports the 'deftest',
   'is', 'are', and 'testing' macros.  Currently 'testing' doc strings
   do not appear in the report output."
-  (:use lazytest.expect
+  (:use [clojure.string :only (join)]
+	lazytest.expect
 	lazytest.test-case
 	[lazytest.expect.thrown :only (throws? throws-with-msg?)])
   (:require clojure.template))
@@ -15,30 +16,34 @@
   `(binding [*testing* (cons ~doc *testing*)]
      ~@body))

-(defmacro thrown? [c expr]
+(defn current-testing-string
+  "Returns the result of concatenating the sequence of nested
+  documentation strings created with the `testing` macro."
+  []
+  (when (seq *testing*)
+    (join " " (reverse *testing*))))
+
+(defmacro thrown?
+  "Returns true if expr throws an exception of class c."
+  [c expr]
   `(throws? ~c (fn [] ~expr)))

-(defmacro thrown-with-msg? [c re expr]
+(defmacro thrown-with-msg?
+  "Returns true if expr throws an exception of class c with a message
+  matching regular expression re."
+  [c re expr]
   `(throws-with-msg? ~c ~re (fn [] ~expr)))

 (defmacro is
   "Generic assertion macro.  'form' is any predicate test.
   'msg' is an optional message to attach to the assertion.

-  Example: (is (= 4 (+ 2 2)) \"Two plus two should be 4\")
-
-  Special forms:
-
-  (is (thrown? c body)) checks that an instance of c is thrown from
-  body, fails if not; then returns the thing thrown.
-
-  (is (thrown-with-msg? c re body)) checks that an instance of c is
-  thrown AND that the message on the exception matches (with
-  re-find) the regular expression re."
+  Example: (is (= 4 (+ 2 2)) \"Two plus two should be 4\")"
   ([expr]
-     `(expect nil ~expr))
+     `(expect (current-testing-string) ~expr))
   ([expr message]
-     `(expect ~message ~expr)))
+     `(testing ~message
+	(expect (current-testing-string) ~expr))))

 (defmacro are [argv expr & args]
   "Checks multiple assertions with a template expression.
@@ -60,4 +65,6 @@
   [sym & body]
   {:pre [(symbol? sym)]}
   `(def ~sym (vary-meta (test-case (fn [] ~@body))
-			assoc :name '~sym)))
+			merge
+			'~(meta (first body))
+			{:name '~sym})))


Reload assets on both `:new` and `:mod` events (#431)

Sometimes, file modifications will result in two events (`:del` followed by `:new`) instead of a single `:mod` event.
Previously, nothing would happen in these situations.
This commit modifies `do-asset-update` to perform updates on both `:new` and `:mod` events.

--- src/main/shadow/cljs/devtools/server/worker/impl.clj
+++ src/main/shadow/cljs/devtools/server/worker/impl.clj
@@ -830,7 +830,7 @@

         updates
         (->> updates
-             (filter #(= :mod (:event %)))
+             (filter #(contains? #{:mod :new} (:event %)))
              (map #(update % :name rc/normalize-name))
              (map #(str watch-path "/" (:name %)))
              (into []))]
@@ -879,4 +879,4 @@
   (-> worker-state
       (cond->
         (seq extra-config-files)
-        (maybe-reload-config-files))))+        (maybe-reload-config-files))))


Delete old code

Delete old code

--- src/midje/emission/plugins/default_failure_lines.clj
+++ src/midje/emission/plugins/default_failure_lines.clj
@@ -21,24 +21,15 @@

 ;; TODO: Retaining these functions for now in case they're useful for Flare-based printing
 (letfn [(diffable? [x]
-          (or (classic-map? x) (sequential? x)))
-
-        (complicated? [expected actual]
-          (and false                    ;; revert to old style
-               (diffable? expected)
-               (diffable? actual)
-               (or (> (count expected) 3)
-                   (> (count actual) 3))))]
+          (or (classic-map? x) (sequential? x)))]

   (defmethod messy-lines :actual-result-did-not-match-expected-value [m]
     (let [expected (:expected-result m)
           actual (:actual m)]
-      (if (complicated? expected actual)
-        (list " THIS SHOULD NEVER BE SEEN - OLD DIFF-PRINTING")
-        (list
-         (str "    Expected: " (attractively-stringified-value (:expected-result m)))
-         (str "      Actual: " (attractively-stringified-value (:actual m)))
-         (notes m))))))
+      (list
+       (str "    Expected: " (attractively-stringified-value (:expected-result m)))
+       (str "      Actual: " (attractively-stringified-value (:actual m)))
+       (notes m)))))

 (defmethod messy-lines :actual-result-should-not-have-matched-expected-value [m]
   (list


CMR-957: Added another special case polygon

--- test/cmr/system_int_test/search/collection_spatial_search_test.clj
+++ test/cmr/system_int_test/search/collection_spatial_search_test.clj
@@ -66,6 +66,9 @@
         east-hemi-poly1 (make-coll :geodetic "east-hemi-poly1"
                                    (polygon 0.0001 -89.9999, 180 -89.9999, 180 89.9999,
                                             0.0001 89.9999, 0.0001 -89.9999))
+        east-hemi-poly2 (make-coll :geodetic "east-hemi-poly2"
+                                   (polygon 0.0001,-89.9999, 180.0,-89.9999, 180.0,-45.0, 180.0,0.0,
+                                            180.0,45.0, 180.0,89.9999, 0.0001,89.9999, 0.0001,-89.9999))
         ;; Combines west-hemi-poly3 and east-hemi-poly1
         combined (make-coll :geodetic "combined"
                             (polygon -179.9999 75, -179.9 75, -179.9 0, -179.9999 0,
@@ -73,7 +76,7 @@
                                      -179.9999 89.9999, -179.9999 75)
                             (polygon 0.0001 -89.9999, 180 -89.9999, 180 89.9999,
                                      0.0001 89.9999, 0.0001 -89.9999))
-        all-colls [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 east-hemi-poly1 combined]]
+        all-colls [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 east-hemi-poly1 east-hemi-poly2 combined]]

     (index/refresh-elastic-index)

@@ -93,7 +96,7 @@
          [0 -90] all-colls

          ;; antimerdian
-         [180 0] [east-hemi-poly1 combined]
+         [180 0] [east-hemi-poly1 east-hemi-poly2 combined]
          [-180 0] [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 combined]

          ;; prime meridian
@@ -102,7 +105,7 @@
          [0 -10] all-colls

          ;; middle of east hemisphere
-         [90 45] [east-hemi-poly1 combined]
+         [90 45] [east-hemi-poly1 east-hemi-poly2 combined]

          ;; middle of west hemisphere
          [-90 45] [west-hemi-poly1 west-hemi-poly2 west-hemi-poly3 combined])))


insights: timezone localize `as-time-since`

- Old code worked for Marc, but not me.

--- src-cljs/frontend/datetime.cljs
+++ src-cljs/frontend/datetime.cljs
@@ -1,6 +1,7 @@
 (ns frontend.datetime
   (:require [frontend.utils :as utils :include-macros true]
             [cljs-time.coerce :refer [from-long]]
+            [cljs-time.core :as time]
             [cljs-time.format :as time-format]
             [goog.string :as g-string]
             goog.string.format
@@ -181,15 +182,16 @@
         (g-string/format "%s:%s" display-minutes display-seconds)))))

 (defn as-time-since [date-string]
-  (let [time (.getTime (js/Date. date-string))
+  (let [time-stamp (.getTime (js/Date. date-string))
+        zone-time (time/to-default-time-zone (from-long time-stamp))
         now (server-now)
-        ago (.floor js/Math (/ (- now time) 1000))]
+        ago (js/Math.floor (/ (- now time-stamp) 1000))]
     (cond (< ago minute) "just now"
           (< ago hour) (str (int (/ ago minute)) "m ago")
-          (< ago day) (time-format/unparse (time-format/formatter-local "h:mma") (from-long time))
+          (< ago day) (time-format/unparse (time-format/formatter "h:mma") zone-time)
           (< ago (* 2 day)) "yesterday"
-          (< ago year) (time-format/unparse (time-format/formatter-local "MMM d") (from-long time))
-          :else (time-format/unparse (time-format/formatter "MMM yyyy") (from-long time)))))
+          (< ago year) (time-format/unparse (time-format/formatter "MMM d") zone-time)
+          :else (time-format/unparse (time-format/formatter "MMM yyyy") zone-time))))

 (def millis-factors [{:unit :hours
                       :display "h"


make update-server-offset robust to parse errors

--- src-cljs/frontend/datetime.cljs
+++ src-cljs/frontend/datetime.cljs
@@ -16,13 +16,13 @@
 (def server-offset (atom nil))

 (defn update-server-offset [date-header]
-  (let [server-date (.fromRfc822String goog.date.DateTime date-header)
-        newval (- (.getTime server-date) (now))]
-    (swap! server-offset
-           (fn [oldval]
-             (if oldval
-               (min oldval newval)
-               newval)))))
+  (when-let [server-date (.fromRfc822String goog.date.DateTime date-header)]
+    (let [newval (- (.getTime server-date) (now))]
+      (swap! server-offset
+             (fn [oldval]
+               (if oldval
+                 (min oldval newval)
+                 newval))))))

 (defn server-now []
   (+ (now) (or @server-offset 0)))


get command line arguments

get command line arguments

--- panc/src/main/clojure/org/quattor/pan/compiler_cli.clj
+++ panc/src/main/clojure/org/quattor/pan/compiler_cli.clj
@@ -82,9 +82,12 @@
     (println (.formatStats compiler-results))))

 (defn -main [& args]
+
   (let [options (apply parse-options args)
-        compiler-options (create-compiler-options options)]
+        compiler-options (create-compiler-options options)
+        arguments args]
     (println options)
+    (println arguments)
     (println compiler-options)
     (run-compiler compiler-options)
     ))


[#1949] Fix AuthService/allow?

[#1949] Fix AuthService/allow?

--- backend/src/akvo/lumen/lib/auth.clj
+++ backend/src/akvo/lumen/lib/auth.clj
@@ -21,8 +21,12 @@
 (defrecord AuthServiceImpl [auth-datasets-set auth-visualisations-set]
   p/AuthService
   (allow? [this d]
-    (and (set/subset? auth-visualisations-set (:auth-visualisations (p/auth? this d)))
-         (set/subset? auth-datasets-set (:auth-datasets (p/auth? this d)))))
+    (let [res (p/auth? this d)]
+      (log/error :res res)
+      (log/error :vis (set/subset? (:auth-visualisations res) auth-visualisations-set))
+      (log/error :ds (set/subset? (:auth-datasets res) auth-datasets-set))
+      (and (set/subset? (:auth-visualisations res) auth-visualisations-set)
+           (set/subset? (:auth-datasets res) auth-datasets-set))))
   (auth? [this {:keys [dataset-ids visualisation-ids]}]
     {:auth-datasets (set/intersection auth-datasets-set (set dataset-ids))
      :auth-visualisations (set/intersection auth-visualisations-set (set visualisation-ids))})


update route replacement for missing routes

--- src-cljs/imago/core.cljs
+++ src-cljs/imago/core.cljs
@@ -46,7 +46,7 @@
         (async/publish bus init-id [state params]))
       (do
         (warn "route handling module not configured:" new-id)
-        (apply route/set-route!
+        (apply route/replace-route!
                (or (-> @state :route :route)
                    (get-in config/app [:routes (:default-route-id config/app) :route])))))))


Inbox: Fix header CSS overflow.

Inbox: Fix header CSS overflow.

--- src-cljs/pepa/style.cljs
+++ src-cljs/pepa/style.cljs
@@ -303,11 +303,11 @@
               :flex-direction :column
               :flex-grow 1}
     [:header {:display :flex
-              :flex-flow [[:row :wrap]]
-              :align-items :center
-              :overflow :hidden
-              :text-overflow :ellipsis
-              :white-space :nowrap}
+              :flex-direction :row
+              :align-items :center}
+     [:span {:overflow :hidden
+             :text-overflow :ellipsis
+             :white-space :nowrap}]
      [:a.show {:font-size (pt 8)
                :padding (px 12)
                :text-decoration :underline}]]