Add keys to the lists

Add keys to the lists

--- dev/pot/core/ui.cljs
+++ dev/pot/core/ui.cljs
@@ -48,19 +48,21 @@
             #(root-key-handler @cursor actions %))))
       om/IRender
       (render [_]
-        (let [board (:board cursor)]
+        (let [board (:board cursor)
+              yc (count board)
+              xc (count (first board))]
           (html
             (into
               [:table]
-              (for [y (range (count board))]
+              (for [y (range yc)]
                 (into
-                  [:tr]
-                  (for [x (range (count (first board)))]
-                    [:td {:style {:width      50 ; todo move to css
+                  [:tr {:key (str "tr" y)}]
+                  (for [x (range xc)]
+                    [:td {:style {:width      50
                                   :height     50
                                   :border     [["1px solid black"]]
-                                  :text-align :center}
-                          :key (str (* (+ 1 y) (+ 1 x)))}
+                                  :text-align :center} ; todo move to css
+                          :key   (str "td" (+ (* yc y) x))}
                      (get-in board [y x])])))))))))
   app-state
   {:target (. js/document (getElementById "app"))


Rename matched-nodes to alternatives.

Rename matched-nodes to alternatives.

--- src/isla/parser.clj
+++ src/isla/parser.clj
@@ -13,7 +13,7 @@
 (defn parse [code]
   (-root (lex code)))

-(defn matched-nodes [input types] ;; bit round the houses
+(defn alternatives [input types] ;; bit round the houses
   (vec (map (fn [t] (t input)) ;; get nodes for each matching type
             (filter (fn [t] (not= nil (t input))) ;; get matching types
                     types))))
@@ -43,7 +43,7 @@
 ;; expressions

 (defn -expression [tokens collected]
-  (def expressions (matched-nodes tokens expression-types)) ;; candidates
+  (def expressions (alternatives tokens [-assignment -invocation]))
   (if (> (count expressions) 0)
     (let [{expr :expr left-tokens :left-tokens} (first expressions)]
       {:expr (nnode :expression [expr]) :left-tokens left-tokens}) ;; return expr
@@ -90,7 +90,7 @@
 ;; values

 (defn -value [token]
-  (def nodes (matched-nodes token value-types))
+  (def nodes (alternatives token [-string -integer -identifier]))
   (if (> (count nodes) 0)
     (nnode :value [(first nodes)])
     nil))


Make `one-token-pattern` take care of whether it has enough tokens so `pattern-sequence` doesn't have to.

--- src/isla/parser.clj
+++ src/isla/parser.clj
@@ -100,11 +100,13 @@
           nil))))) ;; pattern match failure token match failure - return

 (defn one-token-pattern [tokens matcher tag & args]
-  (if (is-type matcher (first tokens))
-    (let [output (if (not= nil args)
-                   ((first args) (first tokens))
-                   [(first tokens)])]
-      {:node (nnode tag output) :left-tokens (rest tokens)})
+  (if-let [token (first tokens)]
+    (if (is-type matcher token)
+      (let [output (if (not= nil args)
+                     ((first args) token)
+                     [token])]
+        {:node (nnode tag output) :left-tokens (rest tokens)})
+      nil)
     nil))

 (defn nnode [tag data]


tidy docstring

tidy docstring

--- src/overtone/sc/cgens/buf_io.clj
+++ src/overtone/sc/cgens/buf_io.clj
@@ -2,7 +2,8 @@
   (:use [overtone.sc defcgen ugens]))

 (defcgen scaled-play-buf
-  "Play back a sample resident in a buffer with a rate scaled depending on the buffer's sample-rate."
+  "Play back a sample resident in a buffer with a rate scaled depending
+   on the buffer's sample-rate."
   [num-channels {:doc "The number of channels that the buffer will be. This must be a fixed integer." :modulatable false}
    buf-num {:default 0 :doc "The index of the buffer to use."}
    rate {:default 1 :doc "Rate multiplier. 1.0 is the default rate for the specified buffer, 2.0 is one octave up, 0.5 is one octave down -1.0 is backwards normal rate ... etc. Interpolation is cubic."}


Parse 'from-date' and 'to-date' attributes before writing to changelog

--- src/main/clojure/pdok/featured/timeline.clj
+++ src/main/clojure/pdok/featured/timeline.clj
@@ -2,7 +2,7 @@
   (:require [pdok.cache :refer :all]
             [pdok.featured.dynamic-config :as dc]
             [pdok.postgres :as pg]
-            [pdok.util :refer [with-bench checked] :as util]
+            [pdok.util :refer [with-bench checked parse-time] :as util]
             [pdok.featured.projectors :as proj]
             [pdok.transit :as transit]
             [pdok.filestore :as fs]
@@ -236,7 +236,9 @@
             (merge
               {:collection collection}
               (when delivery-info
-                {:delivery-info delivery-info}))
+                {:delivery-info (->> [:from-date :to-date]
+                                  (filter delivery-info)
+                                  (reduce #(update %1 %2 util/parse-time) delivery-info))}))
             entries)
           (.closeEntry zip))))))


Removed memcache service dependency.

Removed memcache service dependency.

--- src/appengine_magic/services/url_fetch.clj
+++ src/appengine_magic/services/url_fetch.clj
@@ -6,8 +6,7 @@
             HTTPHeader
             HTTPRequest
             HTTPMethod])
-  (:require [clojure.contrib.string :as string]
-            [appengine-magic.services.memcache :as memcache]))
+  (:require [clojure.contrib.string :as string]))

 (defonce *urlfetch-service* (atom nil))


(PDB-3723) Support upsert in jdbc

(PDB-3723) Support upsert in jdbc

[rlb@puppet.com: adjust message and indentation]

--- src/puppetlabs/puppetdb/jdbc.clj
+++ src/puppetlabs/puppetdb/jdbc.clj
@@ -67,20 +67,112 @@
   ([table columns values]
    (sql/insert! *db* table columns values {})))

+(defn- insert-multi-row
+  "Given a table and a list of columns, followed by a list of column
+  value sequences, return a vector of the SQL needed for the insert
+  followed by the list of column value sequences. The entities
+  function specifies how column names are transformed."
+  [table columns values {:keys [on-conflict] :as opts}]
+  (let [nc (count columns)
+        vcs (map count values)]
+    (if (not (and (or (zero? nc) (= nc (first vcs))) (apply = vcs)))
+      (throw (IllegalArgumentException.
+              "insert! called with inconsistent number of columns / values"))
+      (into [(str "INSERT INTO " (name table)
+                  (when (seq columns)
+                    (str " ( "
+                         (str/join ", " (map (fn [col] (name col)) columns))
+                         " )"))
+                  " VALUES ( "
+                  (str/join ", " (repeat (first vcs) "?"))
+                  " ) "
+                  (when on-conflict
+                    (str "on conflict " on-conflict)))]
+            values))))
+
+(defn- insert-single-row-on-conflict
+  "Given a table and a map representing a row, return a vector of the
+  SQL needed for the insert followed by the list of column values. The
+  entities function specifies how column names are transformed."
+  [table row entities {:keys [on-conflict] :as opts}]
+  (let [ks (keys row)]
+    (into [(str "INSERT INTO " (name table) " ( "
+                (str/join ", " (map (fn [col] (name col)) ks))
+                " ) VALUES ( "
+                (str/join ", " (repeat (count ks) "?"))
+                " ) "
+                (when on-conflict
+                  (str "ON CONFLICT " on-conflict)))]
+          (vals row))))
+
+(defn- insert-cols!
+  "Given a database connection, a table name, a sequence of columns
+  names, a sequence of vectors of column values, one per row, and an
+  options map, insert the rows into the database."
+  [db table cols values opts]
+  (let [{:keys [entities transaction?]} (merge {:entities identity :transaction? true}
+                                               (when (map? db) db)
+                                               opts)
+        sql-params (insert-multi-row table cols values opts)]
+    (if-let [con (sql/db-find-connection db)]
+      (sql/db-do-prepared db transaction? sql-params {:multi? true})
+      (with-open [con (sql/get-connection db)]
+        (sql/db-do-prepared (sql/add-connection db con) transaction?
+                            sql-params {:multi? true})))))
+
+(defn- multi-insert-helper
+  "Given a (connected) database connection and some SQL
+  statements (for multiple inserts), run a prepared statement on each
+  and return any generated keys.  Note: we are eager so an unrealized
+  lazy-seq cannot escape from the connection."
+  [db stmts opts]
+  (doall (map (fn [row] (sql/db-do-prepared-return-keys db false row opts))
+              stmts)))
+
+(defn- insert-helper
+  "Given a (connected) database connection, a transaction flag and some SQL statements
+  (for one or more inserts), run a prepared statement or a sequence of
+  them."
+  [db transaction? stmts opts]
+  (if transaction?
+    (sql/with-db-transaction [t-db db] (multi-insert-helper t-db stmts opts))
+    (multi-insert-helper db stmts opts)))
+
+(defn- insert-rows!
+  "Given a database connection, a table name, a sequence of rows, and
+  an options map, insert the rows into the database."
+  [db table rows {:keys [on-conflict] :as opts}]
+  (let [{:keys [entities identifiers qualifier transaction?]}
+        (merge {:entities identity :identifiers str/lower-case :transaction? true}
+               (when (map? db) db)
+               opts)
+        sql-params (map (fn [row]
+                          (when-not (map? row)
+                            (throw (IllegalArgumentException.
+                                    "insert / insert-multi! called with a non-map row")))
+                          (insert-single-row-on-conflict table row entities opts))
+                        rows)]
+    (if-let [con (sql/db-find-connection db)]
+      (insert-helper db transaction? sql-params
+                     {:identifiers identifiers :qualifier qualifier})
+      (with-open [con (sql/get-connection db)]
+        (insert-helper (sql/add-connection db con) transaction? sql-params
+                       {:identifiers identifiers :qualifier qualifier})))))
+
 (defn insert-multi!
-  "Inserts multiple rows in either map form or lists of columns & values form. The
-  database to use is given by (jdbc/db). Returns a sequence with every inserted
-  row as returned by the database."
+  "Inserts multiple rows in either map form or lists of columns &
+  values form. The database to use is given by (jdbc/db). Returns a
+  sequence with every inserted row as returned by the database."
   ;; since clojure.java.jdbc will open a connection even when given an empty
   ;; rows or values sequence, bypass it here if either of those are empty
   ([table rows]
-   (if (seq rows)
-     (sql/insert-multi! *db* table rows {})
-     ()))
-  ([table columns values]
-   (if (seq values)
-     (sql/insert-multi! *db* table columns values {})
-     ())))
+   (sql/insert-multi! *db* table rows))
+  ([table cols-or-rows values-or-opts]
+   (if (map? values-or-opts)
+     (insert-rows! *db* table cols-or-rows values-or-opts)
+     (insert-cols! *db* table cols-or-rows values-or-opts {})))
+  ([table cols values opts]
+   (sql/insert-multi! *db* table cols values opts)))

 (defn update!
   "Calls clojure.jdbc/update! after adding (jdbc/db) as the first argument."


First attempt at find-all-tests

First attempt at find-all-tests

--- src/radicalzephyr/boot_junit.clj
+++ src/radicalzephyr/boot_junit.clj
@@ -1,7 +1,8 @@
 (ns radicalzephyr.boot-junit
   {:boot/export-tasks true}
   (:require [boot.core :as core])
-  (:import org.junit.runner.JUnitCore))
+  (:import org.junit.runner.JUnitCore
+           org.reflections.Reflections))

 (defn failure->map [failure]
   {:description (.. failure (getDescription) (toString))
@@ -17,7 +18,13 @@
    :failures (map failure->map (.getFailures result))})

 (defn find-all-tests [packages]
-  [])
+  (let [reflections (Reflections. (first packages))
+        test-methods (.getMethodsAnnotatedWith reflections
+                                               org.junit.Test)]
+    (->> test-methods
+         (map (memfn getDeclaringClass))
+         set
+         vec)))

 (core/deftask junit
   "Run the jUnit test runner."


remove unused fn

remove unused fn

--- test/clj_money/api/commodities_test.clj
+++ test/clj_money/api/commodities_test.clj
@@ -38,13 +38,6 @@
 (defn- select-resources [ctx]
   (commodities/search storage-spec {:entity-id (:id (find-entity ctx))}))

-(deftest-list get-a-list-of-commodities
-  {:list-fn api/index
-   :params-fn #(hash-map :entity-id (:id (find-entity %)))
-   :expectation-fn #(= #{"USD"} (->> %
-                                     (map :symbol)
-                                     (into #{})))})
-
 (def ^:private commodity-attributes
   {:resource-name "commodity"
    :type "stock"


Add support for html5 push-state.

Add support for html5 push-state.

--- src/bide/core.cljs
+++ src/bide/core.cljs
@@ -27,7 +27,7 @@
   (:require [bide.impl.router :as rtr]
             [clojure.string :as str]
             [goog.events :as e])
-  (:import goog.History))
+  (:import goog.history.Html5History))

 ;; --- Protocols

@@ -121,8 +121,14 @@

 (defn start!
   "Starts the bide routing handling using the goog.History
-  api as browser history event watching mechanism."
-  [router {:keys [on-navigate default] :as opts}]
+  api as browser history event watching mechanism.
+
+  If you want use the html5 history instance providing
+  a factory function that returns the Html5History object
+  instance."
+  [router {:keys [on-navigate default html5?]
+           :or {html5? false}
+           :as opts}]
   (let [default (if (vector? default) default [default nil])]
     (letfn [(-on-navigate [event]
               (let [[name params query] (-match (.-token event))]
@@ -135,7 +141,14 @@
                 (if (str/blank? token)
                   (or (apply resolve router default) "/")
                   token)))]
-      (let [history (doto (History.) (.setEnabled true))
+      (let [history (if html5?
+                      (doto (Html5History.)
+                        (.setPathPrefix "")
+                        (.setUseFragment false)
+                        (.setEnabled true))
+                      (doto (Html5History.)
+                        (.setUseFragment true)
+                        (.setEnabled true)))
             initial-token (-initial-token history)
             initial-loc (-match initial-token)]
         (e/listen history History.EventType.NAVIGATE -on-navigate)


(PE-2368) Added test for new get-in-config functionality

--- test/clj/puppetlabs/trapperkeeper/services/config/config_service_test.clj
+++ test/clj/puppetlabs/trapperkeeper/services/config/config_service_test.clj
@@ -8,7 +8,8 @@
    {:depends [[:config-service get-in-config get-config]]
     :provides []}
    {:test-fn (fn [ks] (get-in-config ks))
-    :test-fn-2 (fn [] (get-config))})
+    :test-fn-2 (fn [] (get-config))
+    :get-in-config get-in-config})

 (deftest test-config-service
   (testing "Fails if config path doesn't exist"
@@ -33,4 +34,9 @@
           test-fn (get-service-fn app :test-service :test-fn)]
       (is (= (test-fn [:baz :setting1]) "baz1"))
       (is (= (test-fn [:baz :setting2]) "baz2"))
-      (is (= (test-fn [:bam :setting1]) "bam1")))))
+      (is (= (test-fn [:bam :setting1]) "bam1"))))
+
+  (testing "A proper default value is returned if a key can't be found"
+    (let [app     (bootstrap* [(test-service)] {:config "./test-resources/config/dir"})
+          test-fn (get-service-fn app :test-service :get-in-config)]
+      (is (= (test-fn [:doesnt :exist] "foo") "foo")))))


Update for symbol name change

Update for symbol name change

--- breakout/desktop/src-common/breakout/core.clj
+++ breakout/desktop/src-common/breakout/core.clj
@@ -82,12 +82,12 @@
       (width! screen game-w)
       ; attach the ball to the paddle so it can't reach the blocks
       ; (this is only meant to test that joints work)
-      (comment create-joint! screen
-               (joint-def :rope
-                          :body-a (:body ball)
-                          :body-b (:body paddle)
-                          :max-length 5
-                          :collide-connected true))
+      (comment add-joint! screen
+                  (joint-def :rope
+                             :body-a (:body ball)
+                             :body-b (:body paddle)
+                             :max-length 5
+                             :collide-connected true))
       ; return the entities
       [(assoc ball :ball? true)
        (assoc paddle :paddle? true)


added socket-config

added socket-config

--- src/link/socketio.clj
+++ src/link/socketio.clj
@@ -7,7 +7,7 @@
   (:import [com.corundumstudio.socketio
             Configuration SocketIOServer
             SocketIOClient VoidAckCallback
-            AckRequest])
+            AckRequest SocketConfig])
   (:import [com.corundumstudio.socketio.listener
             ConnectListener DisconnectListener
             DataListener ClientListeners]))
@@ -49,9 +49,12 @@
                                  heartbeat-interval
                                  ack-mode]
                           :or {hostname "0.0.0.0"}}]
-  (let [config (doto (Configuration.)
+  (let [socket-config (doto (SocketConfig.)
+                        (.setReuseAddress true))
+        config (doto (Configuration.)
                  (.setPort port)
-                 (.setHostname hostname))]
+                 (.setHostname hostname)
+                 (.setSocketConfig socket-config))]
     (when ssl-keystore-in
       (.setKeyStore ^Configuration config
                     ssl-keystore-in))


run kibit on io

run kibit on io

--- src/civs/io.clj
+++ src/civs/io.clj
@@ -78,7 +78,7 @@
         serializable-data data]
     (set-world-print-method (:world-filename options))
     (miner.tagged/pr-tagged-record-on serializable-data writer)
-    (.toString writer)))
+    (str writer)))

 (defn world-reader [resolver]
   (fn [value]
@@ -129,11 +129,11 @@
     fress/inheritance-lookup))

 (defn- fress-read-handlers [resolve]
-  (-> (merge {
-               world-ftag    (world-freader resolve)
-               language-ftag (language-freader)
-             } fress/clojure-read-handlers)
-          fress/associative-lookup))
+  (fress/associative-lookup
+    (merge
+      {world-ftag (world-freader resolve),
+       language-ftag (language-freader)}
+      fress/clojure-read-handlers)))

 (defn to-serialized-bytes [data]
   (let [os (java.io.ByteArrayOutputStream.)
@@ -154,7 +154,7 @@
     (fn [game group-id]
       (let [current-pe (political-entity-at history t group-id)
             prev-pe    (political-entity-at history prev-t group-id)]
-        (if (not (nil? prev-pe))
+        (if-not (nil? prev-pe)
           (if (= (.culture current-pe) (.culture prev-pe))
             (let [updated-pe (assoc current-pe :culture :unchanged)]
               (update-political-entity game (.id updated-pe) (fn [_ _]  updated-pe)))
@@ -174,7 +174,7 @@
 (defn prepare-history-for-serialization
   "We replace elements unchanged from turn to turn with :unchanged"
   [history]
-  (reduce (fn [acc turn] (prepare-history-turn-for-serialization acc turn)) history (rest (turns history))))
+  (reduce prepare-history-turn-for-serialization history (rest (turns history))))

 (defn- restore-game-from-serialization
   "Return game, updated"
@@ -183,7 +183,7 @@
     (fn [game group-id]
       (let [current-group (political-entity-at history t group-id)
             prev-group    (political-entity-at history prev-t group-id)]
-        (if (not (nil? prev-group))
+        (if-not (nil? prev-group)
           (if (= :unchanged (.culture current-group))
             (let [updated-group (assoc current-group :culture  (.culture prev-group))]
               (update-political-entity game (.id updated-group) (fn [_ _] updated-group)))
@@ -202,7 +202,7 @@

 (defn restore-history-from-serialization [history]
   [history]
-  (reduce (fn [acc turn] (restore-history-turn-from-serialization acc turn)) history (rest (turns history))))
+  (reduce restore-history-turn-from-serialization history (rest (turns history))))

 (defn save-simulation-result-fressian [simulation-result history-filename]
   (let [ bytes (to-serialized-bytes (prepare-history-for-serialization simulation-result))


Remove duplicate mapcat.

Remove duplicate mapcat.

--- src/cljs/cljs_repl_web/cljs_api/utils.cljs
+++ src/cljs/cljs_repl_web/cljs_api/utils.cljs
@@ -17,7 +17,7 @@
                                         distinct? empty? every? not-every? some not-any?))
                          (Topic. "higher-order functions"
                                  '(map map-indexed mapcat reduce filter partition-by
-                                       take-while keep remove merge-with mapcat iterate repeatedly))
+                                       take-while keep remove merge-with iterate repeatedly))

                          (Topic. "functions as data"
                                  '(apply partial comp complement juxt))])


a little comment

a little comment

--- src/cljx/jamesmacaulay/zelkova/signal.cljx
+++ src/cljx/jamesmacaulay/zelkova/signal.cljx
@@ -32,6 +32,7 @@
   "Messages are propagated through the signal graph, and can either be \"fresh\" or \"cached\"."
   (fresh? [msg] "returns `true` if the message represents a fresh value, `false` otherwise"))

+; an external event
 (defrecord Event
   [topic value]
   BoxedValueProtocol


Make DIF organizations test multiple.

Make DIF organizations test multiple.

--- src/cmr/umm/test/generators/collection.clj
+++ src/cmr/umm/test/generators/collection.clj
@@ -150,7 +150,7 @@
                 :projects (ext-gen/nil-if-empty (gen/vector campaigns 0 4))
                 :related-urls (ext-gen/nil-if-empty (gen/vector related-url 0 5))
                 :spatial-coverage (ext-gen/optional spatial-coverages)
-                :organizations (gen/vector distribution-center-organizations 1 1)))))
+                :organizations (gen/vector distribution-center-organizations 1 3)))))

 ; Generator for basic collections that only have the bare minimal fields
 ;; DEPRECATED - this will go away in the future. Don't use it.


Empty status if not in status map

Empty status if not in status map

--- server/src/clinicico/server/tasks.clj
+++ server/src/clinicico/server/tasks.clj
@@ -25,7 +25,7 @@
   [ch metadata ^bytes payload]
   (let [update (json/decode-smile payload true)
         content (into {} (filter (comp not nil? val) (:content update)))
-        status (@statuses (:id update))]
+        status (or (@statuses (:id update)) {})]
     (log/debug (format "[consumer] Received %s" update))
     (swap! statuses assoc (:id update) (merge status content))))


Change tables

Change tables

--- src/airhead_frontend/components.cljs
+++ src/airhead_frontend/components.cljs
@@ -105,6 +105,15 @@
       [action-button track])]
    [:td (track :title)] [:td (track :artist)] [:td (track :album)]])

+
+;; -------------------------
+;; Tables
+
+(defn table [head content]
+  [:table.pure-table.pure-table-horizontal
+   [:thead head]
+   [:tbody content]])
+
 ;; -------------------------
 ;; Playlist

@@ -112,11 +121,10 @@
   [:section#playlist
    [:h2 "Playlist"]
    (if-let [tracks (not-empty (@app-state :playlist))]
-     [:table.pure-table.pure-table-striped
-      [:thead
-       [:tr [:th] [:th  "Title"] [:th "Artist"] [:th "Album"]]]
-      [:tbody (for [track tracks]
-                ^{:key track} [track-tr track playlist-remove-button])]]
+     [table
+      [:tr [:th] [:th  "Title"] [:th "Artist"] [:th "Album"]]
+      (for [track tracks]
+        ^{:key track} [track-tr track playlist-remove-button])]
      "The playlist is empty.")])

 ;; -------------------------
@@ -160,14 +168,13 @@
                :value (@app-state :query)
                :on-change on-query-change}]
       [:span (str "Tracks: " (count tracks))]]
-     [:table.pure-table.pure-table-striped
-      [:thead
-       [:tr [:th]
-        [sorting-th :title "Title"]
-        [sorting-th :artist "Artist"]
-        [sorting-th :album "Album"]]]
-      [:tbody (for [track (sort-tracks tracks)]
-                ^{:key track} [track-tr track playlist-add-button])]]]))
+     [table
+      [:tr [:th]
+       [sorting-th :title "Title"]
+       [sorting-th :artist "Artist"]
+       [sorting-th :album "Album"]]
+      (for [track (sort-tracks tracks)]
+        ^{:key track} [track-tr track playlist-add-button])]]))

 ;; -------------------------
 ;; Main


Fix #7: little hack to make article routing work on page load

--- src/markiki/core.cljs
+++ src/markiki/core.cljs
@@ -30,5 +30,10 @@
 (defn ^:export main
   []
   (dispatch-sync [:initialize-db])
+  ;; HACK: make article routing work on page load (so you can link articles)
+  (let [old-hash (str (.-hash js/location))]
+    (when (not-empty old-hash)
+      (set! (.-hash js/location) "#")
+      (set! (.-hash js/location) old-hash)))
   (r/render [markiki.views/markiki-app]
                   (.getElementById js/document "app")))


[#1189] Fix for when column to import have a trailing space

--- backend/src/akvo/lumen/update.clj
+++ backend/src/akvo/lumen/update.clj
@@ -8,7 +8,6 @@
             [clojure.java.jdbc :as jdbc]
             [clojure.set :as set]
             [clojure.string :as string]
-            [clojure.walk :refer [keywordize-keys]]
             [hugsql.core :as hugsql]))

 (hugsql/def-db-fns "akvo/lumen/job-execution.sql")
@@ -65,14 +64,12 @@
         columns))))

 (defn compatible-columns? [imported-columns columns]
-  (let [imported-columns (map #(cond-> {:id (keyword (:columnName %))
-                                        :type (keyword (:type %))
-                                        :title (:title %)}
-                                 (contains? % :key) (assoc :key (boolean (:key %))))
-                              (->> imported-columns
-                                   (map keywordize-keys)
-                                   (map #(update % :title string/trim))))
-        columns (map keywordize-keys columns)]
+  (let [imported-columns (map (fn [column]
+                                (cond-> {:id (keyword (get column "columnName"))
+                                         :type (keyword (get column "type"))
+                                         :title (string/trim (get column "title"))}
+                                  (contains? column "key") (assoc :key (boolean (get column "key")))))
+                              imported-columns)]
     (set/subset? (set imported-columns)
                  (set columns))))

@@ -81,12 +78,13 @@
     (let [table-name (util/gen-table-name "ds")
           imported-table-name (util/gen-table-name "imported")
           imported-columns (vec
-                            (:columns (imported-dataset-columns-by-dataset-id conn
-                                                                              {:dataset-id dataset-id})))
+                            (:columns (imported-dataset-columns-by-dataset-id
+                                       conn {:dataset-id dataset-id})))
           {:keys [transformations] :as dataset-version} (latest-dataset-version-by-dataset-id
                                                          conn {:dataset-id dataset-id})]
       (with-open [importer (import/dataset-importer (get data-source-spec "source") config)]
-        (let [columns (import/columns importer)]
+        (let [columns (map #(update-in % [:title] string/trim)
+                           (import/columns importer))]
           (if-not (compatible-columns? imported-columns columns)
             (failed-update conn job-execution-id "Column mismatch")
             (do (import/create-dataset-table conn table-name columns)


fix indent

fix indent

--- src/misaki/reader.clj
+++ src/misaki/reader.clj
@@ -32,11 +32,10 @@
   [in]
   (let [line-num (atom 1)]
     (proxy [PushbackReader IDeref] [in]
-      (read []
-            (let [c (proxy-super read)]
-              (if (and (not= -1 c) (= \newline (char c)))
-                (swap! line-num inc))
-              c))
+      (read [] (let [c (proxy-super read)]
+                 (if (and (not= -1 c) (= \newline (char c)))
+                   (swap! line-num inc))
+                 c))
       (deref [] @line-num))))

 ; =skip-to-token


Fix spec for AWS credentials

Fix spec for AWS credentials

--- src/braid/chat/core.cljc
+++ src/braid/chat/core.cljc
@@ -35,7 +35,7 @@
        ;; TODO some of these might better belong elsewhere
        (base/register-config-var! :aws-bucket :optional [:string])
        (base/register-config-var! :aws-region :optional [:string])
-       (base/register-config-var! :aws/credentials-provider :optional [:string])
+       (base/register-config-var! :aws/credentials-provider :optional [:fn fn?])
        (base/register-config-var! :cookie-secure :optional [:boolean])
        (base/register-config-var! :db-url :optional [:re #"^datomic:.*$"])
        (base/register-config-var! :github-client-id :optional [:re #"^[a-f0-9]{20}$"])


Made vis-init slightly more generic.

Made vis-init slightly more generic.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -91,35 +91,8 @@
     :end (fn [vis actx args]
            (let [[chs result] args] 2))}})

-;; ------------------------------------------------
-
-(defn example-add [actx x y delay]
-  (ago example-add actx
-       (<! (timeout delay))
-       (+ x y)))
-
-(defn example-sub [actx x y delay]
-  (ago example-sub actx
-       (<! (timeout delay))
-       (- x y)))
-
-(def cmd-handlers {"add" (fn []
-                           (let [x (js/parseInt (get-el-value "x"))
-                                 y (js/parseInt (get-el-value "y"))
-                                 fence (get-el-value "fence")
-                                 delay (js/parseInt (get-el-value "delay"))]
-                             {:rq #(example-add % x y delay) :fence (= fence "1")})),
-                   "sub" (fn []
-                           (let [x (js/parseInt (get-el-value "x"))
-                                 y (js/parseInt (get-el-value "y"))
-                                 fence (get-el-value "fence")
-                                 delay (js/parseInt (get-el-value "delay"))]
-                             {:rq #(example-sub % x y delay) :fence (= fence "1")}))})
-
-(defn vis-init []
-  (let [cmds (merge [(listen (gdom/getElement "add") "click")
-                     (listen (gdom/getElement "sub") "click")])
-        max-inflight (atom 10)
+(defn vis-init [cmds cmd-handlers]
+  (let [max-inflight (atom 10)
         event-delay (atom 0)
         event-ch (chan)
         last-id (atom 0)
@@ -151,4 +124,31 @@
                        (aput main-in in cmd-handler)
                        (recur)))))))

-(vis-init)
+;; ------------------------------------------------
+
+(defn example-add [actx x y delay]
+  (ago example-add actx
+       (<! (timeout delay))
+       (+ x y)))
+
+(defn example-sub [actx x y delay]
+  (ago example-sub actx
+       (<! (timeout delay))
+       (- x y)))
+
+(def cmd-handlers {"add" (fn []
+                           (let [x (js/parseInt (get-el-value "x"))
+                                 y (js/parseInt (get-el-value "y"))
+                                 fence (get-el-value "fence")
+                                 delay (js/parseInt (get-el-value "delay"))]
+                             {:rq #(example-add % x y delay) :fence (= fence "1")})),
+                   "sub" (fn []
+                           (let [x (js/parseInt (get-el-value "x"))
+                                 y (js/parseInt (get-el-value "y"))
+                                 fence (get-el-value "fence")
+                                 delay (js/parseInt (get-el-value "delay"))]
+                             {:rq #(example-sub % x y delay) :fence (= fence "1")}))})
+
+(vis-init (merge [(listen (gdom/getElement "add") "click")
+                  (listen (gdom/getElement "sub") "click")])
+          cmd-handlers)


Fix: change group after leaving a group

Fix: change group after leaving a group

--- src/braid/client/state/handlers.cljs
+++ src/braid/client/state/handlers.cljs
@@ -481,12 +481,15 @@
       (helpers/set-open-threads (data :user-threads))))

 (defmethod handler :leave-group [state [_ {:keys [group-id group-name]}]]
+  ; need to :remove-group before router is dispatched below
+  (dispatch! :remove-group group-id)
   (when (= group-id (helpers/get-open-group-id state))
     (router/go-to "/"))
   (-> state
       (helpers/display-error (str "left-" group-id)
                              (str "You have been removed from " group-name)
                              :info)
+      ; need this here also so the state gets changed when this dispatcher returns
       (helpers/remove-group group-id)
       ((fn [state]
          (if-let [sidebar-order (:groups-order (helpers/get-user-preferences state))]


no need for id and using latest quota structure

--- src/celestial/persistency/quotas.clj
+++ src/celestial/persistency/quotas.clj
@@ -7,7 +7,7 @@
     [slingshot.slingshot :refer  [throw+]]
     [clojure.core.strint :refer (<<)]))

-(defn used-key [{:keys [env] :as spec} k]
+(defn used-key [{:keys [env] :as spec}]
   [:quotas env (figure-virt spec) :used :count])

 (entity quota :id username)
@@ -28,8 +28,9 @@
 (defn quota-assert
   [{:keys [owner env] :as spec}]
   (let [hyp (figure-virt spec)
-       {:keys [limits used]} (get-in (get-quota owner) [:quotas hyp env])]
-    (when (= (:count used) (:count limits))
+        q (or (get-quota owner) {})
+       {:keys [limits used]} (get-in q [:quotas env hyp])]
+    (when (and (not (empty? q)) (= (:count used) (:count limits)))
       (throw+ {:type ::quota-limit-reached} (<< "Quota limit ~{limits} on ~{hyp} for ~{owner} was reached")))))

 (defn quota-change [{:keys [owner] :as spec} f]
@@ -39,19 +40,18 @@

 (defn increase-use
   "increases user quota use"
-  [id spec]
+  [spec]
   (quota-change spec inc))

 (defn decrease-use
   "decreases usage"
-  [id {:keys [owner] :as spec}]
-  (when-not (empty? (get-in (get-quota owner) (used-key spec)))
+  [{:keys [owner] :as spec}]
+  (when (get-in (get-quota owner) (used-key spec))
     (quota-change spec dec)))

-(defmacro with-quota [action spec & body]
+(defmacro with-quota [spec & body]
   `(do
      (quota-assert ~spec)
-     (let [~'id ~action]
-       (increase-use ~'id ~spec)
-       ~@body)))
+      ~@body
+     (increase-use ~spec)))


use aget with strings to make highlighter install work with advanced compile

--- src/chat/client/clj_highlighter.cljs
+++ src/chat/client/clj_highlighter.cljs
@@ -2,19 +2,19 @@

 (defn install-highlighter
   []
-  (let [PR (.-PR js/window)]
-    (PR.registerLangHandler
-      (PR.createSimpleLexer
+  (let [PR (aget js/window "PR")]
+    ((aget PR "registerLangHandler")
+      ((aget PR "createSimpleLexer")
         (clj->js
           [
            ["opn"  #"^[\(\{\[]+" nil "([{"]
            ["clo"  #"^[\)\}\]]+" nil ")]}"]
-           [(.-PR_COMMENT PR) #"^;[^\r\n]*" nil ";"]
-           [(.-PR_PLAIN PR) #"^[\t\n\r \u00A0]+" nil "\t\n\r \u00A0"]
-           [(.-PR_STRING PR) #"^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)" nil "\""]
+           [(aget PR "PR_COMMENT") #"^;[^\r\n]*" nil ";"]
+           [(aget PR "PR_PLAIN") #"^[\t\n\r \u00A0]+" nil "\t\n\r \u00A0"]
+           [(aget PR "PR_STRING") #"^\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)" nil "\""]
            ])
         (clj->js
           [
-           [(.-PR_KEYWORD PR) #"\b(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil\?|empty\?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list\?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)(?:\s|$)"]
-           [(.-PR_TYPE PR) #":[0-9a-zA-Z\-]+"]]) )
+           [(aget PR "PR_KEYWORD") #"\b(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil\?|empty\?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list\?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)(?:\s|$)"]
+           [(aget PR "PR_TYPE") #":[0-9a-zA-Z\-]+"]]) )
       #js ["clj"])))


Rename exclusiv-resources -> exclusiv-global-resources

--- src/cider_ci/dispatcher/dispatch.clj
+++ src/cider_ci/dispatcher/dispatch.clj
@@ -130,7 +130,8 @@
                                              (hh/from [:trials :active_trials])
                                              (hh/merge-join [:tasks :active_tasks] [:= :active_tasks.id :active_trials.task_id])
                                              (hh/merge-where [:in :active_trials.state  ["executing","dispatching"]])
-                                             (hh/merge-where (hc/raw "active_tasks.exclusive_resources && tasks.exclusive_resources")))])
+                                             (hh/merge-where (hc/raw (str "active_tasks.exclusive_global_resources "
+                                                                          "&& tasks.exclusive_global_resources"))))])
           (hh/merge-join :tasks [:= :tasks.id :trials.task_id])
           (hh/merge-join :jobs [:= :jobs.id :tasks.job_id])
           (hh/order-by [:jobs.priority :desc]


fix step-8 fully working

fix step-8 fully working

--- src/cljs/phonecat_re_frame/core.cljs
+++ src/cljs/phonecat_re_frame/core.cljs
@@ -39,7 +39,7 @@
    (let [phone-details-reaction (reaction (:phone-details @db))]
      (reaction ((keyword phone-id) @phone-details-reaction)))))

-(re-frame/register-pure-handler
+(re-frame/register-handler
  :process-phones-response
  (fn
    [app-state [_ response]]


Sketch updated linter.

Sketch updated linter.

--- src/clj/fleetdb/lint.clj
+++ src/clj/fleetdb/lint.clj
@@ -9,19 +9,21 @@
      (fail ~message ~val)))

 (def- query-types
-  #{:insert :select :count :update :delete :explain :list-collections
-    :create-index :drop-index :list-indexes :multi-read :multi-write
-    :checked-write})
+  #{"insert" "select" "count" "update" "delete" "explain" "list-collections"
+    "create-index" "drop-index" "list-indexes" "multi-read" "multi-write"
+    "checked-write"})

 (defn- lint-coll [coll]
-  (lint keyword? coll "collection not a keyword"))
+  (lint string? coll "collection not a string"))
+
+(def- attr? string?)

 (defn- lint-attr [attr]
-  (lint keyword? attr "attr not a keyword?"))
+  (lint attr? attr "attr not a string"))

 (defn val? [v]
   (or (boolean? v) (nil? v)
-      (string? v) (keyword? v) (number? v)))
+      (string? v)  (number? v)))

 (defn- lint-val [val]
   (lint val? val "value not of a recognized type"))
@@ -31,7 +33,7 @@
   (lint-val val))

 (defn- lint-dir [dir]
-  (lint #{:asc :desc} dir "unrecognized direction"))
+  (lint #{"asc" "desc"} dir "unrecognized direction"))

 (defn- lint-record [r]
   (lint map? r "record not a map")
@@ -49,13 +51,13 @@

 (defn- lint-order [order]
   (lint vector? order "order not a vector")
-  (if (keyword? (first order))
+  (if (attr? (first order))
     (lint-order-comp order)
     (domap lint-order-comp order)))

-(def- sing-ops #{:= :!= :< :<= :> :>=})
-(def- doub-ops #{:>< :>=< :><= :>=<=})
-(def- conj-ops #{:and :or})
+(def- sing-ops #{"=" "!=" "<" "<=" ">" ">="})
+(def- doub-ops #{"><" ">=<" "><=" ">=<="})
+(def- conj-ops #{"and" "or"})

 (defn- lint-where [where]
   (lint vector? where "where not a vector")
@@ -81,32 +83,32 @@
          (let [[_ & sub-wheres] where]
            (lint #(not (empty? %)) sub-wheres "no sub clauses given")
            (domap lint-where sub-wheres))
-       (= :in op)
+       (= "in" op)
          (do
-           (lint #(= 3 (count %)) where ":in clause has 2 arguments")
+           (lint #(= 3 (count %)) where "in clause has 2 arguments")
            (let [[_ attr vals] where]
              (lint-attr attr)
-             (lint vector? vals "vals for :in must be in a vector")
+             (lint vector? vals "vals for in must be in a vector")
              (domap lint-val vals)))
        :else
          (fail "unrecognized where operation" op))))

 (defn- lint-only [only]
   (cond
-    (keyword? only) :ok
+    (attr?    only) :ok
     (vector?  only) (domap lint-attr only)
-    :else           (fail "unrecognized :only value" only)))
+    :else           (fail "unrecognized only value" only)))

 (defn- lint-find-opts [opts allow-only]
   (when-not (nil? opts)
     (lint map? opts "options not a map")
     (doseq [[opt-name opt-val] opts]
       (condp = opt-name
-        :limit  (lint-pos-int opt-val "limit")
-        :offset (lint-pos-int opt-val "offset")
-        :order  (lint-order opt-val)
-        :where  (lint-where opt-val)
-        :only
+        "limit"  (lint-pos-int opt-val "limit")
+        "offset" (lint-pos-int opt-val "offset")
+        "order"  (lint-order opt-val)
+        "where"  (lint-where opt-val)
+        "only"
           (if-not allow-only
             (fail "only option not applicable for this query" opt-val)
             (lint-only opt-val))
@@ -117,19 +119,19 @@

 (defn- lint-ispec [ispec]
   (cond
-    (keyword? ispec) :ok
+    (attr?   ispec) :ok
     (vector? ispec)
       (doseq [ispec-comp ispec]
         (cond
-          (keyword? ispec-comp) :ok
+          (attr?   ispec-comp) :ok
           (vector? ispec-comp)
             (lint #(= 2 (count %)) ispec-comp "index spec component vector must have 2 elements")
             (lint-attr (first ispec-comp))
             (lint-dir  (second ispec-comp)))
           :else
-            (fail "index spec component must be a keyword or vector" ispec-comp))
+            (fail "index spec component must be a string or vector" ispec-comp))
     :else
-      (fail "index spec must be a keyword or vector" ispec)))
+      (fail "index spec must be a string or vector" ispec)))

 (defn lint-num-args [n q]
   (if (integer? n)
@@ -228,29 +230,29 @@
   (if-not (vector? q)
     (fail "query not a vector" q)
     (condp = (first q)
-      :insert           (lint-insert           q)
-      :select           (lint-select           q)
-      :count            (lint-count            q)
-      :update           (lint-update           q)
-      :delete           (lint-delete           q)
-      :explain          (lint-explain          q)
-      :list-collections (lint-list-collections q)
-      :create-index     (lint-create-index     q)
-      :drop-index       (lint-drop-index       q)
-      :list-indexes     (lint-list-indexes     q)
-      :multi-read       (lint-multi-read       q)
-      :multi-write      (lint-multi-write      q)
-      :checked-write    (lint-checked-write    q)
+      "insert"           (lint-insert           q)
+      "select"           (lint-select           q)
+      "count"            (lint-count            q)
+      "update"           (lint-update           q)
+      "delete"           (lint-delete           q)
+      "explain"          (lint-explain          q)
+      "list-collections" (lint-list-collections q)
+      "create-index"     (lint-create-index     q)
+      "drop-index"       (lint-drop-index       q)
+      "list-indexes"     (lint-list-indexes     q)
+      "multi-read"       (lint-multi-read       q)
+      "multi-write"      (lint-multi-write      q)
+      "checked-write"    (lint-checked-write    q)
       (fail "unrecognized query type" (first q)))))

 (defn- lint-read-query [q]
-  (lint #{:select :count :explain :list-collections :list-indexes :multi-read}
+  (lint #{"select" "count" "explain" "list-collections" "list-indexes" "multi-read"}
         (first q)
         "query not a read query")
   (lint-query q))

 (defn- lint-write-query [q]
-  (lint #{:insert :update :delete :create-index :drop-index :multi-write :checked-write}
+  (lint #{"insert" "update" "delete" "create-index" "drop-index" "multi-write" "checked-write"}
         (first q)
         "query not a write query")
   (lint-query q))


Fixed missing numeric-tower/round

Fixed missing numeric-tower/round

--- src/clj/forma/postprocess/output.clj
+++ src/clj/forma/postprocess/output.clj
@@ -3,7 +3,8 @@
         [forma.reproject :only (modis->latlon)]
         [forma.date-time :only (period->datetime datetime->period)]
         [clojure.string :only (split join)]
-        [forma.utils :only (moving-average average)]))
+        [forma.utils :only (moving-average average)]
+        [clojure.math.numeric-tower :only (round)]))

 (defn get-val
   [out-m & k]


Catch sql insertion exceptions and return them as nom/anomalies

--- src/clj/mdr2/db/core.clj
+++ src/clj/mdr2/db/core.clj
@@ -6,7 +6,8 @@
     [clojure.tools.logging :as log]
     [conman.core :as conman]
     [mdr2.config :refer [env]]
-    [mount.core :refer [defstate]]))
+    [mount.core :refer [defstate]]
+    [de.otto.nom.core :as nom]))

 (defstate ^:dynamic *db*
   :start (if-let [jdbc-url (env :database-url)]
@@ -61,6 +62,7 @@
 (defn insert-production
   "Insert the given `production`. Return it with the updated primary key `id`"
   [production]
-  (if-let [key (-> (insert-raw production) first :generated_key)]
-    (assoc production :id key)
-    production))
+  (nom/try-nom
+    (if-let [key (-> (insert-raw production) first :generated_key)]
+      (assoc production :id key)
+      production)))


fixup step-3

fixup step-3

--- src/cljs/phonecat_re_frame/core.cljs
+++ src/cljs/phonecat_re_frame/core.cljs
@@ -12,10 +12,15 @@
 ;; -------------------------
 ;; Re-frame data

+(re-frame/register-sub
+  :search-input
+  (fn [db]
+    (reaction (:search-input @db))))
+
 (re-frame/register-sub        ;; a new subscription handler
-   :phones             ;; usage (subscribe [:phones])
-   (fn [db]
-     (reaction (:phones @db))))  ;; pulls out :phones
+ :phones             ;; usage (subscribe [:phones])
+ (fn [db]
+   (reaction (:phones @db))))  ;; pulls out :phones

 (re-frame/register-handler
  :initialise-db             ;; usage: (dispatch [:initialise-db])
@@ -30,7 +35,7 @@
   [app-state [_ search-input]]
   (assoc-in app-state [:search-input] search-input))

-(re-frame/register-pure-handler
+(re-frame/register-handler
  :search-input-entered
  handle-search-input-entered)
 ;; -------------------------


refactoring http verbs

refactoring http verbs

--- src/clj/ohds/service.clj
+++ src/clj/ohds/service.clj
@@ -13,6 +13,7 @@
 (def apipass (:apipass config))

 (def fieldworkers-bulk-url "/fieldWorkers/bulk.json")
+(def users-bulk-url "/users/bulk.json")
 (def location-hierarchies-bulk-url "/locationHierarchies/bulk.json")
 (def location-url "/locations")
 (def individual-url "/individuals")
@@ -20,18 +21,27 @@
 (defn now []
   (str (LocalDateTime/now) "Z"))

+(defn json->cljs [data]
+  (json/read-str data :key-fn keyword))
+
 (defn post [url req]
-  (-> @(http/post (str apihost url) {:basic-auth [apiuser apipass]
-                                     :body (json/write-str req)
-                                     :headers {"Content-Type" "application/json"}})
-      (:body)
-      (json/read-str :key-fn keyword)
-      (:uuid)))
+  (->
+   {:basic-auth [apiuser apipass]
+    :body (json/write-str req)
+    :headers {"Content-Type" "application/json"}}
+   (http/post (str apihost url))
+   (deref)
+   (:body)
+   (json->cljs)
+   (:uuid)))

 (defn get [url]
-  (-> @(http/get url {:basic-auth [apiuser apipass]})
-      (:body)
-      (json/read-str :key-fn keyword)))
+  (->>
+   {:basic-auth [apiuser apipass]}
+   (http/get (str apihost url))
+   (deref)
+   (:body)
+   (json->cljs)))

 ;;; Login


Cleanup AI code a little bit + add comments about new AI logic

--- src/cljs/zetawar/ai.cljs
+++ src/cljs/zetawar/ai.cljs
@@ -1,30 +1,36 @@
 (ns zetawar.ai
   (:require
-    [cljs.pprint :refer [pprint]]
-    [datascript.core :as d]
-    [zetawar.db :refer [e qe qes]]
-    [zetawar.game :as game]))
+   [datascript.core :as d]
+   [zetawar.db :refer [e qe qes]]
+   [zetawar.game :as game]))

-;; for each unit:
-;; - repair if < 50% health (optional)
-;; - get moves
-;; - pick move that gets closest to a capturable base
-;;   - only move units that can capture onto bases
-;; - capture if on base
-;; - get attacks
-;; - attack a random enemy unit if possible
+;; current AI logic
+;;   - for each unit
+;;     - get moves
+;;     - pick move that gets closest to a capturable base
+;;       - only move units that can capture onto bases
+;;     - capture if on base
+;;     - get attacks
+;;     - attack a random enemy unit if possible

 ;; for each owned base:
 ;; - build a random unit

+;; new AI logic
+;; - check whether build criteria is met
+;;   - if bases exist that can build
+;;     - pick base to build at
+;;     - pick unit to build
+;;     - build unit
+;; - check for units with actions
+;;     - pick unit
+;;     - pick action
+;;     - perform action
+
 (defn move [conn game-id unit]
   (when-not (:unit/capturing unit)
     (let [db @conn
-          game (qe '[:find ?g
-                     :in $ ?game-id
-                     :where
-                     [?g :game/id ?game-id]]
-                   db game-id)
+          game (game/game-by-id db game-id)
           base (game/closest-capturable-base db game unit)
           move (game/closest-move-to-qr db game unit (:terrain/q base) (:terrain/r base))]
       (if (game/on-capturable-base? db game unit)
@@ -35,11 +41,7 @@
 (defn attack [conn game-id unit]
   (when-not (:unit/capturing unit)
     (let [db @conn
-          game (qe '[:find ?g
-                     :in $ ?game-id
-                     :where
-                     [?g :game/id ?game-id]]
-                   db game-id)
+          game (game/game-by-id db game-id)
           enemy (-> (game/enemies-in-range db game unit) shuffle first)]
       (when (and enemy (game/can-attack? db game unit))
         (game/attack! conn game-id
@@ -48,11 +50,7 @@

 (defn build [conn game-id]
   (let [db @conn
-        game (qe '[:find ?g
-                   :in $ ?game-id
-                   :where
-                   [?g :game/id ?game-id]]
-                 db game-id)
+        game (game/game-by-id db game-id)
         current-faction (:game/current-faction game)
         owned-bases (->> (qes '[:find ?t
                                 :in $ ?g


Add case-sibling-uniformity meta-error

Add case-sibling-uniformity meta-error

--- src/clojush/evaluate.clj
+++ src/clojush/evaluate.clj
@@ -173,6 +173,18 @@
                                                (iterate (partial * (- 1 improvement-discount)) 1))
                                  sum (reduce + (mapv * improvements weights))]
                              (- sum)))))))
+              ;
+              (= cat :case-sibling-uniformity)
+              (if (empty? (:parent-uuids ind))
+                (vec (repeat (count (:errors ind)) 1))
+                (let [siblings (filter #(= (first (:parent-uuids ind))
+                                           (first (:parent-uuids %)))
+                                       evaluated-population)]
+                  (vec (for [case-index (range (count (:errors ind)))]
+                         (if (apply = (mapv #(nth (:errors %) case-index)
+                                            siblings))
+                           1
+                           0)))))
               ;
               (= cat :reproductive-infidelity)
               (let [g (:genome ind)]


Hack more

Hack more

--- src/clojush/evaluate.clj
+++ src/clojush/evaluate.clj
@@ -623,7 +623,7 @@
                                              sum (reduce + (mapv * improvements weights))]
                                          (- sum)))))))
                           ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;HACKED STABILITY
-                          (if (not (:print-history argmap))
+                          #_(if (not (:print-history argmap))
                             (throw
                               (Exception.
                                 ":print-history must be true for :case-stagnation"))
@@ -638,6 +638,27 @@
                                                                     (if (= newer-error older-error)
                                                                       0.0
                                                                       -1.0)))
+                                                                (partition 2 1 case-history))
+                                             weights (take (count improvements)
+                                                           (iterate (partial * (- 1 improvement-discount)) 1))
+                                             sum (reduce + (mapv * improvements weights))]
+                                         (- sum)))))))
+                          ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;HACKED STABILITY
+                          (if (not (:print-history argmap))
+                            (throw
+                              (Exception.
+                                ":print-history must be true for :case-stagnation"))
+                            (if (empty? (rest (:history ind)))
+                              (vec (repeat (count (:errors ind)) 1000000))
+                              (vec (for [case-history (apply map list (:history ind))]
+                                     (if (zero? (first case-history))
+                                       -100000  ;; solved, improvement doesn't matter
+                                       (let [improvements (mapv (fn [[newer-error older-error]]
+                                                                  (if (< newer-error older-error)
+                                                                    1.0
+                                                                    (if (= newer-error older-error)
+                                                                      -1.0
+                                                                      0.0)))
                                                                 (partition 2 1 case-history))
                                              weights (take (count improvements)
                                                            (iterate (partial * (- 1 improvement-discount)) 1))


Add with related functions to dsl ns.

Add with related functions to dsl ns.

--- src/cljooq/dsl.clj
+++ src/cljooq/dsl.clj
@@ -215,3 +215,15 @@
   [c]
   (DSL/not c))

+(defn with
+  "Create a WITH clause"
+  [& tables]
+  (->> (into-array org.jooq.CommonTableExpression tables)
+       (DSL/with)))
+
+(defn with-fields
+  "Add a list of fields to this name to make this name a DerivedColumnList."
+  [n & fields]
+  (let [fields' (->> (map clojure.core/name fields)
+                     (into-array String))]
+    (.fields n fields')))


nope, had it right before *facepalm*

nope, had it right before *facepalm*

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -364,7 +364,7 @@
    (let [ice-index (fn [state i] (first (keep-indexed #(when (= (:cid %2) (:cid i)) %1)
                                                       (get-in @state (cons :corp (:zone i))))))
          sunhelp (fn sun [serv] {:prompt "Select two pieces of ICE to swap positions"
-                                 :choices {:req #(and (= serv (card->server state %))
+                                 :choices {:req #(and (= serv (rest (butlast (:zone %))))
                                                       (= (:type %) "ICE")) :max 2}
                                  :effect (req (if (= (count targets) 2)
                                                 (let [fndx (ice-index state (first targets))


Fix bug when user releases mouse button outside board.

--- src/cljs/nonojure/puzzleview.cljs
+++ src/cljs/nonojure/puzzleview.cljs
@@ -303,15 +303,13 @@
             (change-cell-in-board! board x y style)))
       (reset! last-cell [x y]))))

-(defn handle-mouse-up-on-cell [evt]
+(defn stop-dragging []
   (when (= :rect @drag-type)
     (when-let [style @current-fill-style]
-     (let [cell (.-target evt)
-           cur-x (attr-int cell :data-x)
-           cur-y (attr-int cell :data-y)]
-       (update-region-of-board! board @base-cell [cur-x cur-y] style))))
+      (update-region-of-board! board @base-cell @last-cell style)))
   (reset! current-fill-style nil)
-  (reset! base-cell nil))
+  (reset! base-cell nil)
+  (reset! last-cell nil))

 (defn disable-context-menu [evt]
   (.preventDefault evt)
@@ -328,8 +326,10 @@
   (listen! [(sel1 :#puzzle-table) :.cell]
                  :mousedown handle-mouse-down-on-cell
                  :contextmenu disable-context-menu
-                 :mouseenter handle-mouse-enter-on-cell
-                 :mouseup handle-mouse-up-on-cell)
+                 :mouseenter handle-mouse-enter-on-cell)
+  (listen! (sel1 :#puzzle-table)
+           :mouseup stop-dragging
+           :mouseleave stop-dragging)
   (listen! [(sel1 :#puzzle-table) :.num]
                  :mousedown handle-number-click
                  :contextmenu disable-context-menu)
@@ -337,7 +337,7 @@
   (listen! (sel1 :#button-clear) :click clear-puzzle))

 (defn show [nono]
-  (init-board! board (count (:left nono)) (count (:top nono)))
+  (init-board! board (count (:top nono)) (count (:left nono)))
   (dommy/replace! (sel1 :#puzzle-table) (create-template nono))
   (add-handlers)
   (dommy/remove-class! (sel1 :.puzzle-container) "hidden"))


Update and expand docstrings for `mapper!` etc.

--- src/clojure/parkour/mapreduce.clj
+++ src/clojure/parkour/mapreduce.clj
@@ -95,11 +95,17 @@
   (print-method (conf/diff job) w))

 (defn mapper!
-  "Allocate and return a new parkour mapper class for `conf` as invoking `var`.
-The `var` will be called during task-setup with the job Configuration and any
-provided `args` (which must be EDN-serializable).  It should return a function
-of one argument, which will be invoked with the task context, and should perform
-the desired content of the map task."
+  "Allocate and return a new Parkour mapper class for `conf` as invoking `var`.
+The `var` will be called during task-setup with the job `Configuration` and any
+provided `args` (which must be EDN-serializable).  The `var` should return a
+function of two arguments, which will be invoked with the task context and a
+reducible collection of the `unwrap`ed input tuples.  It should return a
+reducible collection of the output tuples, which will be automatically wrapped
+to match the job-configured map ouput types.
+
+If `var` has a truthy value for the `:parkour.mapreduce/raw` metadata key, then
+Parkour will invoke the `var`-returned function with only the task context, and
+will ignore any return value."
   [conf var & args]
   (let [i (conf/get-int conf "parkour.mapper.next" 0)]
     (conf/assoc! conf
@@ -119,11 +125,17 @@
     (Class/forName (format "parkour.hadoop.Reducers$_%d" i))))

 (defn reducer!
-  "Allocate and return a new parkour reducer class for `conf` as invoking `var`.
-The `var` will be called during task-setup with the job Configuration and any
-provided `args` (which must be EDN-serializable).  It should return a function
-of one argument, which will be invoked with the task context, and should perform
-the desired content of the reduce task."
+  "Allocate and return a new Parkour reducer class for `conf` as invoking `var`.
+The `var` will be called during task-setup with the job `Configuration` and any
+provided `args` (which must be EDN-serializable).  The `var` should return a
+function of two arguments, which will be invoked with the task context and a
+reducible collection of the `unwrap`ed input tuples.  It should return a
+reducible collection of the output tuples, which will be automatically wrapped
+to match the job-configured map ouput types.
+
+If `var` has a truthy value for the `:parkour.mapreduce/raw` metadata key, then
+Parkour will invoke the `var`-returned function with only the task context, and
+will ignore any return value."
   [conf var & args]
   (apply reducer!* :reduce conf var args))

@@ -134,13 +146,17 @@
   (apply reducer!* :combine conf var args))

 (defn partitioner!
-  "Allocate and return a new parkour partitioner class for `conf` as invoking
-`var`.  The `var` will be called during task-setup with the job Configuration
-and any provided `args` (which must be EDN-serializable).  It should return a
-function of three arguments: a map-output key, a map-output value, and an
-integral reduce-task count.  That function will called for each map-output
-tuple, and should return an integral value mod the reduce-task count.  Should be
-primitive-hinted as OOLL."
+  "Allocate and return a new Parkour partitioner class for `conf` as invoking
+`var`.  The `var` will be called during task-setup with the job `Configuration`
+and any provided `args` (which must be EDN-serializable).  The `var` should
+return a function of three arguments: an `unwrap`ed map-output key, an
+`unwrap`ed map-output value, and an integral reduce-task count.  That function
+will called for each map-output tuple, must return an integral value mod the
+reduce-task count, and should be primitive-hinted as `OOLL`.
+
+If `var` has a truthy value for the `:parkour.mapreduce/raw` metadata key, then
+Parkour will invoke the `var`-returned partitioner function with the raw (not
+unwrapped) tuple key and value objects."
   [conf var & args]
   (conf/assoc! conf
     "parkour.partitioner.var" (pr-str var)


Added timeout to elasticsearch cluster health check hoping to fix the build issue.

--- src/cmr/elastic_utils/connect.clj
+++ src/cmr/elastic_utils/connect.clj
@@ -24,7 +24,7 @@
   "Returns the health state of elasticsearch."
   [context elastic-key-in-context]
   (let [conn (get-in context [:system elastic-key-in-context :conn])
-        health-detail (admin/cluster-health conn)
+        health-detail (admin/cluster-health conn :wait_for_status "yellow" :timeout "30s")
         status (:status health-detail)]
     (if (some #{status} ["green" "yellow"])
       {:ok? true}


Enhance abacus import to recognize production type

--- src/mdr2/abacus.clj
+++ src/mdr2/abacus.clj
@@ -44,15 +44,34 @@
    :source_edition [:MetaData :ncc :sourceDate text]
    :volumes [:MetaData :ncc :setInfo text]
    :revision_date [:MetaData :ncc :revisionDate text]
+   :mvl_only [:mvl_only text]
+   :command [(attr :command)]
+   :idVorstufe [:MetaData :sbs :idVorstufe text]
    })
+
+(defn clean-raw-production
+  "Return a proper production based on a raw production, i.e. drop
+  `:mvl_only`, `:command` and `:idVorstufe` and add `:production_type`
+  and `periodical_id`"
+  [{:keys [mvl_only command idVorstufe] :as raw-production}]
+  (let [production_type (cond
+                       (= command "mdaDocAdd_Kleinauftrag") "other"
+                       (= mvl_only "yes") "periodical"
+                       :else "book")]
+      (merge (dissoc raw-production :mvl_only :command :idVorstufe)
+             {:production_type production_type
+              :periodical_id (when (= production_type "periodical") idVorstufe)})))

 (defn read-file
   "Read an export file from ABACUS and return a map with all the data"
   [file]
   (let [zipper (-> file io/file xml/parse zip/xml-zip)]
-    (into {} (for [[key path] param-mapping
-                   :let [val (apply xml1-> zipper (concat root-path path))]]
-               [key val]))))
+    (->>
+     (for [[key path] param-mapping
+           :let [val (apply xml1-> zipper (concat root-path path))]]
+       [key val])
+      (into {})
+      clean-raw-production)))

 (defn file-startswith? [f xs]
   (some #(.startsWith (.getName f) %) xs))


ignore production_type when importing a recorded production

or a metadata update. Only consider the production type on the initial
import

--- src/mdr2/abacus.clj
+++ src/mdr2/abacus.clj
@@ -86,7 +86,10 @@
   [f]
   (if-let [error (validation/recorded-validation-errors f)]
     error
-    (let [{product_number :product_number :as new-production} (read-file f)
+    (let [{product_number :product_number :as new-production}
+          (-> (read-file f)
+              ;; ignore production_type when importing a recorded production
+              (dissoc :production_type))
           production (prod/find-by-productnumber product_number)]
       (cond
         (empty? production)
@@ -116,7 +119,10 @@
   [f]
   (if-let [error (validation/metadata-sync-errors f)]
     error
-    (prod/update! (read-file f))))
+    (prod/update!
+     (-> (read-file f)
+         ;; ignore production_type when updating metadata
+         (dissoc :production_type)))))

 (defn wrap-rows
   "Wrap an export record according to ABACUS conventions"


Rename max-size to max-capacity

Rename max-size to max-capacity

As it matches the intent of the var more

--- src/mdr2/encode.clj
+++ src/mdr2/encode.clj
@@ -18,7 +18,7 @@
 ;; according to wikipedia it should be 737280000 (see
 ;; http://en.wikipedia.org/wiki/CD-ROM#Capacity) but according to k3b
 ;; it is 666.4 MiB (2,048 B * 341,186 blocks = 698,748,928 B)
-(def ^:private max-size
+(def ^:private max-capacity
   "Max number of bytes that fit on a CD-ROM"
   698748928)

@@ -111,7 +111,7 @@
         ;; two. The legacy system just added a tolerance of 2% for
         ;; stereo productions.
         sampling-ratio (if (dtb/mono? dtb) 1 1.02)
-        max-bitrate (/ (* (/ max-size duration sampling-ratio) 8) 1000)]
+        max-bitrate (/ (* (/ max-capacity duration sampling-ratio) 8) 1000)]
     (->> bitrates
          ;; for stereo productions use only bitrates larger than 96
          (filter #(or (dtb/mono? dtb) (>= % 96)))


Revert "Add warning for people that upgrade to newer versions"

This isn't needed on releases that use the day8.re-frame/re-frame-10x
coordinates.

This reverts commit 92227465e81f71241c86e3b0121829cf9b323c3a.

--- src/day8/re_frame/trace/preload.cljs
+++ src/day8/re_frame/trace/preload.cljs
@@ -5,7 +5,6 @@

 ;; Use this namespace with the :preloads compiler option to perform the necessary setup for enabling tracing:
 ;; {:compiler {:preloads [day8.re-frame.trace.preload] ...}}
-(js/console.warn "re-frame-trace has been renamed to re-frame-10x: (https://clojars.org/day8.re-frame/re-frame-10x). Update to newer versions of this library by using the `day8.re-frame/re-frame-10x` artifact ID. Thanks!")
 (rf/clear-subscription-cache!)
 (trace/init-db!)
 (defonce _ (trace/init-tracing!))


Revert "Add :x and :y to all screen maps"

This reverts commit 94bf3807eaa488e76859c2d916192b5447d05f97.

--- src/play_clj/core.clj
+++ src/play_clj/core.clj
@@ -61,19 +61,13 @@
   [screen screen-fn]
   (screen-fn))

-(defn ^:private merge-coords
-  [{:keys [input-x input-y] :as screen}]
-  (let [x (or input-x (game :x))
-        y (or input-y (game :y))]
-    (merge screen (input->screen screen x y))))
-
 (defn defscreen*
   [{:keys [screen entities
            on-show on-render on-hide on-pause on-resize on-resume on-timer]
     :as options}]
   (let [execute-fn! (fn [func & {:keys [] :as options}]
                       (when func
-                        (let [screen-map (merge-coords (merge @screen options))
+                        (let [screen-map (merge @screen options)
                               old-entities @entities]
                           (some->> (with-meta
                                      #(normalize (func screen-map old-entities))


update list of reserved slugs

update list of reserved slugs

--- src/open_company/resources/company.clj
+++ src/open_company/resources/company.clj
@@ -54,10 +54,12 @@

 (declare list-companies)

-(def reserved-slugs #{"about" "api" "careers" "companies" "company" "contact" "crowd"
-                      "developer" "developers" "faq" "founder" "founders" "investor"
-                      "investors" "jobs" "login" "logout" "news" "newsletter" "press"
-                      "privacy" "register" "signup" "terms"})
+(def reserved-slugs #{"about" "api" "app" "careers" "companies"
+                      "company" "contact" "crowd" "developer"
+                      "developers" "faq" "founder" "founders"
+                      "investor" "investors" "jobs" "login" "logout"
+                      "news" "newsletter" "press" "privacy" "register"
+                      "signup" "terms"})

 (defn taken-slugs
   "Return all slugs which are in use as a set."


Use ENTRYPOINT in latest

Use ENTRYPOINT in latest

...now that it is openjdk-17 based

--- src/docker_clojure/dockerfile.clj
+++ src/docker_clojure/dockerfile.clj
@@ -34,7 +34,8 @@
       installer-hashes
      (assoc variant :build-tool-version
             (get-in variant [:build-tool-versions "tools-deps"])))
-    ["" "CMD [\"lein\" \"repl\"]"]))
+    ["" "ENTRYPOINT [\"entrypoint\"]"]
+    ["" "CMD [\"repl\"]"]))

 (defn contents [installer-hashes {:keys [build-tool] :as variant}]
   (str/join "\n"


Add a hack for make work the promise in nodejs.

--- src/promesa/core.cljc
+++ src/promesa/core.cljc
@@ -44,6 +44,10 @@
               java.util.function.Function
               java.util.function.Supplier)))

+#?(:cljs
+   (when (= *target* "nodejs")
+     (set! js/Promise js/module.exports.Promise)))
+
 #?(:clj
    (do
      (def ^:dynamic ^:no-doc


Cleanup formatting and clarify documentation.

--- src/pubhouse/core.clj
+++ src/pubhouse/core.clj
@@ -21,7 +21,7 @@
   [path]
   (-> path (relative-path) (strip-extensions) (str ".resource")))

-(defn file-mapping
+(defn mk-page-record
   [analyze-page root file]
   (let [path (.getPath file)]
     (fs/with-cwd root
@@ -35,11 +35,11 @@
   (let [root (fs/file root-path)]
     (->> (file-seq root)
          (filter page-file?)
-         (map #(file-mapping analyze-page root %)))))
+         (map #(mk-page-record analyze-page root %)))))

 (defn page-key
   "Convert a url relative to the root of the site into a sequence of its path parts
-  ,omitting any extensions in the url."
+  ,omitting any extensions in the url. For use with Clojure's *-in functions."
   [url]
   (-> url (strip-extensions) (fs/split)))

@@ -50,24 +50,26 @@
   (str "/" (-> url (clojure.string/replace "index.resource" "") (strip-extensions))))

 (defn add-page
+  "Helper for adding a page map to the site map."
   [site page-info]
-  (assoc-in site (page-key (:url page-info)) (update-in page-info [:url] canonical-url)))
+  (assoc-in site
+            (page-key (:url page-info))
+            (update-in page-info [:url] canonical-url)))

 (defn page?
   "Helper predicate for testing whether an object is a map representing a page."
   [x] (contains? x :url))

+(defn add-all-pages
+  [[name val]]
+  [name
+   (if (and (map? val) (not (page? val)))
+     (fixup-site (assoc val :all (->> val (map last) (filter page?))))
+     val)])
+
 (defn fixup-site
   [x]
-  (clojure.walk/walk
-   (fn [[k v]]
-     (if (and (map? v) (not (page? v)))
-       [k (fixup-site (assoc v
-                             :all
-                             (->> v (map last) (filter page?))))]
-       [k v]))
-   identity
-   x))
+  (clojure.walk/walk add-all-pages identity x))

 (defn mapping->site
   "Convert a sequence of [path url] pairs to a map structure representing


Require clojure.data

Require clojure.data

--- src/day8/re_frame_10x/view/subs.cljs
+++ src/day8/re_frame_10x/view/subs.cljs
@@ -8,7 +8,8 @@
             [day8.re-frame-10x.utils.re-com :as rc :refer [css-join]]
             [day8.re-frame-10x.common-styles :as common]
             [day8.re-frame-10x.view.components :as components]
-            [mranderson048.garden.v1v3v3.garden.units :as units])
+            [mranderson048.garden.v1v3v3.garden.units :as units]
+            [clojure.data])
   (:require-macros [day8.re-frame-10x.utils.macros :as macros]
                    [day8.re-frame-10x.utils.re-com :refer [handler-fn]]))


Format consistency

Format consistency

--- src/desdemona/lifecycles/logging.clj
+++ src/desdemona/lifecycles/logging.clj
@@ -1,9 +1,10 @@
 (ns desdemona.lifecycles.logging
   (:require [taoensso.timbre :refer [info]]))

-(defn log-batch [event lifecycle]
   (let [task-name (:onyx/name (:onyx.core/task-map event))]
     (doseq [m (map :message (mapcat :leaves (:tree (:onyx.core/results event))))]
+(defn log-batch
+  [event lifecycle]
       (info task-name " logging segment: " m)))
   {})


Fix gen-class name for riemann jar.

Fix gen-class name for riemann jar.

Fixes 7f8a6e4ed0616088359ce860c77391c45e295ad6's addition of gen-class
which broke the jar packages.

--- src/riemann/bin.clj
+++ src/riemann/bin.clj
@@ -5,7 +5,7 @@
             riemann.time
             riemann.pubsub)
   (:use clojure.tools.logging)
-  (:gen-class :name com.aphyr.riemann.Main))
+  (:gen-class :name riemann.bin))

 (def config-file
   "The configuration file loaded by the bin tool"


Fix shutdown fn and rework stats output.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -37,10 +37,10 @@
           (let [^ThreadInfo t-info (.getThreadInfo tmxb ^long t-id)
                 t-name (.getThreadName t-info)
                 cpu-time (if cpu-time-supported
-                           (float (/ (.getThreadCpuTime tmxb t-id) 1000000000.0))
+                           (double (/ (.getThreadCpuTime tmxb t-id) 1000000000.0))
                            -1)
                 user-time (if cpu-time-supported
-                            (float (/ (.getThreadUserTime tmxb t-id) 1000000000.0))
+                            (double (/ (.getThreadUserTime tmxb t-id) 1000000000.0))
                             -1)
                 waited (.getWaitedTime t-info)
                 blocked (.getBlockedTime t-info)]
@@ -58,10 +58,14 @@
         no-op false
         delta-cntr (delta-counter)
         stats-fn (fn []
-                   (println
-                     "time-delta:" (delta-cntr :time (System/currentTimeMillis)) "ms;"
-                     "in:" (long (/ (delta-cntr :in (.value in-cntr)) 1000)) "k;"
-                     "out:" (long (/ (delta-cntr :out (.value out-cntr)) 1000)) "k;"))
+                   (let [in (double (/ (.value in-cntr) 1000.0))
+                         out (double (/ (.value out-cntr) 1000.0))]
+                     (println
+                       "time-delta:" (delta-cntr :time (System/currentTimeMillis)) "ms;"
+                       "in:" in "k;"
+                       "out:" out "k;"
+                       "in-delta:" (delta-cntr :in in) "k/s;"
+                       "out-delta:" (delta-cntr :out out) "k/s;")))
         out-fn (fn [_ _]
                  (.inc out-cntr))
 ;        in-data 24N
@@ -89,5 +93,5 @@
                              (thread-info-fn) (println)
                              )
                 1000)
-    (run-once (executor) (fn [] (System/exit 0) 120000))))
+    (run-once (executor) (fn [] (System/exit 0)) 120000)))


Add currency conversions for signing sheet

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

--- src/status_im/ui/screens/signing/views.cljs
+++ src/status_im/ui/screens/signing/views.cljs
@@ -45,11 +45,6 @@

 (defn separator []
   [react/view {:height 1 :background-color colors/gray-lighter}])
-
-(defn acc-text [txt1 txt2]
-  [react/nested-text nil
-   txt1 " "
-   [{:style {:color colors/gray}} txt2]])

 (defn displayed-name [contact]
   (if (or (:preferred-name contact) (:name contact))
@@ -218,9 +213,13 @@
                   sign                  [:signing/sign]
                   chain                 [:ethereum/chain-keyword]
                   {:keys [amount-error gas-error]} [:signing/amount-errors (:address from)]
-                  keycard-multiaccount? [:keycard-multiaccount?]]
+                  keycard-multiaccount? [:keycard-multiaccount?]
+                  prices                [:prices]
+                  wallet-currency       [:wallet/currency]]
     (let [display-symbol     (wallet.utils/display-symbol token)
-          fee-display-symbol (wallet.utils/display-symbol (tokens/native-currency chain))]
+          fee-display-symbol (wallet.utils/display-symbol (tokens/native-currency chain))
+          converted-value (* amount (get-in prices [(keyword display-symbol) (keyword (:code wallet-currency)) :price]))
+          converted-fee-value (* fee (get-in prices [(keyword fee-display-symbol) (keyword (:code wallet-currency)) :price]))]
       [react/view styles/sheet
        [header sign tx display-symbol fee fee-display-symbol]
        [separator]
@@ -239,24 +238,43 @@
               {:type  :small
                :title :t/send-request-amount
                :error amount-error
-               :accessories [[acc-text (if amount (str amount) "0")
-                              (or display-symbol fee-display-symbol)]]}]
-             [separator]])
-          [list-item/list-item
-           {:type        :small
-            :title       :t/network-fee
-            :error       gas-error
-            :accessories [[acc-text fee fee-display-symbol] :chevron]
-            :on-press    #(re-frame/dispatch
-                           [:signing.ui/open-fee-sheet
-                            {:content        (fn [] [sheets/fee-bottom-sheet fee-display-symbol])
-                             :content-height 270}])}]
-          [react/view {:align-items :center :margin-top 16 :margin-bottom 40}
-           (if keycard-multiaccount?
-             [sign-with-keycard-button amount-error gas-error]
-             [button/button {:on-press  #(re-frame/dispatch [:set :signing/sign {:type :password}])
-                             :disabled? (or amount-error gas-error)
-                             :label     :t/sign-with-password}])]])])))
+               :accessories [[react/nested-text {:style {:color colors/gray}}
+                              [{:style {:color colors/black}} (if amount (str amount) "0")]
+                              " "
+                              (or display-symbol fee-display-symbol)
+                              " • "
+                              [{:style {:color colors/black}} (if converted-value (str "~" (i18n/format-currency converted-value (:code wallet-currency)))
+                                                                  [react/activity-indicator {:color   :colors/gray
+                                                                                :ios   {:size  :small}
+                                                                                :android {:size :16}}])]
+                              " "
+                              (str (:code wallet-currency))]]}]
+             [separator]
+             [list-item/list-item
+              {:type        :small
+               :title       :t/network-fee
+               :error       gas-error
+               :accessories [[react/nested-text {:style {:color colors/gray}}
+                              [{:style {:color colors/black}} fee]
+                              " "
+                              fee-display-symbol
+                              " • "
+                              [{:style {:color colors/black}} (if converted-fee-value (str "~" (i18n/format-currency converted-fee-value (:code wallet-currency)))
+                                                                  [react/activity-indicator {:color   :colors/gray
+                                                                                :ios   {:size  :small}
+                                                                                :android {:size :16}}])]
+                              " "
+                              (str (:code wallet-currency))] :chevron]
+               :on-press    #(re-frame/dispatch
+                              [:signing.ui/open-fee-sheet
+                               {:content        (fn [] [sheets/fee-bottom-sheet fee-display-symbol])
+                                :content-height 270}])}]
+             [react/view {:align-items :center :margin-top 16 :margin-bottom 40}
+              (if keycard-multiaccount?
+                [sign-with-keycard-button amount-error gas-error]
+                [button/button {:on-press  #(re-frame/dispatch [:set :signing/sign {:type :password}])
+                                :disabled? (or amount-error gas-error)
+                                :label     :t/sign-with-password}])]])])])))

 (defn signing-view [tx window-height]
   (let [bottom-anim-value (anim/create-value window-height)


[#11883] Unread indicator re-appears for received message after relogin

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

--- src/status_im/chat/models/message.cljs
+++ src/status_im/chat/models/message.cljs
@@ -142,22 +142,18 @@
       acc)))

 (defn receive-many [{:keys [db]} ^js response-js]
-  (let [current-chat-id (:current-chat-id db)
-        messages-js ^js (.splice (.-messages response-js) 0 (if platform/low-device? 3 10))
-        {:keys [db chats senders]}
+  (let [messages-js ^js (.splice (.-messages response-js) 0 (if platform/low-device? 3 10))
+        {:keys [db senders]}
         (reduce reduce-js-messages
                 {:db db :chats #{} :senders {} :transactions #{}}
                 messages-js)]
     ;;we want to render new messages as soon as possible
     ;;so we dispatch later all other events which can be handled async
     {:db db
-
      :utils/dispatch-later
      (concat [{:ms 20 :dispatch [:process-response response-js]}]
-             (when (and current-chat-id
-                        (get chats current-chat-id)
-                        (not (chat-model/profile-chat? {:db db} current-chat-id)))
-               [{:ms 100 :dispatch [:chat/mark-all-as-read (:current-chat-id db)]}])
+             (when-let [chat-id (:current-chat-id db)]
+               [{:ms 100 :dispatch [:chat/mark-all-as-read chat-id]}])
              (when (seq senders)
                [{:ms 100 :dispatch [:chat/add-senders-to-chat-users (vals senders)]}]))}))


Code format

Code format

Reformatting client side realtime polling code

--- src/webapp/framework/client/coreclient.cljs
+++ src/webapp/framework/client/coreclient.cljs
@@ -1355,28 +1355,59 @@
  #(go
    ;(log (pr-str (count (keys @client-query-cache))))

-   (let [x            (remote  !check-for-server-updates  {:client-data-session-id  @data-session-id} )
-         yy            (-> x :queries keys)
+   (let [realtime-update-check-response            (remote  !check-for-server-updates  {:client-data-session-id  @data-session-id} )
+         changed-realtime-queries                  (-> realtime-update-check-response :queries keys)
+         changed-realtime-records                  (-> realtime-update-check-response :records keys)
          ]
      (do
-         (log "Client realtime: " yy)
-     (doseq [y yy]
-       (let [
-             xxx          (merge y {:data-source (keyword (get y :db-table)) :realtime true :table nil})
-             new-key2     (dissoc (dissoc xxx :start) :end)
-             ]
-
-         (>! client-query-cache-requests  {
-                                           :query-key     new-key2
-
-                                           :subset-range  {
-                                                           :start   (:start  y)
-                                                           :end     (:end    y)
-                                                           ;:start    1
-                                                           ;:end      20
-                                                           } })
-
-     ))))) 3000)
+       (log "Client realtime queries: " changed-realtime-queries)
+       (doseq [single-changed-realtime-query    changed-realtime-queries]
+         (let [
+               xxx          (merge single-changed-realtime-query {:data-source (keyword (get single-changed-realtime-query :db-table)) :realtime true :table nil})
+               new-key2     (dissoc (dissoc xxx :start) :end)
+               ]
+
+           (>! client-query-cache-requests  {
+                                             :query-key     new-key2
+
+                                             :subset-range  {
+                                                             :start   (:start  single-changed-realtime-query)
+                                                             :end     (:end    single-changed-realtime-query)
+                                                             ;:start    1
+                                                             ;:end      20
+                                                             } })
+
+           ))
+
+
+
+
+       (log "Client realtime records: " changed-realtime-records)
+       (doseq [single-changed-realtime-record    changed-realtime-records]
+         (let [
+               ;xxx          (merge single-changed-realtime-query {:data-source (keyword (get single-changed-realtime-query :db-table)) :realtime true :table nil})
+               ;new-key2     (dissoc (dissoc xxx :start) :end)
+               ]
+
+           (comment >! client-query-cache-requests  {
+                                             :query-key     new-key2
+
+                                             :subset-range  {
+                                                             :start   (:start  single-changed-realtime-query)
+                                                             :end     (:end    single-changed-realtime-query)
+                                                             ;:start    1
+                                                             ;:end      20
+                                                             } })
+           nil
+
+           ))
+
+
+
+
+
+
+       ))) 3000)


Preserve metadata on datasets when given a dataset in make-dataset

--- src/tabular/grafter/tabular/common.clj
+++ src/tabular/grafter/tabular/common.clj
@@ -57,7 +57,7 @@
                                  [columns-or-f data-seq])
          full-data (fill-gaps-with-nil rows column-headers)]
      (-> (inc/dataset column-headers full-data)
-         (with-meta (meta full-data))))))
+         (with-meta (meta data))))))

 (defn dataset?
   "Predicate function to test whether the supplied argument is a
@@ -109,6 +109,7 @@
   "Adds metadata about where the dataset was loaded from to the object."
   (cond
     (#{String File URI URL} (class data-source)) (with-meta output-ds {:grafter.tabular/data-source data-source})
+    (instance? incanter.core.Dataset data-source) (with-meta output-ds (meta data-source))
     :else (with-meta output-ds {:grafter.tabular/data-source :datasource-unknown})))

 (defmulti ^:no-doc read-dataset*
@@ -174,7 +175,7 @@
   [f source {:keys [format] :as opts}]
   (if-let [format (or format (infer-format-of source))]
     (f source (assoc opts :format format))
-    (throw (IllegalArgumentException. (str "Please specify a format, it could not be from the source: " source)))))
+    (throw (IllegalArgumentException. (str "Please specify a format, it could not be inferred from the source: " source)))))

 (defmethod read-dataset-source Dataset [ds opts] ds)


added type hint

added type hint

--- src/selmer/parser.clj
+++ src/selmer/parser.clj
@@ -35,7 +35,7 @@
 (defn cache-off! []
   (reset! cache? false))

-(defn set-resource-path! [path]
+(defn set-resource-path! [^String path]
   (let [path (if (or (nil? path)
                      (.endsWith path "/"))
                path


Remove some unused destructuring

Remove some unused destructuring

--- src/snergly/core.cljs
+++ src/snergly/core.cljs
@@ -86,7 +86,7 @@
 ;; -----------------------------------------------------------------------------
 ;; Components

-(defn ready-to-go [{:keys [algorithm rows columns grid] :as maze}]
+(defn ready-to-go [{:keys [algorithm rows columns] :as maze}]
   (and (not= "" algorithm)
        (and (integer? rows) (> rows 1) (< rows 100))
        (and (integer? columns) (> columns 1) (< columns 100))))
@@ -104,7 +104,7 @@
   (componentDidUpdate [this _ _]
     (animate-if-active (om/props this)))
   (render [this]
-    (let [{:keys [grid rows columns algorithm cell-size active] :as maze} (om/props this)]
+    (let [{:keys [rows columns cell-size active] :as maze} (om/props this)]
       (let [height (inc (* cell-size rows))
             width (inc (* cell-size columns))]
         (dom/div nil


remove "Connection [ Started | Terminated]." println

--- src/subrosa/netty.clj
+++ src/subrosa/netty.clj
@@ -52,8 +52,8 @@
              (.getValue evt))
     (.add channel-group (.getChannel evt))
     (dosync
-     (add-channel! (.getChannel evt)))
-    (println "Connection Started.")))
+     (add-channel! (.getChannel evt))))
+  evt)

 (defn message-handler [evt]
   (dispatch-message (.getMessage evt) (.getChannel evt))
@@ -64,8 +64,8 @@
              (= (.getState evt) (ChannelState/CONNECTED))
              (not (.getValue evt)))
     (dosync
-     (remove-channel! (.getChannel evt)))
-    (println "Connection Terminated.")))
+     (remove-channel! (.getChannel evt))))
+  evt)

 (defn add-string-codec! [pipeline]
   (doto pipeline


rename show-header-and-footer? to show-footer?

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -99,7 +99,7 @@
               ;; simple optimzation for real-time updates when the build is running
               app-without-container-data (dissoc-in app state/container-data-path)
               dom-com (dominant-component app owner)
-              show-header-and-footer? (not= :signup (:navigation-point app))
+              show-footer? (not= :signup (:navigation-point app))
               project (get-in app state/project-path)]
           (reset! keymap {["ctrl+s"] persist-state!
                           ["ctrl+r"] restore-state!})
@@ -139,7 +139,7 @@
                 [:div.main-body
                  (om/build dom-com app)

-                 (when (and show-header-and-footer? (config/footer-enabled?))
+                 (when (and show-footer? (config/footer-enabled?))
                    [:footer.main-foot
                     (footer/footer)])]]


remove inspect

remove inspect


tweaks

tweaks


Add more document xml functions.

Add more document xml functions.

such as
- wpml/tr
- wpml/td
- wpml/f


Pos int already defined. Covers 5a8d7bde143860195ee58befd937e31a7b9c699e.

--- src/onyx/spec.cljc
+++ src/onyx/spec.cljc
@@ -17,9 +17,6 @@
   (and (keyword? x) (namespace x)))

 (s/def :onyx/name keyword?)
-
-(defn pos-int? [x]
-  (and (integer? x) (pos? x)))

 (s/def :job/workflow
   (s/coll-of (s/coll-of :onyx/name :kind vector? :count 2)


Ordinals mapping and responses in each game

--- src/skat/model.clj
+++ src/skat/model.clj
@@ -16,6 +16,13 @@
   { :7 0 :8 1 :9 3 :Q 4 :K 5 :10 6 :A 7 :W 8 })
 (def figure-ordinal-null "Figures' ordnals in null games"
   { :7 0 :8 1 :9 3 :10 7 :W 4 :Q 5 :K 6 :A 8 })
+(def figure-ordinals "Figures ordinals for each game"
+  { :grand figure-ordinal-normal
+    :kreuz figure-ordinal-normal
+    :grun figure-ordinal-normal
+    :herz figure-ordinal-normal
+    :schell figure-ordinal-normal
+    :null figure-ordinal-null })
 (def figure-values "Values for each card figure"
   { :7 0 :8 0 :9 0 :W 2 :Q 3 :K 4 :10 10 :A 11 })

@@ -69,6 +76,13 @@
           (cards-grouped-by-color []
             (helpers/list-from cards-of-color colors))]
     (flatten (cards-grouped-by-color))))
+(defn deal-cards "Returns dealt cards" []
+  (let [shuffled-cards (shuffle deck)
+        front (take 10 shuffled-cards)
+        middle (take 10 (drop 10 shuffled-cards))
+        rear (take 10 (drop 20 shuffled-cards))
+        skat (take 2 (drop 30 shuffled-cards))]
+    { :front front :middle middle :rear rear :skat skat }))

 ;;; Configuration

@@ -78,12 +92,36 @@
   { :grand 6 :kreuz 5 :grun 4 :herz 3 :schell 2 :null 1 })
 (defrecord Configuration [type with-skat ouvert])

-;;; Game
+;;; Responses

-(defn deal-cards [] "Returns dealt cards"
-  (let [shuffled-cards (shuffle deck)
-        front (take 10 shuffled-cards)
-        middle (take 10 (drop 10 shuffled-cards))
-        rear (take 10 (drop 20 shuffled-cards))
-        skat (take 2 (drop 30 shuffled-cards))]
-    { :front front :middle middle :rear rear :skat skat }))
+(defn allowed-responses-null "Filters allowed responses in null games"
+  [c cards]
+  (let [matching-color (filter-color (:color c) cards)]
+    (if (empty? matching-color) cards matching-color)))
+(defn allowed-responses-grand "Filters allowed responses in grand games"
+  [c cards]
+  (if (property-matches? :figure :W c)
+    (filter-figure :W cards)
+    (allowed-responses-null c cards)))
+(defn allowed-responses-color [color c cards]
+  (let [trump (helpers/append
+                (filter-color color cards)
+                (filter-figure :W cards))]
+    (if (empty? trump)
+      (allowed-responses-null c cards)
+      trump)))
+(def allowed-responses-kreuz "Filters allowed responses in kreuz games"
+  (partial allowed-responses-color :kreuz))
+(def allowed-responses-grun "Filters allowed responses in grun games"
+  (partial allowed-responses-color :grun))
+(def allowed-responses-herz "Filters allowed responses in herz games"
+  (partial allowed-responses-color :herz))
+(def allowed-responses-schell "Filters allowed responses in schell games"
+  (partial allowed-responses-color :schell))
+(def allowed-responses "Allowed responses for each game"
+  { :grand allowed-responses-grand
+    :kreuz allowed-responses-kreuz
+    :grun allowed-responses-grun
+    :herz allowed-responses-herz
+    :schell allowed-responses-schell
+    :null allowed-responses-null })


Fix :a.l.specs.visualisation.maps.layer.point-color-mapping/value

--- backend/specs/akvo/lumen/specs/visualisation/maps/layer.clj
+++ backend/specs/akvo/lumen/specs/visualisation/maps/layer.clj
@@ -38,7 +38,7 @@

 (s/def ::layer.point-color-mapping.s/op #{"equals"})

-(s/def ::layer.point-color-mapping.s/value double?)
+(s/def ::layer.point-color-mapping.s/value (s/or :d double? :s string?))

 (defn valid-hex? [s] (try
                        (Color/decode s)


Return nil if URI fragment is not found

Return nil if URI fragment is not found

--- src/trak/globals.cljs
+++ src/trak/globals.cljs
@@ -27,10 +27,11 @@
                                     :state         (.getRandomString string)}))))

 (defn get-spotify-auth-token []
-  (let [fragment (.getFragment (Uri. (.-href (.-location js/document))))
-        fragment (str/split fragment "&")]
-    (reduce (fn [acc part]
-              (let [kw (str/split part "=")]
-                (merge acc {(keyword (first kw)) (second kw)})))
-            {}
-            fragment)))
+  (let [fragment (.getFragment (Uri. (.-href (.-location js/document))))]
+    (cond (= "" fragment) nil
+          :else (let [fragment (str/split fragment "&")]
+                  (reduce (fn [acc part]
+                            (let [kw (str/split part "=")]
+                              (merge acc {(keyword (first kw)) (second kw)})))
+                          {}
+                          fragment)))))