Kill lossy-worker threads when handler is removed or replaced

--- src/overtone/libs/event.clj
+++ src/overtone/libs/event.clj
@@ -3,6 +3,7 @@
      :author "Jeff Rose, Sam Aaron"}
   overtone.libs.event
   (:import [java.util.concurrent LinkedBlockingQueue])
+  (:use [overtone.helpers.ref :only [swap-returning-prev!]])
   (:require [overtone.config.log :as log]
             [overtone.libs.handlers :as handlers]))

@@ -10,6 +11,13 @@
 (defonce ^:private event-debug* (atom false))
 (defonce ^:private monitoring?* (atom false))
 (defonce ^:private monitor* (atom {}))
+(defonce ^:private lossy-workers* (atom {}))
+
+(defn- log-event
+  "Log event on separate thread to ensure logging doesn't interfere with
+  event handling latency"
+  [msg & args]
+  (future (apply log/debug msg args)))

 (defrecord LossyWorker [queue worker current-val])

@@ -31,12 +39,14 @@
   (let [current-val* (atom nil)
         last-val*    (atom (gensym))
         queue        (LinkedBlockingQueue.)
-        work         #(while (not= (.take queue) :die)
-                        (let [current @current-val*
-                              last @last-val*]
-                          (when (not= current last)
-                            (update-fn current)
-                            (reset! last-val* current))))
+        work         (fn []
+                       (while (not= (.take queue) :die)
+                         (let [current @current-val*
+                               last @last-val*]
+                           (when (not= current last)
+                             (update-fn current)
+                             (reset! last-val* current))))
+                       (log-event "Killing Lossy worker"))
         worker       (Thread. work)]
     (.start worker)
     (LossyWorker. queue worker current-val*)))
@@ -52,13 +62,6 @@
   (reset! (:current-val lossy-worker) new-val)
   (.put (:queue lossy-worker) :job))

-
-(defn- log-event
-  "Log event on separate thread to ensure logging doesn't interfere with
-  event handling latency"
-  [msg & args]
-  (future (apply log/debug msg args)))
-
 (defn on-event
   "Asynchronously runs handler whenever events of event-type are
   fired. This asynchronous behaviour can be overridden if required -
@@ -116,8 +119,12 @@
   potentially long-running handler fns where handling the most recent
   event is all that matters."
   [event-type handler key]
+  (log-event "Registering lossy event handler:: " event-type key)
   (let [worker (lossy-worker (fn [val]
-                               (handler val)))]
+                               (handler val)))
+        [old _] (swap-returning-prev! lossy-workers* assoc key worker)]
+    (when-let [old-worker (get old key)]
+      (.put (:queue old-worker) :die))
     (on-sync-event event-type
                    (fn [msg]
                      (lossy-send worker msg))
@@ -148,11 +155,17 @@
   (remove-handler :foo ::bar-key)
   (event :foo :val 200) ; my-foo-handler no longer called"
   [key]
+  (let [[old new] (swap-returning-prev! lossy-workers* dissoc key)]
+    (when-let [old-worker (get old key)]
+      (.put (:queue old-worker) :die)))
   (handlers/remove-handler! handler-pool key))

 (defn remove-all-handlers
   "Remove all handlers."
   []
+  (let [[old new] (swap-returning-prev! lossy-workers* (fn [_] {}))]
+    (doseq [old-worker (vals old)]
+      (.put (:queue old-worker) :die)))
   (handlers/remove-all-handlers! handler-pool))

 (defn event


[#2925] Reformat code

[#2925] Reformat code

--- backend/test/akvo/lumen/lib/import/clj_data_importer_test.clj
+++ backend/test/akvo/lumen/lib/import/clj_data_importer_test.clj
@@ -46,11 +46,7 @@
       (let [data-group (first data-groups)]
         (is (= (:group_id data-group) "main"))
         (is (= (:group_name data-group) "main"))
-        (is (= (:repeatable data-group) false))
-
-        )
-
-
+        (is (= (:repeatable data-group) false)))
       (is (= (map keys stored-data) expected-stored-data))
       (is (= (map keys data-groups-stored-data) expected-stored-data))))
   (testing "Testing import flow"
@@ -75,7 +71,7 @@
                                                                  {:dataset-id dataset-id})
                            (get-data *tenant-conn*))

-          expected-stored-data '(:rnum
+          expected-stored-data '(:rnum
                                  :device_id
                                  :surveyal_time
                                  :submitted_at


Added function for renaming a User resource. Fixes #14

--- src/prop_shop/data/user.clj
+++ src/prop_shop/data/user.clj
@@ -25,3 +25,10 @@
   {:added "0.1"}
   [uuid]
   (b/get-entity-by-uuid uuid))
+
+
+(defn rename-user
+	"Renames the User specified by the UUID with the provided name."
+	{:added "0.1"}
+	[uuid name]
+	(b/update-entity-by-uuid uuid {:name name}))


Ignore files which no longer exist on classpath

--- src/refactor_nrepl/core.clj
+++ src/refactor_nrepl/core.clj
@@ -20,14 +20,12 @@
        (filter fs/directory?)
        (remove #(-> % str normalize-to-unix-path (.endsWith "target/srcdeps")))))

-(defn- hidden? [path-or-file]
-  (.isHidden (io/file path-or-file)))
-
 (defn find-in-dir
   "Searches recursively under dir for files matching (pred ^File file). "
   [pred ^File dir]
   (->> (file-seq dir)
-       (remove hidden?)
+       (remove (memfn isHidden))
+       (filter (memfn exists))
        (filter pred)))

 (defn cljc-file?


Wroking with patched backend

Wroking with patched backend

--- src/airhead_cljs/core.cljs
+++ src/airhead_cljs/core.cljs
@@ -82,20 +82,21 @@
     [:input {:type "button" :value "Upload" :on-click upload!}]]
    [:div.upload-status (@state :upload-status)]])

-(defn playlist-add-component [uuid]
+(defn playlist-add-component [track]
   [:input.add-button
    {:type "button" :value "+"
-    :on-click #(playlist-add uuid)}])
+    :on-click #(playlist-add (track "uuid"))}])

-(defn playlist-remove-component [uuid]
+(defn playlist-remove-component [track]
   [:input.add-button
    {:type "button" :value "-"
-    :on-click #(playlist-remove uuid)}])
+    :on-click #(playlist-remove (track "uuid"))}])

-(defn track-component [uuid]
+(defn track-component [track]
   [:span.track
-   ;(str " " (track "artist") " - " (track "title"))
-   (str uuid)])
+   (if track
+     (str " " (track "artist") " - " (track "title"))
+     "-")])

 (defn now-playing-component []
   [:div.now-playing
@@ -106,13 +107,13 @@
   [:div.next
    [:span "Next:"]
    [:ul
-    (for [uuid (get-in @state [:playlist "next"])]
+    (for [track (get-in @state [:playlist "next"])]
       [:li
-       [playlist-remove-component uuid]
-       [track-component uuid]])]])
+       [playlist-remove-component track]
+       [track-component track]])]])

 (defn playlist-component []
-  [:div.library
+  [:div.playlist
    [:h2 "Playlist"]
    [now-playing-component]
    [next-component]])
@@ -120,10 +121,10 @@
 (defn library-component []
   [:div.library
    [:h2 "Library"]
-   [:ul (for [uuid (@state :library)]
+   [:ul (for [track (@state :library)]
           [:li
-           [playlist-add-component uuid]
-           [track-component uuid]])]])
+           [playlist-add-component track]
+           [track-component track]])]])

 (defn page-component []
   [:div.page


information about backpacks, shoes, and salads

--- src/babel/encyclopedia.cljc
+++ src/babel/encyclopedia.cljc
@@ -45,7 +45,8 @@
                       :place true}

    {:clothing true}  {:animate false
-                      :edible false
+                      :artifact true
+                      :consumable false
                       :place false
                       :physical-object true}
    {:consumable
@@ -129,8 +130,8 @@
    ;; restrictions on owners (e.g. {:of {:human true}}).

    ;; <preds>
-   {:pred :backpack} {:artifact true
-                      :clothing true}
+   {:pred :backpack} {:clothing true}
+
    {:pred :bag}      {:artifact true
                       :consumable false
                       :event false
@@ -175,8 +176,10 @@
    {:pred :pizza}    {:artifact true
                       :edible true}

-   {:pred :shoe}     {:artifact true
-                      :clothing true}
+   {:pred :salad}    {:artifact true
+                      :edible true}
+
+   {:pred :shoe}     {:clothing true}

    {:pred :student}  {:human true}


remove debug output

remove debug output

--- src/brainbot/nozzle/sys.clj
+++ src/brainbot/nozzle/sys.clj
@@ -24,7 +24,6 @@

 (defn get-filesystems-for-section
   [system section-name]
-  (println "system:" system)
   (or (misc/trimmed-lines-from-string (get-in system [:iniconfig section-name "filesystems"]))
       (get-in system [:config :filesystems])
       (misc/die (str "no filesystems defined in section " section-name))))


reload re-loads system

reload re-loads system

--- src/celestial/workflows.clj
+++ src/celestial/workflows.clj
@@ -64,14 +64,15 @@

 (deflow reload
   "Reloads a machine if one already exists, will distroy the old one"
-  [{:keys [machine] :as spec}]
+  [{:keys [machine system-id] :as spec}]
   (let [vm (vconstruct spec)]
     (info "setting up" machine)
     (when (.status vm)
       (info "clearing prevsious" machine)
       (.stop vm)
       (.delete vm))
-    (let [vm* (.create vm)]
+    (let [reload-spec (assoc (s/get-system system-id) :system-id system-id)
+           vm* (.create (vconstruct reload-spec))]
       (.start vm*)
       (assert (= (.status vm*) "running")) ; might not match all providers
       (info "done system setup"))))


add migration to add invitations

add migration to add invitations

--- src/chat/server/migrate.clj
+++ src/chat/server/migrate.clj
@@ -43,3 +43,37 @@
           all-tags (->> (d/q '[:find ?t :where [?t :tag/id]] (d/db db/*conn*)) (map first))]
       (d/transact db/*conn* (mapv (fn [u] [:db/add [:group/id (group :id)] :group/user u]) all-users))
       (d/transact db/*conn* (mapv (fn [t] [:db/add t :tag/group [:group/id (group :id)]]) all-tags)))))
+
+(defn migrate-2015-08-26
+  "schema change for invites"
+  []
+  (d/transact db/*conn*
+    [
+     ; invitations
+     {:db/ident :invite/id
+      :db/valueType :db.type/uuid
+      :db/cardinality :db.cardinality/one
+      :db/unique :db.unique/identity
+      :db/id #db/id [:db.part/db]
+      :db.install/_attribute :db.part/db}
+     {:db/ident :invite/group
+      :db/valueType :db.type/ref
+      :db/cardinality :db.cardinality/one
+      :db/id #db/id [:db.part/db]
+      :db.install/_attribute :db.part/db}
+     {:db/ident :invite/from
+      :db/valueType :db.type/ref
+      :db/cardinality :db.cardinality/one
+      :db/id #db/id [:db.part/db]
+      :db.install/_attribute :db.part/db}
+     {:db/ident :invite/to
+      :db/valueType :db.type/string
+      :db/cardinality :db.cardinality/one
+      :db/id #db/id [:db.part/db]
+      :db.install/_attribute :db.part/db}
+     {:db/ident :invite/created-at
+      :db/valueType :db.type/instant
+      :db/cardinality :db.cardinality/one
+      :db/id #db/id [:db.part/db]
+      :db.install/_attribute :db.part/db}
+     ]))


export retweets

export retweets

--- src/clj/ceres/collector.clj
+++ src/clj/ceres/collector.clj
@@ -175,7 +175,7 @@

 (defn store-published [uid tid url-id type hids ts]
-  (mc/insert
+  (mc/insert-and-return
    @db
    "published"
    {:user uid
@@ -204,11 +204,30 @@
     :tweet tid
     :ts ts}))

+
+(defn store-mention
+  "Yeah"
+  [uid tid]
+  (mc/insert
+   @db
+   "mentions"
+   {:user uid
+    :tweet tid}))
+
+
 (defn store-hashtag [text]
   (mc/insert
    @db
    "hashtags"
    {:text text}))
+
+
+(defn store-reaction
+  "a reaction"
+  [pub-id source-id]
+  (mc/insert @db "reactions" {:publication pub-id :source source-id}))
+
+

 (comment

@@ -376,15 +395,29 @@
        (doall
         (pmap transact-published tweets)))))

-  (->> (mc/find-maps @db "tweets" {:created_at {$gt (t/date-time 2014 7 1)
-                                                $lt (t/date-time 2014 10 1)}
-                                   :in_reply_to_status_id nil
-                                   :retweeted_status.id nil
-                                   :entities.urls {$ne []}
-                                   :user.screen_name {$nin news-accounts}})
-       count
-       aprint
-       time)
+  ;; export retweets
+  (letfn [(transact-published [{:keys [user _id created_at entities id_str retweeted_status] :as tweet}]
+            (let [uid (:_id (mc/find-one-as-map @db "users" {:id (:id user)}))
+                  hids (if-not (empty? (:hashtags entities))
+                         (->> (:hashtags entities)
+                              (pmap #(:_id (mc/find-one-as-map @db "hashtags" (:text (:text %)))))
+                              (into #{})
+                              vec)
+                         nil)
+                  user-mentions (if-not (empty (:user_mentions entities))
+                                  (->> (:user_mentions entities)
+                                       (pmap #(:_id (mc/find-one-as-map @db "users" {:id (:id %)}))))
+                                  #{})
+                  pub-id (store-published uid _id nil :retweet hids created_at)
+                  source-tid (:_id (mc/find-one-as-map @db "published" {:tweet (:_id (mc/find-one-as-map @db "tweets" {:id_str (:id_str retweeted_status)}))}))]
+              (do
+                (doall (pmap #(when-not (nil? %) (store-mention % pub-id)) user-mentions))
+                (store-reaction pub-id source-tid))))]
+    (let [retweets (mc/find-maps @db "tweets" {:created_at {$gt (t/date-time 2014 7 1)
+                                                            $lt (t/date-time 2014 8 1)}
+                                               :retweeted_status {$ne nil}
+                                               :user.screen_name {$nin news-accounts}})]
+      (time (doall (pmap transact-published retweets)))))

 )


fix typo in encode-cols

fix typo in encode-cols

--- src/clj/cljs/source_map.clj
+++ src/clj/cljs/source_map.clj
@@ -80,8 +80,8 @@
   (loop [vs (seq vs) lastseg nil cols-segs []]
     (if vs
       (let [v (first vs)
-            seg [{:gcol v} source-idx line col]
-            seg (if-let [name (:name seg)]
+            seg [(:gcol v) source-idx line col]
+            seg (if-let [name (:name v)]
                   (let [idx (if-let [idx (get names->idx name)]
                               idx
                               (let [cidx @name-idx]


Pulled in Dan's tweaks to date-time namespace for merging ts

--- src/clj/forma/date_time.clj
+++ src/clj/forma/date_time.clj
@@ -332,3 +332,49 @@
           (if out-of-bounds-idx
             (nth v out-of-bounds-idx))
           nil))))
+
+(defn sorted-ts
+  "Accepts a map with date keys and time series values, and returns a
+  vector with the values appropriately sorted.
+
+  Example:
+    (sorted-ts {:2005-12-31 3 :2006-08-21 1}) => (3 1)"
+  [m]
+  [(vals (into (sorted-map) m))])
+
+(defn key->period
+  [t-res k]
+  (datetime->period t-res (name k)))
+
+(defn period->key
+  [t-res pd]
+  (keyword (period->datetime t-res pd)))
+
+(defn key-span
+  "Returns a list of date keys, beginning and end date inclusive.  The
+  first and last keys represent the periods that start just before the
+  supplied boundary dates.
+
+  Example:
+    (key-span :2005-12-31 :2006-01-18 \"16\")
+    => (:2005-12-19 :2006-01-01 :2006-01-17)"
+  [init-key end-key t-res]
+  (let [init-idx (key->period t-res init-key)
+        end-idx  (inc (key->period t-res end-key))]
+    (map (partial period->key t-res)
+         (range init-idx end-idx))))
+
+(defn same-len? [coll1 coll2]
+  (= (count coll1) (count coll2)))
+
+(defn all-unique?
+  [coll]
+  (same-len? coll (set coll)))
+
+(defn vec->ordered-map
+  "Accepts a collection and a key that indicates the first element in
+  the collection, and a temporal resolution."
+  [init-key t-res coll]
+  (let [init (key->period t-res init-key)
+        end-key  (period->key t-res (+ init (count coll)))]
+    (zipmap (key-span init-key end-key t-res) coll)))


fixed namespace contamination in form cont.

--- src/clj/tsask/form/crud.clj
+++ src/clj/tsask/form/crud.clj
@@ -25,7 +25,7 @@
                                    (if sort (sql/order-by {(keyword sort) (keyword sort-type)}))))
         opposite-sort-type {"desc" "asc", "asc" "desc", nil "asc"}]
     (binding [template/*js-css-files* template/forms-files] ;like let, but deeper into function context
-      (pages
+      (template/pages
        [:dl.txtcont
         [:dt [:div.ltit [:strong "Froms List"]] [:div.clear]]
         [:form {:method "post" :action "/forms/batch/action"}
@@ -76,7 +76,7 @@
     (let [form (first (j/query SQLDB
                                (sql/select [:id :form_name :form_content] :sa_forms
                                            (sql/where {:id id}))))]
-      (form-design-pages form))))
+      (template/form-design-pages form))))

 (defn copy [id]
   (let [form (first (j/query SQLDB


Refactor fasta-indexer

Refactor fasta-indexer

--- src/cljam/fasta_indexer.clj
+++ src/cljam/fasta_indexer.clj
@@ -1,22 +1,31 @@
 (ns cljam.fasta-indexer
   (:refer-clojure :exclude [spit])
-  (:require [clojure.java.io :refer [writer]])
-  (:import java.io.BufferedWriter))
+  (:require [clojure.java.io :refer [writer]]
+            [clojure.string :refer [join]]
+            [cljam.fasta :as fasta])
+  (:import [java.io BufferedWriter RandomAccessFile]))
+
+(defn write-sq
+  [^BufferedWriter wrtr sq]
+  (.write wrtr (join "\t"
+                     [(:ref sq)
+                      (count (:seq sq))
+                      (:offset sq)
+                      (:blen sq)
+                      (inc (count (:seq sq)))]))
+  (.newLine wrtr))

 (defn spit
-  "Opens a fai-file with writer, writes fasta index data, then closes the
-  fai-file."
-  [fai-file fa]
-  (with-open [w ^BufferedWriter (writer fai-file)]
-    (doseq [ref fa]
-      (.write w ^String (:ref ref))
-      (.write w "\t")
-      (.write w (str (count (:seq ref))))
-      (.write w "\t")
-      (.write w (str (:offset ref)))
-      (.write w "\t")
-      (.write w (str (:blen ref)))
-      (.write w "\t")
-      (.write w (str (inc (count (:seq ref)))))
-      (.newLine w))
-    nil))
+  "Opens a FAI file with writer, writes fasta index data, then closes the file."
+  [fai fa-sq]
+  (with-open [w ^BufferedWriter (writer fai)]
+    (doseq [sq fa-sq]
+      (write-sq w sq))))
+
+(defn create-index
+  "Create a FAI file from the specified fasta file."
+  [fasta out-fai]
+  (with-open [r ^RandomAccessFile (fasta/reader fasta)
+              w ^BufferedWriter (writer out-fai)]
+    (doseq [sq (fasta/read r)]
+      (write-sq w sq))))


whitespace test

whitespace test

--- src/cljs/canvas/canvas.cljs
+++ src/cljs/canvas/canvas.cljs
@@ -32,6 +32,8 @@
        (looper update render new-state)))
    10))

+
+
 (defn tick [last-input state]
   (if (:mousedown last-input)
     {:x (:x last-input) :y (:y last-input)}


Safari is way behind on pixelated rendering

--- src/cljs/kindness/game.cljs
+++ src/cljs/kindness/game.cljs
@@ -40,7 +40,8 @@

 (def styles
   {:body {:margin 0}
-   :canvas {:image-rendering "pixelated"}})
+   :canvas [[:image-rendering "-webkit-optimize-contrast"]
+            [:image-rendering "pixelated"]]})

 (def image-assets
   {:owl "owl.png"


Add Value Histograms Again

Add Value Histograms Again

--- src/cljs/lens/workbook.cljs
+++ src/cljs/lens/workbook.cljs
@@ -12,7 +12,8 @@
             [goog.dom :as dom]
             [lens.util :as util]
             [lens.event-bus :as bus]
-            [lens.alert :refer [alert!]]))
+            [lens.alert :refer [alert!]]
+            [lens.schema :as s]))

 ;; Local history of all versions of the current workbook
 (defonce version-history (atom []))
@@ -46,6 +47,27 @@
                               :params {:expr expr}
                               :snapshot (util/get-most-recent-snapshot-id owner)
                               :loaded-topic result-topic}))
+
+;; ---- Item Value Histogram --------------------------------------------------
+
+(defn round [precision x]
+  (let [mag (count (str (int x)))
+        factor (.pow js/Math 10 (max 0 (- precision mag)))]
+    (/ (.round js/Math (* x factor)) factor)))
+
+(defn value-hist [item]
+  (->> (:value-histogram item)
+       (map (fn [[x y]] (hash-map "Bucket" (round 3 x) "Values" y)))))
+
+(defn draw-item-chart [id value-hist]
+  (let [data value-hist
+        svg (.newSvg js/dimple (str "#" id) "100%" 200)
+        chart (new js/dimple.chart svg (clj->js data))]
+    (.setMargins chart 50 10 50 35)
+    (.addCategoryAxis chart "x" "Bucket")
+    (.addMeasureAxis chart "y" "Values")
+    (.addSeries chart nil (.-bar (.-plot js/dimple)))
+    (.draw chart)))

 ;; ---- Headline --------------------------------------------------------------

@@ -80,29 +102,30 @@

 ;; ---- Query Grid ------------------------------------------------------------

-(defn cell-id [query-idx col-idx id]
+(defn cell-id [{:keys [query-idx col-idx]} id]
   (str "Q" query-idx "-C" col-idx "-" id))
+
+(defn result-loaded [{:keys [query-idx col-idx]} id]
+  {:pre [query-idx col-idx id]}
+  [:result-loaded query-idx col-idx id])
+
+(defn term-loaded [{:keys [query-idx col-idx]} id]
+  [:term-loaded query-idx col-idx id])

 (defn single-form-expr [{:keys [id]}]
   {:items [[[:form id]]]})

-(defcomponent form [{:keys [id] :as form} owner {:keys [query-idx col-idx]}]
-  (will-mount [_]
-    (bus/listen-on owner [:loaded-form query-idx col-idx id]
-      (fn [new-form]
-        (om/transact! form #(merge % (select-keys new-form [:name :alias])))))
+(defn load-term! [owner form-rel opts id]
+  (bus/publish! owner :query {:form-rel form-rel
+                              :params {:id id}
+                              :snapshot (util/get-most-recent-snapshot-id owner)
+                              :loaded-topic (term-loaded opts id)}))
+
+(defcomponent form [{:keys [id] :as form} owner opts]
+  (will-mount [_]
     (when-not (:name form)
-      (bus/publish! owner :query {:form-rel :lens/find-form
-                                  :params {:id id}
-                                  :snapshot (util/get-most-recent-snapshot-id owner)
-                                  :loaded-topic [:loaded-form query-idx
-                                                 col-idx id]}))
-    (execute-query! owner (single-form-expr form)
-                    [:result-loaded query-idx col-idx id]))
-  (did-update [_ _ _]
-    (when-let [result (:result form)]
-      (clear-chart (cell-id query-idx col-idx id))
-      (draw-query-result (cell-id query-idx col-idx id) result)))
+      (load-term! owner :lens/find-form opts id))
+    (execute-query! owner (single-form-expr form) (result-loaded opts id)))
   (render [_]
     (d/div
       (d/div
@@ -111,35 +134,30 @@
           id))
       (d/p {:class "text-muted"}
         (or (:name form) "loading..."))
-      (d/div {:id (cell-id query-idx col-idx id)
-              :style {:height "200px"}}))))
+      (d/div {:id (cell-id opts id) :style {:height "200px"}}))))

 (defn single-item-group-expr [{:keys [id]}]
   {:items [[[:item-group id]]]})

-(defcomponent item-group [{:keys [id] :as item-group} owner
-                          {:keys [query-idx col-idx]}]
-  (will-mount [_]
+(defcomponent item-group [{:keys [id] :as item-group} owner opts]
+  (will-mount [_]
+    (when-not (:name item-group)
+      (load-term! owner :lens/find-item-group opts id))
     (execute-query! owner (single-item-group-expr item-group)
-                    [:result-loaded query-idx col-idx id]))
+                    (result-loaded opts id)))
+  (render [_]
+    (d/div
+      (d/div (or (util/add-soft-hyphen (:name item-group)) "loading..."))
+      (d/div {:id (cell-id opts id) :style {:height "200px"}}))))
+
+(defcomponent item [{:keys [id] :as item} owner opts]
+  (will-mount [_]
+    (when-not (if (s/is-numeric? item) (:value-histogram item) (:question item))
+      (load-term! owner :lens/find-item opts id)))
   (did-update [_ _ _]
-    (when-let [result (:result item-group)]
-      (clear-chart (cell-id query-idx col-idx id))
-      (draw-query-result (cell-id query-idx col-idx id) result)))
-  (render [_]
-    (d/div
-      (d/div (util/add-soft-hyphen (:name item-group)))
-      (d/p {:class "text-muted"}
-        (str "Form: " (:name (:parent item-group))))
-      (d/div {:id (cell-id query-idx col-idx id)}))))
-
-(defcomponent item [{:keys [id] :as item} _ _]
-  (will-mount [_]
-    )
-  (will-update [_ _ _]
-    )
-  (did-update [_ _ _]
-    )
+    (when-let [value-histogram (value-hist item)]
+      (clear-chart (cell-id opts id))
+      (draw-item-chart (cell-id opts id) value-histogram)))
   (render [_]
     (d/div
       (d/div
@@ -147,11 +165,15 @@
           (str alias " (" id ")")
           id))
       (d/p {:class "text-muted"}
-        (:question item))
-      (d/div {:id id}))))
+        (or (:question item) "loading..."))
+      (when (s/is-numeric? item)
+        (d/div {:id (cell-id opts id) :style {:height "200px"}})))))

 (defn query-grid-cell-mouse-leave [state]
   (assoc state :hover false :dropdown-hover false :dropdown-active false))
+
+(defn merge-into-term [term new-term]
+  (merge term (dissoc new-term :embedded :forms :links)))

 (defcomponent query-grid-cell
   "A cell in a query grid.
@@ -169,10 +191,16 @@
      :dropdown-hover false
      :dropdown-active false})
   (will-mount [_]
-    (bus/listen-on owner [:result-loaded query-idx col-idx id]
-      #(om/update! term :result (select-keys % [:visit-count-by-study-event]))))
+    (bus/listen-on owner (result-loaded opts id)
+      #(om/update! term :result (select-keys % [:visit-count-by-study-event])))
+    (bus/listen-on owner [:term-loaded query-idx col-idx id]
+      (fn [new-term] (om/transact! term #(merge-into-term % new-term)))))
   (will-unmount [_]
     (bus/unlisten-all owner))
+  (did-update [_ _ _]
+    (when-let [result (:result term)]
+      (clear-chart (cell-id opts id))
+      (draw-query-result (cell-id opts id) result)))
   (render-state [_ {:keys [hover dropdown-hover dropdown-active]}]
     (d/div {:class "query-cell"
             :on-mouse-enter #(om/set-state! owner :hover true)


button to delete question

button to delete question

--- src/cljs/relembra/core.cljs
+++ src/cljs/relembra/core.cljs
@@ -15,6 +15,8 @@
             [relembra.reagent-hack :refer (synthetic-text-field)]
             [relembra.sente :as sente]
             [taoensso.sente :refer (cb-success?)]))
+
+(enable-console-print!)

 (defonce conn (let [conn (d/create-conn)]
                 (d/transact! conn [{:db/id 0
@@ -242,6 +244,17 @@
                             {:db/id lembrando
                              :lembrando/due-date new-due-date
                              :lembrando/needs-repeat? needs-repeat?}]))))))
+
+(defn delete-lembrando [lembrando]
+  (let [txn [[:db.fn/retractEntity lembrando]]]
+    (sente/send!
+     [:db/ops [[:transact txn]]]
+     10000
+     (fn [resp]
+       (if (cb-success? resp)
+         (d/transact! conn txn)
+         (js/alert "Error tratando de apagar pergunta: "
+                   (pr-str resp)))))))

 (defn review []
   (let [[all due] (lembrandos)]
@@ -291,7 +304,13 @@
               [ui/flat-button
                {:label "Editar"
                 :icon (icons/editor-mode-edit)
-                :on-touch-tap #(set0! :review/editing? true)}]]]
+                :on-touch-tap #(set0! :review/editing? true)}]
+              [ui/flat-button
+               {:label "Apagar"
+                :icon (icons/action-delete)
+                :on-touch-tap (fn [_]
+                                (delete-lembrando lembrando)
+                                (set0! :review/show-answer? false))}]]]
             [:div
              [rui/flat-button
               {:label "Mostrar resposta"


Refactoring

Refactoring

--- src/cljs/triboard/core.cljs
+++ src/cljs/triboard/core.cljs
@@ -150,7 +150,7 @@
     :green :blue))

 (defn- with-next-player
-  "Find the next player to act"
+  "Find the next player to act - dismiss those that cannot play any move"
   [{:keys [moves player] :as game}]
   (let [nexts (take 3 (iterate next-player (next-player player)))]
     (assoc game :player
@@ -165,20 +165,15 @@
     (update-in [:scores looser] - (count taken))
     ))

-(defn- apply-moves
-  [game moves]
-  (reduce apply-move game moves))
-
 (defn play-move
   "On player playing the move [x y]"
   [{:keys [player board] :as game} [x y]]
   (if-let [moves (get-in game [:moves player [x y]])]
-    (-> game
-      (apply-moves (conj moves (take-empty-cell-move player [x y])))
+    (->
+      (reduce apply-move game moves)
+      (apply-move (take-empty-cell-move player [x y]))
       (with-available-moves)
-      ;(update-in [:player] next-player)
-      (with-next-player)
-      ) ;; TODO - Use available moves to switch player
+      (with-next-player))
     game))


fix some regexp

fix some regexp

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>


Fixed bug in computing layout for force-layout

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

--- src/conexp/layout/force.clj
+++ src/conexp/layout/force.clj
@@ -325,11 +325,12 @@
 	   inter-layout   (layout-by-placement lattice point-hash),

 	   ;; move points such that top element is at [top-x, top-y] again
+	   inter-points   (seq (positions inter-layout)),
 	   placement      (apply hash-map
-				 (interleave (nodes inter-layout)
+				 (interleave (map first inter-points)
 					     (map (fn [[x y]]
 						    [(+ x top-x), (+ y top-y)])
-						  (vals (positions inter-layout)))))]
+						  (map second inter-points))))]

        (make-layout placement (connections inter-layout)))))


Fix for content type issue. It seems webnoir sucks.

--- src/statuses/views/main.clj
+++ src/statuses/views/main.clj
@@ -5,7 +5,7 @@
             [clj-time.local :as local])
   (:use [statuses.backend.persistence :only [db get-save-time]]
         [noir.core :only [defpage defpartial render]]
-        [noir.response :only [redirect set-headers]]
+        [noir.response :only [redirect set-headers content-type]]
         [noir.request :only [ring-request]]
         [hiccup.element]
         [hiccup.form]
@@ -98,13 +98,14 @@
     [q lmt off next]))

 (defpage "/statuses/authors/:author" {:keys [author] :as req}
-  (let [[query limit offset next] (parse-args req)]
-    (let [current-etag (make-etag (first (core/get-latest @db 1 offset author)))
-          last-etag (get-in (ring-request) [:headers "if-none-match"])]
-      (println "Current ETag:" current-etag "Last ETag: " last-etag)
-      (if (not= current-etag last-etag)
-        (list-page (core/get-latest @db limit offset author) next)
-        (redirect (:uri (ring-request)) :not-modified)))))
+  (content-type "text/html;charset=utf-8"
+    (let [[query limit offset next] (parse-args req)]
+      (let [current-etag (make-etag (first (core/get-latest @db 1 offset author)))
+            last-etag (get-in (ring-request) [:headers "if-none-match"])]
+        (println "Current ETag:" current-etag "Last ETag: " last-etag)
+        (if (not= current-etag last-etag)
+          (list-page (core/get-latest @db limit offset author) next)
+          (redirect (:uri (ring-request)) :not-modified))))))

 (defpage "/statuses/search" {:as req}


split core tests up

split core tests up

--- test/complico/core_test.clj
+++ test/complico/core_test.clj
@@ -7,38 +7,42 @@
 (def server-port "3000")
 (def host "http://somelink.com/")

-(deftest build-link-replacements
-
+(deftest dont-grease-the-link-elements
   (testing "Dont grease the link elements"
     (is (= (let [html "<link href=\"duff.css\"/>"]
               (replace-all-in-string html
                  (build-link-replacement-map html server-name server-port host)))
-            "<link href=\"duff.css\"/>")))
+            "<link href=\"duff.css\"/>"))))

+(deftest grease-the-anchor-links-full
   (testing "Grease the anchor (full link)"
     (is (= (let [html ""]
               (replace-all-in-string html
                  (build-link-replacement-map html server-name server-port host)))
-            "")))
+            ""))))

+(deftest grease-the-anchor-links-relative-no-slash
   (testing "Grease the anchor (relative link no slash)"
     (is (= (let [html ""]
               (replace-all-in-string html
                  (build-link-replacement-map html server-name server-port host)))
-            "")))
+            ""))))

+(deftest grease-the-anchor-links-relative-with-slash
   (testing "Grease the anchor (relative link with slash)"
     (is (= (let [html ""]
               (replace-all-in-string html
                  (build-link-replacement-map html server-name server-port host)))
-            "")))
+            ""))))

+(deftest grease-the-dirty-anchor
   (testing "Grease the dirty anchor"
     (is (= (let [html ""]
               (replace-all-in-string html
                  (build-link-replacement-map html server-name server-port host)))
-            "")))
+            ""))))

+(deftest grease-the-area-links
   (testing "Grease the area element links"
     (is (= (let [html "<area href=\"http://anotherhost.com/duff\"/>"]
               (replace-all-in-string html


extract single-pass-scheduler, rename processor fns & old "async" (unordered) context

--- src/thi/ng/fabric/core.cljc
+++ src/thi/ng/fabric/core.cljc
@@ -333,7 +333,7 @@
                   (->result :converged i sigs colls t0)))
               (->result :max-iter-reached i sigs colls t0))))))))

-(defn default-async-vertex-processor
+(defn probabilistic-vertex-processor
   [s-thresh c-thresh]
   (fn [[active sigs colls] v]
     (let [active (conj active v)]
@@ -347,7 +347,7 @@
               [active sigs (inc colls)])
           [active sigs colls])))))

-(defn eager-async-vertex-processor
+(defn eager-probabilistic-vertex-processor
   [s-thresh c-thresh]
   (fn [[active sigs colls] v]
     (let [active (conj active v)]
@@ -369,15 +369,24 @@
   ([acc] acc)
   ([[act as ac] [act' s c]] [(into act act') (+ as s) (+ ac c)]))

+(defn single-pass-scheduler
+  [workgroup-size processor vertices]
+  (r/fold workgroup-size combine-stats processor vertices))
+
+(defn two-pass-scheduler
+  [workgroup-size processor vertices]
+  )
+
 (defn default-async-context-opts
   []
   {:collect-thresh 0
    :signal-thresh  0
-   :processor      eager-async-vertex-processor
+   :processor      eager-probabilistic-vertex-processor
+   :scheduler      single-pass-scheduler
    :max-ops        1e6
    :threads        #?(:clj (inc (.availableProcessors (Runtime/getRuntime))) :cljs 1)})

-(defn async-execution-context
+(defn execution-context
   [opts]
   (let [ctx       (merge (default-async-context-opts) opts)
         g         (:graph ctx)
@@ -385,6 +394,7 @@
         s-thresh  (:signal-thresh ctx)
         max-ops   (:max-ops ctx)
         processor ((:processor ctx) s-thresh c-thresh)
+        scheduler (:scheduler ctx)
         threads   (:threads ctx)
         watch-id  (keyword (gensym))
         v-filter  (filter #(or (should-signal? % s-thresh) (should-collect? % c-thresh)))
@@ -419,11 +429,8 @@
             ;;(warn :active-count (count @active))
             (if (seq @active)
               (if (<= (+ colls sigs) max-ops)
-                (let [[act' sigs' colls']
-                      (r/fold
-                       (max 512 (long (/ (count @active) threads)))
-                       combine-stats
-                       processor @active)]
+                (let [grp-size            (max 512 (long (/ (count @active) threads)))
+                      [act' sigs' colls'] (scheduler grp-size processor @active)]
                   ;;(warn :auto (count @enable))
                   (reset! active (into (into #{} v-filter act') @enable))
                   (reset! enable #{})
@@ -431,7 +438,7 @@
                 (->result :max-ops-reached sigs colls t0))
               (->result :converged sigs colls t0))))))))

-(defn async-execution-context2
+(defn async-execution-context
   [opts]
   (let [ctx         (merge (default-async-context-opts) opts)
         g           (:graph ctx)


Développements en cours sur CSB (CodinGame). Au fin fond du classement de la league Silver... Algorithme à améliorer. Pas encore d'utilisation du bouclier.

--- clojure/codingame/competition/coders-strike-back/src/coders_strike_back/core.clj
+++ clojure/codingame/competition/coders-strike-back/src/coders_strike_back/core.clj
@@ -1,53 +1,41 @@
 (ns coders-strike-back.core
   (:gen-class))

-;(defn rand-boolean [] (= (rem (rand-int 10) 2) 0))
+(defn inc-atom [curr-val] (inc curr-val))
+(defn dec-atom [curr-val] (dec curr-val))

-;; Random boost using
-;(defn rand-boost [boost-used?] (if (not @boost-used?) (if (rand-boolean) (do (reset! boost-used? true) "BOOST") "100") "100"))
-
-;; Distance entre 2 points ou norme du vecteur Norme = ||(x, y) || = sqrt(x*x+y*y)
-(defn distance [x y] (Math/sqrt (+ (* x x) (* y y))))
+;; norme du vecteur Norme = ||(x, y) || = sqrt(x*x+y*y)
+(defn norm [x y] (Math/sqrt (+ (* x x) (* y y))))
+;;distance between 2 points
+(defn distance [x1 y1 x2 y2] (Math/sqrt (+ (Math/pow (- x2 x1) 2) (Math/pow (- y2 y1) 2))))
 ;; Conversion degrés en radians :
 ;; rad  = degrés * M_PI / 180
 (defn convert-degree-to-radian [degree]
-  (* degree (/ Math/PI 180) )
-  )
+  (* degree (/ Math/PI 180)))

-(defn calculate-thrust-from-angle [angle] (str (Integer/valueOf (Math/round (* 100 (Math/abs (Math/cos (convert-degree-to-radian angle))))))))
+;;Compute boost value between 0 and 100
+(defn compute-boost [next-checkpoint-distance next-checkpoint-angle]
+  (cond
+    (> (Math/abs next-checkpoint-angle) 90) "0"
+    (< (Math/abs next-checkpoint-angle) 30) "100"
+    (and (< next-checkpoint-distance 1000) (> (Math/abs next-checkpoint-angle) 30)) "0"
+    (and (< next-checkpoint-distance 1000) (< (Math/abs next-checkpoint-angle) 30)) "50"
+    (> next-checkpoint-distance 4000) "100"
+    true (str (Integer/valueOf (Math/round (* 100 (Math/abs (Math/cos (convert-degree-to-radian next-checkpoint-angle)))))))))

-;; Ajouter le boost quand l’angle est bon et la distance assez grande
-;; Si il reste un boost
-;; Si l’angle est < 10
-;; Si la distance à la cible est > 4000
-;;Alors « BOOST »
-;;(defn use-boost [next-checkpoint-angle next-checkpoint-x next-checkpoint-y boost-used?]
-;;      (if (and (not @boost-used?) (or (< next-checkpoint-angle 10) (> next-checkpoint-angle -10)) (> (distance next-checkpoint-x next-checkpoint-y) 4000))
-;;          (do (reset! boost-used? true)
-;;              "BOOST"
-;;              (calculate-thrust-from-angle next-checkpoint-angle)) (calculate-thrust-from-angle next-checkpoint-angle)))
+(defn compute-x [next-checkpoint-x] next-checkpoint-x)

-;;(defn compute-action [next-checkpoint-angle next-checkpoint-x next-checkpoint-y boost-used?]
-;;      (cond
-;;        (>= (Math/abs next-checkpoint-angle) 90) "0"
-;;        (<= 90 (Math/abs next-checkpoint-angle)  60) "25"
-;;        (<= 60 (Math/abs next-checkpoint-angle)  45) "50"
-;;        (<= 45 (Math/abs next-checkpoint-angle)  30) "75"
-;;         true (use-boost next-checkpoint-angle next-checkpoint-x next-checkpoint-y boost-used?)))
+(defn compute-y [next-checkpoint-y] next-checkpoint-y)

 (def boost-used? (atom false))
+(def turn-counter (atom 0))

-(defn compute-action [next-checkpoint-angle next-checkpoint-x next-checkpoint-y boost-used?]
-      (binding [*out* *err*]
-          (println (str
-                     "distance next-checkpoint-x next-checkpoint-y : " (str (distance next-checkpoint-x next-checkpoint-y))
-                     " ; pod angle with checkpoint : " (str next-checkpoint-angle))))
-      (binding [*out* *err*]
-                    (println (str "Boost used ? (in compute-action) : " @boost-used? )))
-      (if (and (not @boost-used?) (< (Math/abs next-checkpoint-angle) 10) (> (distance next-checkpoint-x next-checkpoint-y) 4000))
+;;Compute BOOST, SHIELD or boost value between 0 and 100
+(defn compute-action [next-checkpoint-x next-checkpoint-y next-checkpoint-distance next-checkpoint-angle opponent-x opponent-y boost-used? turn-counter]
+      (if (and (not @boost-used?) (> @turn-counter 3) (< (Math/abs next-checkpoint-angle) 10) (> next-checkpoint-distance 4000))
           (do (reset! boost-used? true)
-              "BOOST"
-              (calculate-thrust-from-angle next-checkpoint-angle)) (calculate-thrust-from-angle next-checkpoint-angle)))
+              "BOOST")
+          (compute-boost next-checkpoint-distance next-checkpoint-angle)))

 (defn -main [& args]
       (while true
@@ -57,16 +45,27 @@
                   ; nextCheckpointDist: distance to the next checkpoint
                   ; nextCheckpointAngle: angle between your pod orientation and the direction of the next checkpoint

+                  (swap! turn-counter inc-atom)
+
                   ; (binding [*out* *err*]
                   ;   (println "Debug messages..."))
                   (binding [*out* *err*]
-                    (println (str "Boost used ?" @boost-used? )))
+                    (println (str "Has the boost be used ? : " @boost-used? ))
+                    (println (str "Given next check point distance : " nextCheckpointDist))
+                    (println (str "Calculated next check point distance : " (distance x y opponentX opponentY)))
+                    (println (str "Pod angle with checkpoint : " nextCheckpointAngle))
+                    (println (str "Turn : " @turn-counter)))
+
                   ; You have to output the target position
                   ; followed by the power (0 <= thrust <= 100)
                   ; i.e.: "x y thrust"
-                  (print nextCheckpointX)
+                  (print (compute-x nextCheckpointX))
                   (print " ")
-                  (print nextCheckpointY)
+                  (print (compute-y nextCheckpointY))
                   (print " ")
-                  (print (compute-action (Integer/valueOf nextCheckpointAngle) (Integer/valueOf nextCheckpointX) (Integer/valueOf nextCheckpointY) boost-used?))
+                  (print (compute-action
+                           (Integer/valueOf nextCheckpointX) (Integer/valueOf nextCheckpointY)
+                           (Integer/valueOf nextCheckpointDist) (Integer/valueOf nextCheckpointAngle)
+                           (Integer/valueOf opponentX) (Integer/valueOf opponentY)
+                           boost-used? turn-counter))
                   (println ""))))


Cosmetic changes on history events.

Cosmetic changes on history events.

--- src/uxbox/data/history.cljs
+++ src/uxbox/data/history.cljs
@@ -74,7 +74,7 @@

 (defrecord FetchPageHistory [id since max]
   rs/WatchEvent
-  (-apply-watch [this state s]
+  (-apply-watch [_ state s]
     (letfn [(on-success [{history :payload}]
               (let [history (into [] history)]
                 (->PageHistoryFetched history (not (nil? since)))))]


Reduce namespace loading logging

Reduce namespace loading logging

--- src/yetibot/core/loader.clj
+++ src/yetibot/core/loader.clj
@@ -1,6 +1,6 @@
 (ns yetibot.core.loader
   (:require
-    [taoensso.timbre :refer [info warn error]]
+    [taoensso.timbre :refer [debug info warn error]]
     [clojure.stacktrace :as st]
     [yetibot.core.hooks]
     [clojure.tools.namespace.find :as ns]
@@ -24,7 +24,7 @@
     #"^yetibot\.(.(?!(core)))*"))

 (defn load-ns [arg]
-  (info "Loading" arg)
+  (debug "Loading" arg)
   (try (require arg :reload)
        arg
        (catch Exception e
@@ -36,7 +36,9 @@
    namespaces and return the seq of matched namespaces."
   [ns-patterns]
   (let [nss (flatten (map find-namespaces ns-patterns))]
+    (info "☐ Loading" (count nss) " namespaces...")
     (dorun (map load-ns nss))
+    (info "☑ Loaded" (count nss) " namespaces")
     nss))

 (defn load-commands []


oops duplicated

oops duplicated

--- clojure/src/dnd/core.cljs
+++ clojure/src/dnd/core.cljs
@@ -53,8 +53,6 @@

 (defn pusher! [& arguments]
   (swap! queue conj arguments))
-
-(defonce clients (atom []))

 (defn remove-client [client]
   (swap! clients (fn [fucks]


Click to flip

Click to flip

--- clojure/src/life/core.clj
+++ clojure/src/life/core.clj
@@ -51,6 +51,15 @@
 (defn key-pressed [state event]
   (case (event :key-code)
     32 (update state :paused not)
+    state))
+
+(def flip-life {0 1 1 0})
+
+(defn mouse-clicked [state event]
+  (if (= :left (:button event))
+    (let [x (quot (:x event) cell-size)
+          y (quot (:y event) cell-size)]
+      (update-in state [:board (p2->1 [x y])] flip-life))
     state))

 (defn setup []
@@ -112,5 +121,6 @@
   :update update-state
   :draw draw-state
   :key-pressed key-pressed
+  :mouse-clicked mouse-clicked
   :features [:keep-on-top]
   :middleware [m/fun-mode])


use 1.2 and 1.3 compatible meta for dynamic vars

--- src/cake.clj
+++ src/cake.clj
@@ -4,20 +4,20 @@

 (def project-root nil)

-(def ^:dynamic *current-task* nil)
-(def ^:dynamic *project*      nil)
-(def ^:dynamic *context*      nil)
-(def ^:dynamic *script*       nil)
-(def ^:dynamic *opts*         nil)
-(def ^:dynamic *pwd*          nil)
-(def ^:dynamic *env*          nil)
-(def ^:dynamic *vars*         nil)
-(def ^:dynamic *File*         nil)
-(def ^:dynamic *root* (System/getProperty "cake.project"))
+(def ^{:dynamic true} *current-task* nil)
+(def ^{:dynamic true} *project*      nil)
+(def ^{:dynamic true} *context*      nil)
+(def ^{:dynamic true} *script*       nil)
+(def ^{:dynamic true} *opts*         nil)
+(def ^{:dynamic true} *pwd*          nil)
+(def ^{:dynamic true} *env*          nil)
+(def ^{:dynamic true} *vars*         nil)
+(def ^{:dynamic true} *File*         nil)
+(def ^{:dynamic true} *root* (System/getProperty "cake.project"))

-(def ^:dynamic *ins*  nil)
-(def ^:dynamic *outs* nil)
-(def ^:dynamic *errs* nil)
+(def ^{:dynamic true} *ins*  nil)
+(def ^{:dynamic true} *outs* nil)
+(def ^{:dynamic true} *errs* nil)

 (defn read-config [file]
   (if (.exists file)
@@ -25,6 +25,6 @@
       (into {} (doto (Properties.) (.load f))))
     {}))

-(def ^:dynamic *config*
+(def ^{:dynamic true} *config*
   (merge (read-config (File. (System/getProperty "user.home") ".cake/config"))
          (read-config (File. ".cake/config"))))


Handle games that are for sale

Handle games that are for sale

Print also the product number and the price

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -305,7 +305,8 @@

 (defmethod entry-sexp :ludo
   [{:keys [source-publisher genre-text description
-           game-description accompanying-material library-signature] :as item}
+           game-description accompanying-material library-signature
+           product-number price] :as item}
    {:keys [show-genre?] :or {show-genre? true}}]
   (list-item
    (entry-heading-sexp item)
@@ -314,7 +315,8 @@
      (block (wrap genre-text)))
    (block (wrap description))
    (block (wrap game-description))
-   (ausleihe library-signature)))
+   (ausleihe-multi library-signature)
+   (verkauf product-number price)))

 (defmethod entry-sexp :musiknoten
   [{:keys [description producer-brief library-signature product-number price] :as item} opts]


Drop the inline for the euro sign

Drop the inline for the euro sign

When using Arial as a fallback font we no longer need to place the euro
sign in an inline

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -546,9 +546,7 @@
              (block {:space-after "1em"}
                     "Erscheint sechsmal jährlich und weist alle seit der letzten Ausgabe neu in die SBS aufgenommenen Bücher nach")
              (block {:space-after "1em"}
-                    "«Neu im Sortiment» kann im Jahresabonnement per Post zu CHF / "
-                    (inline {:font-family  "Arial"} "€")
-                    " 78.– oder per E-Mail gratis bezogen werden")
+                    "«Neu im Sortiment» kann im Jahresabonnement per Post zu CHF / € 78.– oder per E-Mail gratis bezogen werden")
              (block {:font-family "StoneSansSemibold"
                      :color (color :blue)
                      :space-before "3em" :space-after "1em" :role "H2"}


removing populate

removing populate

--- src/celestial/populate.clj
+++ src/celestial/populate.clj
@@ -1,4 +0,0 @@
-(ns celestial.populate
-  "A tool for populating Celestial with data in production envs"
-
- )


adding sign-in resp fixing ui redirection

--- src/celestial/security.clj
+++ src/celestial/security.clj
@@ -37,12 +37,15 @@
       (info request-method " on " uri "by" (current-user))
       (app req))))

-
 (defn login-redirect
   [{:keys [form-params params] :as request}]
   (let [ user (java.net.URLEncoder/encode (or (get form-params "username") (:username params "")))
          param (<< "&login_failed=Y&user=~{user}")]
    (ring.util.response/redirect (<< "/login?~{param}"))))
+
+(defn sign-in-resp
+   [req]
+   {:status 401 :body "please sign in first"})

 (defn user-with-pass [id]
   {:post [(not-empty (% :password ))]}
@@ -51,8 +54,10 @@
 (defn secured-app [routes]
   (friend/authenticate
     (friend/wrap-authorize (user-tracking routes) roles/user)
-    {:allow-anon? true
+    {:allow-anon? false
      :credential-fn #(if (p/user-exists? (:username %)) (creds/bcrypt-credential-fn user-with-pass %) nil)
-     :unauthenticated-handler #(assoc (workflows/http-basic-deny "basic-celestial" %) :body {:message "login failed" } )
-     :workflows [(workflows/interactive-form :login-failure-handler login-redirect) (workflows/http-basic :realm "basic-celestial")]}))
+     :unauthenticated-handler sign-in-resp
+     :workflows [
+        (workflows/interactive-form :login-failure-handler login-redirect)
+        (workflows/http-basic :realm "basic-celestial")]}))


formatting

formatting

--- src/chat/client/views.cljs
+++ src/chat/client/views.cljs
@@ -38,26 +38,27 @@
   (apply dom/div #js {:className "tags-preview"}
     (map (fn [tag]
            (dom/div #js {:className "tag"
+                         ; TODO: style ambiguous tags in some way
                          :style #js {:background-color (if-let [tag-id (tag :id)]
                                                          (tag->color {:id tag-id}))}}

+             ; If the tag is ambiguous, show the groups it could be in
              (when-let [possible-tags (tag :possibilities)]
-             ; If the tag is ambiguous, show the groups it could be in
                (apply dom/div #js {:className "ambiguous"}
-               (interpose
-                 " or "
-                 (map (fn [t]
-                        (dom/span #js {:className "group"
-                                       :onClick
-                                       (fn [_]
-                                         (om/update-state!
-                                           owner [:ambiguous-tags (tag :idx)]
-                                           (fn [amb-tag]
-                                             (-> amb-tag
-                                                 (dissoc :possibilities)
-                                                 (assoc :id (t :id))))))}
-                          (t :group-name)))
-                      possible-tags))))
+                 (interpose
+                   " or "
+                   (map (fn [t]
+                          (dom/span #js {:className "group"
+                                         :onClick
+                                         (fn [_]
+                                           (om/update-state!
+                                             owner [:ambiguous-tags (tag :idx)]
+                                             (fn [amb-tag]
+                                               (-> amb-tag
+                                                   (dissoc :possibilities)
+                                                   (assoc :id (t :id))))))}
+                            (t :group-name)))
+                        possible-tags))))

              (tag :name)))
          tags)))


Clean up some of the session schemas

Clean up some of the session schemas

--- src/clj/shale/sessions.clj
+++ src/clj/shale/sessions.clj
@@ -14,7 +14,7 @@
             [com.stuartsierra.component :as component]
             [io.aviso.ansi :refer [bold-red bold-green bold-blue]]
             [shale.logging :as logging]
-            [shale.nodes :as nodes :refer [NodeView]]
+            [shale.nodes :as nodes]
             [shale.utils :refer :all]
             [shale.redis :as redis]
             [shale.selenium :as selenium]
@@ -54,20 +54,19 @@

 (s/defschema SessionView
   "A session, as presented to library users."
-  {(s/required-key :id)             s/Str
-   (s/required-key :webdriver-id)   s/Str
-   (s/required-key :tags)         #{s/Str}
-   (s/required-key :reserved)       s/Bool
-   (s/required-key :current-url)   (s/maybe s/Str)
-   (s/required-key :browser-name)   s/Str
-   (s/required-key :node)           NodeView
-   (s/required-key :capabilities)   {s/Keyword s/Any}})
+  {:id             s/Str
+   :webdriver-id   s/Str
+   :tags         #{s/Str}
+   :reserved       s/Bool
+   :current-url   (s/maybe s/Str)
+   :browser-name   s/Str
+   :node           nodes/NodeView
+   :capabilities   {s/Keyword s/Any}})

 (s/defschema TagChange
   "Add/remove a session/node tag"
-  {:resource (s/either (literal-pred :session) (literal-pred :node))
-   :action   (s/either (literal-pred :add) (literal-pred :remove))
-   :tag      s/Str})
+  {:action (s/enum :add :remove)
+   :tag    s/Str})

 (s/defschema Requirement
   "A schema for a session requirement."
@@ -267,8 +266,8 @@
   "Modification to a session"
   (any-pair
     :change-tag TagChange
-    :go-to-url s/Str
-    :reserve s/Bool))
+    :go-to-url  s/Str
+    :reserve    s/Bool))

 (s/defn ^:always-validate save-session-tags-to-redis
   [pool :- SessionPool


Handling known responses in more modular way

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -125,6 +125,19 @@
 (defn is-factorial?
     [input]
     (re-matches #"[0-9]+!" input))
+
+(defn find-word-in-known-responses
+    [input]
+    (let [responses (-> @dyncfg/configuration :responses)]
+        (responses (.toLowerCase input))))
+
+(defn is-word-from-known-responses?
+    [input]
+    (find-word-in-known-responses input))
+
+(defn return-known-response
+    [input]
+    (find-word-in-known-responses input))

 (defn is-word-from-dictionary?
     [input]
@@ -232,9 +245,6 @@
                           "time"     (calendar/format-time (calendar/get-calendar))
                           "sunrise"  (schedule/get-sunrise (:geolocation @dyncfg/configuration))
                           "sunset"   (schedule/get-sunset  (:geolocation @dyncfg/configuration))
-                          "die"      "thanks for your feedback, I appreciate it"
-                          "Good bot" "I know"
-                          "Good bot." "I know"
                           "rainbow"   (apply str (for [color (range 16)]
                                                      (str (char 3) (format "%02d" color) (format "test%02d " color) (char 3) "99")))
                           (cond
@@ -243,6 +253,7 @@
                               (and number-cruncher? (is-factorial? input))            (print-factorial input)
                               (and s-expressions?   (is-s-expression? input))         (s-expression input)
                               (congrats? input)                                       (congratulate input)
+                              (is-word-from-known-responses? input) (return-known-response input)
                               (is-word-from-dictionary? input) (return-words-from-dictionary input)
                               (one-word-like-this? input)      (return-word-like-this input)
                               (more-words-like-this? input)    (return-more-words-like-this input)


Cleanup.

Cleanup.

--- src/cljc/sudoku/rules.cljc
+++ src/cljc/sudoku/rules.cljc
@@ -33,11 +33,12 @@
    (some #(when (apply = %) (first %))
          (partition 2 (iterate #(reduce simplify % all-coords) board)))))

+(defn expand [board cell]
+  (map #(assoc-in board cell %) (get-in board cell)))
+
 (defn neighbors [board]
   (let [most-constrained (apply min-key #(count (get-in board %)) (unknowns board))]
-    (filter (complement invalid?)
-            (map #(simplify (assoc-in board most-constrained %))
-                 (get-in board most-constrained)))))
+    (filter (complement invalid?) (map simplify (expand board most-constrained)))))

 (defn solve [board]
   (let [start (simplify (initialize board))]


Checking for the history API before ajaxifying.

--- src/cljs/ajaxify/main.cljs
+++ src/cljs/ajaxify/main.cljs
@@ -137,16 +137,17 @@
 (defn ^:export main
   "Entry point for the Clojurescript, to be called on load"
   []
-  (.delegate (js/jQuery "nav") "li" "click" (fn [event]
-    (let [my-anchor (.find (js/jQuery (js* "this")) "a")]
-      (when-not (= 0 (.length my-anchor))
-        (macros/object-call event preventDefault)
-        (on-anchor-click my-anchor))
-      false)))
-  (.addEventListener js/window "popstate" (fn [event]
-    (let [state (.state event)
-          ; At this point the URL has already been updated
-          to-href (current-page-relative-href)]
-      (when state
-        (when (.href state)
-          (on-pop-state to-href)))) false)))
+  (when js/history ; Don't do anything if the History API isn't available
+    (.delegate (js/jQuery "nav") "li" "click" (fn [event]
+      (let [my-anchor (.find (js/jQuery (js* "this")) "a")]
+        (when-not (= 0 (.length my-anchor))
+          (macros/object-call event preventDefault)
+          (on-anchor-click my-anchor))
+        false)))
+    (.addEventListener js/window "popstate" (fn [event]
+      (let [state (.state event)
+            ; At this point the URL has already been updated
+            to-href (current-page-relative-href)]
+        (when state
+          (when (.href state)
+            (on-pop-state to-href)))) false))))


Remove unused refers

Remove unused refers

--- src/cljs/ji/websocket.cljs
+++ src/cljs/ji/websocket.cljs
@@ -1,6 +1,6 @@
 (ns ji.websocket
   (:require [cljs.reader :refer [read-string]]
-            [cljs.core.async :as async :refer [<! >! chan close! put! take! sliding-buffer dropping-buffer timeout]])
+            [cljs.core.async :as async :refer [<! >! chan close! put!]])
   (:require-macros [cljs.core.async.macros :refer [go go-loop]]))

 (defn connect!


remove debugging

remove debugging

--- src/cljs/memtest/core.cljs
+++ src/cljs/memtest/core.cljs
@@ -100,9 +100,6 @@
        [:h1 "The Memory Game"]
        ; win status
        [:h2 (if (won-game?) "You won!!!")]
-       [:h2 (count @gameboard)]
-       [:h2 (count @matched)]
-       [:h2 @counter]
        ; the gameboard
        [:table#gameboard
         ; taking 4 cells at a time for each row


Add circle and square tools

Add circle and square tools

--- src/cljs/pizarra/core.cljs
+++ src/cljs/pizarra/core.cljs
@@ -38,9 +38,45 @@
     (.stroke context)
     (.restore context)))

+(defn square [[[x0 y0] [x1 y1]]]
+  [[x0 y0] [x1 y0] [x1 y1] [x0 y1]])
+
+(defrecord SquareAction [points props]
+  Drawable
+  (-draw [this context]
+    (.save context)
+    (doseq [[k val] props]
+      (aset context (name k) val))
+    (.beginPath context)
+    (let [[x0 y0] (first points)]
+      (.moveTo context x0 y0)
+      (doseq [[x y] (square points)]
+        (.lineTo context x y))
+      (.lineTo context x0 y0))
+    (.stroke context)
+    (.restore context)))
+
+(defrecord CircleAction [origin radius props]
+  Drawable
+  (-draw [this context]
+    (.save context)
+    (doseq [[k val] props]
+      (aset context (name k) val))
+    (.beginPath context)
+    (let [[x y] origin]
+      (.arc context x y radius (* 2 js/Math.PI) false))
+    (.stroke context)
+    (.restore context)))
+
 (defn new-line-action []
   (->LineAction [] (merge {:lineCap "round"
                            :lineJoin "round"} (get-in @app-state [:tools :props]))))
+(defn new-square-action []
+  (->SquareAction [] (merge {:lineCap "round"
+                             :lineJoin "round"} (get-in @app-state [:tools :props]))))
+(defn new-circle-action []
+  (->CircleAction nil 0 (get-in @app-state [:tools :props])))
+
 (def freehand-tool
   (reify
     ITool
@@ -54,6 +90,11 @@
 (defn slope [[[x0 y0] [x1 y1]]]
   (/ (- y1 y0) (- x1 x0)))

+(defn distance [[x0 y0] [x1 y1]]
+  (let [a (- x1 x0)
+        b (- y1 y0)]
+    (Math/sqrt (+ (* a a) (* b b)))))
+
 (defn adjusted-slope [m]
   (cond
     (< 0.5 m 2) 1
@@ -73,11 +114,11 @@
       (adjust-points m points))
     points))

-(defn next-point [points x y]
+(defn next-point [points x y f]
   (if (zero? (count points))
     [[x y]]
     (let [points (assoc points 1 [x y])]
-      (snap points))))
+      (f points))))

 (def straight-line-tool
   (reify
@@ -85,14 +126,39 @@
     (-start [_ actions]
       (conj actions (new-line-action)))
     (-move [_ action x y]
-      (let [points (next-point (:points action) x y)]
+      (let [points (next-point (:points action) x y snap)]
         (assoc action :points points)))
     (-end [_ actions]
       actions)))

+(def square-tool
+  (reify
+    ITool
+    (-start [_ actions]
+      (conj actions (new-square-action)))
+    (-move [_ action x y]
+      (let [points (next-point (:points action) x y identity)]
+        (assoc action :points points)))
+    (-end [_ actions]
+      actions)))
+
+(def circle-tool
+  (reify
+    ITool
+    (-start [_ actions]
+      (conj actions (new-circle-action)))
+    (-move [_ action x y]
+      (if-let [o (:origin action)]
+        (assoc action :radius (distance o [x y]))
+        (assoc action :origin [x y])))
+    (-end [_ actions]
+      actions)))
+
 (def all-tools
   {:line straight-line-tool
-   :freehand freehand-tool})
+   :freehand freehand-tool
+   :square square-tool
+   :circle circle-tool})

 (defn current-tool []
   (all-tools (get-in @app-state [:tools :current])))
@@ -170,6 +236,12 @@
                (dom/button #js {:disabled (= (om/value (:current tools)) :line)
                                 :onClick (fn [e]
                                            (om/update! tools [:current] :line))} "Line")
+               (dom/button #js {:disabled (= (om/value (:current tools)) :square)
+                                :onClick (fn [e]
+                                           (om/update! tools [:current] :square))} "Square")
+               (dom/button #js {:disabled (= (om/value (:current tools)) :circle)
+                                :onClick (fn [e]
+                                           (om/update! tools [:current] :circle))} "Circle")
                ))))

 (defn app-component [app owner]
@@ -248,15 +320,10 @@

 (comment

-(swap! app-state assoc-in [:canvas :actions 0 :props :strokeStyle] "#999999")
-(swap! app-state update-in [:canvas :actions] pop)
-
 (deref app-state)

-(swap! app-state assoc-in [:tools :props :lineWidth] 3)
-(swap! app-state assoc-in [:tools :current] :line)
-
 (swap! app-state update-in [:canvas :dimensions] assoc :width 900 :height 300)

+(square [[587 229] [554 333]])

 )


Consmetic changes.

Consmetic changes.

--- src/cljs/replumb/repl.cljs
+++ src/cljs/replumb/repl.cljs
@@ -56,7 +56,7 @@
    (remove-ns env/*compiler* ns))
   ([state ns]
    {:pre [(symbol? ns)]}
-   (swap! state update-in [::ana/namespaces] dissoc ns)))
+   (swap! state update-in [:cljs.analyzer/namespaces] dissoc ns)))

 (defn map-keys
   [f m]
@@ -423,6 +423,8 @@
   It initializes the repl harness if necessary."
   [opts cb source]
   (init-repl-if-necessary! opts cb)
+  (when (:verbose opts)
+    (debug-prn "Evaluating: " source))
   (try
     (let [expression-form (repl-read-string source)
           opts (valid-opts opts)]


add notes to data generator for history template

--- src/cljs_api_gen/write.clj
+++ src/cljs_api_gen/write.clj
@@ -275,9 +275,25 @@
 ;;--------------------------------------------------------------------------------
 ;; history file
 ;;--------------------------------------------------------------------------------
-
 (defn history-file-data
   [result]
+  ;;; The problem we're trying to solve here is to merge the history information
+  ;;; of all the API categories.
+  ;;;
+  ;;; What this function receives:
+  ;;;   {:api {:library {}, :compiler {}, :syntax {}}}
+  ;;;
+  ;;; But each API has its own list of changes, all the same size and with the same version keys per change.
+  ;;;
+  ;;; What this function should output:
+  ;;;   {:versions [
+  ;;;               {;; version keys present but not shown.
+  ;;;                :library-api {}
+  ;;;                :compiler-api {}
+  ;;;                :syntax-api {}}]
+  ;;;
+  ;;; This data transformation is messy.  Need to do this in result.clj
+
   (let [add-change-info
         (fn [change symbols api-type]
           (let [changes (version-changes symbols change)
@@ -308,6 +324,7 @@
         syn-changes (get-api-changes :syntax)
         com-changes (get-api-changes :compiler)
         lib-changes (get-api-changes :library)
+
         all (reverse (map #(merge %1 %2 %3) syn-changes com-changes lib-changes))]
     {:versions all}))


Call handler with worker pool

Call handler with worker pool

--- src/cljs_workers/core.cljs
+++ src/cljs_workers/core.cljs
@@ -59,3 +59,19 @@
      (catch js/Object e
        (when fun
          (fun {:state :error, :error e}))))))
+
+(defn do-with-pool!
+  ([pool request]
+   (do-with-pool! pool request nil))
+
+  ([pool {:keys [handler arguments transfer] :as request} fun]
+   (go
+     (let [worker
+           (<! pool)
+
+           fun
+           (fn [response]
+             (go (>! pool worker))
+             (when fun (fun response)))]
+
+       (do-with-worker! worker request fun)))))


rewrite worker-body to work with different compile modes

--- worker/src/worker/worker.cljs
+++ worker/src/worker/worker.cljs
@@ -2,58 +2,32 @@
   :getElementsByTagName "function() {return [];}"
 })

+(defn worker-body [[ns* fn*]]
+  (let [
+    multi-loader (str
+     "var CLOSURE_BASE_PATH = '" *closure-base-path* "';"
+     "var CLOSURE_IMPORT_SCRIPT = (function(global) {"
+     "return function(src) {"
+        ;;"global['console'].log(src);"
+        "global['importScripts'](src);"
+        "return true;"
+     "};"
+     "})(self);"
+     "importScripts('" *closure-base-file* "','" *cljs-output-file* "');"
+     "goog.require('" ns* "');")
+    single-loader (str
+      "importScripts('" *cljs-output-file* "');"
+    )]
   (str
     "var document=" (serialize *document*) ";"
-   "var CLOSURE_BASE_PATH = '" closure-base-path "';"
-   "var CLOSURE_IMPORT_SCRIPT = (function(global) {"
-   "return function(src) {"
-      ;;"global['console'].log(src);"
-      "global['importScripts'](src);"
-      "return true;"
-   "};"
-   "})(self);"
-   "importScripts('" closure-base-file "','" cljs-deps-file "');"
-   "goog.require('worker.worker');"
+    (if (empty? *closure-base-path*) single-loader multi-loader)
+    "self.onmessage = function(e) {"
+      ns* "." fn* ".apply();"
+    "};")))

-   "self.onmessage = function(e) {"
-     "worker.worker.wrk();"
-   "};"))
+(defn full-func-name [wrk]
+  (js->clj (.split (str wrk) "/")))

-(defn worker-body-min [fn-name]
- (str
-  "importScripts('file:///Users/sbondaryev/clojure/sandbox/worker/resources/public/js/compiled/worker-min.js');"
-  "self.onmessage = function(e) {"
-    "worker.worker.wrk();"
-  "};"))
-
-
-(defn func-name [f]
-  (let [fstr (str f)
-        fname (subs fstr (count "function ") (.indexOf fstr "("))
-        fsplit (.split fname "$")]
-    (.join fsplit ".")))
-
-
-(defn ^:export wrk []
-  (enable-console-print!)
-  (println tm)
-  (sleep tm)
-  (println "test")
-  ;;(throw (js/Error. "test"))
-  )
-
-
-(defn do-some []
-(println goog.basePath)
-  (let [a (worker-body (func-name wrk))]
-    (println a)
-
-    (def b (js/Blob. (clj->js [a])))
-
-    (def w (js/Worker. (.createObjectURL js/URL b)))
-
-    (.postMessage w nil)
-    ))
 (defn do-some [wrk]
   (let [a (worker-body (full-func-name wrk))
         b (js/Blob. (clj->js [a]))


Fix tests around label name changes

Fix tests around label name changes

- Make them more granular enabling testing of small label changes.
- Plus, the ip and hostname can't be asserted on in tests since they are
  machine dependent.

--- test/wonko/streams_test.clj
+++ test/wonko/streams_test.clj
@@ -43,27 +43,31 @@
         (is (boolean histogram))
         (is (boolean summary))

-        (is (= {:label-names ["status"],
-                :label-values ["success"],
-                :name "feed_length_histogram_sum",
-                :value 30.0}
-               (tu/find-metric-sample histogram "feed_length_histogram_sum")))
+        (testing "histograms"
+          (let [res (tu/find-metric-sample histogram "feed_length_histogram_sum")]
+            (is (= (:label-names res) ["host" "ip_address" "status"]))
+            (is (= (nth (:label-values res) 2) "success"))
+            (is (= (:name res) "feed_length_histogram_sum"))
+            (is (= (:value res) 30.0)))

-        (is (= {:label-names ["status"],
-                :label-values ["success"],
-                :name "feed_length_histogram_count",
-                :value 3.0}
-               (tu/find-metric-sample histogram "feed_length_histogram_count")))
+          (let [res (tu/find-metric-sample histogram "feed_length_histogram_count")]
+            (is (= (:label-names res) ["host" "ip_address" "status"]))
+            (is (= (nth (:label-values res) 2) "success"))
+            (is (= (:name res) "feed_length_histogram_count"))
+            (is (= (:value res) 3.0))))

-        (is (= [{:label-names ["status"],
-                 :label-values ["success"],
-                 :name "feed_length_summary_count",
-                 :value 3.0}
-                {:label-names ["status"],
-                 :label-values ["success"],
-                 :name "feed_length_summary_sum",
-                 :value 30.0}]
-               (tu/metric-samples summary))))
+        (testing "summaries"
+          (let [[f s] (tu/metric-samples summary)]
+            (is (= ["host" "ip_address" "status"]
+                   (:label-names f)
+                   (:label-names s)))
+            (is (= "success"
+                   (nth (:label-values f) 2)
+                   (nth (:label-values s) 2)))
+            (is (= (:name f) "feed_length_summary_count"))
+            (is (= (:value f) 3.0))
+            (is (= (:name s) "feed_length_summary_sum"))
+            (is (= (:value s) 30.0)))))

       (consume/stop thread-pool)
       (tu/delete-topics events-topic alerts-topic))))


Use :on-hide

Use :on-hide

--- minicraft-online/desktop/src-common/minicraft_online/core.clj
+++ minicraft-online/desktop/src-common/minicraft_online/core.clj
@@ -134,7 +134,7 @@
           (when-not (:player? entity)
             (e/attack entities entity))))))

-  :on-dispose
+  :on-hide
   (fn [screen entities]
     (disconnect! screen)))


Rename import symbol to match new name of imported module.

--- clstreams/src/clstreams/examples/count_words_prc/topology.clj
+++ clstreams/src/clstreams/examples/count_words_prc/topology.clj
@@ -2,7 +2,7 @@
   (:require [clojure.spec.alpha :as s]
             [clojure.string :as str]
             [clstreams.landscape :as ldsc]
-            [clstreams.processor :as topology]
+            [clstreams.processor :as prc]
             [clstreams.store :as store]
             [clstreams.topology :as tp])
   (:import org.apache.kafka.common.serialization.Serdes
@@ -39,13 +39,13 @@
   (-> (TopologyBuilder.)
       (.addSource "src1" (into-array String '("input")))
       (.addProcessor "prc1"
-                     (topology/value-processor
+                     (prc/value-processor
                       (mapcat #(str/split % #"\W+"))
                       (filter #(> (count %) 0))
                       (map str/lower-case))
                      (into-array String '("src1")))
       (.addProcessor "prc2"
-                     (topology/key-value-processor
+                     (prc/key-value-processor
                       (map (fn [[key value]] [value value])))
                      (into-array String '("prc1")))
       (.addSink "snk1" "words" (into-array String '("prc2")))
@@ -56,7 +56,7 @@
        ;(make-counts-store)
        (into-array String '()))
       (.addProcessor "prc3"
-                     (topology/transducing-processor
+                     (prc/transducing-processor
                       (fn [context]
                         (completing
                          (fn [store [key value]]


fixed pdf and log-pdf for negative s2

fixed pdf and log-pdf for negative s2

--- src/distributions/normal-inverse-gamma.clj
+++ src/distributions/normal-inverse-gamma.clj
@@ -10,15 +10,21 @@
                 [mu s2]))
   (sample [d n] (take n (repeatedly #(sample d))))
   probability-function
-  (P [d [mu s2]] (* (pdf (inverse-gamma shape scale) s2)
-                      (pdf (normal location (/ s2 lambda)) mu)))
+  (P [d [mu s2]] (if (< s2 0)
+                   0
+                   (* (pdf (inverse-gamma shape scale) s2)
+                      (pdf (normal location (/ s2 lambda)) mu))))
   (P [d] (fn [x] (pdf d x)))
   density-function
-  (pdf [d [mu s2]] (* (pdf (inverse-gamma shape scale) s2)
-                      (pdf (normal location (/ s2 lambda)) mu)))
+  (pdf [d [mu s2]] (if (< s2 0)
+                     0
+                     (* (pdf (inverse-gamma shape scale) s2)
+                        (pdf (normal location (/ s2 lambda)) mu))))
   (pdf [d] (fn [x] (pdf d x)))
-  (log-pdf [d [mu s2]] (+ (log-pdf (inverse-gamma shape scale) s2)
-                          (log-pdf (normal location (/ s2 lambda)) mu)))
+  (log-pdf [d [mu s2]] (if (< s2 0)
+                         Double/NEGATIVE_INFINITY
+                         (+ (log-pdf (inverse-gamma shape scale) s2)
+                            (log-pdf (normal location (/ s2 lambda)) mu))))
   (log-pdf [d] (fn [x] (pdf d x))))

 (defn normal-inverse-gamma [location prec shape scale] (new NormalInverseGamma location prec shape scale))
@@ -41,8 +47,7 @@
                                          (square (- post-mean
                                                     prior-mean))))
                                      2))
-        post-shape (+ prior-shape (/ n 2))
-        ]
+        post-shape (+ prior-shape (/ n 2))]
     (normal-inverse-gamma post-mean post-lambda post-shape post-scale)))

 (defmethod marginal [distributions.core.Normal distributions.core.NormalInverseGamma]
@@ -57,64 +62,56 @@
                              (* prior-lambda prior-shape))))))

 (comment
-(sample (marginal (normal :mu :s2) (normal-inverse-gamma 2 3 1 2)))
+  (sample (marginal (normal :mu :s2) (normal-inverse-gamma 2 3 1 2)))

-(def Y [1 1 1 2 2 3 1 2 5])
-(def n (count Y))
+  (def Y [1 1 1 2 2 3 1 2 5])
+  (def n (count Y))

-(def mu1 3)
-(def s21 10)
-(def mu2 3)
-(def s22 1)
-(def prior-mean 3)
-(def prior-lambda 2)
-(def prior-shape 10)
-(def prior-scale 3)
-(- (log-pdf (posterior Y (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale)) [mu1 s21])
-   (log-pdf (posterior Y (normal :mu :s2) (normal-inverse-gamma  prior-mean prior-lambda prior-shape prior-scale)) [mu2 s22]) )
+  (def mu1 3)
+  (def s21 10)
+  (def mu2 3)
+  (def s22 1)
+  (def prior-mean 3)
+  (def prior-lambda 2)
+  (def prior-shape 10)
+  (def prior-scale 3)
+  (- (log-pdf (posterior Y (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale)) [mu1 s21])
+     (log-pdf (posterior Y (normal :mu :s2) (normal-inverse-gamma  prior-mean prior-lambda prior-shape prior-scale)) [mu2 s22]))

-(- (+ (log-pdf (normal prior-mean (/ s21 prior-lambda)) mu1)
-      (log-pdf (inverse-gamma prior-shape prior-scale) s21)
-      (reduce + (map #(log-pdf (normal mu1 s21) %) Y)))
-   (+ (log-pdf (normal prior-mean (/ s22 prior-lambda)) mu2)
-      (log-pdf (inverse-gamma prior-shape prior-scale) s22)
-      (reduce + (map #(log-pdf (normal mu2 s22) %) Y)))
-   )
+  (- (+ (log-pdf (normal prior-mean (/ s21 prior-lambda)) mu1)
+        (log-pdf (inverse-gamma prior-shape prior-scale) s21)
+        (reduce + (map #(log-pdf (normal mu1 s21) %) Y)))
+     (+ (log-pdf (normal prior-mean (/ s22 prior-lambda)) mu2)
+        (log-pdf (inverse-gamma prior-shape prior-scale) s22)
+        (reduce + (map #(log-pdf (normal mu2 s22) %) Y))))

+  (double (+ prior-scale (/ (+ (* (/ (* n prior-lambda) (+ n prior-lambda)) (square (- (mean Y) prior-mean)))
+                               (reduce + (map square (sub Y (mean Y))))) 2)))

-(double (+ prior-scale (/ (+ (* (/ (* n prior-lambda) (+ n prior-lambda)) (square (- (mean Y) prior-mean)))
-                            (reduce + (map square (sub Y (mean Y))))) 2)))
+  (double (:scale (posterior Y (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale))))

-(double (:scale (posterior Y (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale))))
+  (variance (t-distribution 4))
+  (variance (t-distribution 4 0 10))

+  (* (variance (t-distribution (* 2 prior-shape)))  (/ (* prior-scale (+ 1 prior-lambda)) (* prior-lambda prior-shape)))
+  (variance (map (fn [[mu s2]] (sample (normal mu s2))) (sample (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale) 100000)))
+  (variance (marginal (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale)))
+  (variance (sample (marginal (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale)) 10000))

-(variance (t-distribution 4))
-(variance (t-distribution 4 0 10))
+  (* (variance (t-distribution (* 2 prior-shape))) (/ (* prior-lambda prior-shape) prior-scale))
+  (variance (map first
+                 (sample (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale) 10000)))

-(* (variance (t-distribution (* 2 prior-shape)))  (/ (* prior-scale (+ 1 prior-lambda)) (* prior-lambda prior-shape)))
-(variance (map (fn [[mu s2]] (sample (normal mu s2))) (sample (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale) 100000)))
-(variance (marginal (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale)))
-(variance (sample (marginal (normal :mu :s2) (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale)) 10000))
+  (double (variance (inverse-gamma 10 10)))
+  (variance (sample (inverse-gamma 10 10) 100000))

-(* (variance (t-distribution (* 2 prior-shape))) (/ (* prior-lambda prior-shape) prior-scale))
-(variance (map first
-               (sample (normal-inverse-gamma prior-mean prior-lambda prior-shape prior-scale) 10000)))
+  (def d (inverse-gamma 10 3))
+  (double (variance d))
+  (variance (sample d 100000))

-(double (variance (inverse-gamma 10 10 )))
-(variance (sample (inverse-gamma 10 10) 100000))
-
-(def d (inverse-gamma 10 3))
-(double (variance d))
-(variance (sample d 100000))
-
-
-
-
-(variance (map (fn [[mu s2]] (sample (normal mu s2))) (sample (normal-inverse-gamma 4 2 1000 4) 100000)))
-(variance (map second (sample (normal-inverse-gamma 4 3 5 4) 10000)))
-(variance (inverse-gamma 5 4))
-(variance (sample (marginal (normal :mu :s2) (normal-inverse-gamma 4 2 1000 4)) 100000))
-(variance (marginal (normal :mu :s2) (normal-inverse-gamma 4 2 1000 4)))
-(variance (t-distribution 30000 3 10))
-
-)
+  (variance (map (fn [[mu s2]] (sample (normal mu s2))) (sample (normal-inverse-gamma 4 2 1000 4) 100000)))
+  (variance (map second (sample (normal-inverse-gamma 4 3 5 4) 10000)))
+  (variance (inverse-gamma 5 4))
+  (variance (sample (marginal (normal :mu :s2) (normal-inverse-gamma 4 2 1000 4)) 100000))
+  (variance (marginal (normal :mu :s2) (normal-inverse-gamma 4 2 1000 4)))
+  (variance (t-distribution 30000 3 10)))


bio update

bio update

--- src/dchristopher/index.cljs
+++ src/dchristopher/index.cljs
@@ -5,7 +5,7 @@
 (defn hello-world []
   [:div
    [:h1 "Daniel Christopher"]
-   [:h3 "Front end engineer, father, wannabe chef, occasional artist, and clojure fanboy."]
+   [:h3 "Front end engineer, wannabe chef, occasional artist, and clojure fanboy."]
    [:div.links
     [:a {:href "/assets/resume-public.pdf" :download true} "Resume"]
     [:span "|"]


Formatting faffage.

Formatting faffage.

--- src/depends/neo4jwriter.clj
+++ src/depends/neo4jwriter.clj
@@ -29,15 +29,15 @@
   (let [source-id (name-id-map (:source edge))
         target-id (name-id-map (:target edge))
         type      (:type edge)]
-  {
-    :method "POST"
-    :to     (str "/node/" source-id "/relationships")
-    :body
     {
-      :to   (str target-id)
-      :type type
-    }
-  }))
+      :method "POST"
+      :to     (str "/node/" source-id "/relationships")
+      :body
+      {
+        :to   (str target-id)
+        :type type
+      }
+    }))

 (defn- write-edges!
   "Writes the edges of the graph into a Neo4J database. Returns nil."


show spinner while branch data loads

show spinner while branch data loads

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -1315,6 +1315,18 @@
         api-ch (get-in current-state [:comms :api])]
     (api/delete-code-signing-key org-name id api-ch uuid)))

+(defmethod control-event :project-insights-branch-changed
+  [_ _ {:keys [new-branch]} state]
+  (let [projects (get-in state state/projects-path)
+        navigation-data (:navigation-data state)
+        new-projects (map (fn [project]
+                            (if (and (= (:reponame project) (:repo navigation-data))
+                                     (= (:username project) (:org navigation-data)))
+                              (assoc project :insights-selected-branch new-branch)
+                              project))
+                          projects)]
+    (assoc-in state state/projects-path new-projects)))
+
 (defmethod post-control-event! :project-insights-branch-changed
   [target message {:keys [new-branch]} _ current-state]
   (let [nav-data (get-in current-state [:navigation-data])


Remove elevio feature flag

Remove elevio feature flag

--- src-cljs/frontend/config.cljs
+++ src-cljs/frontend/config.cljs
@@ -80,7 +80,7 @@

 (defn elevio-enabled?
   []
-  (and (aget js/window "elevSettings") (feature/enabled? "elevio")))
+  (boolean (aget js/window "elevSettings")))

 (defn zd-widget-enabled?
   []


elevio Direct free customers to Discuss support

--- src-cljs/frontend/elevio.cljs
+++ src-cljs/frontend/elevio.cljs
@@ -21,10 +21,18 @@
                                  (aget "ldUser")
                                  (aget "custom")
                                  (aget "free")))
-        user-info (aget js/window "elevSettings")]
+        user-info (aget js/window "elevSettings")
+        support-module-id "2968"
+        discuss-link-module-id "3003"
+        discuss-support-link-module-id "3762"]
     (-> user-info
         (aget "traits")
         (aset "free" is-free))
+    (if is-free
+      ;; disable support module, discuss link module
+      (set-elev! "disabledModules" #js [support-module-id discuss-link-module-id])
+      ;; else disable discuss support link module
+      (set-elev! "disabledModules" #js [discuss-support-link-module-id]))
     (set-elev! "account_id" account-id)
     (set-elev! "user" user-info)
     (set-elev! "pushin" "false")


Added wireframe content to profile.cljs

Added wireframe content to profile.cljs

--- src-cljs/rmfu_ui/profile.cljs
+++ src-cljs/rmfu_ui/profile.cljs
@@ -1,4 +1,206 @@
 (ns rmfu-ui.profile)

 (defn profile []
-  [:h1 "profile"])+  [:div.container.jumbotron
+  {:style {:max-width "700px"}}
+ [:div.row
+  [:div.col-lg-12
+   [:h3.text-center
+    "Tell Us About Yourself"]
+   [:div.col-lg-6
+    [:input.form-control.pull-left
+     {:type "firstname", :placeholder "First Name", :value ""}]]
+   [:div.col-lg-6
+    [:input.form-control.pull-right
+     {:type "lastname", :placeholder "Last Name", :value ""}]]
+   [:br]
+   [:br]
+   [:div.dropdown.col-lg-3
+    [:button#dropdownMenu1.btn.btn-secondary.dropdown-toggle
+     {:type "button", :data-toggle "dropdown", :aria-haspopup "true", :aria-expanded "false"}
+     "\n            Demographic\n          "]
+    [:div.dropdown-menu
+     [:a.dropdown-item
+      {:href "#"}
+      "Action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Another action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Something else here"]
+     [:div.dropdown-divider]
+     [:a.dropdown-item
+      {:href "#"}
+      "Separated link"]]]
+   [:div.dropdown.col-lg-3
+    [:button#dropdownMenu1.btn.btn-secondary.dropdown-toggle
+     {:type "button", :data-toggle "dropdown", :aria-haspopup "true", :aria-expanded "false"}
+     "\n            Demographic\n          "]
+    [:div.dropdown-menu
+     [:a.dropdown-item
+      {:href "#"}
+      "Action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Another action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Something else here"]
+     [:div.dropdown-divider]
+     [:a.dropdown-item
+      {:href "#"}
+      "Separated link"]]]
+   [:div.dropdown.col-lg-3
+    [:button#dropdownMenu1.btn.btn-secondary.dropdown-toggle
+     {:type "button", :data-toggle "dropdown", :aria-haspopup "true", :aria-expanded "false"}
+     "\n            Demographic\n          "]
+    [:div.dropdown-menu
+     [:a.dropdown-item
+      {:href "#"}
+      "Action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Another action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Something else here"]
+     [:div.dropdown-divider]
+     [:a.dropdown-item
+      {:href "#"}
+      "Separated link"]]]
+   [:div.dropdown.col-lg-3
+    [:button#dropdownMenu1.btn.btn-secondary.dropdown-toggle
+     {:type "button", :data-toggle "dropdown", :aria-haspopup "true", :aria-expanded "false"}
+     "\n            Demographic\n          "]
+    [:div.dropdown-menu
+     [:a.dropdown-item
+      {:href "#"}
+      "Action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Another action"]
+     [:a.dropdown-item
+      {:href "#"}
+      "Something else here"]
+     [:div.dropdown-divider]
+     [:a.dropdown-item
+      {:href "#"}
+      "Separated link"]]]
+   [:div.col-lg-12 {:style {:height "20px"}} ]
+   [:h4
+    "Regions of Interest"]
+   [:div.input-group.select-group
+
+    [:div.col-lg-10
+     {:style {:padding-right 0}}
+     [:input.form-control
+      {:type "zip", :placeholder "Enter Zip Code", :value ""}]]
+    [:select.c-select.col-lg-2
+     [:option
+      "Item 1"]
+     [:option
+      "Item 2"]
+     [:option
+      "Item 3"]]
+    [:div.input-group-btn
+     [:button.btn.btn-default
+      {:name "type", :type "button", :value "add"}
+      "Add"]]]
+   [:ul.list-inline
+    [:li
+     "80246 +5 Miles"]
+    [:li
+     "80246 +10 Miles"]
+    [:li
+     "80123 +50 Miles"]]
+   [:h4
+    "Topics of Interest"]
+   [:div.input-group
+    [:input.form-control
+     {:type "topics", :placeholder "Enter Keywords or select from suggestions below", :value ""}]
+    [:span.input-group-btn
+     [:button.btn.btn-default
+      {:type "button", :value "add"}
+      "Add"]]]
+   [:ul.list-inline
+    [:li
+     [:a
+      {:href "#"}
+      "Dairy"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Organic"]]
+    [:li
+     [:a
+      {:href "#"}
+      "GMO"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Fertilizer"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Equipment"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Poultry"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Sustainable"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Green"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Pests"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Tobacco"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Fuel"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Seeds"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Wool"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Solar"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Wind"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Legislation"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Vegetables"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Fruit"]]
+    [:li
+     [:a
+      {:href "#"}
+      "Polls"]]]
+   [:p.text-center
+    [:button.btn
+     {:name "type", :type "button", :value "continue"}
+     "Continue to your custom feed"]]]]])


Generalize benchmarking code to allow getting any func

--- bench/clojush/interpreter_bench.clj
+++ bench/clojush/interpreter_bench.clj
@@ -7,42 +7,43 @@
             [clojush.core :refer [-main]]
             [clojush.interpreter :refer [eval-push]]))

-(defn grab-executions
-  "Returns the first `n` executions of the interpreter, from Running
+(defn grab-call-inputs
+  "Returns the first `n` inputs to the `func-var`, from Running
    the cli args.

-  Does this by wrapping the `run-push` function to save each call, and
+  Does this by wrapping `func-var` function to save each call, and
   raising an exception after we have enough calls done, which is then caught."
-  [n cli-args]
-  (let [calls-atom (atom (list))
-        eval-push-default eval-push ;; https://www.reddit.com/r/Clojure/comments/5esre1/how_to_call_the_original_function_in_withredefs/daf401z/
+  [func-var n cli-args]
+  (let [inputs-atom (atom (list))
+        func-original (var-get func-var)
         done-fn #(>= (count %) n)
-        eval-push-log (fn [state & args]
-                        (let [ret (apply eval-push-default state args)
-                              calls (swap! calls-atom conj {:input state :output ret})]
-                          (when (done-fn calls)
+        func-log (fn [& input]
+                        (let [ret (apply func-original input)
+                              inputs (swap! inputs-atom conj input)]
+                          (when (done-fn inputs)
                             (throw (Exception. "")))
                           ret))]

-    (with-redefs [eval-push eval-push-log]
-      (try
-        (with-out-str (apply -main cli-args))
-        (catch Exception e
-          (when-not (done-fn @calls-atom)
-            (throw e))))
-      @calls-atom)))
+    (with-redefs-fn {func-var func-log}
+      (fn []
+        (try
+          (with-out-str (apply -main cli-args))
+          (catch Exception e
+            (when-not (done-fn @inputs-atom)
+              (throw e))))))
+    @inputs-atom))

-(defmacro defbench-eval-push [number-programs problem]
-  `(defbench ~(symbol (str "eval-push-on-" number-programs "-from-" problem))
-    (println "Grabbing executions...")
-    (let [args# [~problem ":use-single-thread" "true"]
-          executions# (grab-executions ~number-programs args#)
-          inputs# (into [] (map :input executions#))]
+(defmacro defbench-grab-then-benchmark [func-var n-inputs args]
+  `(defbench ~(symbol (str (:name (meta (eval func-var))) "-on-" n-inputs "-from-" (first args)))
+    (println "Grabbing inputs...")
+    (let [total-args# [~@args ":use-single-thread" "true"]
+          inputs# (grab-call-inputs ~func-var ~n-inputs total-args#)
+          func# (var-get ~func-var)]
       (println "Running benchmark...")
       (is (c/quick-bench
             (doseq [input# inputs#]
-              (eval-push input#)))))))
+              (apply func# input#)))))))

-(defbench-eval-push 1000 "clojush.problems.software.replace-space-with-newline")
-(defbench-eval-push 1000 "clojush.problems.integer-regression.nth-prime")
-(defbench-eval-push 10000 "clojush.problems.integer-regression.nth-prime")
+(defbench-grab-then-benchmark #'eval-push 1000 ["clojush.problems.software.replace-space-with-newline"])
+(defbench-grab-then-benchmark #'eval-push 1000 ["clojush.problems.integer-regression.nth-prime"])
+(defbench-grab-then-benchmark #'eval-push 10000 ["clojush.problems.integer-regression.nth-prime"])