spinner on loading matches

spinner on loading matches

--- src/cljs/foosball/locations/matches.cljs
+++ src/cljs/foosball/locations/matches.cljs
@@ -4,7 +4,8 @@
             [foosball.date :as d]
             [foosball.table :as table]
             [foosball.format :as f]
-            [foosball.location :as loc]))
+            [foosball.location :as loc]
+            [foosball.spinners :refer [spinner]]))

 (defn handle [app v]
   (data/ensure-player-data app)
@@ -16,7 +17,8 @@
   (loc/set-location app (:id v)))

 (defn render [{:keys [matches player-lookup]}]
-  (when player-lookup
+  (if-not (and matches player-lookup)
+    (spinner)
     (let [players-from-team (fn [{:keys [player1 player2]}] (mapv :id [player1 player2]))
           date-column {:heading "Date played"
                        :fn      :matchdate


Adjust formatting.

Adjust formatting.

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -282,7 +282,8 @@
         instruction-mutator (fn [token]
                               (assoc token
                                 :instruction
-                                (:instruction (first (random-plush-genome 1 atom-generators argmap)))))
+                                (:instruction
+                                  (first (random-plush-genome 1 atom-generators argmap)))))
         token-mutator (fn [token]
                         (if (< (lrand) uniform-mutation-rate)
                           (instruction-mutator token)
@@ -302,7 +303,8 @@
 (defn uniform-integer-mutation
   "Uniformly mutates individual. For each integer in the genome, there is
    uniform-mutation-constant-tweak-rate probability of being mutated."
-  [ind {:keys [uniform-mutation-constant-tweak-rate uniform-mutation-int-gaussian-standard-deviation
+  [ind {:keys [uniform-mutation-constant-tweak-rate
+               uniform-mutation-int-gaussian-standard-deviation
                maintain-ancestors atom-generators]
         :as argmap}]
   (let [uniform-mutation-constant-tweak-rate
@@ -317,7 +319,8 @@
                                (assoc token
                                  :instruction
                                  (round (perturb-with-gaussian-noise
-                                          uniform-mutation-int-gaussian-standard-deviation const)))
+                                          uniform-mutation-int-gaussian-standard-deviation
+                                          const)))
                                token)))
         token-mutator (fn [token]
                         (if (< (lrand) uniform-mutation-constant-tweak-rate)
@@ -748,12 +751,13 @@
   "Replaces input instructions with noops and  autoconstructive_<type>_rand
   with <type>_rand."
   [genome]
-  (let [input-instruction? (fn [instruction]
-                             (and (symbol? instruction)
-                                  (or (re-seq #"in\d+" (name instruction)) ;; from input-output
-                                      (re-seq #"in_dm" (name instruction)) ;; from digital-multiplier
-                                      (some #{instruction}
-                                            '(a0 a1 a2 d0 d1 d2 d3 d4 d5 d6 d7)))))] ;; from mux problems
+  (let [input-instruction?
+        (fn [instruction]
+          (and (symbol? instruction)
+               (or (re-seq #"in\d+" (name instruction)) ;; from input-output
+                   (re-seq #"in_dm" (name instruction)) ;; from digital-multiplier
+                   (some #{instruction}
+                         '(a0 a1 a2 d0 d1 d2 d3 d4 d5 d6 d7)))))] ;; from mux problems
     (mapv (fn [instruction-map]
             (if (input-instruction? (:instruction instruction-map))
               (assoc instruction-map :instruction 'code_noop)
@@ -1120,9 +1124,10 @@
                                              {:genome child-genome}
                                              argmap)))
                          nil)
-          variant (diversifying? child-genome (-> argmap
-                                                  (assoc :parent1-genome parent1-genome)
-                                                  (assoc :parent2-genome parent2-genome)))
+          variant (diversifying? child-genome
+                                 (-> argmap
+                                     (assoc :parent1-genome parent1-genome)
+                                     (assoc :parent2-genome parent2-genome)))
           use-child (or variant
                         (and autoconstructive-improve-or-diversify
                              (some (fn [[child-error parent1-error parent2-error]]
@@ -1151,6 +1156,3 @@
         :is-random-replacement
         (if use-child false true)))))

-
-
-


Fixed bug in uniform-mutation that made it also change :close values

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -57,7 +57,9 @@
                                            c))
                                        st)))
         instruction-mutator (fn [token]
-                              (first (random-plush-genome 1 atom-generators argmap)))
+                              (assoc token
+                                     :instruction
+                                     (:instruction (first (random-plush-genome 1 atom-generators argmap)))))
         constant-mutator (fn [token]
                            (let [const (:instruction token)]
                              (if (tag-instruction? const)


Changed max size of alternation from 10,000 to 2*max-points

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -334,14 +334,14 @@
 ;  (println (balance s)))

 (defn alternate
-  [s1 s2 alternation-rate alignment-deviation]
+  [s1 s2 alternation-rate alignment-deviation max-points]
   (let [s1 (vec s1)
         s2 (vec s2)]
     (loop [i 0
            use-s1 (lrand-nth [true false])
            result []]
       (if (or (>= i (count (if use-s1 s1 s2)))
-              (> (count result) 10000)) ;; runaway growth
+              (> (count result) (* 2 max-points))) ;; runaway growth
         (apply list result)
         (if (< (lrand) alternation-rate)
           (recur (max 0 (+' i (Math/round (*' alignment-deviation (gaussian-noise-factor)))))
@@ -374,7 +374,8 @@

 (defn ultra-operate-on-programs
   [p1 p2 alternation-rate alignment-deviation mutation-rate
-   use-ultra-no-paren-mutation ultra-pads-with-empties atom-generators]
+   use-ultra-no-paren-mutation ultra-pads-with-empties atom-generators
+   max-points]
   (if (or (not (seq? p1))
           (not (seq? p2)))
     p1 ;; can't do if either program isn't a list
@@ -393,7 +394,8 @@
               (alternate (list-to-open-close-sequence p1)
                          (list-to-open-close-sequence p2)
                          alternation-rate
-                         alignment-deviation)
+                         alignment-deviation
+                         max-points)
               mutation-rate
               use-ultra-no-paren-mutation
               atom-generators)))))))
@@ -427,7 +429,8 @@
                                                ultra-mutation-rate
                                                use-ultra-no-paren-mutation
                                                ultra-pads-with-empties
-                                               atom-generators)]
+                                               atom-generators
+                                               max-points)]
     (if (> (count-points new-program) max-points)
       parent1
       (make-individual :program new-program :history (:history parent1)


Prevent divide-by-zero errors in new genetic operators; lein release :patch

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -465,7 +465,9 @@
   [ind {:keys [uniform-addition-and-deletion-rate maintain-ancestors atom-generators]
         :as argmap}]
   (let [addition-rate (number uniform-addition-and-deletion-rate)
-        deletion-rate (/ 1 (+ (/ 1 addition-rate) 1))
+        deletion-rate (if (zero? addition-rate)
+                        0
+                        (/ 1 (+ (/ 1 addition-rate) 1)))
         after-addition (vec (apply concat
                                    (map #(if (< (lrand) addition-rate)
                                            (lshuffle [%
@@ -496,7 +498,9 @@
    {:keys [uniform-combination-and-deletion-rate maintain-ancestors atom-generators]
     :as argmap}]
   (let [combination-rate (number uniform-combination-and-deletion-rate)
-        deletion-rate (/ 1 (+ (/ 1 combination-rate) 1))
+        deletion-rate (if (zero? combination-rate)
+                        0
+                        (/ 1 (+ (/ 1 combination-rate) 1)))
         after-combination (vec
                             (apply concat
                                    (map (fn [g1 g2]
@@ -955,3 +959,4 @@

+


Remove placeholder test

Remove placeholder test

--- test/robb1e/core_test.clj
+++ test/robb1e/core_test.clj
@@ -1,7 +1,3 @@
 (ns robb1e.core-test
   (:require [clojure.test :refer :all]
             [robb1e.core :refer :all]))
-
-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))


Added section on parameterized reads.

Added section on parameterized reads.

--- src/tutorial/untangled_tutorial/H_Server_Interactions.cljs
+++ src/tutorial/untangled_tutorial/H_Server_Interactions.cljs
@@ -256,6 +256,50 @@
   Therefore, you almost *never* want to use a hand-written query that has not been placed on a `defui`. It is perfectly
   acceptable to define queries via `defui` to ensure normalization will work, and this will commonly be the case if your
   UI needs to ask for data in a structure different from what you want to run against the server.
+
+  ### Parameterized Reads
+
+  You may add parameters to your remote reads using an optional argument to data fetch:
+
+  ```
+  (defui Article
+    static om/IQuery (query [this] [:id :content {:comments (om/get-query Comments)}])
+    static om/Ident (ident [this props] [:article/by-id (:id props)])
+    (render [this]
+      ;; render article content
+      ;; ...
+      ;; render a load comments button:
+      (dom/button #js {:onClick #(df/load-field this :comments
+                                  :params {:comments {:lowValue 0 :highValue 10}})}
+        \"Load Comments\")))
+  ```
+  This sample query parameterizes the read to this article's comments with a range, say so that the server only returns
+   the first ten most recent comments. The keys of the params map specify the keywords in the query that should be
+   parameterized, and the values specify the parameter maps for their respective keys.
+
+  So, `(load-field this :comments)` above would yield a query of the form:
+
+  ```
+  [{[:article/by-id 32] [{:comments [:other :props]]}]
+  ```
+
+  while `(load-field this :comments :params {:comments {:lowValue 0 :highValue 10}})` would yield a query of the form:
+
+  ```
+  [{[:article/by-id 32] [{(:comments {:lowValue 0 :highValue 10}) [:other :props]]}]
+  ```
+
+  So, when you specify parameters to one of the items in your query, Untangled will add the parameters at that level
+  of the query, which you will be able to access when parsing the query on the server-side read:
+
+  ```
+  (defmethod api-read :comments [{:keys [db ast]} k {:keys [lowValue highValue]}]
+    {:value (get-comments-in-range db (:key ast) lowValue highValue)})
+    ;; calls (get-comments-in-range db [:article/by-id 32] 0 10), assuming code snippet above
+
+  (defmethod api-read :article/by-id [{:keys [parser query] :as env} k params]
+    {:value (parser env query)})
+  ```

   ### Query narrowing


test multiple relationships

test multiple relationships

--- test/er_cassandra/model/alia/relationship_test.clj
+++ test/er_cassandra/model/alia/relationship_test.clj
@@ -53,7 +53,7 @@
   (tu/create-table :ck_relationship_test
                    "(ida uuid, idb uuid, nick text, nock text, primary key ((ida, idb)))")
   (tu/create-table :ck_relationship_test_target
-                   "(id uuid primary key, source_ida uuid, , source_idb uuid, target_nick text, target_nock text)")
+                   "(id uuid primary key, source_ida uuid, source_idb uuid, target_nick text, target_nock text)")
   (tu/create-table :ck_relationship_test_target_by_source_ids
                    "(id uuid, source_ida uuid, source_idb uuid, target_nick text, target_nock text, primary key ((source_ida, source_idb)))")
   (let [target (t/create-entity
@@ -89,3 +89,67 @@
             :target_nick "foo" :target_nock "foofoo"} potr))
     (is (= {:id tid :source_ida sida :source_idb sidb
             :target_nick "foo" :target_nock "foofoo"} potri))))
+
+(defn create-multi-relationship
+  []
+  (tu/create-table :multi_relationship_test
+                   "(ida uuid, idb uuid, nick text, nock text, primary key ((ida, idb)))")
+  (tu/create-table :multi_relationship_test_target_a
+                   "(tida uuid primary key, source_ida uuid, source_idb uuid, target_nick text)")
+  (tu/create-table :multi_relationship_test_target_a_by_source_ids
+                   "(tida uuid, source_ida uuid, source_idb uuid, target_nick text, primary key ((source_ida, source_idb)))")
+  (tu/create-table :multi_relationship_test_target_b
+                   "(tidb uuid primary key, source_ida uuid, source_idb uuid, target_nock text)")
+  (tu/create-table :multi_relationship_test_target_b_by_source_ids
+                   "(tidb uuid, source_ida uuid, source_idb uuid, target_nock text, primary key ((source_ida, source_idb)))")
+  (let [target-a (t/create-entity
+                  {:primary-table {:name :multi_relationship_test_target_a
+                                   :key [:tida]}
+                   :secondary-tables [{:name :multi_relationship_test_target_a_by_source_ids
+                                       :key [[:source_ida :source_idb]]}]})
+        target-b (t/create-entity
+                  {:primary-table {:name :multi_relationship_test_target_b
+                                   :key [:tidb]}
+                   :secondary-tables [{:name :multi_relationship_test_target_b_by_source_ids
+                                       :key [[:source_ida :source_idb]]}]})
+        source (t/create-entity
+                {:primary-table {:name :multi_relationship_test
+                                 :key [[:ida :idb]]}
+                 :denorm-targets {:test-a {:target target-a
+                                           :denormalize {:nick :target_nick}
+                                           :cascade :none
+                                           :foreign-key [:source_ida :source_idb]}
+                                  :test-b {:target target-b
+                                           :denormalize {:nock :target_nock}
+                                           :cascade :none
+                                           :foreign-key [:source_ida :source_idb]}}})]
+    [source target-a target-b]))
+
+(deftest update-composite-key-relationship-test
+  (let [[s ta tb] (create-multi-relationship)
+        [sida sidb tida tidb] [(uuid/v1) (uuid/v1) (uuid/v1) (uuid/v1)]
+        sr {:ida sida :idb sidb :nick "foo" :nock "foofoo"}
+        _ (insert-record :multi_relationship_test sr)
+        _ (upsert-instance ta {:tida tida :source_ida sida :source_idb sidb
+                               :target_nick "bar"})
+        _ (upsert-instance tb {:tidb tidb :source_ida sida :source_idb sidb
+                               :target_nock "bar"})
+
+        resp @(rel/denormalize tu/*model-session* s sr :upsert {})
+        potra (fetch-record :multi_relationship_test_target_a [:tida] [tida])
+        potrai (fetch-record :multi_relationship_test_target_a_by_source_ids
+                             [:source_ida :source_idb] [sida sidb])
+        potrb (fetch-record :multi_relationship_test_target_b [:tidb] [tidb])
+        potrbi (fetch-record :multi_relationship_test_target_b_by_source_ids
+                             [:source_ida :source_idb] [sida sidb])
+        ]
+    (is (= [[:test-a [:ok]]
+            [:test-b [:ok]]] resp))
+    (is (= {:tida tida :source_ida sida :source_idb sidb
+            :target_nick "foo"} potra))
+    (is (= {:tida tida :source_ida sida :source_idb sidb
+            :target_nick "foo"} potrai))
+    (is (= {:tidb tidb :source_ida sida :source_idb sidb
+            :target_nock "foofoo"} potrb))
+    (is (= {:tidb tidb :source_ida sida :source_idb sidb
+            :target_nock "foofoo"} potrbi))))


Improve test println output.

Improve test println output.

--- test/onyx/windowing/basic_windowing_crash_test.clj
+++ test/onyx/windowing/basic_windowing_crash_test.clj
@@ -173,11 +173,10 @@
         (let [{:keys [job-id]} (onyx.api/submit-job peer-config job)
               _ (onyx.test-helper/feedback-exception! peer-config job-id)
               results (take-segments! @out-chan 5)]
-          (println "COORDS" (onyx.api/job-snapshot-coordinates peer-config id job-id))
+          (println "gc-checkpoints:" (onyx.api/job-snapshot-coordinates peer-config id job-id))
           (onyx.api/gc-checkpoints peer-config id job-id)
-          (println "Try again" )
+          (println "gc-checkpoints:" (onyx.api/job-snapshot-coordinates peer-config id job-id))
           (onyx.api/gc-checkpoints peer-config id job-id)
           ;; FIXME: improve test by pulling in old coordinates, recovering and then starting gc again.
           ;; TODO, allow gc to take part over tenancy history.
-
           (is (= expected-windows (output->final-counts @test-state))))))))


CMR-1852: Minor cleanup

CMR-1852: Minor cleanup

--- umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
+++ umm-spec-lib/test/cmr/umm_spec/test/generate_and_parse.clj
@@ -63,7 +63,6 @@

 (comment

-
   (println (core/generate-metadata :collection :iso-smap user/failing-value))

   (is (= (expected-conversion/convert user/failing-value :iso-smap)


Add `pst` repl-special form (WIP)

Add `pst` repl-special form (WIP)

Former-commit-id: 708314b4dbf2bd777dc7a07068f1d6e1653ef7ec

--- planck-cljs/src/planck/core.cljs
+++ planck-cljs/src/planck/core.cljs
@@ -36,7 +36,7 @@
 (defn ns-form? [form]
   (and (seq? form) (= 'ns (first form))))

-(def repl-specials '#{in-ns require require-macros doc})
+(def repl-specials '#{in-ns require require-macros doc pst})

 (defn repl-special? [form]
   (and (seq? form) (repl-specials (first form))))
@@ -49,7 +49,10 @@
     require-macros {:arglists ([& args])
                     :doc      "Similar to the require REPL special function but\n  only for macros."}
     doc            {:arglists ([name])
-                    :doc      "Prints documentation for a var or special form given its name"}})
+                    :doc      "Prints documentation for a var or special form given its name"}
+    pst            {:arglists ([] [e])
+                    :doc      (str "Prints a stack trace of the exception. If none supplied, uses the root cause of the "
+                                   "most recent repl exception (*e)")}})

 (defn- repl-special-doc [name-symbol]
   (assoc (repl-special-doc-map name-symbol)
@@ -200,7 +203,10 @@
                   (repl/print-doc (repl-special-doc (second expression-form)))
                   (repl/print-doc
                     (let [sym (second expression-form)]
-                          (with-compiler-env st (resolve env sym))))))
+                          (with-compiler-env st (resolve env sym)))))
+            pst (let [sym (or (-> expression-form second second) '*e)
+                      err (with-compiler-env st (resolve env sym))]
+                  (print-error err)))
           (prn nil))
         (try
           (cljs/eval-str


Simplify make-svg, make-vertices and auto resize.

--- src/constraint/core.cljs
+++ src/constraint/core.cljs
@@ -88,7 +88,7 @@

-(defn svg-vertex [id inflow [weight [x y]]]
+(defn svg-vertex [[id inflow [weight [x y]]]]
   (let [free (- inflow weight)]
     (list
       [:svg:circle
@@ -151,21 +151,33 @@
     (fmap (partial prepare-edge locations world-state) edges)))

-
-(defn make-svg [[width height] {:keys [vertices edges] :as world-state}]
+(defn make-vertices [{:keys [vertices edges]}]
+  (map vector
+       (range)
+       (map (partial inflow edges) (range))
+       vertices))
+
+
+(defn make-svg [[width height] edges vertices]
   [:svg:svg {:width width :height height}
    [:svg:defs
     triangle-marker-ok
     triangle-marker-not-ok]
-   (map svg-edge (make-edges world-state))
-   (map svg-vertex (range) (map (partial inflow edges) (range)) vertices)])
-
+   (map svg-edge edges)
+   (map svg-vertex vertices)])
+
+
+
+(defn map-size [{:keys [vertices]}]
+  (map + [50 50] (apply (comp max (partial map vector)) vertices)))

 (defn draw-world [world-state]
   (dommy/replace! (dommy.core/sel1 :#forsvg)
                   (crate/html [:div#forsvg
-                                (make-svg [1000 1000] world-state)])))
+                               (make-svg (map-size world-state)
+                                         (make-edges world-state)
+                                         (make-vertices world-state))])))


indenting license

indenting license

--- src/digital/provider.clj
+++ src/digital/provider.clj
@@ -1,13 +1,13 @@
 (comment
-      Celestial, Copyright 2012 Ronen Narkis, narkisr.com
-      Licensed under the Apache License,
-      Version 2.0  (the "License") you may not use this file except in compliance with the License.
-      You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-      Unless required by applicable law or agreed to in writing, software
-      distributed under the License is distributed on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-      See the License for the specific language governing permissions and
-      limitations under the License.)
+  Celestial, Copyright 2012 Ronen Narkis, narkisr.com
+  Licensed under the Apache License,
+  Version 2.0  (the "License") you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.)

 (ns digital.provider
    "Digital ocean provider"


Fix react key warning

Fix react key warning

--- tutorial.moan/src/tutorial/moan/frontend/main.cljs
+++ tutorial.moan/src/tutorial/moan/frontend/main.cljs
@@ -16,34 +16,36 @@
         tweet))
     tweets))

-(defn Tweet
-  [tweet]
-  (html
-    [:div.card.tweet
-     [:div.tweet__content
-      [:span.tweet__author-name (-> tweet :author :name)]
-      [:a.tweet__author-username
-       {:href "javascript:;"
-        :onClick (fn [e]
-                   (.preventDefault e))}
-       (str "@" (-> tweet :author :username))]
-      [:p.tweet__body (:text tweet)]]
-     [:div.tweet__actions
-      [:a.tweet__action {:href "#"}
-       [:span.eye.tweet__action-icon]
-       "Hide"]
-      [:a.tweet__action
-       {:href "#"
-        :class (when (:favorite? tweet)
-                 "tweet__action--active")
-        :onClick (fn [e]
-                   (.preventDefault e)
-                   (swap! state
-                          update :tweets
-                          update-tweet (:id tweet)
-                          update :favorite? not))}
-       [:span.star.tweet__action-icon]
-       "Favorite"]]]))
+(def Tweet
+  (br/component
+    'Tweet
+    (fn [tweet]
+      (html
+        [:div.card.tweet
+         [:div.tweet__content
+          [:span.tweet__author-name (-> tweet :author :name)]
+          [:a.tweet__author-username
+           {:href "javascript:;"
+            :onClick (fn [e]
+                       (.preventDefault e))}
+           (str "@" (-> tweet :author :username))]
+          [:p.tweet__body (:text tweet)]]
+         [:div.tweet__actions
+          [:a.tweet__action {:href "#"}
+           [:span.eye.tweet__action-icon]
+           "Hide"]
+          [:a.tweet__action
+           {:href "#"
+            :class (when (:favorite? tweet)
+                     "tweet__action--active")
+            :onClick (fn [e]
+                       (.preventDefault e)
+                       (swap! state
+                              update :tweets
+                              update-tweet (:id tweet)
+                              update :favorite? not))}
+           [:span.star.tweet__action-icon]
+           "Favorite"]]]))))

 (defn Tweets
   [tweets]
@@ -51,7 +53,7 @@
     [:div.tweets
      (for [tweet tweets]
        (when-not (:hidden? tweet)
-         (Tweet tweet)))]))
+         (Tweet tweet {:key (:id tweet)})))]))

 (defn Loader
   []


Make things pretty

Make things pretty

--- src/aurora/language.cljs
+++ src/aurora/language.cljs
@@ -64,8 +64,8 @@
                  (when (-del-facts facts fields other-index (into-array other-fields))
                    (set!! changed? true)))
                changed?))
-  (clear-facts [this name]
-               (doseq [[_ index] (get-in kind->name->fields->index ["know" name])]
+  (clear-facts [this kind name]
+               (doseq [[_ index] (concat (get-in kind->name->fields->index [kind name]))]
                  (.reset index)))
   (update-facts [this name]
                 (let [[fields remember-index] (first (get-in kind->name->fields->index ["remember" name]))]
@@ -86,20 +86,18 @@
                                 (let [remember (.seek-gte remember-iter key)]
                                   (when (or (nil? remember) (btree/key-not= key remember))
                                     (.push forgets key)))))
-                    (doseq [[_ index] (get-in kind->name->fields->index ["remember" name])]
-                      (.reset index))
-                    (doseq [[_ index] (get-in kind->name->fields->index ["forget" name])]
-                      (.reset index))
+                    (.clear-facts this "remember" name)
+                    (.clear-facts this "forget" name)
                     (let [added (.add-facts this "know" name fields remembers)
-                          remmed (.del-facts this "know" name fields forgets)]
-                      (or added remmed)))))
+                          deled (.del-facts this "know" name fields forgets)]
+                      (or added deled)))))
   (tick [this name->transient?]
         (let [names (js/Object.keys name->transient?)
               changed? false]
           (dotimes [i (alength names)]
             (let [name (aget names i)]
               (if (true? (aget name->transient? name))
-                (.clear-facts this name)
+                (.clear-facts this "know" name)
                 (when (true? (.update-facts this name))
                   (set!! changed? true)))))
           changed?)))


Fixes task creation

Fixes task creation

--- src/front/gtd/state.cljs
+++ src/front/gtd/state.cljs
@@ -207,7 +207,7 @@
   @tasks)

 (defn register-task
-  [task-name {:keys [project parent tags tasks description remind-date due-date show-before repeating]
+  [task-name & {:keys [project parent tags tasks description remind-date due-date show-before repeating]
               :or   {project     (inbox)
                      parent      (inbox)
                      tags        []


[core] Refactor 'listen.

[core] Refactor 'listen.

Take a 'gossip-handler and a 'port. Create 'input-stream-handler and
'output-stream-handler fns. Open a listening socket on the specified 'port and
pass in the composed connection handler.

--- src/birdie_tell/core.clj
+++ src/birdie_tell/core.clj
@@ -197,10 +197,17 @@
     nil))

 (defn- listen
-  "Start listening on 'port, calling 'receive-gossip with 'max-hotness
-  on connect."
-  [max-hotness port]
-  (socket/create-server port (partial receive-gossip max-hotness)))
+  "Start listening on 'port, calling 'parse-gossip with
+  'gossip-handler and input/output handlers on connect."
+  [gossip-handler port]
+  (let [input-stream-handler (fn [input-stream]
+                               (with-open [rdr (io/reader input-stream)]
+                                 (reduce str (line-seq rdr))))
+        output-stream-handler (fn [output-stream] nil)]
+    (socket/create-server port (partial parse-gossip
+                                        gossip-handler
+                                        input-stream-handler
+                                        output-stream-handler))))

 ;; TODO: think about core.async
 (defn- send-gossip


add comments

add comments

--- src/hatti/views/map.cljs
+++ src/hatti/views/map.cljs
@@ -330,6 +330,7 @@
                                                 formid ["id"] flat-form query))
         ;; generated geojson
         geojson (or updated-map-geojson map-geojson)
+        ;; function that renders layer with features
         load-layers (fn []
                       (mu/map-on-load
                        mapboxgl-map shared/event-chan id_string
@@ -338,12 +339,15 @@
                        :geofield geofield
                        :owner owner)
                       (om/set-state! owner :zoomed? false))
+        ;; function that fits bounds on features
         fitBounds (fn [geojson]
                     (when (and (.loaded mapboxgl-map)
                                (not (om/get-state owner :zoomed?)))
                       (if (and (om/get-state owner :zoom)
                                (om/get-state owner :loaded?))
+                        ;; fit bounds on current zoom zevel
                         (.on mapboxgl-map "zoom" #(mu/set-zoom-level owner))
+                        ;; fit bounds on features if not loaded
                         (mu/fitMapBounds
                          mapboxgl-map (:id_string dataset-info) geojson))
                       (om/set-state! owner :zoomed? true)))]


Issue 19614: Added tests

Issue 19614: Added tests

git-svn-id: b7e9aa1d6cd963481915708f70423d437278b157@19637 bd66a97b-2aff-0310-9095-89ca5cabf5a6

--- src/main/clojure/com/imcode/imcms/db.clj
+++ src/main/clojure/com/imcode/imcms/db.clj
@@ -13,11 +13,58 @@
       [logging :as log]))

   (:use
-    [clojure.set :only (select)]
+    (clojure
+      test
+      [set :only (select)])

     (clojure.contrib
       [except :only (throw-if throwf)])))

+;;;
+;;; Pure fns
+;;;
+
+(defn version-rec-to-double
+  "Creates a double from database_version table row."
+  [{:keys [major minor]}]
+  (Double/valueOf (format "%s.%s" major minor)))
+
+
+(defn double-to-version-rec
+  "Creates a record intended to insert/update row in database_version table."
+  [version]
+  (let [[major minor] (su/re-split #"\." (str version))]
+    {
+      :major major,
+      :minor (if minor minor "0")
+    }))
+
+
+(defn required-diff
+  "Returns a diff required to update db or nil if no corresponding diff exists.
+   db-conf-diffs - a set of diffs; see conf.clj and tests to learn more about diffs definition.
+   current-version - current db version as double."
+  [db-conf-diffs current-version]
+  (when-first [diff (select #(= current-version (:from %)) db-conf-diffs)]
+    diff))
+
+
+(defn required-diffs
+  "Returns a seq of diffs beginning from a current version or nil.
+   db-conf-diffs - a set of diffs; see conf.clj and tests to learn more about diffs definition.
+   current-version - current db version as double."
+  [db-conf-diffs current-version]
+  (loop [from current-version, diffs []]
+    (if-let [diff (required-diff db-conf-diffs from)]
+      (let [new-current-version (:to diff)
+            collected-diffs (conj diffs diff)]
+        (recur new-current-version collected-diffs))
+      (seq diffs))))
+
+
+;;;
+;;; Fns with side-effect
+;;;

 (defn tables
   "Returns all db tables."
@@ -28,17 +75,6 @@
   ([]
     (sql/with-query-results rs ["SHOW TABLES"]
       (mapcat vals (doall rs)))))
-
-
-(defn double-to-version-rec [version]
-  (let [[major minor] (su/re-split #"\." (str version))]
-    {:major major,
-     :minor (if-not minor 0 minor)
-    }))
-
-
-(defn version-rec-to-double [{:keys [major minor]}]
-  (Double/valueOf (format "%s.%s" major (if minor minor 0))))

 (defn get-version
@@ -68,21 +104,6 @@
     (sql/update-or-insert-values
       "database_version" ["major IS NOT NULL"]
       (double-to-version-rec version))))
-
-
-(defn required-diff
-  [db-conf-diffs from]
-  (when-first [diff (select #(= from (:from %)) db-conf-diffs)]
-    diff))
-
-
-(defn required-diffs
-  "Returns diffs seq or nil."
-  [db-conf-diffs current-version]
-  (loop [from current-version, diffs []]
-    (if-let [diff (required-diff db-conf-diffs from)]
-      (recur (:to diff) (conj diffs diff))
-      (seq diffs))))

 (defn prepare
@@ -121,4 +142,94 @@

             (set-version to))))))

-    (log/info (format "The database is prepared. Database version is %s." (get-version spec)))))+    (log/info (format "The database is prepared. Database version is %s." (get-version spec)))))
+
+
+;;;
+;;; Tests
+;;;
+
+(def
+  #^{:doc "db-diffs test configuration."
+     :private true}
+
+  db-conf-diffs #{
+      {
+          :from 4.11
+          :to 4.12
+          :scripts ["a.sql" "b.sql"]
+      }
+
+      {
+          :from 4.12
+          :to 4.13
+          :scripts ["c.sql" "d.sql"]
+      }
+
+      {
+          :from 4.13
+          :to 6.2
+          :scripts ["e.sql" "f.sql"]
+      }
+  })
+
+
+(deftest test-version-rec-to-double
+  (is (= 4 (version-rec-to-double {:major 4, :minor 0})))
+  (is (= 4.1 (version-rec-to-double {:major 4, :minor 1}))))
+
+
+(deftest test-double-to-version-rec
+  (is (= {:major "4", :minor "0"} (double-to-version-rec 4)))
+  (is (= {:major "4", :minor "0"} (double-to-version-rec 4.0)))
+  (is (= {:major "4", :minor "1"} (double-to-version-rec 4.1))))
+
+
+(deftest test-required-diff
+  (is (nil? (required-diff db-conf-diffs 4.10)))
+
+  (is (= (required-diff db-conf-diffs 4.11)
+         {
+            :from 4.11
+            :to 4.12
+            :scripts ["a.sql" "b.sql"]
+         }))
+
+  (is (= (required-diff db-conf-diffs 4.13)
+         {
+             :from 4.13
+             :to 6.2
+             :scripts ["e.sql" "f.sql"]
+         })))
+
+
+(deftest test-required-diffs
+  (is (nil? (required-diffs db-conf-diffs 4.10)))
+
+  (is (= (set (required-diffs db-conf-diffs 4.11))
+         db-conf-diffs))
+
+  (is (= (set (required-diffs db-conf-diffs 4.12))
+         #{
+              {
+                  :from 4.12
+                  :to 4.13
+                  :scripts ["c.sql" "d.sql"]
+              }
+
+              {
+                  :from 4.13
+                  :to 6.2
+                  :scripts ["e.sql" "f.sql"]
+              }
+         }))
+
+
+  (is (= (set (required-diffs db-conf-diffs 4.13))
+         #{
+              {
+                  :from 4.13
+                  :to 6.2
+                  :scripts ["e.sql" "f.sql"]
+              }
+         })))


Added comments with example structures

Added comments with example structures

'cause I'm dumb and I was getting confused.

I wonder if I should use generators


Send the board-uuid with the entry for use with the change service.

--- src/oc/storage/representations/entry.clj
+++ src/oc/storage/representations/entry.clj
@@ -162,8 +162,7 @@
             (clojure.set/rename-keys  {:slug :org-slug})
             (merge full-entry)
             (assoc :board-slug board-slug))
-          ;; don't need the extra props
-          (dissoc full-entry :board-uuid))
+          full-entry)
       (clojure.set/rename-keys org-prop-mapping)
       (select-keys representation-props)
       (clean-blank-topic)


Store rollup within rollup time.

Store rollup within rollup time.

--- src/org/spootnik/cyanite/store_cache.clj
+++ src/org/spootnik/cyanite/store_cache.clj
@@ -53,7 +53,8 @@
 (defn- run-delayer!
   [rollup fn-flusher]
   (let [delayer (future
-                  (Thread/sleep (to-ms (calc-delay rollup (rand-int 59)))))
+                  (Thread/sleep
+                   (to-ms (calc-delay rollup (rand-int (dec (int rollup)))))))
         flusher (future
                   (try
                     (deref delayer)


Remove autoWatch from config

Remove autoWatch from config

--- library/src/doo/karma.clj
+++ library/src/doo/karma.clj
@@ -52,7 +52,7 @@
      "plugins" (into ["karma-cljs-test"] (mapv js-env->plugin js-envs))
      "browsers" (mapv js-env->browser js-envs)
      "files" files
-     "autoWatchBatchDelay" 1000
+     "autoWatch" false
      "client" {"args" ["doo.runner.run_BANG_"]}
      "singleRun" true}))


use the proper font in the svg

use the proper font in the svg

--- src/pc/svg.clj
+++ src/pc/svg.clj
@@ -28,7 +28,7 @@
           :y (:layer/start-y layer)
           :fill (if invert-colors? "#ccc" "black")
           :stroke-width 0
-          :font-family (h/h (:layer/font-family layer "Helvetica"))
+          :font-family (h/h (:layer/font-family layer "Roboto"))
           :font-size   (:layer/font-size layer 20)}
          layer-props))


Hook up the button and the link

Hook up the button and the link

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -179,7 +179,10 @@
     (render [_]
       (html
        [:div.refresh-repos
-       [:button.btn.btn-primary.set-user "Reload repositories"]]))))
+       [:button.btn.btn-primary.set-user
+        {:on-click #(raise! owner [:refreshed-user-orgs {}]) ;; TODO: spinner while working?
+         :class "active"}
+        "Reload repositories"]]))))

 (defn repo-item [data owner]
   (reify


[CIRCLE-2995] Add tooltip to platform number (#1747)

* Add tooltip to platform number

--- src-cljs/frontend/components/builds_table.cljs
+++ src-cljs/frontend/components/builds_table.cljs
@@ -4,6 +4,7 @@
             [frontend.components.common :as common]
             [frontend.components.forms :as forms]
             [frontend.components.pieces.icon :as icon]
+            [frontend.components.pieces.popover :as popover]
             [frontend.components.pieces.status :as status]
             [frontend.datetime :as datetime]
             [frontend.experimental.workflow-spike :as workflow]
@@ -79,7 +80,8 @@
         should-show-cancel? (and (project-model/can-trigger-builds? project)
                                  (build-model/can-cancel? build))
         should-show-rebuild? (and (project-model/can-trigger-builds? project)
-                                  (#{"timedout" "failed"} (:outcome build)))]
+                                  (#{"timedout" "failed"} (:outcome build)))
+        platform (:platform build)]
     [:div.build {:class (-> build build-model/build-status build-model/status-class name)}
      [:div.status-area
       [:a {:href url
@@ -168,7 +170,17 @@
        (om/build pull-requests {:build build})
        (om/build commits {:build build})]]
      [:div.build-list-notes
-        [:span.platform (:platform build)]]]))
+       (popover/popover {:title nil
+                         :body [:span (if (= "1.0" platform)
+                                          "2.0 is coming soon!\n"
+                                          "This build ran on 2.0.\n")
+                                [:a {:href "https://discuss.circleci.com/c/circleci-2-0"
+                                     :target "_blank"}
+                                 "Learn more"]]
+                         :placement :left
+                         :trigger-mode :click}
+        [:span.platform platform])]]))
+

 (defn job-waiting-badge
   "badge for waiting job."


remove leading # from channel name

remove leading # from channel name

--- src-cljs/frontend/components/integrations.cljs
+++ src-cljs/frontend/components/integrations.cljs
@@ -126,7 +126,10 @@
                                    #(om/set-state! owner :show-options? false)
                                    #(om/set-state! owner :show-options? true))}
          (common/icon :slack)
-         (:slack-hook/channel-name slack-hook)]
+         (let [ch (:slack-hook/channel-name slack-hook)]
+           (if (= \# (first ch))
+             (subs ch 1)
+             ch))]
         (when (om/get-state owner :show-options?)
           (if (om/get-state owner :you-sure?)


Saner CLI option names

Saner CLI option names

--- src/buildviz/go/sync.clj
+++ src/buildviz/go/sync.clj
@@ -41,11 +41,11 @@
    ["-f" "--from DATE" "Date from which on builds are loaded, if not specified tries to pick up where the last run finished"
     :id :sync-start-time
     :parse-fn #(tf/parse date-formatter %)]
-   ["-j" "--sync-jobs PIPELINE" "Pipeline for which Go jobs will be synced individually and not aggregated inside stage"
-    :id :sync-jobs
+   ["-j" "--sync-jobs PIPELINE" "Pipelines for which Go jobs will be synced individually and not aggregated inside stage"
+    :id :sync-jobs-for-pipelines
     :default nil
     :assoc-fn (fn [previous key val] (assoc previous key (conj (get previous key) val)))]
-   ["-g" "--pipeline-groups PIPELINE_GROUPS" "Go pipeline groups to be synced, all by default"
+   ["-g" "--pipeline-group PIPELINE_GROUP" "Go pipeline groups to be synced, all by default"
     :id :pipeline-groups
     :default nil
     :assoc-fn (fn [previous key val] (assoc previous key (conj (get previous key) val)))]
@@ -194,7 +194,7 @@
   (def buildviz-url (:buildviz-url (:options args)))

   (let [sync-start-time (get-start-date (:sync-start-time (:options args)))
-        sync-jobs-for-pipelines (set (:sync-jobs (:options args)))
+        sync-jobs-for-pipelines (set (:sync-jobs-for-pipelines (:options args)))
         selected-pipeline-group-names (set (:pipeline-groups (:options args)))]

     (->> (goapi/get-stages go-url)


Test positive CAS mutations.

Test positive CAS mutations.

--- src/cbfg/store-test.cljs
+++ src/cbfg/store-test.cljs
@@ -114,9 +114,57 @@
                     (e n (atake test c)
                        {:status :wrong-cas, :key "a", :opaque @n}
                        (atake test c)))
-                  (let [c (store/store-get test s @n "a")]
-                    (e n (atake test c)
-                       {:status :ok, :key "a", :opaque @n, :sq 5, :val "prefixAAAsuffix"}
-                       (atake test c))))
+                  (let [gc (store/store-get test s @n "a")
+                        gv (atake test gc)
+                        _ (atake test gc)
+                        sc (store/store-set test s @n "a" (:cas gv) "AAAA" :set)
+                        sv (atake test sc)]
+                    (and (e n sv
+                            {:status :ok, :key "a", :opaque @n, :sq 6, :cas (:cas sv)}
+                            (atake test sc))
+                         (let [gc2 (store/store-get test s @n "a")]
+                           (e n (atake test gc2)
+                              {:status :ok, :key "a", :opaque @n, :sq 6, :cas (:cas sv)
+                               :val "AAAA"}
+                              (atake test gc2)))))
+                  (let [gc (store/store-get test s @n "a")
+                        gv (atake test gc)
+                        _ (atake test gc)
+                        sc (store/store-set test s @n "a" (:cas gv) "AAAAA" :replace)
+                        sv (atake test sc)]
+                    (and (e n sv
+                            {:status :ok, :key "a", :opaque @n, :sq 7, :cas (:cas sv)}
+                            (atake test sc))
+                         (let [gc2 (store/store-get test s @n "a")]
+                           (e n (atake test gc2)
+                              {:status :ok, :key "a", :opaque @n, :sq 7, :cas (:cas sv)
+                               :val "AAAAA"}
+                              (atake test gc2)))))
+                  (let [gc (store/store-get test s @n "a")
+                        gv (atake test gc)
+                        _ (atake test gc)
+                        sc (store/store-set test s @n "a" (:cas gv) "suffix" :append)
+                        sv (atake test sc)]
+                    (and (e n sv
+                            {:status :ok, :key "a", :opaque @n, :sq 8, :cas (:cas sv)}
+                            (atake test sc))
+                         (let [gc2 (store/store-get test s @n "a")]
+                           (e n (atake test gc2)
+                              {:status :ok, :key "a", :opaque @n, :sq 8, :cas (:cas sv)
+                               :val "AAAAAsuffix"}
+                              (atake test gc2)))))
+                  (let [gc (store/store-get test s @n "a")
+                        gv (atake test gc)
+                        _ (atake test gc)
+                        sc (store/store-set test s @n "a" (:cas gv) "prefix" :prepend)
+                        sv (atake test sc)]
+                    (and (e n sv
+                            {:status :ok, :key "a", :opaque @n, :sq 9, :cas (:cas sv)}
+                            (atake test sc))
+                         (let [gc2 (store/store-get test s @n "a")]
+                           (e n (atake test gc2)
+                              {:status :ok, :key "a", :opaque @n, :sq 9, :cas (:cas sv)
+                               :val "prefixAAAAAsuffix"}
+                              (atake test gc2))))))
            "pass"
            (str "FAIL: on test #" @n)))))


Fix suboptimal code found by eastwood linter

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/chaintool/codecs.clj
+++ src/chaintool/codecs.clj
@@ -39,7 +39,7 @@

    {:name "lzma"
     :output #(-> (LzmaOutputStream$Builder. %) .build)
-    :input #(-> (LZMACompressorInputStream. %))}
+    :input #(LZMACompressorInputStream. %)}

    {:name "bzip2"
     :output #(BZip2CompressorOutputStream. %)


also broadcast new message to sender, so they get server time

--- src/chat/server/sync.clj
+++ src/chat/server/sync.clj
@@ -71,7 +71,7 @@
   (when-let [user-id (get-in ring-req [:session :user-id])]
     (if (db/with-conn (db/user-can-see-thread? user-id (?data :thread-id)))
       (do (db/with-conn (db/create-message! (assoc ?data :created-at (java.util.Date.))))
-        (broadcast-thread (?data :thread-id) [user-id]))
+        (broadcast-thread (?data :thread-id) []))
       ; TODO: indicate permissions error to user?
       (timbre/warnf "User %s attempted to add message to disallowed thread %s"
                     user-id (?data :thread-id)))))


Allow upstream :foreign-libs to be used [CLJS-588]

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -515,7 +515,7 @@
   (concat
    (mapcat #(load-library % true) ups-libs) ;upstream deps
    (mapcat load-library libs)
-   (mapcat #(load-foreign-library % true) ups-flibs) ;upstream deps
+   (map #(load-foreign-library % true) ups-flibs) ;upstream deps
    (map load-foreign-library foreign-libs)))

 (comment


Pass options to simulation run

Pass options to simulation run

--- src/clj_gatling/core.clj
+++ src/clj_gatling/core.clj
@@ -19,7 +19,7 @@
        results-dir (if (nil? (:root options))
                       "target/results"
                       (:root options))
-       result (simulation/run-simulation scenario users)
+       result (simulation/run-simulation scenario users options)
        csv (csv/write-csv (report/create-result-lines start-time result) :delimiter "\t" :end-of-line "\n")]
    (create-dir (str results-dir "/input"))
    (spit (str results-dir "/input/simulation.log") csv)


refine import for efficiency

refine import for efficiency

instead of reading the entire file into memory,
insert records as they are found

--- src/clj_money/import.clj
+++ src/clj_money/import.clj
@@ -31,12 +31,6 @@
         result (accounts/create (:storage context) to-create)]
     (update-in context [:accounts] #(assoc % original-id (:id result)))))

-(defn- import-accounts
-  [context accounts]
-  (reduce import-account
-          context
-          accounts))
-
 (defn- import-transaction
   [context transaction]
   (let [to-create (-> transaction
@@ -48,28 +42,16 @@
     (transactions/create (:storage context) to-create)
     context)) ; Update anything in the context? don't want to include all transactions, as that can be many

-(defn- import-transactions
-  [context transactions]
-  (reduce import-transaction
-          context
-          transactions))
-
 (defn import-data
   "Reads the contents from the specified input and saves
   the information using the specified storage. If an entity
   with the specified name is found, it is used, otherwise it
   is created"
   [storage-spec user entity-name input source-type]
-  ; TODO this strategy will load all transactions into memory
-  ; it would be good to find a way that didn't
-  (let [accounts (atom [])
-        transactions (atom [])]
-    (read-source source-type input (->Callback (fn [account] (swap! accounts #(conj % account)))
-                                               (fn [transaction] (swap! transactions #(conj % transaction)))))
-    (with-transacted-storage [s storage-spec]
-      (let [entity (entities/find-or-create s user  entity-name)]
-        (-> {:storage s
-             :accounts {}
-             :entity-id (:id entity)}
-            (import-accounts @accounts)
-            (import-transactions @transactions))))))
+  (with-transacted-storage [s storage-spec]
+    (let [entity (entities/find-or-create s user  entity-name)
+          context (atom {:storage s
+                         :accounts {}
+                         :entity-id (:id entity)})]
+      (read-source source-type input (->Callback (fn [account] (swap! context #(import-account % account)))
+                                                 (fn [transaction] (swap! context #(import-transaction % transaction))))))))


Leave a note about researching transit after processing glTF file

--- src/cljs/gampg/gltf.cljs
+++ src/cljs/gampg/gltf.cljs
@@ -9,6 +9,10 @@
 ;; uris), and even then there may be race conditions with image
 ;; data. The next major rework will turn it into an asynchronously
 ;; loading library to remove this major limitation.
+
+;; TODO: Support a pre-processing step to do all of this and save it
+;; out to transit, hopefully with similar file size and already 99%
+;; processed upon load.

 (defn decode-data-uri-text [base-64? data]
   (let [result (js/window.decodeURIComponent data)]


No need for this extra newline

No need for this extra newline

--- src/cljs/go/compiler.clj
+++ src/cljs/go/compiler.clj
@@ -1157,8 +1157,7 @@
 (defn url-path [^File f]
   (.getPath (.toURL (.toURI f))))

-(def main-src "
-// +build ignore
+(def main-src "// +build ignore

 package main


Cleaning up...

Cleaning up...

--- src/clojousvide/core.clj
+++ src/clojousvide/core.clj
@@ -4,7 +4,9 @@
             [clojousvide.db.migrations :as migrations]
             [clojure.tools.nrepl.server :as nrepl]
             [taoensso.timbre :as timbre]
-            [environ.core :refer [env]])
+            [environ.core :refer [env]]
+            [clojousvide.hardware.heater :as heater]
+            [clojousvide.hardware.thermometer :as temp])
   (:gen-class))

 (defonce nrepl-server (atom nil))
@@ -67,4 +69,13 @@
     (do (migrations/migrate args) (System/exit 0))
     :else
     (start-app args)))
-
+
+(defn ghetto-pid
+  "I don't do a whole lot ... yet."
+  []
+  (loop []
+    (if (>= (temp/get-water-temp) 60) (heater/heater-off!) (heater/heater-on!))
+    (Thread/sleep 120000)
+    (recur)
+    )
+  )


Add energy units

Add energy units

--- src/test_utils/fracture_diagnostics.cljc
+++ src/test_utils/fracture_diagnostics.cljc
@@ -15,18 +15,18 @@
   (rand-nth physical-quantities))

 (defn rand-unit [physical-quantity]
-  (let [quantity-units-map {:density [:lb-per-cu-ft :kg-per-m3]
-                            :length [:ft :m]
-                            :mass [:lb :kg]
-                            :pressure [:psi :kPa :MPa]
+  (let [quantity-units-map {:density                [:lb-per-cu-ft :kg-per-m3]
+                            :energy                 [:ft-lb :J]
+                            :length                 [:ft :m]
+                            :mass                   [:lb :kg]
+                            :pressure               [:psi :kPa :MPa]
                             :proppant-concentration [:lb-per-gal :lb/gal :kg-per-m3 :kg/m3]
-                            :slurry-rate [:bbl-per-min :bpm :m3-per-min :m3/min]
-                            :volume [:bbl :m3]}]
-
-
+                            :slurry-rate            [:bbl-per-min :bpm :m3-per-min :m3/min]
+                            :volume                 [:bbl :m3]}]
     (fn [] (rand-nth (get quantity-units-map physical-quantity)))))

 (def rand-density-unit (rand-unit :density))
+(def rand-energy-unit (rand-unit :energy))
 (def rand-length-unit (rand-unit :length))
 (def rand-mass-unit (rand-unit :mass))
 (def rand-pressure-unit (rand-unit :pressure))
@@ -520,29 +520,29 @@
 (defn typical-density
   ([]
    (let [density-unit (rand-density-unit)
-         substance (rand-nth substances)]
+         substance    (rand-nth substances)]
      (typical-density density-unit substance)))
   ([density-unit-or-substance]
-   (let [is-density-unit (fn [to-test] (#{:kg-per-m3 :lb-per-cu-ft} to-test))
-         is-substance (fn [to-test] ((set substances) to-test))
+   (let [is-density-unit          (fn [to-test] (#{:kg-per-m3 :lb-per-cu-ft} to-test))
+         is-substance             (fn [to-test] ((set substances) to-test))
          [density-unit substance] (cond
-                                      (is-density-unit density-unit-or-substance)
-                                      [density-unit-or-substance (rand-nth substances)]
-                                      (is-substance density-unit-or-substance)
-                                      [(rand-nth [:kg-per-m3 :lb-per-cu-ft]) density-unit-or-substance])]
+                                    (is-density-unit density-unit-or-substance)
+                                    [density-unit-or-substance (rand-nth substances)]
+                                    (is-substance density-unit-or-substance)
+                                    [(rand-nth [:kg-per-m3 :lb-per-cu-ft]) density-unit-or-substance])]
      (typical-density density-unit substance)))
   ([density-unit substance]
    (condp = density-unit
      :lb-per-cu-ft (let [[density density-unit substance] (typical-density :kg-per-m3)]
                      [((convert-units-f :kg-per-m3 :lb-per-cu-ft) density) :lb-per-cu-ft substance])
-     :kg-per-m3 (condp = substance
+     :kg-per-m3    (condp = substance
                   ;; Typical values for different substances taken from
                   ;; https://serc.carleton.edu/mathyouneed/density/index.html#:~:text=Typical%20densities%20for%20gasses%20are,or%207%20g%2Fcm3.
                   ;; accessed on 23-Dec-2020. Additionally, the data for metals was taken from
                   ;; https://theengineeringmindset.com/density-of-metals/ accessed on 23-Dec-2020.
-                  (let [density (condp = substance
-                                  :gas (tuc/draw-normal 1 0.11)
-                                  :liquid (tuc/draw-normal 1000 110)
-                                  :rock (tuc/draw-normal 3000 330)
-                                  :metal (tuc/draw-normal) 10355 5431)]
-                    [density density-unit substance])))))
+                     (let [density (condp = substance
+                                     :gas    (tuc/draw-normal 1 0.11)
+                                     :liquid (tuc/draw-normal 1000 110)
+                                     :rock   (tuc/draw-normal 3000 330)
+                                     :metal  (tuc/draw-normal) 10355 5431)]
+                       [density density-unit substance])))))


[#3157] Fix pivot count with data-groups

--- backend/src/akvo/lumen/lib/aggregation/pivot.clj
+++ backend/src/akvo/lumen/lib/aggregation/pivot.clj
@@ -67,12 +67,13 @@
     {:columns []
      :rows [[]]}))

-(defn apply-query [conn table-name {:keys [row-column category-column value-column] :as query} filter-str]
+(defn apply-query [conn table-name {:keys [row-column category-column value-column flow?] :as query} filter-str]
   (cond

     (and (nil? row-column) (nil? category-column))
     {:columns [{:type "number" :title "Total"}]
-     :rows    (run-query conn (format "SELECT count(*) FROM %s WHERE %s"
+     :rows    (run-query conn (format "SELECT count(%s) FROM %s WHERE %s"
+                                      (if flow? "distinct instance_id" "*")
                                       table-name
                                       filter-str))}

@@ -124,6 +125,7 @@
                       "count" "count"
                       (throw (ex-info "Unsupported aggregation function"
                                       {:aggregation (:aggregation query )})))
+   :flow? (some #(= "instance_id" (:columnName %)) columns)
    :filters         (:filters query)})

 (defn query [tenant-conn {:keys [columns table-name]} query]


Refine test

Refine test

--- backend/test/akvo/lumen/lib/aggregation_test.clj
+++ backend/test/akvo/lumen/lib/aggregation_test.clj
@@ -25,9 +25,14 @@
                  {:id "c2", :title "B", :type "text"}
                  {:id "c3", :title "C", :type "number"}]
         rows [[{:value "a1"} {:value "b1"} {:value 10}]
-               [{:value "a1"} {:value "b1"} {:value 11}]
-               [{:value "a1"} {:value "b2"} {:value 9}]
-               [{:value "a1"} {:value "b2"} {:value 10}]]
+              [{:value "a1"} {:value "b1"} {:value 11}]
+              [{:value "a1"} {:value "b2"} {:value 9}]
+              [{:value "a1"} {:value "b2"} {:value 10}]
+              [{:value "a2"} {:value "b1"} {:value 12}]
+              [{:value "a2"} {:value "b1"} {:value 10}]
+              [{:value "a2"} {:value "b2"} {:value 11}]
+              [{:value "a2"} {:value "b2"} {:value 10}]
+              [{:value "a2"} {:value "b2"} {:value 10}]]
         data {:columns columns :rows rows}
         [job dataset] (import-file *tenant-conn* *error-tracker* {:dataset-name "pivot"
                                                                   :kind "clj"
@@ -41,27 +46,9 @@
       (let [[tag query-result] (query {:aggregation "count"})]
         (is (= query-result
                {:columns [{:type "number" :title "Total"}]
-                :rows [[4]]
-                :metadata {:categoryColumnTitle nil}})))
-
-
-      (update-file *tenant-conn* *error-tracker* dataset-id data-source-id
-                   {:kind "clj"
-                    :data {:columns columns
-                           :rows (conj rows
-                                       [{:value "a2"} {:value "b1"} {:value 12}]
-                                       [{:value "a2"} {:value "b1"} {:value 10}]
-                                       [{:value "a2"} {:value "b2"} {:value 11}]
-                                       [{:value "a2"} {:value "b2"} {:value 10}])}})
-
-      (let [[tag query-result] (query {:aggregation "count"})]
-        (is (= query-result
-               {:columns [{:type "number" :title "Total"}]
-                :rows [[8]]
+                :rows [[9]]
                 :metadata {:categoryColumnTitle nil}}))))

-
-
     (testing "Empty query with filter"
       (let [[tag query-result] (query {:aggregation "count",
                                        :filters
@@ -77,7 +64,7 @@
                {:columns [{:title "" :type "text"}
                           {:title "a1" :type "number"}
                           {:title "a2" :type "number"}]
-                :rows [["Total" 4 4]]
+                :rows [["Total" 4 5]]
                 :metadata {:categoryColumnTitle "A"}}))))

     (testing "Row Column Only"
@@ -86,7 +73,7 @@
                {:columns [{:title "B" :type "text"}
                           {:title "Total" :type "number"}]
                 :rows [["b1" 4]
-                       ["b2" 4]]
+                       ["b2" 5]]
                 :metadata {:categoryColumnTitle nil}}))))

     (testing "Row & Category Column with count aggregation"
@@ -96,7 +83,7 @@
                           {:title "a1", :type "number"}
                           {:title "a2", :type "number"}]
                 :rows [["b1" 2.0 2.0]
-                       ["b2" 2.0 2.0]]
+                       ["b2" 2.0 3.0]]
                 :metadata {:categoryColumnTitle "A"}}))))

     (testing "Row & Category Column with mean aggregation"
@@ -109,7 +96,7 @@
                           {:title "a1", :type "number"}
                           {:title "a2", :type "number"}]
                 :rows [["b1" 10.5 11.0]
-                       ["b2" 9.5 10.5]]
+                       ["b2" 9.5 10.333333333333334]]
                 :metadata {:categoryColumnTitle "A"}}))))

     (testing "Row & Category Column with mean aggregation and filter"
@@ -127,7 +114,7 @@
                           {:title "a1" :type "number"}
                           {:title "a2" :type "number"}]
                 :rows [["b1" 10.5 10.0]
-                       ["b2" 9.5 10.5]]
+                       ["b2" 9.5 10.333333333333334]]
                 :metadata {:categoryColumnTitle "A"}}))))))

 (deftest pie-tests


editing and adding new entities works :-)

--- resources/leiningen/new/closp/cljs/cc/left_panel.cljs
+++ resources/leiningen/new/closp/cljs/cc/left_panel.cljs
@@ -8,8 +8,6 @@
   (swap! state assoc :new-entity (first (filter #(= name (:name %)) (:ex-entities @state)))))

 (s/defn render-ex-entities [state entities :- schem/cc-entity-definitons]
-        (println (first entities))
-        (println (:columns (first entities)))
         [:div
          [:h3 "Existing Entities"]
          [:hr]


improved readability of tasks

improved readability of tasks

--- src/distillery/tasks.clj
+++ src/distillery/tasks.clj
@@ -17,6 +17,7 @@
   [& msg]
   (println (str "# " (apply str msg))))

+
 (defmacro long-task
   [msg & body]
   `(do
@@ -24,6 +25,7 @@
        (let [result# (do ~@body)]
          (print-progress (str "END   " ~msg))
          result#)))
+

 (defn- load-speech-recognition-result
   "Loads the speech recognition results for a video."
@@ -35,11 +37,13 @@
                     proc/reverse-index-results)]
     (assoc video :results results)))

+
 (defn load-speech-recognition-results
   "Loads the speech recognition results for the videos."
   [job]
   (long-task "Loading speech recognition results"
     (update-in job [:videos] #(vec (map load-speech-recognition-result %)))))
+

 (defn- build-video-index
   "Analyzes the speech recognition results of a single video and builds the video word index."
@@ -49,6 +53,7 @@
         predicate (partial multi-filter filters)
         index (proc/video-word-index video :predicate predicate)]
     (assoc video :index index)))
+

 (defn- build-video-statistics
   [{:keys [id results] :as video}]
@@ -60,6 +65,7 @@
       :word-count (count (proc/words results))
       :confidence (mean (map :confidence results))
       :duration duration)))
+

 (defn analyze-speech-recognition-results
   "Analyzes the speech recognition results an generates the index structures."
@@ -92,6 +98,7 @@
          (apply render)
          (save-page target-file))))

+
 (defn- create-include
   [include-name include-f {:keys [output-dir] :as args}]
   (let [target-file (combine-path output-dir include-name)]
@@ -106,11 +113,13 @@
   (print-progress "Creating index page")
   (create-page "index.html" v-index/render-main-page job))

+
 (defn create-categories-page
   "Creates the overview page for all categories."
   [job]
   (print-progress "Creating categories overview page")
   (create-page "categories.html" v-index/render-categories-page job))
+

 (defn create-videos-page
   "Creates the overview page for all videos."
@@ -118,11 +127,13 @@
   (print-progress "Creating videos overview page")
   (create-page "videos.html" v-index/render-videos-page job))

+
 (defn create-glossary-page
   "Creates the overview page for all words."
   [job]
   (print-progress "Creating global glossary page")
   (create-page "glossary.html" v-index/render-glossary-page job))
+

 (defn create-video-word-include
   [{:keys [output-dir] :as job} video {:keys [path] :as word}]
@@ -130,6 +141,7 @@
     (str path ".inc.html")
     v-word/render-video-word-include
     (assoc job :video video :word word)))
+

 (defn create-video-word-includes
   [{:keys [output-dir] :as job} {:keys [id index path] :as video}]
@@ -139,6 +151,7 @@
       (doseq [word (vals index)]
         (let [word-path (combine-path words-path (:id word))]
           (create-video-word-include job video (assoc word :path word-path)))))))
+

 (defn create-video-page
   "Create the main page for a certain video."
@@ -161,6 +174,7 @@

     (create-video-word-includes job video*)))

+
 (defn create-video-pages
   "Creates the main pages for all videos."
   [job]
@@ -168,6 +182,7 @@
     (doseq [video (:videos job)]
       (create-video-page job video))))

+
 (defn print-reverse-indexed-results
   [{:keys [video]}]
   (let [results (load-data (:results-file video))]


Fix defissuer

Fix defissuer

--- src/eulalie/support.cljc
+++ src/eulalie/support.cljc
@@ -3,7 +3,7 @@
             [plumbing.map]
             [eulalie.core :as eulalie]
             #? (:clj
-                [glossop.core]
+                [glossop.core :refer [<? go-catching]]
                 :cljs
                 [cljs.core.async]))
   #? (:cljs (:require-macros [glossop.macros :refer [<? go-catching]])))
@@ -32,11 +32,10 @@
             fname!! (-> target-name name (str "!!") symbol)
             args'   (into '[creds] (conj args '& '[extra]))
             body  `(eulalie.support/issue-request!
-                    (merge {:service ~service
-                            :target ~(keyword target-name)
-                            :creds ~'creds}
-                           (plumbing.map/keyword-map ~@args)
-                           ~'extra)
+                    {:service ~service
+                     :target  ~(keyword target-name)
+                     :creds   ~'creds
+                     :body    (merge (plumbing.map/keyword-map ~@args) ~'extra)}
                     ~req-fn ~resp-fn)
             md     (cond-> (meta target-name)
                      doc (assoc :doc doc))]


OO: Use correct key, _rank, not _id

OO: Use correct key, _rank, not _id

--- src/hatti/views/map.cljs
+++ src/hatti/views/map.cljs
@@ -81,7 +81,7 @@
             (put! shared/event-chan
                   {:mapped-submission-to-rank
                    (get-in @app-state
-                           [:map-page :submission-clicked :data _id])})
+                           [:map-page :submission-clicked :data _rank])})
             (put! shared/event-chan
                   {:view-by (get-in @app-state [:map-page :view-by])})))))))


Add a series-list component.

Add a series-list component.

--- metlog-vault/src-client/metlog.cljs
+++ metlog-vault/src-client/metlog.cljs
@@ -21,26 +21,32 @@
 (defn error-handler [{:keys [status status-text]}]
   (.log js/console (str "something bad happened: " status " " status-text)))

-(defn update-series-names [ response ]
-  (let [ series-names (reader/read-string (str response))]
-    (.log js/console series-names)
-    (swap! dashboard-state assoc :series-names series-names)))
-
 (defn ajax-get [ url callback ]
   (GET url {:handler callback
             :error-handler error-handler}))

-(defn fetch-series-names []
-  (ajax-get "/series-names" update-series-names))
+(defn fetch-series-names [ cb ]
+  (ajax-get "/series-names" cb))

 (defn fetch-server-time [ cb ]
   (ajax-get "/server-time" cb))

-(defn item-list [ items owner ]
+(defn series-pane [ state owner ]
   (om/component
-   (apply dom/ul nil
-          (map (fn [text] (dom/li nil text))
-               items))))
+   (dom/div nil state)))
+
+(defn series-list [ state owner ]
+  (reify
+    om/IWillMount
+    (will-mount [ this ]
+      (go
+        (om/update! state :series-names (<! (<<< fetch-series-names)))))
+
+    om/IRender
+    (render [ this ]
+      (apply dom/div nil
+             (map #(om/build series-pane %)
+                  (:series-names state))))))

 (defn server-time [ state owner ]
   (reify
@@ -63,9 +69,8 @@
   (om/component
       (dom/div nil
             (om/build server-time state)
-            (om/build item-list (:series-names state)))))
+            (om/build series-list state))))

 (om/root dashboard dashboard-state
   {:target (. js/document (getElementById "metlog"))})

-(fetch-series-names)


Return emtpy list if no extensions found

--- src/clojure/puppetlabs/certificate_authority/core.clj
+++ src/clojure/puppetlabs/certificate_authority/core.clj
@@ -697,7 +697,8 @@
   {:pre [(or (certificate? ext-container)
              (certificate-request? ext-container))]
    :post [(extension-list? %)]}
-  (-> (ExtensionsUtils/getExtensionList (javaize ext-container))
+  (-> (or (ExtensionsUtils/getExtensionList (javaize ext-container))
+          [])
       clojureize))

 (defn get-extension


Lisätty funktio kyselyn tulosten lukumäärän selvittämistä varten

--- clj-elasticsearch/src/clj_elasticsearch/elastic_connect.clj
+++ clj-elasticsearch/src/clj_elasticsearch/elastic_connect.clj
@@ -32,6 +32,10 @@
       (let [query-map (apply array-map query-params)]
            (elastic-post (elastic-url index mapping-type "_search") query-map)))

+(defn count [index mapping-type & query-params]
+      (let [query-map (apply array-map query-params)]
+           (:count (elastic-post (elastic-url index mapping-type "_count") query-map))))
+
 (defn parse-search-result [res] (map :_source (get-in res [:hits :hits])))

 (defn get-document [index mapping-type id] ;TODO URL encoding


Use core.async to allow concurrent event msg handling

--- components/sente/src/gorillalabs/tesla/component/router.clj
+++ components/sente/src/gorillalabs/tesla/component/router.clj
@@ -1,6 +1,7 @@
 ( ns gorillalabs.tesla.component.router
   (:require [mount.core :as mnt]
             [clojure.tools.logging :as log]
+            [clojure.core.async :as async :refer (<! <!! >! >!! put! chan go go-loop close!)]
             [gorillalabs.tesla.component.socket :as socket]
             [taoensso.sente :as sente]))

@@ -8,27 +9,33 @@

 (defn- event-msg-handler
   "Wraps `-event-msg-handler` with logging, error catching, etc."
-  [{:as ev-msg :keys [id ?data event ?reply-fn]}]
-
-  (if-let [event-fn (get @(:events router) id)]
-    (event-fn ev-msg)
-    (do (log/info "Unhandled event: %s" id)
-        (when ?reply-fn
-          (?reply-fn {:umatched-event-as-echoed-from-from-server event})))))
+  [event-msg-channel]
+  (go-loop [event-msg (<! event-msg-channel)]
+           (when event-msg
+             (let [{:keys [id event ?reply-fn]} event-msg]
+               (go (if-let [event-fn (get @(:events router) id)]
+                     (event-fn event-msg)
+                     (do (log/info "Unhandled event: %s" id)
+                         (when ?reply-fn
+                           (?reply-fn {:umatched-event-as-echoed-from-from-server event}))))))
+             (recur (<! event-msg-channel)))))

 (defn register [router-component id callback]
   (swap! (:events router-component) assoc id callback))

 (defn deregister [router-component id]
-  (swap! (:events  router-component) dissoc id))
+  (swap! (:events router-component) dissoc id))

 (defn- start []
   (log/info "-> Starting sente router")
-  {:events (atom {}) :router (sente/start-server-chsk-router!  (:ch-recv socket/socket) event-msg-handler) })
+  (let [event-msg-channel (chan)]
+    (event-msg-handler event-msg-channel)
+    {:event-msg-channel event-msg-channel :events (atom {}) :router (sente/start-server-chsk-router! (:ch-recv socket/socket) #(go (>! event-msg-channel %)))}))

 (defn- stop [self]
   (log/info "<- Stopping sente router.")
-  (when (:router self) ((:router self))))
+  (when (:router self) ((:router self)))
+  (when (:event-msg-channel self) (close! (:event-msg-channel self))))

 (mnt/defstate router
   :start (start)


Add user-id-fn

Add user-id-fn

--- components/sente/src/gorillalabs/tesla/component/socket.clj
+++ components/sente/src/gorillalabs/tesla/component/socket.clj
@@ -8,7 +8,7 @@

 (defn- start []
   (log/info "-> Starting sente socket ")
-  (sente/make-channel-socket! (get-sch-adapter) {:packet :edn}))
+  (sente/make-channel-socket! (get-sch-adapter) {:packet :edn :user-id-fn (fn [ring-req] (str (java.util.UUID/randomUUID)))}))

 (defn- stop [self]
   (log/info "<- Stopping sente socket."))


[scamp] reformat 'read-mail

[scamp] reformat 'read-mail

--- modules/scamp/src/scamp/core.clj
+++ modules/scamp/src/scamp/core.clj
@@ -518,11 +518,14 @@
     (if (< (get-in destination-node [:messages-seen envelope-id])
            message-dup-drop-after)
       (condp = message-type
-        :new-upstream-node (receive-msg-new-upstream-node logging destination-node message-body)
+        ;; TODO: refactor into 'receive-msg multimethod
+        :new-upstream-node (receive-msg-new-upstream-node logging
+                                                          destination-node
+                                                          message-body)
         :forwarded-subscription (receive-msg-forwarded-subscription logging
-                                                               destination-node
-                                                               message-body
-                                                               envelope-id)
+                                                                    destination-node
+                                                                    message-body
+                                                                    envelope-id)
         :node-unsubscription (receive-msg-node-unsubscription logging
                                                               destination-node
                                                               message-body


Minor improvements on tests.

Minor improvements on tests.

--- test/buddy/auth/backends/token_tests.clj
+++ test/buddy/auth/backends/token_tests.clj
@@ -4,97 +4,105 @@
             [buddy.core.codecs :refer :all]
             [buddy.sign.jws :as jws]
             [buddy.auth :refer [throw-unauthorized]]
-            [buddy.auth.backends.token :refer (parse-authorization-header
-                                               jws-backend
-                                               token-backend)]
+            [buddy.auth.backends.token :as token]
             [buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]))

-(def secret-key "test-secret-key")
+(def secret "test-secret-key")

-(defn authfn
-  [request token]
-  (let [data {:token1 {:userid 1}
-              :token2 {:userid 2}}]
-    (get data (keyword token))))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Helpers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn make-request
-  ([] {})
-  ([token]
-   (let [header (format "Token %s" token)]
-     {:headers {"auThorIzation" header}})))
+  [token]
+  (let [header (format "Token %s" token)]
+    {:headers {"auThorIzation" header}}))
+
+(defn make-jws-request
+  [data secret]
+  (let [header (->> (jws/sign {:userid 1} secret)
+                    (format "Token %s"))]
+    {:headers {"authorization" header}}))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Tests: parse
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (deftest token-parse-test
   (testing "Parse authorization header"
     (let [request (make-request "foo")
-          parsed  (parse-authorization-header request "Token")]
+          parsed  (token/parse-authorization-header request "Token")]
       (is (= parsed "foo"))))

   (testing "Parse authorization header different header name yields nil"
-    (let [parsed (parse-authorization-header (make-request "foo") "MyToken")]
+    (let [parsed (token/parse-authorization-header (make-request "foo") "MyToken")]
      (is (= parsed nil)))))

-(defn make-jws-token
-  ([id] (make-jws-token id secret-key))
-  ([id secret]
-   (jws/sign {:userid 1} secret)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Tests: JWS
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defn make-jws-request
-  ([id] (make-jws-request id secret-key))
-  ([id secret]
-   (let [header (->> (make-jws-token id secret)
-                     (format "Token %s"))]
-     {:headers {"authorization" header}})))
-
-(def jbackend (jws-backend {:secret secret-key}))
+(def jws-secret "mysuperjwssecret")
+(def jws-backend (token/jws-backend {:secret jws-secret}))
+(def jws-data {:userid 1})

 (deftest jws-backend-test
   (testing "Jws token backend authentication"
-    (let [request (make-jws-request 1)
-          handler (wrap-authentication identity jbackend)
+    (let [request (make-jws-request jws-data jws-secret)
+          handler (wrap-authentication identity jws-backend)
           response (handler request)]
-      (is (= (:identity response) {:userid 1}))))
+      (is (= (:identity response) jws-data))))

   (testing "Jws token backend authentication with wrong key yields nil"
-    (let [request (make-jws-request 1 "wrong-key")
-          handler (wrap-authentication identity jbackend)
+    (let [request (make-jws-request jws-data  "wrong-key")
+          handler (wrap-authentication identity jws-backend)
           response (handler request)]
       (is (nil? (:identity response)))))

   (testing "Jws token backend authentication with no token yields nil"
     (let [request {}
-          handler (wrap-authentication identity jbackend)
+          handler (wrap-authentication identity jws-backend)
           response (handler request)]
       (is (nil? (:identity response)))))

   (testing "Jws token authorizaton with wrong key yields 401"
-    (let [request (make-jws-request 1 "wrong-key")
+    (let [request (make-jws-request jws-data "wrong-key")
           handler (-> (fn [req] (throw-unauthorized))
-                      (wrap-authorization jbackend)
-                      (wrap-authentication jbackend))
+                      (wrap-authorization jws-backend)
+                      (wrap-authentication jws-backend))
           response (handler request)]
       (is (= (:status response) 401))))

   (testing "Jws token authorization - authenticated but unathorized thrown yields 403"
-    (let [request (make-jws-request 1)
+    (let [request (make-jws-request {:userid 1} jws-secret)
           handler (-> (fn [req] (throw-unauthorized))
-                      (wrap-authorization jbackend)
-                      (wrap-authentication jbackend))
+                      (wrap-authorization jws-backend)
+                      (wrap-authentication jws-backend))
           response (handler request)]
       (is (= (:status response) 403))))

   (testing "Jws token unathorized - unauth handler called when provided"
-    (let [request (make-jws-request 1 "wrong-key")
+    (let [request (make-jws-request jws-data "wrong-key")
           onerror (fn [_ _] {:status 3000})
-          backend (jws-backend {:secret secret-key
-                                :unauthorized-handler onerror})
+          backend (token/jws-backend {:secret jws-secret
+                                      :unauthorized-handler onerror})
           handler (-> (fn [req] (throw-unauthorized))
                       (wrap-authorization backend)
                       (wrap-authentication backend))
           response (handler request)]
       (is (= (:status response) 3000)))))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Tests: Token
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(def backend (token-backend {:authfn authfn}))
+(defn token-authfn
+  [request token]
+  (let [data {:token1 {:userid 1}
+              :token2 {:userid 2}}]
+    (get data (keyword token))))
+
+(def backend (token/token-backend {:authfn token-authfn}))

 (deftest token-backend-test
   (testing "Basic token backend authentication 01"
@@ -128,8 +136,8 @@
   (testing "Token backend with unauthorized requests 3"
     (let [request (make-request "token3")
           onerror (fn [_ _] {:status 3000})
-          backend (token-backend {:authfn authfn
-                                  :unauthorized-handler onerror})
+          backend (token/token-backend {:authfn token-authfn
+                                        :unauthorized-handler onerror})
           handler (-> (fn [request] (throw-unauthorized))
                       (wrap-authorization backend)
                       (wrap-authentication backend))


Rename functions to avoid name clashes

Rename functions to avoid name clashes


help for cmd-save

help for cmd-save


Fix: ensures that scalars returns tick values that fall within the range of data

--- src/xvsy/scale.clj
+++ src/xvsy/scale.clj
@@ -84,7 +84,8 @@
       (->LinMinMaxScalar new-min new-max)))
   (->scale [this range] (partial linear [minimum maximum] range))
   Ticker
-  (->ticks [this] (:ticks (ticks/search [minimum maximum]))))
+  (->ticks [this] (filter #(and (>= % minimum) (<= % maximum))
+                          (:ticks (ticks/search [minimum maximum])))))

 ;; FactorScalar keeps track of previously seen values and can produce
@@ -171,6 +172,7 @@
 (defn color-continuous
   "maps x, with domain [0, 1] to the given colors"
   [colors x]
+  {:pre [(>= x 0) (<= x 1)]}
   (let [n (count colors)
         bin (int (* n x))
         bin (if (== n bin) (- bin 1) bin)]


refactor to be more idiomatic in clojure

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -26,22 +26,35 @@
      :direction direction}))

+(defn decorate-arrow-node [arrow-node text]
+  (.. (DOMElement. arrow-node)
+               (setProperty "color" "white")
+               (setContent text)
+               (setProperty "fontSize" "40px")
+               (setProperty "lineHeight" "40px")
+               (setProperty "cursor" "pointer")
+               (setProperty "textHighlight" "none")
+               (setProperty "zIndex" "2")))
+
 (defn Carousel [selector data]
   (let [context (.. FamousEngine (createScene selector))
         root (.. context addChild)
-        back (Arrow. (.. root addChild) {:direction -1})
-        next (Arrow. (.. root addChild) {:direction 1})
+        back-node (.. root addChild)
+        next-node (.. root addChild)
+
+        back (decorate-arrow-node back-node "<")
+        next (decorate-arrow-node next-node ">")
         carousel-obj {:context  context
                       :root     root
                       :back back
                       :next next}]
-    (.. (:node back)
+    (.. back-node
         (setSizeMode 1 1)
         (setAbsoluteSize 40 40)
         (setPosition 40 0 0)
         (setAlign 0 0.5 0)
         (setMountPoint 0 0.5 0))
-    (.. (:node next)
+    (.. next-node
         (setSizeMode 1 1)
         (setAbsoluteSize 40 40)
         (setPosition -40 0 0)


CMR-3409: Minor cleanup.

CMR-3409: Minor cleanup.

--- message-queue-lib/src/cmr/message_queue/queue/sqs.clj
+++ message-queue-lib/src/cmr/message_queue/queue/sqs.clj
@@ -194,6 +194,8 @@
                   ;; subscribe the queue to the topic
                   subscription-arn (.getSubscriptionArn (.subscribe sns-client topic-arn "sqs" q-arn))]])))

+      ; (.setSubscriptionAttributes sns-client subscription-arn "RawMessageDelivery" "true"))))
+
 (defn- normalized-queue-name->original-queue-name
   "Convert a normalized queue name to the original queue name used to create it."
   [queue-broker queue-name]


Implement DELETE for devices.

Implement DELETE for devices.

--- src/kixi/hecuba/amon.clj
+++ src/kixi/hecuba/amon.clj
@@ -405,7 +405,7 @@
       (ring-response {:headers {"Location" location}}))))

 (defresource device [{:keys [commander querier]} handlers]
-  :allowed-methods #{:get}
+  :allowed-methods #{:get :delete}
   :available-media-types #{"application/json"}
   :authorized? (authorized? querier :device)

@@ -416,6 +416,14 @@
                {::item (-> item
                            (assoc :device-id device-id)
                            (dissoc :id))}))
+
+  :delete-enacted? (fn [{item ::item}]
+             (let [device-id (:device-id item)
+                   response  (delete! commander :device device-id)]
+               (if (empty? response) true false)))
+
+  :respond-with-entity? (fn [ctx] (constantly true)) ;; the only way to return 200 ok
+
   :handle-ok (fn [{item ::item}]
                (-> item
                    ;; These are the device's sensors.


Process messages when they arrive

Process messages when they arrive

--- src/lambda_demo/core.clj
+++ src/lambda_demo/core.clj
@@ -1,9 +1,11 @@
 (ns lambda-demo.core
-  (:require [uswitch.lambada.core :refer [deflambdafn]]
+  (:require [lambda-demo.handler :refer [process]]
+            [uswitch.lambada.core :refer [deflambdafn]]
             [clojure.java.io :as io]
             [cheshire.core :refer [parse-stream]]))

 (deflambdafn lambda-demo.LambdaFn
   [in out ctx]
   (let [input (parse-stream (io/reader in) true)]
-    (println "Hello from Lambda with input" input)))
+    (println "Hello from Lambda with input" input)
+    (process input)))


Use proper URLs on Windows for webjars

Use proper URLs on Windows for webjars

--- src/less4clj/webjars.clj
+++ src/less4clj/webjars.clj
@@ -7,7 +7,7 @@

 (defn- asset-path [resource]
   (let [[_ name version path] (re-matches webjars-pattern resource)]
-    (str name File/separator path)))
+    (str name "/" path)))

 (defn asset-map
   "Create map of asset path to classpath resource url. Asset path is


Add team / remainder rendering - fake teams atm

--- src/matchmaker/core.cljs
+++ src/matchmaker/core.cljs
@@ -1,19 +1,19 @@
 (ns matchmaker.core
     (:require [reagent.core :as reagent :refer [atom]]
-              [clojure.string :refer [split]]))
+              [clojure.string :as string]))

-(def players-tsv (atom ""))
-(def attendance-tsv (atom ""))
+(defonce players-tsv (atom ""))
+(defonce attendance-tsv (atom ""))

 (defn columns [tsv]
-  (let [rows (split tsv #"\n")
-        cols (map #(split % #"\t") rows)]
+  (let [rows (string/split tsv #"\n")
+        cols (map #(string/split % #"\t") rows)]
     cols))

 (defn parse-players [tsv]
   (map (fn [c]
            {:name (nth c 0)
-            :rank (nth c 3 nil)})
+            :rank (nth c 3 "NONE")})
        (columns tsv)))

 (defn parse-attendance [tsv]
@@ -23,25 +23,65 @@
 (defn can-play [players attendance]
   (filter (fn [p] (attendance (:name p))) players))

-(defn group-teams [players]
-  [])
+(defn teams-by-skill [players]
+  {:teams [{:name "foobar"
+            :a {:name "foo"
+                :players (take 5 players)}
+            :b {:name "bar"
+                :players (take 5 (drop 5 players))}}]
+   :remainder players})
+
+(defn make-teams []
+  (let [players (parse-players @players-tsv)
+        attendance (parse-attendance @attendance-tsv)]
+    (-> players
+        (can-play attendance)
+        (teams-by-skill))))

 ;; -------------------------
 ;; Views

 (defn editor [placeholder value]
-  [:textarea {:placeholder placeholder
-              :value @value
-              :on-change #(reset! value (-> % .-target .-value))}])
+  [:textarea.editor {:placeholder placeholder
+                     :value @value
+                     :on-change #(reset! value (-> % .-target .-value))}])
+
+(defn tsv-editors []
+  [:section.editors
+   [editor "Players" players-tsv]
+   [editor "Attendance" attendance-tsv]])
+
+(defn player [p]
+  [:p (:name p) " " [:span.rank (:rank p)]])
+
+(defn player-list [players]
+  [:ul.players (map (fn [p] [:li {:key (hash p)} (player p)]) players)])
+
+(defn team [t]
+  [:section.team-pair
+   [:section.team-a
+    (player-list (-> t :a :players))]
+   [:h4.vs "vs"]
+   [:section.team-b
+    (player-list (-> t :b :players))]])
+
+(defn team-list [teams]
+  [:ul.teams (map (fn [t] [:li {:key (hash t)} (team t)]) teams)])
+
+(defn results []
+  (let [result (make-teams)]
+    [:section.results
+     [:section.teams
+      [:h3 "Teams"]
+      (team-list (:teams result))]
+     [:section.remainder
+      [:h3 "Remainder"]
+      (player-list (:remainder result))]]))

 (defn root []
-  [:div
-   [editor "Players" players-tsv]
-   [editor "Attendance" attendance-tsv]
-   (let [players (parse-players players-tsv)
-         attendance (parse-attendance attendance-tsv)
-         teams (group-teams (can-play players attendance))]
-     [:p "TODO: Everything. " (count @players-tsv) " - " (count @attendance-tsv)])])
+  [:section.root
+   (tsv-editors)
+   (results)])

 ;; -------------------------
 ;; Initialize app


Get rid of annoying output from `unfinished`

--- src/midje/semi_sweet.clj
+++ src/midje/semi_sweet.clj
@@ -36,7 +36,8 @@
                                         '~name line-separator '~name (join " " (map pprint# args#)))))))

                ;; A reliable way of determining if an `unfinished` function has since been defined.
-               (alter-meta! (var ~name) assoc :midje/unfinished-fun ~name))))]
+               (alter-meta! (var ~name) assoc :midje/unfinished-fun ~name)
+               :ok)))]

   (defmacro unfinished
     "Defines a list of names as functions that have no implementation yet. They will


fixed some comments.

fixed some comments.

--- src/misaki/html/core.clj
+++ src/misaki/html/core.clj
@@ -104,7 +104,8 @@
       ;=> <link rel=\"stylesheet\" type=\"text/css\" href=\"foo.css\" />
       ;=> <link rel=\"stylesheet\" type=\"text/css\" href=\"bar.css\" />
       (css {:media \"screen\"} \"foo.css\" \"bar.css\")
-      ;=> <link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"foo.css\" />"
+      ;=> <link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"foo.css\" />
+      ;=> <link rel=\"stylesheet\" type=\"text/css\" media=\"screen\" href=\"bar.css\" />"
   [& args]
   (let [args (flatten args)
         [opt & hrefs] (if (map? (first args)) args (cons {} args))
@@ -183,7 +184,7 @@
       (link \"foo.html\")
       ;=> foo.html
       (link \"foo\" \"bar.html\")
-      ;=> bar"
+      ;=> foo"
   ([href] (link href href))
   ([label href] [:a {:href href} (parse-string label)]))


Use soup to read the HTML body and truncate it at around 3 lines. Show the note at the top of invite and share emails if a note is preset. Fix avatar retrieve.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -3,9 +3,11 @@
             [clojure.walk :refer (keywordize-keys)]
             [clj-time.format :as format]
             [hiccup.core :as h]
-            [oc.email.config :as config]))
+            [oc.email.config :as config]
+            [jsoup.soup :as soup]))

 (def max-logo 32)
+(def author-logo 32)

 (def profile-url (str config/web-url "/profile"))

@@ -140,11 +142,11 @@
     (str "https://process.filestackapi.com/"
          (when-not is-filestack-resource?
            (str config/filestack-api-key "/"))
-         "resize=w:32,h:32,fit:crop,align:faces/"
+         "resize=w:" author-logo ",h:" author-logo ",fit:crop,align:faces/"
          "circle/"
          filestack-resource)))

-(defn- share-note [body avatar-url author]
+(defn- personal-note [note-body avatar-url author]
   [:table {:class "row body-block share-note"}
     [:tr
       [:th {:class "small-1 large-2 first columns"}]
@@ -162,12 +164,13 @@
               [:table {:class "row white-block"}
                 [:tr
                   [:th {:class "small-1 large-1"}
-                    [:img {:class "note-author-avatar" :src (circle-image avatar-url 32)}]]
+                    (when-not (s/blank? avatar-url)
+                      [:img {:class "note-author-avatar" :src (circle-image avatar-url 32)}])]
                   [:th {:class "small-11 large-11"}
                     [:table {:class "white-block"}
                       [:tr
                         [:th
-                          (spacer 8 "white-block" "body-spacer")]]]
+                          (spacer 7 "white-block" "body-spacer")]]]
                     [:table {:class "white-block"}
                       [:tr
                         [:th
@@ -184,7 +187,7 @@
             [:th {:class "small-1 large-1 first columns"}]
             [:th {:class "small-10 large-10 columns"}
               [:span {:class "note-body"}
-                body]]
+                note-body]]
             [:th {:class "small-1 large-1 last columns"}]]]
         [:table {:class "row note-block bottom"}
           [:tr
@@ -347,7 +350,10 @@
         logo-height (:org-logo-height invite)
         logo? (not (s/blank? logo-url))
         org-name (:org-name invite)
-        from (if (s/blank? (:from invite)) "Someone" (:from invite))]
+        from (if (s/blank? (:from invite)) "Someone" (:from invite))
+        from-avatar (when-not (s/blank? (:from invite)) (:from-avatar invite))
+        note (:note invite)
+        note? (not (s/blank? note))]
     [:td
       (spacer 40)
       (when logo? (org-logo {:org-name org-name
@@ -362,6 +368,8 @@
       (spacer 28 "body-block" "body-spacer")
       (paragraph carrot-explainer "body-block")
       (spacer 35 "body-block" "body-spacer")
+      (when note? (personal-note note from-avatar from))
+      (when note? (spacer 35 "body-block" "body-spacer"))
       (cta-button (str "Join " org-name " on Carrot") (:token-link invite))
       (spacer 40 "body-block bottom" "body-spacer")
       (spacer 33)
@@ -408,13 +416,20 @@
         org-name (:org-name entry)
         org-name? (not (s/blank? org-name))
         headline (:headline entry)
-        entry-body (:body entry)
+        parsed-body (.text (soup/parse (:body entry)))
+        body-length 159
+        entry-body (if (> (count parsed-body) body-length)
+                      (str (subs parsed-body 0 (- body-length 3)) "...")
+                      parsed-body)
+        entry-body? (not (s/blank? entry-body))
         org-slug (:org-slug entry)
         sharer (:sharer-name entry)
-        attribution (str (-> entry :publisher :name) " posted to " (:board-name entry))
+        publisher (:publisher entry)
+        attribution (str (:name publisher) " posted to " (:board-name entry))
         note (:note entry)
         note? (not (s/blank? note))
         from (if (s/blank? sharer) "Someone" sharer)
+        from-avatar (when-not (s/blank? sharer) (:sharer-avatar-url entry))
         secure-uuid (:secure-uuid entry)
         origin-url config/web-url
         entry-url (s/join "/" [origin-url org-slug "post" secure-uuid])]
@@ -425,14 +440,14 @@
       (h1 (str from "<br>" share-message))
       (spacer 31)
       (spacer 35 "body-block top" "body-spacer")
-      (spacer 15 "body-block" "body-spacer")
-      (share-note "Hello here is the note" "https://cdn.filestackcontent.com/qemc9YslR9yabfqL4GTe" "Iacopo Carraro")
-      (spacer 15 "body-block" "body-spacer")
+      (spacer 5 "body-block" "body-spacer")
+      (when note? (personal-note note from-avatar from))
+      (when note? (spacer 35 "body-block" "body-spacer"))
       (h2 headline "body-block" "")
       (spacer 5 "body-block" "body-spacer")
       (paragraph attribution "body-block" "attribution")
-      (when note? (spacer 5 "body-block" "body-spacer"))
-      (when note? (paragraph entry-body "body-block" ""))
+      (when entry-body? (spacer 5 "body-block" "body-spacer"))
+      (when entry-body? (paragraph entry-body "body-block" ""))
       (spacer 35 "body-block" "body-spacer")
       (cta-button share-cta entry-url)
       (spacer 40 "body-block bottom" "body-spacer")


More card implementations

More card implementations

--- src/node/game/cards.cljs
+++ src/node/game/cards.cljs
@@ -1151,6 +1151,14 @@
    "Running Interference"
    {:prompt "Choose a server" :choices (req servers) :effect (effect (run target))}

+   "Sacrificial Clone"
+   {:abilities [{:effect (req (doseq [c (concat (get-in runner [:rig :hardware])
+                                                (filter #(not (has? % :subtype "Virtual"))
+                                                        (get-in runner [:rig :resource]))
+                                                (:hand runner))]
+                                (trash state side c))
+                              (lose state side :credit :all :tag :all))}]}
+
    "Sacrificial Construct"
    {:abilities [{:msg "prevent an installed program or hardware from being trash"
                  :effect (effect (trash card))}]}
@@ -1717,6 +1725,9 @@
     :abilities [{:msg "do 1 brain damage" :effect (effect (damage :brain 1))}
                 {:msg "end the run" :effect (effect (end-run))}]}

+   "Fire Wall"
+   {:advanceable :always :abilities [{:msg "end the run" :effect (effect (end-run))}]}
+
    "Flare"
    {:abilities [{:prompt "Choose a piece of hardware to trash"
                  :msg (msg "trash " (:title target)) :label "Trash a piece of hardware"
@@ -1839,6 +1850,12 @@
                 {:msg "end the run if the runner is tagged" :req (req tagged)
                  :effect (effect (end-run))}]}

+   "Nebula"
+   {:advanceable :always
+    :abilities [{:prompt "Choose a program to trash" :msg (msg "trash " (:title target))
+                 :label "Trash a program"
+                 :choices (req (get-in runner [:rig :program])) :effect (effect (trash target))}]}
+
    "Neural Katana"
    {:abilities [{:msg "do 3 net damage" :effect (effect (damage :net 3))}]}

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

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