Use buffered channel

Use buffered channel

--- src/connect_four/frontend.cljs
+++ src/connect_four/frontend.cljs
@@ -13,7 +13,7 @@

 (def config (atom {:difficulty :hard}))

-(def ai-chan (chan))
+(def ai-chan (chan 1))

 (def pieces {:empty [:span {:style {:color "black"}} "_"]
              :red [:span {:style {:color "red"}} "RED"]


add member joined and leave listeners

add member joined and leave listeners

--- src/group_redis/core.clj
+++ src/group_redis/core.clj
@@ -1,5 +1,6 @@
 (ns group-redis.core
   (:require [fun-utils.core :refer [fixdelay]]
+            [clojure.core.async :refer [chan >! <! >!! go mult tap untap sliding-buffer close!]]
             [taoensso.carmine :as car :refer [wcar]])
   (:import [java.net InetAddress]))

@@ -25,8 +26,11 @@
   (clojure.string/join ["/" (clojure.string/join "/" (flatten [group-name "locks" path]))]))

-(defn close [{:keys [state-ref]}]
+(defn close [{:keys [state-ref member-event-ch heart-beat-ch]}]
   ;delete connection's state
+  (close! heart-beat-ch)
+  (close! member-event-ch)
+
   (dosync (alter state-ref (fn [state] {}))))

 (defn create-connection
@@ -107,16 +111,15 @@

 (defn get-members [{:keys [conn] :as connector}]
-  (map (fn [path]
-         {:path path :val (System/currentTimeMillis)})
-       (car/wcar conn
-            (car/keys (clojure.string/join [(members-path connector) "/*"])))))
-
+  (into #{} (map (fn [path]
+									 {:path path :val (System/currentTimeMillis)})
+                 (car/wcar conn
+									            (car/keys (clojure.string/join [(members-path connector) "/*"]))))))

 (defn join
   ([connector]
     (join connector host-name))
-  ([{:keys [conn conf state-ref] :as connector} node-name]
+  ([{:keys [conn conf member-event-ch state-ref] :as connector} node-name]
     (let [{:keys [heart-beat-freq]} conf
           path (members-path connector node-name)
           val (System/currentTimeMillis)]
@@ -126,22 +129,45 @@
                 )
      (dosync (alter state-ref
             (fn [state]
-               (assoc state :members (conj (:members state) {:path path :val val}))
-              ))))))
+               (assoc state :members (into #{} (conj (:members state) {:path path :val val})))
+              )))
+     (>!! member-event-ch {:left-members #{} :joined-members #{node-name}})
+     )))

+(defn- members-left [members u-members]
+  (clojure.set/difference (into #{} (map :path members)) (into #{} (map :path u-members))))
+
+(defn- members-joined [members u-members]
+  (clojure.set/difference (into #{} (map :path u-members)) (into #{} (map :path members))))
+
 (defn heart-beat [connector {:keys [members locks empherals] :as state}]
   "Sends out the heart beat and updates all TTL nodes,
    The members are queried and if any difference a fresh list created for the state
    which is returned"
   (send-updates connector (concat members locks empherals))
-  (let [u-members (get-members connector)]
-
-    (if (not (= members u-members))
-     (merge state {:members u-members})
-      state)))
+    ;(prn "calling lef-members " members " " u-members)
+    (let [u-members (get-members connector)
+          left-members (if (> (count members) 0) (members-left members u-members) #{})
+          joined-members (members-joined members u-members)]
+
+         ;publish event
+        (if (or (> (count left-members) 0) (> (count joined-members) 0))
+          (>!! (:member-event-ch connector) {:left-members left-members :joined-members joined-members}))

+        (if (not (= members u-members))
+		      (merge state {:members u-members})
+		           state)))
+
+(defn unregister-event-ch [{:keys [member-event-mult]} ch]
+  (untap member-event-mult ch))
+
+(defn register-member-event-ch [{:keys [member-event-mult]}]
+  "Returns a channel from which member register events can be read"
+  (let [ch (chan (sliding-buffer 10))]
+    (tap member-event-mult ch)
+    ch))

 (defn create-group-connector
   ([host]
@@ -152,11 +178,14 @@
   (let [state-ref (ref {:members #{} :locks #{} :empherals #{}})
         conf2 (merge conf {:group-name group-name :heart-beat-freq heart-beat-freq})
         c (create-connection host conf)
-        connector {:conn c :state-ref state-ref :conf conf2 :host host :group-name group-name}]
+        member-event-ch (chan (sliding-buffer 10))
+        member-event-mult (mult member-event-ch)
+        connector {:conn c :state-ref state-ref :conf conf2 :host host :group-name group-name
+                   :member-event-ch member-event-ch :member-event-mult member-event-mult}

-    (fixdelay (* heart-beat-freq 1000)
-              (dosync
-                (alter state-ref (partial heart-beat connector))))
-     connector)))
+		    heart-beat-ch (fixdelay (* heart-beat-freq 1000)
+								              (dosync
+								                (alter state-ref (partial heart-beat connector))))]
+      (assoc connector :heart-beat-ch heart-beat-ch))))


Add submission review constants

Add submission review constants

Signed-off-by: ivermac <cd640042a8f3b0ff08bacdf4feae34fdd495051d@gmail.com>

--- src/hatti/constants.cljs
+++ src/hatti/constants.cljs
@@ -9,6 +9,8 @@
 (def _submission_time "_submission_time")
 (def _media_all_received "_media_all_received")
 (def _submitted_by "_submitted_by")
+(def _review_status "_review_status")
+(def _review_comment "_review_comment")
 (def photo "Photo")

 ;; Attachments keys


Use better argument names in adadelta-clojure

--- cortex/src/cortex/optimise/optimisers.clj
+++ cortex/src/cortex/optimise/optimisers.clj
@@ -81,15 +81,15 @@
      (* (- 1 decay-rate) value)))

 (defn adadelta-clojure
-  [& {:keys [rho epsilon]
-      :or {rho 0.95
-           epsilon 1e-6}}]
+  [& {:keys [decay conditioning]
+      :or {decay 0.95
+           conditioning 1e-6}}]
   (letfn [(acc [acc-x x]
-            (accumulate rho acc-x x))
+            (accumulate decay acc-x x))
           (rms [acc-x]
             (m/sqrt
               (+ acc-x
-                 epsilon)))]
+                 conditioning)))]
     {:initialize (fn [param-count]
                    {:acc-gradient (m/new-vector :vectorz param-count)
                     :acc-step (m/new-vector :vectorz param-count)})


New version of the Pong 3D

New version of the Pong 3D


add type hints

add type hints

--- pigpen-avro/src/main/clojure/pigpen/avro/core.clj
+++ pigpen-avro/src/main/clojure/pigpen/avro/core.clj
@@ -63,9 +63,10 @@
 (defmethod pigpen.pig/native->clojure GenericData$Array [value]
   (vec (map pigpen.pig/native->clojure value)))

-(defmethod pigpen.pig/native->clojure GenericData$Record [value]
-  (let [fields (->> value .getSchema .getFields (map #(.name %)))]
-    (zipmap (map keyword fields) (map #(pigpen.pig/native->clojure (.get value %)) fields))))
+(defmethod pigpen.pig/native->clojure GenericData$Record [^GenericData$Record value]
+  (let [fields (->> value .getSchema .getFields (map (fn [^Schema$Field fd] (.name fd))))]
+    (zipmap (map keyword fields) (map #(pigpen.pig/native->clojure
+                                        (.get value ^{:tag String} %)) fields))))

 (defn dotted-keys->nested-map [kvs]
   (->> kvs


Refactor of pager

Refactor of pager

--- src-cljs/arcis/pages/pager.cljs
+++ src-cljs/arcis/pages/pager.cljs
@@ -1,6 +1,6 @@
 ;;      Filename: pager.cljs
 ;; Creation Date: Friday, 25 September 2015 07:06 PM AEST
-;; Last Modified: Monday, 05 October 2015 05:08 PM AEDT
+;; Last Modified: Monday, 05 October 2015 08:34 PM AEDT
 ;;        Author: Tim Cross <theophilusx AT gmail.com>
 ;;   Description:
 ;;
@@ -11,25 +11,33 @@
             [arcis.utils :as u]
             [goog.string :as gstring]))

-(defn page-size []
-  (state/value-in [(state/this-page) :pager :page-size]))
+(defn set-page-count! [cnt]
+  (state/set-value-in! [(state/this-page) :pager :page-count] cnt))

-(defn set-page-size! [size]
-  (state/set-value-in! [(state/this-page) :pager :page-size] size))
-
-(defn get-active []
-  (or (state/value-in [(state/this-page) :pager :current])
-      1))
+(defn get-page-count []
+  (state/value-in [(state/this-page) :pager :page-count]))

 (defn set-active! [i]
   (state/set-value-in! [(state/this-page) :pager :current] i))

-(defn get-page []
-  (or (state/value-in [(state/this-page) :pager :page])
-      1))
+(defn get-active []
+  (let [idx (state/value-in [(state/this-page) :pager :current])]
+    (if-not idx
+      (do
+        (set-active! 1)
+        1)
+      idx)))

 (defn set-page! [p]
   (state/set-value-in! [(state/this-page) :pager :page] p))
+
+(defn get-page []
+  (let [pg (or (state/value-in [(state/this-page) :pager :page]) 1)]
+    (if (> pg (get-page-count))
+      (do
+        (set-page! 1)
+        1)
+      pg)))

 (defn is-active? [p]
   (= p (get-active)))
@@ -82,6 +90,7 @@

 (defn header [page-index]
   (.log js/console (str "header: page-index: " page-index))
+  (set-page-count! (count (keys page-index)))
   [:nav
    (conj (into [:ul.pagination [previous-page page-index]]
                (for [i (current-page-list page-index)]


Added tests for new pages.

Added tests for new pages.

--- search-app/test/cmr/search/test/site/routes.clj
+++ search-app/test/cmr/search/test/site/routes.clj
@@ -25,6 +25,21 @@
       (testing "returns the welcome page HTML"
         (is (substring? "The CMR Search API" (:body response)))))))

+(deftest landing-links-page
+  (testing "landing links page returns content"
+    (let [path "/site/collections/landing-pages"
+          response (site (request :get (str "https://cmr.example.com/search" path)))]
+      (is (= (:status response) 200))
+      (is (substring? "Collections Landing Pages" (:body response)))
+      (is (substring? "Landing Pages for EOSDIS Collections" (:body response))))))
+
+(deftest eosdis-landing-links-page
+  (testing "eosdis collections landing links page returns content"
+    (let [path "/site/collections/eosdis-landing-pages"
+          response (site (request :get (str "https://cmr.example.com/search" path)))]
+      (is (= (:status response) 200))
+      (is (substring? "Landing Pages for EOSDIS Collections" (:body response))))))
+
 (deftest test-404
   (testing "a 404 is returned for a missing document"
     (is (= 404


nothing important, more review on ref

nothing important, more review on ref

--- src/Miscellaneous/role_play.clj
+++ src/Miscellaneous/role_play.clj
@@ -5,7 +5,6 @@
   (vec (for [_ (range n)
              expr exprs]
          `(future ~expr))))
-

 (defmacro wait-futures
   [& args]
@@ -21,7 +20,7 @@

 (def bilbo (character "Bilbo" :health 100 :strength 100))

-(def gandalf (character "Gandalf" :health 75 :mana 750))
+(def gandalf (character "Gandalf" :health 75 :mana 7500))

 (defn loot
   [from to]
@@ -42,3 +41,85 @@
 (map (comp count :items deref) [bilbo gandalf])

 (filter (:items @gandalf) (:items @bilbo))
+
+(defn attack
+  [aggressor target]
+  (dosync
+   (let [damage (* (rand 0.1) (:strength @aggressor))]
+     (commute target update-in [:health] #(max 0 (- % damage)))
+     )))
+
+(defn heal
+  [healer target]
+  (dosync
+   (let [aid (* (rand 0.1) (:mana @healer))]
+     (when (pos? aid)
+       (commute healer update-in [:mana] - (max 5 (/ aid 5)))
+       (commute target update-in [:health] + aid)))))
+
+(def alive? (comp pos? :health))
+
+(defn play
+  [character action other]
+  (while (and (alive? @character)
+              (alive? @other)
+              (action character other))
+    (Thread/sleep (rand-int 50))))
+
+(wait-futures 1
+              (play bilbo attack smaug)
+              (play smaug attack bilbo))
+
+(dosync
+ (alter smaug assoc :health 500)
+ (alter bilbo assoc :health 100))
+
+(wait-futures 1
+              (play bilbo attack smaug)
+              (play smaug attack bilbo)
+              (play gandalf heal bilbo))
+
+@bilbo
+
+(map (comp #(select-keys % [:name :health :mana]) deref) [smaug bilbo gandalf])
+
+
+(defn- enforce-max-health
+  [{:keys [name health]}]
+  (fn [character-data]
+    (or (<= (:health character-data) health)
+        (throw (IllegalStateException. (str name " is already at max health!"))))))
+
+(defn character
+  [name & {:as opts}]
+  (let [cdata (merge {:name name :items #{} :health 500} opts)
+        cdata (assoc cdata :max-health (:health cdata))
+        validators (list* (enforce-max-health {:name name :health (:health cdata)})
+                          (:validators cdata))]
+    (ref (dissoc cdata :validators)
+         :validator #(every? (fn [v] (v %)) validators))))
+
+(def bilbo (character "Bilbo" :health 100 :strength 100))
+
+@bilbo
+
+(heal gandalf bilbo)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


elmish-subapps: rf view-model

elmish-subapps: rf view-model

--- examples/elmish-subapps/src/app/core.cljs
+++ examples/elmish-subapps/src/app/core.cljs
@@ -41,9 +41,9 @@
          (update model :counter-visible? not)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defn view-model
-  [model]
-  (carry/track-keys model [:friend-list-visible? :counter-visible?]))
+(def view-model (-> (fn [model] (carry/track-keys model [:friend-list-visible? :counter-visible?]))
+                    (subapps/include-view-model :friend-list-subapp friend-list/view-model)
+                    (subapps/include-view-model :counter-subapp counter/view-model)))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 (defn view
@@ -88,9 +88,6 @@
         app-spec (-> (new-spec history friend-list-api/search)
                      logging/add)
         app (carry/app app-spec)
-        view-model (-> view-model
-                       (subapps/include-view-model :friend-list-subapp friend-list/view-model)
-                       (subapps/include-view-model :counter-subapp counter/view-model))
         [app-view-model app-view] (carry/connect-ui app view-model view)]
     ((:dispatch-signal app) :on-start)


added example for minprofiler

added example for minprofiler

--- resources/leiningen/new/closp/clj/routes/user.clj
+++ resources/leiningen/new/closp/clj/routes/user.clj
@@ -35,8 +35,9 @@
   (not (vali/errors? :id :pass :confirm)))

 (defn admin-page [params]
-  (layout/render "user/admin.html" (merge {:users (db/get-all-users (get params :filter)) :roles available-roles}
-                                          params)))
+  (let [users (cjmp/trace "all users" (db/get-all-users (get params :filter)))]
+    (layout/render "user/admin.html" (merge {:users users :roles available-roles}
+                                            params))))

 (defn login-page [& [content]]
   (layout/render "user/login.html" content))


Add assets folder to the frontend-options

--- resources/leiningen/new/lambone/common/build.boot
+++ resources/leiningen/new/lambone/common/build.boot
@@ -158,6 +158,7 @@

 (def frontend-options
   {:env {:source-paths #{"src/frontend" "src/common"}
+         :asset-paths #{"assets"}
          :dependencies frontend-deps}
    :reload {:on-jsload '<<project-ns>>.app/init}
    :cljs-repl {:nrepl-opts {:port 5088}}


set :persistent true to enable reliable persistent messaging for worker tickets

--- src/lcmap/clownfish/ticket.clj
+++ src/lcmap/clownfish/ticket.clj
@@ -21,7 +21,7 @@
         payload (json/encode ticket)]
     (log/debugf "publish '%s' ticket: %s" routing payload)
     (lb/publish amqp-channel exchange routing payload
-                {:content-type "application/json"}))
+                {:content-type "application/json" :persistent true}))
   ticket)

 (defn create


Add better docstrings to postal functions and protocols.

--- src/clojure/catacumba/handlers/postal.clj
+++ src/clojure/catacumba/handlers/postal.clj
@@ -95,9 +95,23 @@
   (http/ok frame {:headers {:content-type content-type}}))

 (defprotocol IExceptionAdapter
+  "A protocol that defines the behavior of adapting
+  a possible exception that can happens in the body
+  of postal handler to a valid postal frame.
+
+  It comes with default implementation for:
+  `clojure.lang.ExceptionInfo` and generic
+  `java.lang.Throwable`."
   (-adapt-exception [_] "Adapt an exception into proper return message."))

 (defprotocol IHandlerResponseMessage
+  "A protocol that defines the behavior of how
+  the return value of postal frame can be transformed
+  into valid frame instance.
+
+  It comes with default implementation for:
+  `clojure.lang.PersistentMap`, `java.util.concurrent.CompletableFuture`
+  and `manifold.deferred.IDeferred`."
   (-handle-response-message [_ context]))

 (extend-protocol IExceptionAdapter
@@ -161,15 +175,34 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn frame
-  "A convenience helper for easy
-  create postal response messages."
+  "A convenience helper that allow easy create a frame compatible
+  hash-map instance.
+
+  ```
+  (frame {:num 1})
+  ;; => {:type :response :data {:num 1}}
+
+  (frame :error {:num 1})
+  ;; => {:type :error :data {:num 1}}
+  ```"
   ([data]
    {:type :response :data data})
   ([type data]
    {:type type :data data}))

 (defn router
-  "A postal message router chain handler."
+  "Given a postal handler function returns a catacumba compatible
+  handler that can be attached to the main catacumba routes:
+
+  ```
+  (require '[catacumba.core :as ct])
+  (require '[catacumba.handlers.postal :as pc])
+
+  (defmulti -handler
+    (comp (juxt :type :dest) second vector))
+
+  (def app (ct/routes [[:post \"api\" (pc/router -handler)]]))
+  ```"
   ([handler]
    (router handler {}))
   ([handler options]


mark java stack-traces for better client-side presentation

--- sidecar/src/figwheel_sidecar/repl/driver.clj
+++ sidecar/src/figwheel_sidecar/repl/driver.clj
@@ -22,6 +22,8 @@

 (defn make-driver [extra-settings]
   (merge (get-initial-settings) extra-settings))
+
+; -- getters/setters --------------------------------------------------------------------------------------------------------

 (defn set-sniffer! [driver sniffer-key sniffer]
   (vreset! (get-in driver [:sniffers sniffer-key]) sniffer))
@@ -244,7 +246,15 @@
             (stop-recording! driver)
             (orig-call)
             (start-recording! driver))
-          (orig-call))))))                                                                                ; TODO: in case of long clojure stacktraces we can do more user-friendly job
+          (do
+            ; we've got a java exception with a possibly long stack trace
+            ; it will be printed in cljs.repl/repl-caught via (.printStackTrace e *err*)
+            ; we capture output and send it to client side with special kind :java-trace
+            ; with this hint, client-side should implement a nice way how to present this to the user
+            (suppress-flushing driver :stderr)
+            (orig-call)
+            (unsuppress-flushing driver :stderr)
+            (flush-sniffer! driver :stderr :java-trace)))))))

 ; -- sniffer handlers -------------------------------------------------------------------------------------------------------


scendere is essere

scendere is essere

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -1791,6 +1791,7 @@
                          :sem {:pred :get-off}}
                 :italiano {:passato "sceso"}}
                {:synsem {:cat :verb
+                         :essere true
                          :sem {:pred :go-downstairs}}
                 :italiano {:passato "sceso"}}]


looking for stack overflow

looking for stack overflow

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -144,11 +144,11 @@
                    :sem {:subj subject-semantics}}}))

       ;; commenting out: getting stack overflow.
-;      (default ;;  a verb's second argument is the semantic object of the verb.
-;       (let [object-semantics (atom :top)]
-;         {:synsem {:cat :verb
-;                   :subcat {:2 {:sem object-semantics}}
-;                   :sem {:obj object-semantics}}}))
+      (default ;;  a verb's second argument is the semantic object of the verb.
+       (let [object-semantics (atom :top)]
+         {:synsem {:cat :verb
+                   :subcat {:2 {:sem object-semantics}}
+                   :sem {:obj object-semantics}}}))

       (default ;; a verb agrees with its first argument
        (let [subject-agreement (atom :top)]


throw exception if lexicon's values are not maps

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -63,6 +63,8 @@
                                  evaluated
                                  true [evaluated])]
                   (map (fn [v]
+                         (if (not (map? v))
+                           (throw (Exception. (str "Lexeme: " v " is not a map."))))
                          (reduce unify
                                  (cons
                                   (dissoc v :unify)


use overlay-path instead of doc-path

use overlay-path instead of doc-path

--- src-cljs/frontend/components/doc_viewer.cljs
+++ src-cljs/frontend/components/doc_viewer.cljs
@@ -52,7 +52,7 @@

             (for [doc bucket-docs]
               (html
-                [:a.recent-doc.make {:href (str (urls/doc-path doc) "/doc-viewer")
+                [:a.recent-doc.make {:href (str (urls/overlay-path doc "doc-viewer"))
                                      :on-touch-end #(do
                                                       (.preventDefault %)
                                                       (put! (om/get-shared owner [:comms :nav]) [:navigate! {:path (str (urls/doc-path doc))}]))}


pretty much working

pretty much working

--- src/bracketolojy/tournament.clj
+++ src/bracketolojy/tournament.clj
@@ -45,7 +45,7 @@
 (defmethod compute-matchup :default [_ _ matchup]
   matchup)
 (defmethod compute-matchup :branch [pick-scoring upset-scoring [[upper-field] [lower-field] :as fields]]
-  (let [round (log2 (count upper-field))
+  (let [round (log2 (reduce + (map count fields)))
         pick-pts (get pick-scoring round)
         upset-pts (get upset-scoring round)]
     (->>
@@ -109,13 +109,9 @@

 (println
   (compute-tournament
-    [0 1 2 3 4 5]
-    [0 1 2 3 4 5]
+    [0 1 2 4 8 12 16]
+    [0 1 2 3 4 5 6]
     (to-tournament-bracket
       bracket
       (to-tournament-teams (data/get-kenpom-teams-bundled)))))

-;(println (to-tournament-bracket
-;          bracket
-;          (to-tournament-teams (data/get-kenpom-teams-bundled))))
-


Change all schema/String references to String

--- src/cfpb/qu/data/definition.clj
+++ src/cfpb/qu/data/definition.clj
@@ -7,15 +7,15 @@
             [cheshire.core :as json]
             [cheshire.factory :as factory]))

-(def InfoS {(s/required-key :name) s/String
-            (s/optional-key :description) s/String
-            (s/optional-key :url) s/String
+(def InfoS {(s/required-key :name) String
+            (s/optional-key :description) String
+            (s/optional-key :url) String
             s/Keyword s/Any
             })

 (def TypeS (s/enum "string" "integer" "date" "dollars" "number"))

-(def IndexS (s/either s/String [s/String]))
+(def IndexS (s/either String [String]))

 (defn ref-col-count-eq?
   "Make sure that if you have multiple columns in a reference that you
@@ -26,47 +26,47 @@
     (not (coll? (:id ref)))))

 (def ReferenceS (s/both (s/pred ref-col-count-eq?)
-                        {(s/required-key :column) (s/either s/String [s/String])
-                         (s/required-key :concept) s/String
-                         (s/optional-key :id) (s/either s/String [s/String])
-                         (s/required-key :value) s/String
+                        {(s/required-key :column) (s/either String [String])
+                         (s/required-key :concept) String
+                         (s/optional-key :id) (s/either String [String])
+                         (s/required-key :value) String
                          }))

-(def TableSliceS {(s/optional-key :info) {s/Keyword s/String}
+(def TableSliceS {(s/optional-key :info) {s/Keyword String}
                   (s/required-key :type) (s/eq "table")
-                  (s/required-key :table) s/String
-                  (s/required-key :dimensions) [s/String]
-                  (s/required-key :metrics) [s/String]
+                  (s/required-key :table) String
+                  (s/required-key :dimensions) [String]
+                  (s/required-key :metrics) [String]
                   (s/optional-key :indexes) [IndexS]
                   (s/optional-key :references) {s/Keyword ReferenceS}
                   })

-(def DerivedSliceS {(s/optional-key :info) {s/Keyword s/String}
+(def DerivedSliceS {(s/optional-key :info) {s/Keyword String}
                     (s/required-key :type) (s/eq "derived")
-                    (s/required-key :slice) s/String
-                    (s/required-key :dimensions) [s/String]
-                    (s/required-key :metrics) [s/String] ;; TODO remove metrics from here
+                    (s/required-key :slice) String
+                    (s/required-key :dimensions) [String]
+                    (s/required-key :metrics) [String] ;; TODO remove metrics from here
                     (s/optional-key :indexes) [IndexS]
-                    (s/required-key :aggregations) {s/Keyword [s/String]}
+                    (s/required-key :aggregations) {s/Keyword [String]}
                     })

 (def SliceS (s/either TableSliceS DerivedSliceS))

-(def SimpleConceptS {(s/optional-key :description) s/String
+(def SimpleConceptS {(s/optional-key :description) String
                      (s/optional-key :type) TypeS})
 (def TableConceptS (merge SimpleConceptS
-                          {(s/required-key :table) s/String
+                          {(s/required-key :table) String
                            (s/required-key :properties) {s/Keyword
                                                          {(s/required-key :type) TypeS
-                                                          s/Keyword s/String}}}))
+                                                          s/Keyword String}}}))
 (def ConceptS (s/either SimpleConceptS TableConceptS))

-(def ColumnS {(s/optional-key :name) s/String
+(def ColumnS {(s/optional-key :name) String
               (s/optional-key :skip) boolean
               (s/optional-key :type) TypeS
-              (s/optional-key :format) s/String})
+              (s/optional-key :format) String})

-(def TableS {:sources [s/String]
+(def TableS {:sources [String]
              :columns {s/Keyword ColumnS}})

 (def DataDefinitionS {(s/required-key :info) InfoS


Add missing parenthesis in civs.logic.demographics

--- src/civs/logic/demographics.clj
+++ src/civs/logic/demographics.clj
@@ -199,7 +199,7 @@
   (memoize (fn [world pos activity] (*
     (base-prosperity-per-activity-in-biome (biome-at world pos) activity)
     (prosperity-temperature-multiplier-at world pos)
-    (prosperity-humidity-multiplier-at world pos))))
+    (prosperity-humidity-multiplier-at world pos)))))

 (defn crowding-per-activity [group activity]
   (let [ actives (-> group .population active-persons)


remove unecessary nohup

remove unecessary nohup

--- src/clj/backtype/storm/util.clj
+++ src/clj/backtype/storm/util.clj
@@ -335,7 +335,7 @@
 (defnk launch-process [command :environment {}]
   (let [command (->> (seq (.split command " "))
                      (filter (complement empty?)))
-        builder (ProcessBuilder. (cons "nohup" command))
+        builder (ProcessBuilder. command)
         process-env (.environment builder)]
     (doseq [[k v] environment]
       (.put process-env k v))


login status api endpoint

login status api endpoint

--- src/clj/foosball/routes/api.clj
+++ src/clj/foosball/routes/api.clj
@@ -8,6 +8,7 @@
             [foosball.statistics.team-player :as team-player]
             [foosball.util :as util]
             [foosball.software :as sw]
+            [foosball.auth :as auth]
             [clojure.data.json :as json]))

 (extend java.util.UUID
@@ -60,6 +61,25 @@
                (let [matches (d/get-matches db)]
                  (team-player/calculate-team-stats matches))))

+(defresource login-status []
+  :available-media-types media-types
+  :handle-ok (fn [_]
+               (let [a    (auth/current-auth)
+                     name (str (:firstname a) " " (:lastname a))
+                     existy? (fn [x] (not (nil? x)))]
+                 (merge
+                  {:logged-in (existy? a)}
+                  (when a
+                    {:user?       (existy? (auth/user?))
+                     :admin?      (existy? (auth/admin?))
+                     :name        name
+
+                     :logout-form (auth/logout-form :extra-class "navbar-form"
+                                                    :text (str "Logout")
+                                                    :title name)})
+                  (when-not a
+                    {:login-form  (auth/login-form :form-class "navbar-form")})))))
+
 (defresource about-software [project]
   :available-media-types media-types
   :handle-ok (fn [_]
@@ -78,4 +98,5 @@
      (GET "/api/ratings/log/:playerid" [playerid] (player-log db (util/uuid-from-string playerid)))
      (GET "/api/ratings/player-stats" [] (player-stats db))
      (GET "/api/ratings/team-stats" [] (team-stats db))
+     (GET "/api/login/status" [] (login-status))
      (GET "/api/about/software" [] (about-software project)))))


Incorporate update to thrift api date handling, allowing use of nullable date field

--- src/clj/forma/source/static.clj
+++ src/clj/forma/source/static.clj
@@ -115,12 +115,12 @@
                                "?val"
                                nodata)]
     (<- [?tile-chunk]
-        (src ?dataset ?s-res ?t-res _ ?h ?v  _ ?id ?window)
+        (src ?dataset ?s-res ?t-res !date ?h ?v  _ ?id ?window)
         (p/flatten-window ?window :> ?data)
         (count ?data :> ?count)
         (= ?count chunk-size)
         (thrift/ModisChunkLocation* ?s-res ?h ?v ?id chunk-size :> ?tile-loc)
-        (thrift/DataChunk* ?dataset ?tile-loc ?data ?t-res :> ?tile-chunk))))
+        (thrift/DataChunk* ?dataset ?tile-loc ?data ?t-res :date !date :> ?tile-chunk))))

 (defn static-chunks
   "TODO: DOCS!"


make Doppelganger and Dorm Computer ask for runnable servers

--- src/clj/game/cards-hardware.clj
+++ src/clj/game/cards-hardware.clj
@@ -217,7 +217,7 @@
               {:req (req (:dopp-active card))
                :prompt "Use Doppelgänger to run again?" :player :runner
                :yes-ability {:prompt "Choose a server"
-                             :choices (req servers)
+                             :choices (req runnable-servers)
                              :msg (msg "make a run on " target)
                              :effect (effect (update! (dissoc card :dopp-active)) (run target))}}}}}

@@ -225,7 +225,7 @@
    {:data {:counter 4}
     :abilities [{:counter-cost 1 :cost [:click 1]
                  :req (req (not run))
-                 :prompt "Choose a server" :choices (req servers)
+                 :prompt "Choose a server" :choices (req runnable-servers)
                  :msg "make a run and avoid all tags for the remainder of the run"
                  :effect (effect (update! (assoc card :dorm-active true))
                                  (run target))}]
@@ -509,7 +509,7 @@
    {:in-play [:memory 1]
     :recurring 2
     :events {:successful-trace {:req (req run) :effect (effect (damage :brain 1 {:card card}))}}}
-
+
    "Sports Hopper"
    {:in-play [:link 1]
     :abilities [{:label "Draw 3 cards"


Fix http-kit.

Fix http-kit.

--- src/clj/geschichte/platform.clj
+++ src/clj/geschichte/platform.clj
@@ -126,7 +126,7 @@
                                (if (= (:topic m) :binary-fetched)
                                  (send! channel ^bytes (let [out (ByteArrayOutputStream.)]
                                                          (.write out (byte 0))
-                                                         (.write out (:value m))
+                                                         (io/copy (:value m) out)
                                                          (.toByteArray out)))
                                  (send! channel (str " " (pr-str m)))))
                              (debug "dropping msg because of closed channel: " url (pr-str m)))


Fix bug in creation of date

Fix bug in creation of date

--- src/clj_applenewsapi/crypto.clj
+++ src/clj_applenewsapi/crypto.clj
@@ -5,7 +5,7 @@
             [clj-time.core :as t]))

 (defn now []
-  (tf/unparse (tf/formatter  "Y-m-d'T'H:m:s'Z'") (t/now)))
+  (tf/unparse (tf/formatter  "YYYY-MM-dd'T'HH:mm:ss'Z'") (t/now)))

 (defn canonical [method url t]
   (str method url t))


Don't try to activate history (it's broken!)

--- src/cljs/comic_reader/main.cljs
+++ src/cljs/comic_reader/main.cljs
@@ -68,4 +68,3 @@
                                (.-body js/document)))))

 (init!)
-(hook-browser-navigation!)


Fix codestyle on hash ns.

Fix codestyle on hash ns.

--- src/clojure/buddy/core/hash.clj
+++ src/clojure/buddy/core/hash.clj
@@ -31,19 +31,20 @@

 (def ^{:doc "Available digests."
        :dynamic true}
-  *available-digests* {:sha256   #(SHA256Digest.)
-                       :sha384   #(SHA384Digest.)
-                       :sha512   #(SHA512Digest.)
-                       :sha1     #(SHA1Digest.)
-                       :tiger    #(TigerDigest.)
-                       :md5      #(MD5Digest.)
-                       :sha3-256 #(SHA3Digest. 256)
-                       :sha3-384 #(SHA3Digest. 284)
-                       :sha3-512 #(SHA3Digest. 512)})
+  *available-digests*
+  {:sha256   #(SHA256Digest.)
+   :sha384   #(SHA384Digest.)
+   :sha512   #(SHA512Digest.)
+   :sha1     #(SHA1Digest.)
+   :tiger    #(TigerDigest.)
+   :md5      #(MD5Digest.)
+   :sha3-256 #(SHA3Digest. 256)
+   :sha3-384 #(SHA3Digest. 284)
+   :sha3-512 #(SHA3Digest. 512)})

-(defn resolve-digest
+(defn- resolve-digest
   "Helper function for make Digest instances
-from algorithm parameter."
+  from algorithm parameter."
   [alg]
   (cond
    (instance? Keyword alg) (let [factory (*available-digests* alg)]


Include NAGs in PGN/ECN output.

Include NAGs in PGN/ECN output.

--- src/clojure/clj_chess/game.cljc
+++ src/clojure/clj_chess/game.cljc
@@ -708,6 +708,10 @@
                                           (or (not include-variations?)
                                               (empty? (rest children))))
                              " ")))
+                    ;; NAG
+                    (when include-comments?
+                      (when-let [nag (:nag (first children))]
+                        (str "$" nag " ")))
                     ;; Comment for first child move:
                     (when include-comments?
                       (when-let [c (:comment (first children))]
@@ -757,6 +761,10 @@
                         ; String representation of first child move (main variation):
                         ~(-> (first children) :board board/last-move
                              board/move-to-uci)
+                        ; NAG
+                        ~(when include-comments?
+                           (when-let [nag (:nag (first children))]
+                             [:nag nag]))
                         ; Comment for first child move:
                         ~(when include-comments?
                            (when-let [c (:comment (first children))]


Microcosmetics

Microcosmetics

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

--- src/conexp/fca/implications.clj
+++ src/conexp/fca/implications.clj
@@ -285,8 +285,7 @@
   (loop [stem-base    #{},
          implications (pmap #(make-implication (premise %)
                                                (close-under-implications implications
-                                                                         (union (premise %)
-                                                                                (conclusion %))))
+                                                                         (into (premise %) (conclusion %))))
                             implications),
          all          (vec implications)]
     (if (empty? implications)


into-atom funciton

into-atom funciton

--- browser/cljs/settings.cljs
+++ browser/cljs/settings.cljs
@@ -3,21 +3,6 @@
           [mediakeys.browser.rx :only [from-async multi-sub]])
     (:require [rx-cljs.observable :as rx]))

-
-; (def print #(.log js/console %))
-; (subscribe modifiers print)
-
-;TODO! how to set what u need to set
-; when a modifier comes in, check to see if u should set something
-; if so, check to see if the text is ONLY MODIFIERS OR NOTHING if it is,
-; then u can append the modifier to the string and pop it back into settings
-;
-; when a "character" (not actually characters, necesarily) comes in
-; check to see if there's one or more modifiers as the text. if YES
-; append this character, send shit 2 the server, (also want a socket interface to make
-; setting accurate anyhow), then reset changing and any other UI stuff to nil
-
-; both of those^ scenarios are if changing has been set by change-setting!

 (def changing (atom nil))
@@ -36,11 +21,26 @@
                 (when (not (nil? callback))
                     (callback which new-text))))))

-(def mods (from-async modifiers))
+; (def print #(.log js/console %))
+; (subscribe modifiers print)

-(def mods1 (multi-sub mods #(.log js/console %)))
+;TODO! how to set what u need to set
+; when a modifier comes in, check to see if u should set something
+; if so, check to see if the text is ONLY MODIFIERS OR NOTHING if it is,
+; then u can append the modifier to the string and pop it back into settings
+;
+; when a "character" (not actually characters, necesarily) comes in
+; check to see if there's one or more modifiers as the text. if YES
+; append this character, send shit 2 the server, (also want a socket interface to make
+; setting accurate anyhow), then reset changing and any other UI stuff to nil

-(rx/subscribe (rx/map mods1 #(str % " yoyoyo")) #(.log js/console %) )
+; both of those^ scenarios are if changing has been set by change-setting!
+
+(-> modifiers
+    from-async
+    (multi-sub #(.log js/console %))
+    (rx/map #(str % "!!!!!!!"))
+    (rx/subscribe #(.log js/console %)))
 ; (subscribe modifiers (with-append))

 (subscribe characters
@@ -49,10 +49,4 @@
             (reset! changing nil))))

 (defn change-setting! [settings button]
-    (let [action (keyword button)]
-        (.log js/console button)
-        (swap! settings assoc action "enter a new key combination")
-        (reset! changing {
-                :settings settings
-                :which action
-            })))
+    (let [action (keyword button)]))


Drawing build timing start lines.

Drawing build timing start lines.

--- src-cljs/frontend/components/build_timings.cljs
+++ src-cljs/frontend/components/build_timings.cljs
@@ -4,6 +4,8 @@
   (:require-macros [frontend.utils :refer [html]]))

 (def timings-width 800)
+(def bar-height 20)
+(def bar-gap 10)

 (defn create-x-scale [start-time stop-time]
   (let [start-time (js/Date. start-time)
@@ -18,20 +20,35 @@
       (.attr "width" timings-width)))

 (defn draw-containers! [x-scale step]
-  (let [bar-height 10
-        step-length    #(- (x-scale (js/Date. (aget % "end_time")))
-                           (x-scale (js/Date. (aget % "start_time"))))
-        container-pos  #(* (+ 2 bar-height) (inc (aget % "index")))
-        step-start-pos #(x-scale (js/Date. (aget % "start_time")))]
+  (let [step-length      #(- (x-scale (js/Date. (aget % "end_time")))
+                             (x-scale (js/Date. (aget % "start_time"))))
+        container-pos    #(* bar-height (inc (aget % "index")))
+        container-height #(- bar-height bar-gap)
+        step-start-pos   #(x-scale (js/Date. (aget % "start_time")))]
     (-> step
         (.selectAll "rect")
           (.data #(aget % "actions"))
         (.enter)
           (.append "rect")
+          (.attr "fill" "green")
           (.attr "width" step-length)
-          (.attr "height" bar-height)
+          (.attr "height" container-height)
           (.attr "y" container-pos)
           (.attr "x" step-start-pos))))
+
+(defn draw-step-start-line! [x-scale step]
+  (-> step
+      (.selectAll "line")
+        (.data #(aget % "actions"))
+      (.enter)
+        (.append "line")
+        (.attr "x1" #(x-scale (js/Date. (aget % "start_time"))))
+        (.attr "x2" #(x-scale (js/Date. (aget % "start_time"))))
+        (.attr "y1" #(* bar-height (inc (aget % "index"))))
+        (.attr "y2" #(+ (* bar-height (inc (aget % "index")))
+                        (- bar-height bar-gap)))
+        (.attr "stroke" "black")
+        (.attr "stroke-width" 1)))

 (defn draw-steps! [x-scale chart steps]
   (let [step (-> chart
@@ -39,6 +56,7 @@
                    (.data (clj->js steps))
                  (.enter)
                    (.append "g"))]
+    (draw-step-start-line! x-scale step)
     (draw-containers! x-scale step)))

 (defn draw-chart! [{:keys [parallel steps start_time stop_time] :as build}]


Adding the duration to each steps hover text.

--- src-cljs/frontend/components/build_timings.cljs
+++ src-cljs/frontend/components/build_timings.cljs
@@ -75,10 +75,10 @@
   (-> (.axis js/d3.svg)
         (.tickValues (clj->js (range 0 (inc build-duration) (/ build-duration 4))))
         (.scale axis-scale)
-        (.tickFormat #(str (datetime/as-duration %) "m"))
+        (.tickFormat #(datetime/as-duration %))
         (.orient "top"))))

-(defn build-duration [start-time stop-time]
+(defn duration [start-time stop-time]
   (- (.getTime (js/Date. stop-time))
      (.getTime (js/Date. start-time))))

@@ -131,7 +131,8 @@
 (defn draw-containers! [x-scale step]
   (let [step-length         #(- (scaled-time x-scale % "end_time")
                                 (scaled-time x-scale % "start_time"))
-        step-start-pos      #(x-scale (js/Date. (aget % "start_time")))]
+        step-start-pos      #(x-scale (js/Date. (aget % "start_time")))
+        step-duration       #(datetime/as-duration (duration (aget % "start_time") (aget % "end_time")))]
     (-> step
         (.selectAll "rect")
           (.data #(aget % "actions"))
@@ -147,7 +148,7 @@
                                          (highlight-selected-container! %)))
             (.on   "mouseout"  #(reset-selected! step))
           (.append "title")
-            (.text #(gstring/format "%s (%s)" (aget % "name") (aget % "index"))))))
+            (.text #(gstring/format "%s (%s) - %s" (aget % "name") (aget % "index") (step-duration %))))))

 (defn draw-step-start-line! [x-scale step]
   (let [step-start-position #(scaled-time x-scale % "start_time")]
@@ -195,7 +196,7 @@
 (defn draw-chart! [{:keys [parallel steps start_time stop_time] :as build}]
   (let [x-scale (create-x-scale start_time stop_time)
         chart   (create-root-svg parallel)
-        x-axis  (create-x-axis (build-duration start_time stop_time))
+        x-axis  (create-x-axis (duration start_time stop_time))
         y-axis  (create-y-axis parallel)]
     (draw-axis!  chart x-axis "x-axis")
     (draw-axis!  chart y-axis "y-axis")


Eng. Support => Support

Eng. Support => Support

--- src-cljs/frontend/components/pieces/topbar.cljs
+++ src-cljs/frontend/components/pieces/topbar.cljs
@@ -67,7 +67,7 @@
            "Discuss"]]
          [:li.top-nav-dropdown.header-nav-item
           [:a.header-nav-link support-info
-           "Eng. Support"]]
+           "Support"]]
          [:li.header-nav-item.divider-vertical]
          [:li.top-nav-dropdown.header-nav-item.dropdown
           [:a.header-nav-link.dropdown-toggle.dropbtn


Segment service messenger-buffer-count by task-name

--- src/onyx/monitoring/events.clj
+++ src/onyx/monitoring/events.clj
@@ -286,7 +286,7 @@
                              (let [timeout-ch (timeout 1000)
                                    v (<!! timeout-ch)]
                                (run! (fn [[[peer-id task-name] cnt]]
-                                       (>!! ch {:service "task.messenger-buffer count"
+                                       (>!! ch {:service (str (format "%s task-messenger-buffer-count" task-name))
                                                 :value cnt
                                                 :tags ["monitoring-config" (str task-name) (str peer-id)]
                                                 :state "ok"}))


Add table header

Add table header

--- src/braid/users/client/views/users_page.cljs
+++ src/braid/users/client/views/users_page.cljs
@@ -21,6 +21,9 @@

         :else
         [:table.users
+         [:thead
+          [:tr
+           [:th "Nickname"]]]
          [:tbody
           (doall
            (for [user users]


Call begin/end on SpriteBatch directly again

--- src/play_clj/core_graphics.clj
+++ src/play_clj/core_graphics.clj
@@ -167,18 +167,6 @@
   [{:keys [^Stage renderer]}]
   (.getSpriteBatch renderer))

-(defmulti batch-begin! type)
-
-(defmethod batch-begin! SpriteBatch
-  [^SpriteBatch batch]
-  (.begin batch))
-
-(defmulti batch-end! type)
-
-(defmethod batch-end! SpriteBatch
-  [^SpriteBatch batch]
-  (.end batch))
-
 ; rendering

 (defmulti draw-entity! #(-> % second :type))
@@ -206,10 +194,10 @@
 (defn draw! [{:keys [renderer] :as screen} entities]
   (assert renderer)
   (let [^SpriteBatch batch (batch screen)]
-    (batch-begin! batch)
+    (.begin batch)
     (doseq [entity entities]
       (draw-entity! [batch entity]))
-    (batch-end! batch))
+    (.end batch))
   entities)

 (defn ^:private render-map!


a comment in shreds.clj

a comment in shreds.clj

--- src/launchpad/shreds.clj
+++ src/launchpad/shreds.clj
@@ -18,4 +18,7 @@
      (light lp 0 row col)
      (dotimes [n 7]
        (wait ms)
-       (light lp (+ n 1) row col)))))+       (light lp (+ n 1) row col)))))
+
+;; this is a work in progress, a scratch pad while I figure out the most
+;; chuck-y and clojure-y pattern to use for working with time


added doc strings

added doc strings

--- src/structural_typing/type.clj
+++ src/structural_typing/type.clj
@@ -1,38 +1,55 @@
 (ns structural-typing.type
-  ""
+  "Structural types, loosely inspired by Elm's way of looking at [records](http://elm-lang.org/learn/Records.elm)."
   (:refer-clojure :exclude [instance?])
   (:require [clojure.string :as str]
             [bouncer.core :as b]
             [bouncer.validators :as v]
             [such.immigration :as immigrate]))

-(immigrate/selection 'bouncer.validators '[required])
-
 ;;; About our type

 (defn- default-formatter [error-map checked-map]
   (flatten (vals error-map)))

-(defn- default-failure-handler [msgs]
-  (doseq [s msgs]
+(defn default-failure-handler
+  "This failure handler prints each error message on a separate line. It returns
+   `nil`, allowing constructs like this:
+
+        (some-> (type/checked :frobnoz x)
+                (assoc :goodness true)
+                ...)
+"
+  [messages]
+  (doseq [s messages]
     (println s))
   nil)

-(defn throwing-failure-handler [messages]
+(defn throwing-failure-handler
+  "In contrast to the default failure handler, this one throws a
+   `java.lang.Exception` whose message is the concatenation of the
+   type-mismatch messages.
+
+   To make all type mismatches throw failures, do this:
+
+          (type/set-failure-handler! type/throwing-failure-handler)
+"
+  [messages]
   (throw (new Exception (str/join "\n" messages))))

 (def ^:private default-success-handler identity)

-(defn- formatter [type-repo]
-  (get type-repo :formatter default-formatter))
-(defn- failure-handler [type-repo]
-  (get type-repo :failure-handler default-failure-handler))
-(defn- success-handler [type-repo]
-  (get type-repo :success-handler default-success-handler))
-
-(def empty-type-repo {:failure-handler default-failure-handler
-                      :success-handler default-success-handler
-                      :formatter default-formatter})
+(def empty-type-repo
+  "A repository that contains no type descriptions. It contains
+   default behavior for both success and failure cases. Here's
+   an example of changing the behavior and adding a type:
+
+         (-> type/empty-type-repo
+             (assoc :failure-handler type/throwing-failure-handler)
+             (type/named :frobable [:left :right :arrow]))
+"
+  {:failure-handler default-failure-handler
+   :success-handler default-success-handler
+   :formatter default-formatter})

 (declare ^:private own-types)

@@ -49,15 +66,28 @@
 (defn- checked-internal [type-repo name kvs]
   (let [[errors actual] (b/validate kvs (get-in type-repo [:validators name]))]
     (if (empty? errors)
-      ((success-handler type-repo) kvs)
-      (-> ( (formatter type-repo) errors (dissoc actual :bouncer.core/errors))
-          ((failure-handler type-repo))))))
+      ((:success-handler type-repo) kvs)
+      (-> ( (:formatter type-repo) errors (dissoc actual :bouncer.core/errors))
+          ((:failure-handler type-repo))))))

-(defn named [type-repo name keys]
+(defn named
+  "Define the type `name` as being a map or record containing all of the given `keys`.
+   Returns the augmented `type-repo`. See also [[named!]].
+"
+  [type-repo name keys]
   (checked-internal own-types :type-repo type-repo)
   (named-internal type-repo name keys))

 (defn checked
+  "Check the map `kvs` against the previously-defined type `name` in the given
+   `type-repo`. If the `type-repo` is omitted, the global one is used.
+
+       (type/checked :frobbish {:twerk true, :tweek false})
+
+   Types are defined with [[named]] or [[named!]]. By default, `checked` returns
+   the `kvs` argument if it checks out, `nil` otherwise. Those defaults can be
+   changed.
+"
   ([type-repo name kvs]
      (checked-internal own-types :type-repo type-repo)
      (checked-internal type-repo name kvs))
@@ -65,6 +95,11 @@
      (checked @global-type-repo name kvs)))

 (defn instance?
+  "Return `true` iff the map or record `kvs` typechecks against the type named `name` in
+   `type-repo`. If `type-repo` is omitted, the global repo is used.
+
+       (type/instance? :frobbable kvs)
+"
   ([type-repo name kvs]
      (checked (assoc type-repo
                      :failure-handler (constantly false)
@@ -74,11 +109,27 @@
   ([name kvs]
      (instance? @global-type-repo name kvs)))

-(defn coercion [type-repo name f]
+(defn coercion
+  "Register function `f` as one that can coerce a map or record into
+   one that matches type `name`. The updated `type-repo` is returned.
+   See also [[coercion!]], which updates the global type repo."
+  [type-repo name f]
   (checked-internal own-types :type-repo type-repo)
   (assoc-in type-repo [:coercions name] f))

 (defn coerce
+  "Coerce the map or record `kvs` into the type named `name` in the `type-repo`
+   and check the result with [[checked]]. The coerced version of `kvs` is returned.
+
+   If the type repo is omitted, the global type repo is used.
+   Coercions are defined with [[coercion]] or [[coercion!]].
+
+        (some-> (coerce :user-v2 legacy-json)
+                (update-in [:stats :logins] inc))
+
+   If `name` hasn't been defined (via [[name]] or [[named!]]), the final
+   call to `checked` is omitted.
+"
   ([type-repo name kvs]
      (checked-internal own-types :type-repo type-repo)
      (let [coercer (get-in type-repo [:coercions name] identity)]
@@ -90,28 +141,59 @@

 ;;; Own types

-(def own-types (-> empty-type-repo
-                   (assoc :failure-handler throwing-failure-handler)
-                   (named-internal :type-repo [:success-handler :failure-handler :formatter])))
+(def ^:private own-types
+  (-> empty-type-repo
+      (assoc :failure-handler throwing-failure-handler)
+      (named-internal :type-repo [:success-handler :failure-handler :formatter])))

 ;;; Side-effecting API

 (def ^:private global-type-repo)

-(defn ^:no-doc start-over! []
+(defn start-over!
+  "Reset the global type repo to its starting state: no types defined, and default
+   handling of failure and success."
+  []
   (alter-var-root #'global-type-repo (fn [_] (atom empty-type-repo))))
 (start-over!)

-(defn set-success-handler! [f]
+(defn set-success-handler!
+  "Change the global type repo so that `f` is called when [[checked]]
+   succeeds. `f` is given the original map or record. `f`'s return value becomes
+   the return value of `checked`.
+"
+  [f]
   (swap! global-type-repo assoc :success-handler f))
-(defn set-failure-handler! [f]
+
+(defn set-failure-handler!
+  "Change the global type repo so that `f` is called when [[checked]]
+   fails. `f` is given a list of error messages. `f`'s return value becomes
+   the return value of `checked`.
+"
+  [f]
   (swap! global-type-repo assoc :failure-handler f))
-(defn set-formatter! [f]
+
+;; This will be relevant once more of bouncer is exposed.
+(defn ^:no-doc set-formatter!
+  "If a map or record doesn't match the type, the formatter is called with
+   two arguments. The first is a map from key to list of error messages
+   (as created by [Bouncer](https://github.com/leonardoborges/bouncer)).
+   The second is the original map or record passed to `checked`."
+  [f]
   (swap! global-type-repo assoc :formatter f))

-(defn named! [name keys]
+(defn named!
+  "Modifies the global type repo to define the type `name` as being
+   a map or record containing all of the given `keys`.
+   See also [[named]].
+"
+  [name keys]
   (swap! global-type-repo named name keys))

-(defn coercion! [name f]
+(defn coercion!
+  "Modify the global type repo to register function `f` as one that
+   can coerce a map or record into one matching type `name`.
+   See also [[coercion]]."
+  [name f]
   (swap! global-type-repo coercion name f))


Act on @otfrom's comment.

Act on @otfrom's comment.

--- src-cljs/kixi/hecuba/tabs/hierarchy/projects.cljs
+++ src-cljs/kixi/hecuba/tabs/hierarchy/projects.cljs
@@ -102,8 +102,10 @@
            history                (om/get-shared owner :history)
            refresh-chan           (om/get-shared owner :refresh)
            all-programmes         (om/observe owner (programmes))
-           available-programmes   (sort-by :display (mapv #(hash-map :display (:name %)
-                                                                     :value (:programme_id %)) all-programmes))]
+           available-programmes   (sort-by :display (keep (fn [p]
+                                                            (when (:editable p)
+                                                              (hash-map :display (:name p)
+                                                                        :value (:programme_id p)))) all-programmes))]
        (html
         [:div
          [:h3 (:name cursor)]


add notify! calls for async triple test

add notify! calls for async triple test

--- src/thi/ng/fabric/triples.cljc
+++ src/thi/ng/fabric/triples.cljc
@@ -508,6 +508,7 @@
            [toxi knows noah]
            [geom tag clojure]
            [fabric tag clojure]])
+        (f/notify! ctx)
         (let [res (<! ctx-chan)]
           (warn :result2 res)
           (warn :all (sort @all))
@@ -516,6 +517,7 @@
           (warn :tq @tq)
           (remove-triple! g '[geom tag clojure])
           (remove-triple! g '[fabric tag clojure])
+          (f/notify! ctx)
           (let [res (<! ctx-chan)]
             (warn :result3 res)
             (warn :jq @jq)


clojure is cool

clojure is cool

--- src/vignette/storage/local.clj
+++ src/vignette/storage/local.clj
@@ -53,10 +53,7 @@
       (proxy [FileInputStream] [file]
         (close []
           (proxy-super close)
-          (loop [callbacks (:stream-close-callbacks stored-object)]
-            (when (> (count callbacks) 0)
-              ((first callbacks) stored-object)
-              (recur (rest callbacks)))))))))
+          (doall (map #(% stored-object) (:stream-close-callbacks stored-object))))))))

 (defn create-local-storage-system
   [directory]


Address weird edge case with not being able to message a thread

--- src/braid/core/server/db/thread.clj
+++ src/braid/core/server/db/thread.clj
@@ -3,6 +3,7 @@
    [braid.core.server.db :as db]
    [braid.core.server.db.common :refer :all]
    [braid.core.server.db.tag :as tag]
+   [braid.core.server.db.group]
    [clj-time.coerce :refer [to-date-time to-long]]
    [clj-time.core :as t]
    [clojure.set :refer [difference]]
@@ -75,16 +76,17 @@
 (defn user-can-see-thread?
   [user-id thread-id]
   (or
-    ;user can see the thread if it's a new (i.e. not yet in the database) thread...
+    ;; user can see the thread if it's a new (i.e. not yet in the
+    ;; database) thread...
     (nil? (d/entity (db/db) [:thread/id thread-id]))
-    ; ...or they're already subscribed to the thread...
+    ;; ...or they're already subscribed to the thread...
     (contains? (set (users-subscribed-to-thread thread-id)) user-id)
-    ; ...or they're mentioned in the thread
-    ; TODO: is it possible for them to be mentioned but not subscribed?
+    ;; ...or they're mentioned in the thread
+    ;; TODO: is it possible for them to be mentioned but not subscribed?
     (contains? (-> (d/pull (db/db) [:thread/mentioned] [:thread/id thread-id])
                    :thread/mentioned set)
                user-id)
-    ; ...or they are in the group of any tags on the thread
+    ;; ...or they are in the group of any tags on the thread
     (seq (d/q '[:find (pull ?group [:group/id])
                 :in $ ?thread-id ?user-id
                 :where
@@ -93,7 +95,22 @@
                 [?tag :tag/group ?group]
                 [?group :group/user ?user]
                 [?user :user/id ?user-id]]
-              (db/db) thread-id user-id))))
+              (db/db) thread-id user-id))
+    ;; ...or they're in the group & already have a message in the thread
+    ;; this is quite the edge case -- can happen if a user creates a
+    ;; thread, tags it, leaves the group, then re-joins it & deletes
+    ;; the tag
+    (-> (d/q '[:find ?m
+               :in $ ?user-id ?thread-id
+               :where
+               [?u :user/id ?user-id]
+               [?t :thread/id ?thread-id]
+               [?t :thread/group ?g]
+               [?g :group/user ?u]
+               [?m :message/thread ?t]
+               [?m :message/user ?u]]
+             (db/db) user-id thread-id)
+        seq boolean)))

 (defn thread-has-tags?
   [thread-id]


bugfix: must preserve all routing information

--- src/blackbox/src/leela/blackbox/czmq/router.clj
+++ src/blackbox/src/leela/blackbox/czmq/router.clj
@@ -24,7 +24,7 @@
   (java.util.concurrent.LinkedBlockingQueue. size))

 (defn enqueue [fh queue]
-  (let [[peer blank & msg] (z/recvmulti fh)]
+  (let [[peer [blank & msg]] (split-with #(not (empty? %)) (z/recvmulti fh))]
     (when (empty? blank)
       (.put queue [peer msg]))))

@@ -39,11 +39,11 @@
   (try
     (let [reply ((:onjob worker) msg)]
       (debug (format "REQUEST/DONE: %s ~> %s" (pr-str (map f/bytes-to-str-unsafe msg)) (pr-str reply)))
-      (cons peer (cons "" reply)))
+      (concat peer (cons "" reply)))
     (catch Exception e
       (let [reply (:onerr worker)]
         (error e (format "REQUEST/FAIL: %s ~> %s" (pr-str (map f/bytes-to-str-unsafe msg)) (pr-str reply)))
-        (cons peer (cons "" reply))))))
+        (concat peer (cons "" reply))))))

 (defn run-worker [ctx endpoint queue worker]
   (with-open [fh (.socket ctx ZMQ/PUSH)]


Validators are called when you first set them.

--- src/midje/semi_sweet.clj
+++ src/midje/semi_sweet.clj
@@ -61,11 +61,12 @@
   ^{:doc "True by default.  If set to false, Midje checks are not
      included into production code, whether compiled or loaded."
      :dynamic true}
-  *include-midje-checks* true)
+  *include-midje-checks* :original-truthy-value)

 (set-validator! #'*include-midje-checks*
-                (fn [_]
-                  (deprecate "Set #'midje.sweet/*include-midje-checks* instead of the #'midje.semi-sweet version.")
+                (fn [val]
+                  (when-not (= val :original-truthy-value)
+                    (deprecate "Set #'midje.sweet/*include-midje-checks* instead of the #'midje.semi-sweet version."))
                   true))


Fix auto reload core from looping through the setup function infinitely

--- src/clj/robinson/autoreloadcore.clj
+++ src/clj/robinson/autoreloadcore.clj
@@ -63,12 +63,12 @@
                                   (catch Throwable e
                                     (log/error e)
                                     state))]
-                    (recur new-state)))))))
+                    (recur new-state)))))
+          (async/<!! done-chan)))
       ; setup function changed, restart with new setup
       (let [setup-fn  (get-setup-fn)
             setup-var (var-get setup-fn)]
         (println "(Re)starting loop with new setup-fn")
         (recur setup-fn setup-var)))
-        (async/<!! done-chan)
         (println "Core exiting")))


working set filter

working set filter

--- src/cljs/netrunner/cardbrowser.cljs
+++ src/cljs/netrunner/cardbrowser.cljs
@@ -2,17 +2,15 @@
   (:require-macros [cljs.core.async.macros :refer [go]])
   (:require [om.core :as om :include-macros true]
             [sablono.core :as sab :include-macros true]
-            [cljs.core.async :refer [chan put! close!] :as async]
+            [cljs.core.async :refer [chan put!] :as async]
             [goog.net.XhrIo :as xhr]))

 (defn fetch [url]
-  (let [ch (chan 1)]
-    (xhr/send url
-              (fn [event]
-                (let [response (-> event .-target .getResponseText JSON/parse
+  (let [ch (chan)]
+    (xhr/send url (fn [event]
+                    (let [response (-> event .-target .getResponseText JSON/parse
                                    (js->clj :keywordize-keys true))]
-                  (put! ch response)
-                  (close! ch))))
+                      (put! ch response))))
     ch))

 (def app-state
@@ -20,55 +18,52 @@
    {:cards []
     :sets []}))

-(defn set-view [{:keys [name]} owner]
+(defn card-view [card owner]
+  (om/component
+   (let [base-url "http://netrunnerdb.com/web/bundles/netrunnerdbcards/images/cards/en/"]
+     (sab/html [:img.card-img {:src (str base-url (:code card) ".png")}]))))
+
+(defn set-view [{:keys [set set-filter]} owner]
   (reify
     om/IRenderState
     (render-state [this state]
-      (sab/html
-       [:div {:class (if (= (:set-filter state) name) "active" "")
-              :on-click #(om/set-state! owner [:set-filter] name)}
-        name]))))
+      (let [name (:name set)]
+        (sab/html
+         [:div {:class (if (= set-filter name) "active" "")
+                :on-click #(put! (:ch state) {:filter :set-filter :value name})}
+          name])))))

-(defn card-view [card owner]
-  (om/component
-   (let [base-url "http://netrunnerdb.com/web/bundles/netrunnerdbcards/images/cards/en/"]
-     (sab/html [:img.card-img {:src (str base-url (:code card) ".png")}]
-               ;; [:div {} (:title card)]
-               ))))
-
-(defn card-list-view [cards owner]
-  (om/component
-   (sab/html
-    [:div.card-list
-     (om/build-all card-view cards)])))
-
-(defn handle-change [e owner {:keys [set-filter]}]
-  (om/set-state! owner :set-filter (.. e -target -value)))
-
-(defn card-browser-app [cursor owner]
+(defn card-browser [cursor owner]
   (reify
     om/IInitState
     (init-state [this]
-      {:set-filter "Core Set"})
+      {:set-filter "Core Set"
+       :filter-ch (chan)})
+
+    om/IWillMount
+    (will-mount [this]
+      (go (while true
+            (let [f (<! (om/get-state owner :filter-ch))]
+              (om/set-state! owner (:filter f) (:value f))))))

     om/IRenderState
     (render-state [this state]
       (sab/html
        [:div.cardbrowser
-        [:input {:type "text" :value (:set-filter state)
-                 :on-change #(handle-change % owner state)}]
         [:div.blue-shade.panel.set-list {}
-         (om/build-all set-view (:sets cursor) {:init-state state})]
-        [:div.main
-         ;;  (om/build filter-view cursor)
-         (om/build card-list-view
-                   (let [set-filter (:set-filter state)
-                         cards (:cards cursor)]
-                     (if (zero? (alength set-filter))
-                       cards
-                       (filter #(= (:setname %) set-filter) cards))))]]))))
+         (for [set (:sets cursor)]
+           (om/build set-view
+                     {:set set :set-filter (:set-filter state)}
+                     {:init-state {:ch (:filter-ch state)}}))]
+        [:div.card-list
+         (om/build-all card-view
+                       (let [set-filter (:set-filter state)
+                             cards (:cards cursor)]
+                         (if (empty? set-filter)
+                           cards
+                           (filter #(= (:setname %) set-filter) cards))))]]))))

-(om/root card-browser-app app-state {:target (. js/document (getElementById "cardbrowser"))})
+(om/root card-browser app-state {:target (. js/document (getElementById "cardbrowser"))})

 (go (swap! app-state assoc :sets (<! (fetch "data/sets"))))
 (go (swap! app-state assoc :cards (<! (fetch "data/cards"))))


minor bugfix

minor bugfix

--- src/cljs/tictag/views/settings.cljs
+++ src/cljs/tictag/views/settings.cljs
@@ -82,10 +82,7 @@
     (if-let [username (:slack/username slack)]
       (let [{:keys [slack/dm? slack/channel? slack/id slack/channel-name]} slack]
         [re-com/v-box
-         :children [[re-com/title :level :level2 :label "Remove slackbot"]
-                    [re-com/button
-                     :label (str "Delete slack (authed as " username ")")
-                     :on-click #(dispatch [:db/delete :slack/by-id (:slack/id slack)])]
+         :children [[slack-help]
                     [re-com/title :level :level2 :label "Slack notification preferences"]
                     [re-com/checkbox
                      :model (let [[_ dm?] (or (find slack :pending-slack/dm?)
@@ -108,13 +105,18 @@
                       [re-com/input-text
                        :placeholder "#channel"
                        :model (or (:pending-slack/channel-name slack)
-                                  (:slack/channel-name slack))
+                                  (:slack/channel-name slack)
+                                  "")
                        :status (when (and (:pending-slack/channel-name slack)
                                           (:slack/channel-name errors)) :error)
                        :status-tooltip (or (first (:slack/channel-name errors)) "")
                        :status-icon? true
                        :on-change #(dispatch-n [:slack/update id :channel-name %]
-                                               [:db/save :slack/by-id id])]]]]])
+                                               [:db/save :slack/by-id id])]]]
+                    [re-com/title :level :level2 :label "Remove slackbot"]
+                    [re-com/button
+                     :label (str "Delete slack (authed as " username ")")
+                     :on-click #(dispatch [:db/delete :slack/by-id (:slack/id slack)])]]])
         [slack-authorize])))

 (defn slack-preferences []
@@ -126,8 +128,7 @@
 (defn slack []
   [re-com/v-box
    :children [[re-com/title :level :level1 :label "Slack"]
-              [slack-preferences]
-              [slack-help]]])
+              [slack-preferences]]])

 (defn goal-editor [id]


remove logging of clients atom

remove logging of clients atom

--- src/clj/com/matthiasnehlsen/inspect/matcher.clj
+++ src/clj/com/matthiasnehlsen/inspect/matcher.clj
@@ -45,11 +45,7 @@
   "cleanup after connection was closed"
   [client-uuid]
   (log/info "Connection closed:" client-uuid)
-  (println client-maps)
-
-  (swap! client-maps dissoc client-uuid)
-  (println client-maps)
-  )
+  (swap! client-maps dissoc client-uuid))

 (defn send-event-types
   "send set with known event types to connected UIs"


Added example of creating a texture out of a pixel-ship drawing

--- pixel-ship-play-clj/desktop/src-common/pixel_ship_play_clj/core.clj
+++ pixel-ship-play-clj/desktop/src-common/pixel_ship_play_clj/core.clj
@@ -1,11 +1,13 @@
 (ns pixel-ship-play-clj.core
   (:require [play-clj.core :refer :all]
             [play-clj.ui :refer :all]
+            [play-clj.g2d :refer [texture]]
             [pixel-ships.core :as psc :refer :all]
             [pixel-ships.bollinger :as bollinger :refer :all]
-            [clojure.pprint :refer :all]))
+            [clojure.pprint :refer :all])
+  (:import [com.badlogic.gdx.graphics Pixmap Texture TextureData Pixmap$Format]))

-(declare create-pixel-ship-play-clj custom-shape play-clj-color hsv-to-rgb change-ship)
+(declare create-pixel-ship-play-clj custom-shape play-clj-color hsv-to-rgb change-ship draw-rect-pixelmap)

 (defn create-entity [screen]
   (let [pixel-ship (bundle nil)]
@@ -21,13 +23,41 @@
          shape-builder (fn[s] (reduce (fn[acc n] (conj acc (custom-shape n))) [] s))]
      (reduce (fn[acc tag](concat (shape-builder (tag pixels)) acc)) [] tags))))

+(defn create-pixel-map-list
+  ([]
+   (create-pixel-map-list (rand-int Integer/MAX_VALUE)))
+  ([seed]
+   (let [ship-map (psc/color-pixel-ship (psc/create-pixel-ship (assoc bollinger/model :seed seed)))
+         tags (keys (:pixels ship-map))
+         pixels (:pixels ship-map)
+         shape-builder (fn[s] (reduce (fn[acc n] (conj acc n)) [] s))]
+     (reduce (fn[acc tag](concat (shape-builder (tag pixels)) acc)) [] tags))))
+
+(defn create-pixel-ship-texture
+  ([]
+   (create-pixel-ship-texture (rand-int Integer/MAX_VALUE)))
+  ([seed]
+   (let [pixel-map-list (create-pixel-map-list seed)
+         pix-map (pixmap* 16 16 Pixmap$Format/RGBA8888)]
+     (doseq [pixel pixel-map-list] (draw-rect-pixelmap pix-map pixel))
+     (texture pix-map))))
+
+(defn draw-rect-pixelmap [pix-map {:keys [x y color]}]
+  (let [c (play-clj-color color)]
+    (doto pix-map
+      (pixmap! :set-color c)
+      (pixmap! :fill-rectangle x y 1 1))))
+
 (defscreen main-screen
   :on-show
   (fn [screen entities]
     (let [screen (update! screen :renderer (stage))
-          pixel-ship (create-entity screen)]
+          pixel-ship (create-entity screen)
+          pixel-ship-texture (create-pixel-ship-texture Integer/MAX_VALUE)]
       [(assoc pixel-ship :entities (create-pixel-ship-play-clj Integer/MAX_VALUE)
-         :id :pixel-ship :ship? true :x 200 :y 200 :angle 180)]
+         :id :pixel-ship :ship? true :x 200 :y 200 :angle 180)
+       (assoc pixel-ship-texture :x 400 :y 400 :width 64 :height 64
+         :id :pixel-ship-texture :ship-texture? true)]
       ))

   :on-render
@@ -49,13 +79,17 @@
     (set-screen! this main-screen)))

 (defn change-ship [screen entities]
-  (->> entities
-       (map (fn [entity]
-              (cond (:ship? entity)
-                    (assoc entity :entities (create-pixel-ship-play-clj))
-              )))
+  (let [seed (rand-int Integer/MAX_VALUE)]
+    (->> entities
+         (map (fn [entity]
+                (cond (:ship? entity)
+                      (assoc entity :entities (create-pixel-ship-play-clj seed))
+                      (:ship-texture? entity)
+                      (assoc (create-pixel-ship-texture seed) :x 400 :y 400 :width 64 :height 64
+                        :id :pixel-ship-texture :ship-texture? true)
+                )))

-       ))
+         )))

 (def p-per-c 20)


Update cljs compiler version to 1.9.494

Update cljs compiler version to 1.9.494

--- frontend/project.clj
+++ frontend/project.clj
@@ -10,7 +10,7 @@
   :profiles {:dev {:source-paths ["dev"]}}

   :dependencies [[org.clojure/clojure "1.9.0-alpha14" :scope "provided"]
-                 [org.clojure/clojurescript "1.9.293" :scope "provided"]
+                 [org.clojure/clojurescript "1.9.494" :scope "provided"]

                  ;; Build
                  [figwheel-sidecar "0.5.9" :scope "provided"]


Add defgame to backlisted symbols

Add defgame to backlisted symbols

--- src/nightmod/sandbox.clj
+++ src/nightmod/sandbox.clj
@@ -29,7 +29,7 @@
        agent send send-off
        pmap pcalls
        System/out System/in System/err
-       set-screen-wrapper! set-screen! setScreen app! app on-gl})
+       defgame set-screen! setScreen set-screen-wrapper! app! app on-gl})
    (jail-test/blacklist-nses '[clojure.main])
    (jail-test/blanket "clojail")])


aggregation query

aggregation query

--- src/ophion/aggregate.clj
+++ src/ophion/aggregate.clj
@@ -229,7 +229,7 @@
 (defn evaluate
   ([db query] (evaluate db :vertex query))
   ([db collection query]
-   (log/info query)
+   (log/info collection query)
    (let [aggregate (translate query)]
      (log/info aggregate)
      (mongo/raw-aggregate


poking around

poking around

--- boiled.clj
+++ boiled.clj
@@ -1,37 +1,155 @@

 (ns hard.boiled
-	(:use hard.core)
 	(:require
 	 arcadia.core
    [clojure.string :as string])
   (:import [UnityEngine]))

- (defn hyphen->camel [charseq]
-	(let [parted (partition-by #(= \- %) charseq)]
-	(apply str (cons (apply str (first parted))
-		(map
-		(fn [col]
-			(cond (= '(\-) col) nil
-				:else (str (string/upper-case (str (first col)))
-						(apply str (rest col)))))
-		(rest parted))))))
+(def serial-fields (atom {}))

-(defn kw->sym [kw]
-	(symbol (hyphen->camel (rest (str kw)))))
+(defprotocol ISerializable
+  (serialize [this])
+  (deserialize [this s]))
+
+(defn type-name [sym] (.Name ^MonoType (resolve sym)))

 (defmacro fun-printer [t]
-  (let [v (with-meta (gensym "value")
-                     {:tag t})
-        w (with-meta (gensym "writer")
-                     {:tag 'System.IO.TextWriter})]
+  (let [v (with-meta (gensym "value") {:tag t})
+        w (with-meta (gensym "writer") {:tag 'System.IO.TextWriter})]
     `(fn [~v ~w]
-       (.Write ~w
-               (str "$:) " ~v )))))
+       (.Write ~w (str "#"  ~t " " (serialize ~v))))))

-(defmacro install-fun-printer
-  "Register a printer for t with clojure's print-method"
-  [t]
-  `(. ~(with-meta 'print-method
-                  {:tag 'clojure.lang.MultiFn})
+(defmacro install-fun-printer  [t]
+  `(. ~(with-meta 'print-method {:tag 'clojure.lang.MultiFn})
       ~'addMethod ~t (fun-printer ~t)))

+(defn constructor-arguments [^MonoType t]
+  (get @serial-fields t))
+
+(defmacro vector-constructor [t]
+  (let [ctor (constructor-arguments (resolve t))
+        params (map #(gensym %) ctor)]
+    (list 'fn [(vec params)]
+       (list* 'list ''new (list 'quote t) params))))
+
+(defmacro install-type-parser [t]
+  `(def ~(symbol (str "parse-" (type-name t)))
+     (vector-constructor ~t)))
+
+(deftype Bird [^{:volatile-mutable true :tag int} age])
+(swap! serial-fields conj {Bird '[age]})
+
+(extend-protocol ISerializable
+  Bird
+  (serialize [this] (str "[" (.age this) "]"))
+  (deserialize [this s]
+    (Bird. (first (read-string s)))))
+
+(install-type-parser Bird)
+(install-fun-printer Bird)
+(hard.boiled.Bird. 7)
+
+(comment
+(use 'hard.core)
+(import 'ArcadiaState)
+
+(let [go (create-primitive :cube)
+      c (cmpt+ go ArcadiaState)]
+     (rotation! go (rand-vec 360 360 360))
+    (set! (.state c) (Bird. 2048)))
+
+
+
+
+(macroexpand-1 '(fun-printer Bird))
+(install-fun-printer Bird)
+(deserialize (Bird. 0) (serialize (Bird. 56)))
+
+(read-string (prn-str (Bird. 156)))
+
+
+(deserialize (Bird. 1) "[45]"))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+(defn longest-constructor-signature
+  "Returns the longest parameter list for all constructors in type t"
+  [^System.MonoType t]
+  (->> (.GetConstructors t)
+       (map #(.GetParameters ^ConstructorInfo %))
+       (sort (fn [a b] (compare (count a)
+                                (count b))))
+       last))
+
+
+
+
+(defmacro reconstructor [targetsym t]
+  (mapv
+    (fn [arg]
+      `(. ~targetsym
+          ~(symbol arg)))
+    (constructor-arguments (resolve t))))
+
+(defmacro type-printer [t]
+  (let [v (with-meta (gensym "value")  {:tag t})
+        w (with-meta (gensym "writer") {:tag 'System.IO.TextWriter})]
+    `(fn [~v ~w]
+       (.Write ~w (str "#" ~(str t) " " (reconstructor ~v ~t))))))
+
+(defmacro install-type-printer [t]
+  `(. ~(with-meta 'print-method {:tag 'clojure.lang.MultiFn})
+      ~'addMethod ~t (type-printer ~t)))
+
+(defmacro serializability [types]
+  `(do
+     ~@(mapcat
+         (fn [t]
+           [`(install-type-printer ~t)
+            `(install-type-parser ~t)])
+         types)))
+
+
+
+
+
+
+
+(comment
+
+(install-type-parser fun.core.fart)
+
+
+((juxt (comp read-string prn-str) prn) (fun.core.fart. false "bad"))
+
+(read-string "#fun.core.fart [false \"big\"]\r\n")
+(prn-str (fun.core.fart. false "bad"))
+
+((juxt (comp read-string prn-str) prn) (Vector3. 1 2 3))
+
+((vector-constructor fun.core.fart) [false "bad"])
+
+(constructor-arguments fun.core.fart))


Update font-weight to be light for tab buttons

--- src/day8/re_frame/trace/styles.cljs
+++ src/day8/re_frame/trace/styles.cljs
@@ -226,7 +226,7 @@
                    :font-weight   "normal"}]

    [:.icon-button {:font-size "10px"}]
-   [:button.tab {}]
+   [:button.tab {:font-weight 300}]
    [:.nav-icon
     {:width   "30px"
      :height  "30px"


Fix wrap-cors to return 404s when appropriate.

--- src/event_data_event_bus/server.clj
+++ src/event_data_event_bus/server.clj
@@ -51,7 +51,8 @@
 (defn wrap-cors [handler]
   (fn [request]
     (let [response (handler request)]
-      (assoc-in response [:headers "Access-Control-Allow-Origin"] "*"))))
+      (when response
+        (assoc-in response [:headers "Access-Control-Allow-Origin"] "*")))))

 (defn get-token
   "Retrieve a token from a request. Return nil if missing or malformed."
@@ -66,7 +67,7 @@
   (try
     (.verify verifier token)
     ; Can be IllegalStateException, JsonParseException, SignatureException.
-    (catch Exception e (prn "EX" verifier e))))
+    (catch Exception e nil)))

 (defn wrap-jwt [handler secrets-str]
   (let [secrets (clojure.string/split secrets-str #",")


Update groovy_test.clj

Update groovy_test.clj

--- jvm-runner/test/codewars/runners/groovy_test.clj
+++ jvm-runner/test/codewars/runners/groovy_test.clj
@@ -39,7 +39,7 @@
       )
       ;(with-java-out-str (run-all-tests))

-     (let [test-out-string (groovy-java-fixt (-main))]
+     (let [test-out-string (with-java-out-str (-main))]
         (is (.contains test-out-string "<DESCRIBE::>testGreet(MyTestCase)"))
         (is (.contains test-out-string "Lets sum"))
         (is (.contains test-out-string "<PASSED::>Test Passed<:LF:>"))


Doubled max points

Doubled max points

--- src/clojush/problems/software/wallis_pi.clj
+++ src/clojush/problems/software/wallis_pi.clj
@@ -149,7 +149,7 @@
 (def argmap
   {:error-function (wallis-pi-error-function wallis-pi-data-domains)
    :atom-generators wallis-pi-atom-generators
-   :max-points 1200
+   :max-points 2400
    :max-genome-size-in-initial-program 300
    :evalpush-limit 8000
    :population-size 1000


Missing check for fact_values_string_trgm

The code for index handling was only checking one index, but not the other.
This corrects the logic, and drops and extra INFO when creating the new index.

Signed-off-by: Ken Barber <470bc578162732ac7f9d387d34c4af4ca6e1b6f7@bob.sh>

--- src/com/puppetlabs/puppetdb/scf/migrate.clj
+++ src/com/puppetlabs/puppetdb/scf/migrate.clj
@@ -940,7 +940,10 @@
   (when-not (scf-utils/index-exists? "fact_paths_path_trgm")
     (log/info "Creating additional index `fact_paths_path_trgm`")
     (sql/do-commands
-     "CREATE INDEX fact_paths_path_trgm ON fact_paths USING gist (path gist_trgm_ops)"
+     "CREATE INDEX fact_paths_path_trgm ON fact_paths USING gist (path gist_trgm_ops)"))
+  (when-not (scf-utils/index-exists? "fact_values_string_trgm")
+    (log/info "Creating additional index `fact_values_string_trgm`")
+    (sql/do-commands
      "CREATE INDEX fact_values_string_trgm ON fact_values USING gist (value_string gist_trgm_ops)")))

 (defn indexes!


fixes the functional test on ci

fixes the functional test on ci

--- src/cljs/conference_rating/add_rating_page/add_rating_page.cljs
+++ src/cljs/conference_rating/add_rating_page/add_rating_page.cljs
@@ -26,9 +26,9 @@
     [:span
      [:i {:class "glyphicon glyphicon-star"}]
      [:span "I would go again!"]]
-    [:div {:data-e2e "checkbox-rating-voice"}
+    [:div
      [:input {:field :checkbox :type "checkbox" :id :recommended}]
-     [:label {:for :recommended}
+     [:label {:for :recommended :data-e2e "checkbox-rating-voice"}
       [:span {:class "checkbox checkbox-lg"}]]]]]
   )


Load hidapi library by system architecture.

--- src/org/playasophy/wonderdome/input/usb_hid.clj
+++ src/org/playasophy/wonderdome/input/usb_hid.clj
@@ -13,11 +13,6 @@

 ;;;;; CONFIGURATION ;;;;;

-(def ^:private library-name
-  "JNI library to load when finding devices."
-  "hidapi-jni-64")
-
-
 (def ^:private ^:const poll-period
   "Milliseconds to wait for new input from USB device."
   100)
@@ -31,24 +26,31 @@

 ;;;;; HELPER FUNCTIONS ;;;;;

-(defn device-info
-  "Builds a map with a device's manufacturer, product, and serial number."
-  [^HIDDevice device]
-  (when device
-    {:manufacturer (.getManufacturerString device)
-     :product (.getProductString device)
-     :serial (.getSerialNumberString device)}))
+(defn- load-hidapi-library
+  "Attempts to load the JNI hidapi library."
+  []
+  (let [arch (System/getProperty "os.arch")
+        bits (condp re-find arch
+               #"32" 32
+               #"64" 64
+               (throw (IllegalStateException.
+                 (str "Unknown architecture bit size: " arch))))
+        libname (str "hidapi-jni-" bits)]
+    (log/info (str "Loading HID library " libname))
+    (clojure.lang.RT/loadLibrary libname)))

 (defn find-device
+  "Loads a USB device by vendor and product id. Loads the JNI library and returns
+  an initialized device, or nil on failure."
   [vendor-id product-id]
   (try
-    (clojure.lang.RT/loadLibrary library-name)
-    ; TODO: release the manager?
+    (load-hidapi-library)
     (when-let [manager (HIDManager/getInstance)]
+      ; TODO: release the manager?
       (.openById manager vendor-id product-id nil))
     (catch UnsatisfiedLinkError e
-      (log/error e "Failed to load USB library!")
+      (log/error e "Failed to load USB HID library!")
       nil)
     (catch NullPointerException e
       (log/warn (str "No USB input device present matching "
@@ -59,6 +61,18 @@
       (log/error e "Error loading USB input device!")
       nil)))

+
+(defn device-info
+  "Builds a map with a device's manufacturer, product, and serial number."
+  [^HIDDevice device]
+  (when device
+    {:manufacturer (.getManufacturerString device)
+     :product (.getProductString device)
+     :serial (.getSerialNumberString device)}))
+
+
+
+;;;;; INPUT HANDLING ;;;;;

 (defn- read-loop
   "Constructs a new runnable looping function which reads the device state and


Conserve vertical space.

Conserve vertical space.

--- src/randometer/core.cljs
+++ src/randometer/core.cljs
@@ -41,7 +41,7 @@
                        :vertical-align "middle"
                        :margin "0.5em"}}
    (for [row board]
-     [:div.row (apply str (map show-trial row))])])
+     [:div.row {:style {:line-height "1"}} (apply str (map show-trial row))])])

 (defn board-chooser [{:keys [on-guess on-reset flavortext answertext]} boards keymap guess]
   [:fieldset {:on-click #(when (some? guess) (on-reset))}


throw if attempt to bind variable that is not a program input

--- src/gamma_driver/impl/variable.cljs
+++ src/gamma_driver/impl/variable.cljs
@@ -18,6 +18,15 @@

 (defn bind-attribute [gl program attribute input]
+  (when (not ((:inputs program) attribute))
+    (throw (js/Error.
+             (str "Invalid input variable: "
+                  attribute
+                  " for program"
+                  (if-let [id (pr-str (:id program))]
+                    (str " " id ".")
+                    ".")
+                  ". Valid inputs: " (:inputs program)))))
   (let [location (attribute-location gl program attribute)
         {:keys [size type normalized? stride offset]}
         ((or (:layout input) default-layout) attribute)]
@@ -41,6 +50,15 @@

 (defn bind-uniform [gl program uniform input]
+  (when (not ((:inputs program) uniform))
+    (throw (js/Error.
+             (str "Invalid input variable: "
+                  uniform
+                  " for program"
+                  (if-let [id (pr-str (:id program))]
+                    (str " " id ".")
+                    ".")
+                  ". Valid inputs: " (:inputs program)))))
   (let [location (uniform-location gl program uniform)
         type (:type uniform)
         data (:data input)]
@@ -66,6 +84,15 @@

 (defn bind-texture-uniform [gl program uniform texture]
+  (when (not ((:inputs program) uniform))
+    (throw (js/Error.
+             (str "Invalid input variable: "
+                  uniform
+                  " for program"
+                  (if-let [id (pr-str (:id program))]
+                    (str " " id ".")
+                    ".")
+                  ". Valid inputs: " (:inputs program)))))
   (let [location (uniform-location gl program uniform)
         id       (:texture-id texture)
         target   (:target texture)]


fixes #7355

fixes #7355

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/extensions/capacities/events.cljs
+++ src/status_im/extensions/capacities/events.cljs
@@ -311,6 +311,32 @@
  (fn [cofx [_ _ {:keys [url]}]]
    (browser/open-url cofx url)))

+(handlers/register-handler-fx
+ :extensions/profile-settings-close
+ (fn [{:keys [db] :as cofx} [_ _ {:keys [on-close on-failure]}]]
+   (let [view-id (:view-id db)]
+     ;; ensure the current view-id is the profile settings view
+     (if (= view-id :my-profile-ext-settings)
+       (fx/merge cofx
+                 (when on-close (on-close))
+                 (navigation/navigate-back))
+       (if on-failure
+         (on-failure {:value "extension is not currently showing profile settings"})
+         {})))))
+
+(handlers/register-handler-fx
+ :extensions/wallet-settings-close
+ (fn [{:keys [db] :as cofx} [_ _ {:keys [on-close on-failure]}]]
+   (let [view-id (:view-id db)]
+     ;; ensure the current view-id is the wallet settings view
+     (if (= view-id :wallet-settings-hook)
+       (fx/merge cofx
+                 (when on-close (on-close))
+                 (navigation/navigate-back))
+       (if on-failure
+         (on-failure {:value "extension is not currently showing wallet settings"})
+         {})))))
+
 ;;CAPACITIES

 (def all
@@ -684,4 +710,14 @@
    'ethereum/shh-get-messages
    {:permissions [:read]
     :data        :extensions/shh-get-messages
-    :arguments   {:id :string}}})+    :arguments   {:id :string}}
+   'profile.settings/close
+   {:permissions [:read]
+    :data        :extensions/profile-settings-close
+    :arguments   {:on-close?   :event
+                  :on-failure? :event}}
+   'wallet.settings/close
+   {:permissions [:read]
+    :data        :extensions/wallet-settings-close
+    :arguments   {:on-close?   :event
+                  :on-failure? :event}}})


Hopefully fixes bug where last post of thread wasn't scanned for votes

--- src/mafia_votecount/scraper/team_liquid.clj
+++ src/mafia_votecount/scraper/team_liquid.clj
@@ -225,9 +225,9 @@
     '()
     (let [posts (select-keys indexed
                             (range (first start-end)
-                                   (if (empty? (rest start-end))
-                                     (last (keys indexed))
-                                     (inc (last start-end)))))]
+                                   (inc (if (empty? (rest start-end))
+                                          (last (keys indexed))
+                                          (last start-end)))))]
      (->> (mapcat get-votes-from-message posts)
           (sort vote-cmp)
           (map #(dissoc % :subindex))))))


simple recursion

simple recursion

--- src/sandbox/4clojure.clj
+++ src/sandbox/4clojure.clj
@@ -205,3 +205,5 @@
 ;;56 Find Distinct Items
 (fn [xs] (reduce #(if (some #{%2} %1) %1 (conj %1 %2)) [] xs))

+;;57 Simple Recursion
+[5 4 3 2 1]


[#2212] Spec for wrap-authorization

[#2212] Spec for wrap-authorization

--- backend/src/akvo/lumen/auth.clj
+++ backend/src/akvo/lumen/auth.clj
@@ -187,5 +187,5 @@
                                 not-authorized)
           :else not-authorized)))))

-#_(defmethod ig/pre-init-spec :akvo.lumen.auth/wrap-authorization [_]
-    (s/keys :req-un [::keycloak]))
+(defmethod ig/pre-init-spec :akvo.lumen.auth/wrap-authorization [_]
+  (s/keys :req-un [::keycloak/keycloak]))


Add options to rename scaled key to scaling

--- src/clj/clojurewerkz/statistiker/scaling.clj
+++ src/clj/clojurewerkz/statistiker/scaling.clj
@@ -65,9 +65,11 @@
   (mapv (make-l2-normalize-fn x) x))

 (defn scale-feature
-  [maps key scale-fn-factory]
-  (let [extracted (map #(get % key) maps)
-        scale-f   (scale-fn-factory extracted)
-        scaled    (map scale-f extracted)]
-    (map (fn [v scaled]
-           (assoc v key scaled)) maps scaled)))
+  ([maps key scaled-key scale-fn-factory]
+     (let [extracted (map #(get % key) maps)
+           scale-f   (scale-fn-factory extracted)
+           scaled    (map scale-f extracted)]
+       (map (fn [v scaled]
+              (assoc v scaled-key scaled)) maps scaled)))
+  ([maps key scale-fn-factory]
+     (scale-feature maps key key scale-fn-factory)))


Rearrange query

Rearrange query

--- src/cljs/koeeoadi/components/faceeditor.cljs
+++ src/cljs/koeeoadi/components/faceeditor.cljs
@@ -60,11 +60,11 @@
   (query [this]
     `[:face/id
       :face/name
-      {:face/color-fg ~(om/get-query Color)}
-      {:face/color-bg ~(om/get-query Color)}
       :face/bold
       :face/italic
-      :face/underline])
+      :face/underline
+      {:face/color-fg ~(om/get-query Color)}
+      {:face/color-bg ~(om/get-query Color)}])

   Object
   (render [this]


Fix bad merge on test.

Fix bad merge on test.

--- test/onyx/scheduler/percentage_multi_job_test.clj
+++ test/onyx/scheduler/percentage_multi_job_test.clj
@@ -17,14 +17,6 @@
    :onyx.peer/job-scheduler :onyx.job-scheduler/percentage})

 (deftest log-percentage-multi-job
-  (let [onyx-id (java.util.UUID/randomUUID)
-        config (load-config)
-        env-config (assoc (:env-config config) :onyx/tenancy-id onyx-id)
-        peer-config (assoc (:peer-config config)
-                           :onyx/tenancy-id onyx-id
-                           :onyx.peer/job-scheduler :onyx.job-scheduler/percentage)
-        env (onyx.api/start-env env-config)
-        peer-group (onyx.api/start-peer-group peer-config)
   (let [job-1-id "job-1"
         job-1 {:workflow [[:a :b]]
                :catalog [{:onyx/name :a


Prefer `(case …)` to `(condp = …)`.

Prefer `(case …)` to `(condp = …)`.


add more dox

add more dox

--- src/metabase/driver/generic_sql.clj
+++ src/metabase/driver/generic_sql.clj
@@ -97,6 +97,8 @@
       (format "Field is missing required information:\n%s" (u/pprint-to-str 'red field)))
     (let [table           @table
           name-components (rest @qualified-name-components)
+          ;; This function returns a chunked lazy seq that will fetch some range of results, e.g. 0 - 500, then concat that chunk of results
+          ;; with a recursive call to (lazily) fetch the next chunk of results, until we run out of results or hit the limit.
           fetch-chunk     (fn -fetch-chunk [start step limit]
                             (lazy-seq
                              (let [results (->> (k/select (korma-entity table)


Fix error in 'resolution-rollup-finder'.

--- src/org/spootnik/cyanite/rollup.clj
+++ src/org/spootnik/cyanite/rollup.clj
@@ -16,7 +16,6 @@
   "Find most precise storage period given the oldest point wanted"
   [{:keys [rollups]}]
   (info "creating precise rollup finder")
-  (info "rollups:" rollups)
   (reify
     RollupFinder
     (find-rollup
@@ -28,8 +27,6 @@
   "Find most suitable rollup for given resolution"
   [{:keys [rollups resolution] :or {resolution 800}}]
   (info "creating resolution rollup finder")
-  (info "rollups:" rollups)
-  (info "resolution:" resolution)
   (reify
     RollupFinder
     (find-rollup
@@ -38,5 +35,6 @@
             sorted-rollups (sort-by :rollup rollups)
             within (filter within-fn sorted-rollups)
             resolution-fn (fn [{:keys [rollup period] :as rollup-def}]
-                            (>= (/ (- to from) rollup) resolution))]
-        (and within (or (some resolution-fn (rseq within)) (first within)))))))
+                            (and (>= (/ (- to from) rollup) resolution)
+                                 rollup-def))]
+        (and within (or (some resolution-fn (reverse within)) (first within)))))))


Added Browser Width atom to timeline.cljs

--- src/redbrick_20/views/timeline.cljs
+++ src/redbrick_20/views/timeline.cljs
@@ -8,6 +8,8 @@
 (enable-console-print!)

 (def years-atom (reagent/atom {}))
+(def browser-width (reagent/atom js/window.innerWidth))
+

 (defn timeline-row [atom-state]
   [:div


remove redundant doall

remove redundant doall

--- src/kixi/hecuba/data/measurements/upload.clj
+++ src/kixi/hecuba/data/measurements/upload.clj
@@ -80,7 +80,7 @@
       (let [entity                   (entities/get-by-id session entity_id)
             devices                  (devices/get-devices session entity_id)
             sensors                  (sensors/get-sensors-by-device_ids (map :id devices) session)
-            aliases                  (doall  (map (partial str/join \|) (rest (transpose header-rows))))
+            aliases                  (map (partial str/join \|) (rest (transpose header-rows)))
             sensors-in-alias-order   (for [a aliases s sensors :when (= a (:alias s))] s)
             ds-and-ss-in-alias-order (for [s sensors-in-alias-order
                                            d devices


show inventory count. meh

show inventory count. meh

--- clojure/src/dnd/showScreen.cljs
+++ clojure/src/dnd/showScreen.cljs
@@ -26,7 +26,8 @@

   (.color256    term 7)
   (.bgColor256  term 0)
-  (.moveTo term (+ 2 width) 0 (str "HP: " (:hp character)))
+  (.moveTo term (+ 2 width) 1 (str "HP: " (:hp character)))
+  (.moveTo term (+ 2 width) 2 (str "INV: " (count (:inventory character))))
   (.moveTo term 0 (inc height) "got some text down below\n\n")

   )


Fix issue where -C/--no-colors boot option was being ignored (fixes #150)

--- boot/pod/src/boot/util.clj
+++ boot/pod/src/boot/util.clj
@@ -129,13 +129,13 @@

 (defn auto-flush
   [writer]
-  (let [fmt (if @*colorize?*
-              identity
-              (fn [s] (if (string? s)
-                        (ansi/strip-ansi s)
-                        s)))]
+  (let [fmt #(if @*colorize?*
+               identity
+               (fn [s] (if (string? s)
+                         (ansi/strip-ansi s)
+                         s)))]
     (proxy [java.io.PrintWriter] [writer]
-      (write [s] (.write writer (fmt s)) (flush)))))
+      (write [s] (.write writer ((fmt) s)) (flush)))))

 (defn extract-ids
   [sym]


Add bin packing

Add bin packing

Signed-off-by: Wil <41c73e1c187a64e501bf473cfef5419e8eb5a640@twosigma.com>

--- scheduler/src/cook/mesos/scheduler.clj
+++ scheduler/src/cook/mesos/scheduler.clj
@@ -1067,6 +1067,7 @@
       (withLeaseOfferExpirySecs (max (-> offer-incubate-time-ms time/millis time/in-seconds) 1)) ;; should be at least 1 second
       (withRejectAllExpiredOffers)
       (withDebugEnabled)
+      (withFitnessCalculator BinPackingFitnessCalculators/cpuMemBinPacker)
       (withLeaseRejectAction (reify com.netflix.fenzo.functions.Action1
                                (call [_ lease]
                                  (let [offer (:offer lease)


Add support for circle shape in size geom function.

With minor private function naming refactor.

--- src/uxbox/main/geom.cljs
+++ src/uxbox/main/geom.cljs
@@ -130,23 +130,32 @@

 ;; --- Size

-(declare rect-size)
+(declare size-rect)
+(declare size-circle)

 (defn size
   "Calculate the size of the shape."
   [shape]
   (case (:type shape)
-    :text (rect-size shape)
-    :rect (rect-size shape)
-    :icon (rect-size shape)
-    :path (rect-size shape)))
-
-(defn- rect-size
+    :circle (size-circle shape)
+    :text (size-rect shape)
+    :rect (size-rect shape)
+    :icon (size-rect shape)
+    :path (size-rect shape)))
+
+(defn- size-rect
   "A specialized function for calculate size
   for rect-like shapes."
   [{:keys [x1 y1 x2 y2] :as shape}]
   {:width (- x2 x1)
    :height (- y2 y1)})
+
+(defn- size-circle
+  "A specialized function for calculate size
+  for circle shape."
+  [{:keys [rx ry]}]
+  {:width (* rx 2)
+   :height (* ry 2)})

 ;; --- Vertex Access


Categories renders in JSON

Categories renders in JSON

--- src/swanson/routes/transactions.clj
+++ src/swanson/routes/transactions.clj
@@ -73,6 +73,10 @@
   (let [result (category/ytd)]
     (utils/json-response result)))

+(defn category-by-week [category-id]
+  (let [result (category/by-week (Integer/parseInt category-id))]
+    (utils/json-response result)))
+
 (defn months []
   (let [result (transaction/last-n-months (:months default-params))]
     (utils/json-response result)))
@@ -109,6 +113,7 @@
   (GET "/transactions/:id" [id] (transaction id))                  ; show
   (PUT "/transactions/:id" [id] (update-transaction id))           ; update
   (GET "/categories/:id" [id] (category id))                       ; show
+  (GET "/category-by-week/:id" [id] (category-by-week id))
   (GET "/categories" {params :params} []
        (categories-handler params))
   (GET "/by-week" [] (by-week))


Changed comment

Changed comment

--- src/voxxed/functions.clj
+++ src/voxxed/functions.clj
@@ -13,7 +13,7 @@
   (reduce #(* %1 %2) (range 1 (inc x))))
 ; that is right * could have been used on it's own :)

-; Another HOF
+; F returning f
 (def inc-double (comp (partial * 2) inc))

 ;(println (map inc-double [1 2 3 4 5 6]))


[CS] Docstrings for pipeline fns

[CS] Docstrings for pipeline fns

--- src/vip/data_processor/pipeline.clj
+++ src/vip/data_processor/pipeline.clj
@@ -2,7 +2,11 @@
   (:require [clojure.tools.logging :as log]
             [clojure.stacktrace :as stacktrace]))

-(defn try-processing-fn [processing-fn ctx]
+(defn try-processing-fn
+  "Attempt to run the processing function on the context. If the
+  processing function throws, add a `:stop` key and the `Throwable` to
+  the context."
+  [processing-fn ctx]
   (try
     (processing-fn ctx)
     (catch Throwable e
@@ -11,7 +15,11 @@
                  :thrown-by processing-fn
                  :exception e))))

-(defn run-pipeline [c]
+(defn run-pipeline
+  "Run the `pipeline` attached to a processing context. Will return
+  the context after all processing functions in the pipeline have
+  been completed or until a `:stop` key is added to the context."
+  [c]
   (loop [ctx c]
     (let [pipeline (:pipeline ctx)]
       (if-let [next-step (first pipeline)]
@@ -26,7 +34,11 @@
   "A pipeline is a sequence of functions that take and return a
   `processing context`. The `initial-input` will be placed as the
   `:input` on the processing context for the first function in the
-  pipeline."
+  pipeline.
+
+  Runs the pipeline, returning the final context. An exception on the
+  context will result in logging the exception, and this function
+  throwing it."
   [pipeline initial-input]
   (let [ctx {:input initial-input
              :warnings {}