Solve the invalid fop problem with empty items more elegantly

When generating the grossdruck catalog for a future date where we have
no items and no editorial and also no recommendations we get nil as
subitems. This will generate an empty toc and hence an empty fo:flow
which is not valid. The other catalogs will at least have a block for
the title of the toc and are valid under the same circumstances. This
is because the items will be an empty map.

So to get the same effect we default the subitems to an empty map if
they are nil.

--- src/clj/catalog/layout/fop.clj
+++ src/clj/catalog/layout/fop.clj
@@ -828,19 +828,20 @@
         (header :recto)
         (header :verso)

-        (let [subitems (-> items
-                           (get fmt)
-                           (cond->
-                               (not (string/blank? editorial)) (assoc :editorial editorial)
-                               (not (string/blank? recommendations)) (assoc :recommendation recommendations)))]
-          (if (seq subitems)
-            [:fo:flow {:flow-name "xsl-region-body"}
+        (let [subitems (or
+                        (-> items
+                            (get fmt)
+                            (cond->
+                                (not (string/blank? editorial)) (assoc :editorial editorial)
+                                (not (string/blank? recommendations)) (assoc :recommendation recommendations)))
+                        ;; if there are no items and neither an editorial nor any recommendations
+                        ;; then default to an empty map. This will make sure at least the title of
+                        ;; the toc is printed and the fop will be valid.
+                        {})]
+          [:fo:flow {:flow-name "xsl-region-body"}
              (toc subitems [fmt] 2 {:heading? true})
              (realize-lazy-seqs
-              (mapcat #(genre-sexp (get subitems %) fmt % 1 {}) (keys subitems)))]
-            ;; hm, we have neither an editorial, recommendations nor any items
-            ;; just add some dummy block to make the fop valid
-            [:fo:flow {:flow-name "xsl-region-body"} (block " ")]))]
+              (mapcat #(genre-sexp (get subitems %) fmt % 1 {}) (keys subitems)))])]
        (coverpage-verso title issue fmt)])))

 (defmethod document-sexp :hörbuch


Add a fn for getting the chapter-list data for a site

This makes it so that there is a uniform interface for extracting a list
of html entities from a site.

--- src/clj/comic_reader/sites.clj
+++ src/clj/comic_reader/sites.clj
@@ -14,6 +14,11 @@
                        {url :href} :attrs}]
                    {:name name
                     :url url})
+      :chapter-list-data (fn [chapter-url]
+                           {:url chapter-url
+                            :selector [:div#chapters :ul.chlist
+                                       :li :div :h3 :a]
+                            :normalize (fn [data] data)})
       :url->feed (fn [url]
                    (some->> url
                             (re-matches manga-pattern)
@@ -28,4 +33,8 @@
       :normalize (fn [{[name] :content
                        {url :href} :attrs}]
                    {:name (s/trim name)
-                    :url (str canonical-url url)})})])
+                    :url (str canonical-url url)})
+      :chapter-list-data (fn [chapter-url]
+                           {:url chapter-url
+                            :selector [:div#chapterlist :tr :td :a]
+                            :normalize (fn [data] data)})})])


Better centroid calculation for poly rotation

--- src/clj/genartlib/geometry.clj
+++ src/clj/genartlib/geometry.clj
@@ -14,8 +14,12 @@
     points
     (let [xs (map first points)
           ys (map second points)
-          x-centroid (/ (apply + xs) (count xs))
-          y-centroid (/ (apply + ys) (count ys))
+          min-x (apply min xs)
+          max-x (apply max xs)
+          min-y (apply min ys)
+          max-y (apply max ys)
+          x-centroid (/ (+ min-x max-x) 2.0)
+          y-centroid (/ (+ min-y max-y) 2.0)
           points (map vector xs ys)]
       (map (fn [[x y]]
              (let [current-angle (angle x-centroid y-centroid x y)


Change indentation

Change indentation

--- src/clj/rumahsewa141/views.clj
+++ src/clj/rumahsewa141/views.clj
@@ -6,18 +6,20 @@
     "was billed"
     "paid"))

-(defn describe-transaction [{:keys [username rent
-                                    internet others transaction_timestamp]}]
-  {:description (apply
-                 str
-                 (drop-last
-                  (str username " " (find-verb rent internet others)
-                       (when-not (zero? rent)
-                         (str " RM " (abs rent) " for rent,"))
-                       (when-not (zero? internet)
-                         (str " RM " (abs internet) " for internet,"))
-                       (when-not (zero? others)
-                         (str "  RM " (abs others) " for other bills,")))))
+(defn describe-transaction [{:keys [username
+                                    rent
+                                    internet
+                                    others
+                                    transaction_timestamp]}]
+  {:description (apply str (drop-last (str username
+                                           " "
+                                           (find-verb rent internet others)
+                                           (when-not (zero? rent)
+                                             (str " RM " (abs rent) " for rent,"))
+                                           (when-not (zero? internet)
+                                             (str " RM " (abs internet) " for internet,"))
+                                           (when-not (zero? others)
+                                             (str "  RM " (abs others) " for other bills,")))))
    :timestamp transaction_timestamp})

 (defn history-view [page get-count-fn get-transactions-fn]


Use >! instead of put!

Use >! instead of put!

--- src/clj_gatling/simulation.clj
+++ src/clj_gatling/simulation.clj
@@ -37,11 +37,11 @@
         response (async/chan)
         function (memoize (request-fn request))
         callback (fn [result & context]
-                   (put! response [{:name (:name request)
+                   (go (>! response [{:name (:name request)
                                    :id user-id
                                    :start start
                                    :end (now)
-                                   :result result} (first context)]))]
+                                   :result result} (first context)])))]
     (go
       (function user-id context callback)
       (let [[result c] (alts! [response (async/timeout timeout)])]


Update maps utils

Update maps utils

--- src/cljs/gtfve/utils/maps.cljs
+++ src/cljs/gtfve/utils/maps.cljs
@@ -1 +1,19 @@
-(ns gtfve.utils.maps)
+(ns gtfve.utils.maps
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
+  (:require [cljs.core.async :as async :refer [put! chan <! close!]]))
+
+(defonce Maps google.maps)
+
+(defonce map-types (js->clj Maps.MapTypeId :keywordize-keys true))
+
+(defonce default-map-opts {:center {:lat 14.653386
+                                    :lng 121.032520}
+                           :mapTypeId (:ROADMAP map-types)
+                           :zoom 15})
+
+(defn listen
+  ([gmap type]
+   (listen gmap type (chan)))
+  ([gmap type c]
+   (.. Maps -event (addListener gmap type (fn [] (put! c (js/Date.)))))
+   c))


Use a sequence rather than a map for PGN tags.

Using a map turns out not to be a good idea, because we want to make
sure the tags are written in the right order when exporting a game to
PGN. We could have tried using an array-map, but this would probably
still break when trying to manipulate tags with assoc-in and friends.

--- src/clojure/clj_chess/game.clj
+++ src/clojure/clj_chess/game.clj
@@ -14,22 +14,35 @@
   (swap! counter inc))

 (defn new-game
-  "Creates a new game object with the given PGN tags and start position."
-  [& {:keys [white black event site date round result start-fen]
+  "Creates a new game object with the given PGN tags and start position. The
+  seven standard tags that make up the \"Seven Tag Roster\" in the PGN standard
+  are supplied by induvidual keyword parameters, as is the start-fen parameter
+  that is used to specify the initial position of the game. If any further PGN
+  tags are desired, they should be supplied in a sequence of two-element
+  vectors of the form [<tag-name> <tag-value>]."
+  [& {:keys [white black event site date round result start-fen other-tags]
       :or {white "?" black "?" event "?" site "?" date "?" round "?"
            result "*"
            start-fen board/start-fen}}]
   (let [root-node {:board (board/make-board start-fen)
                    :node-id (generate-id)}]
-     {:white white
-      :black black
-      :event event
-      :site site
-      :date date
-      :round round
-      :result result
+     {:tags (concat [["White" white]
+                     ["Black" black]
+                     ["Event" event]
+                     ["Site" site]
+                     ["Date" date]
+                     ["Round" round]
+                     ["Result" result]]
+                    other-tags)
       :root-node root-node
       :current-node root-node}))
+
+(defn tag-value
+  "Returns the value of the given PGN tag in the game, or nil if no such
+  tag exists."
+  [game tag-name]
+  (second (first (filter #(= tag-name (first %))
+                         (game :tags)))))

 (defn board
   "Returns the current board position of a game."
@@ -317,18 +330,13 @@
   variations."
   [game & {:keys [include-comments? include-variations?]
            :or {include-comments? true include-variations? true}}]
-  (str (cl-format nil "[Event \"~a\"]\n" (game :event))
-       (cl-format nil "[Site \"~a\"]\n" (game :site))
-       (cl-format nil "[Date \"~a\"]\n" (game :date))
-       (cl-format nil "[Round \"~a\"]\n" (game :round))
-       (cl-format nil "[White \"~a\"]\n" (game :white))
-       (cl-format nil "[Black \"~a\"]\n" (game :black))
-       (cl-format nil "[Result \"~a\"]\n" (game :result))
+  (str (apply str (map #(cl-format nil "[~a ~s]\n" (first %) (second %))
+                       (g :tags)))
        "\n"
        (WordUtils/wrap (move-text game
                                   :include-comments? include-comments?
                                   :include-variations? include-variations?)
                        80)
        " "
-       (game :result)
+       (tag-value game "Result")
        "\n"))


Use correct units in :text-size (fix #14)

--- src/clojure/neko/ui/traits.clj
+++ src/clojure/neko/ui/traits.clj
@@ -177,9 +177,11 @@

 (deftrait :text-size
   "Takes `:text-size` attribute which should be either integer or a
-  dimenstion vector, and sets it to the widget."
+  dimension vector, and sets it to the widget."
   [^TextView wdg, {:keys [text-size]} _]
-  (.setTextSize wdg (to-dimension text-size)))
+  (if (vector? text-size)
+    (.setTextSize wdg (kw->unit-id (second text-size)) (first text-size))
+    (.setTextSize wdg text-size)))

 (deftrait :image
   "Takes `:image` attribute which can be a resource ID, resource


fixed and parallelized wikipedia parser

fixed and parallelized wikipedia parser

--- src/corpus_utils/wikipedia.clj
+++ src/corpus_utils/wikipedia.clj
@@ -4,7 +4,9 @@
             [corpus-utils.document :refer :all]
             [clojure.spec.alpha :as s]
             [net.cgrand.xforms :as x]
-            [clojure.string :as string]))
+            [parallel.xf :as xf]
+            [clojure.string :as string]
+            [me.raynes.fs :as fs]))

 (defn is-open? [s]
   (re-seq #"^<doc id" s))
@@ -107,16 +109,23 @@
 (defn document-seq
   "Given a suitable (quasi)XML file generated from a Wikipedia dump, returns a lazy sequence of maps containing sources meta-information and parsed paragraphs."
   [{:keys [corpus-dir]}]
-  (let [[year _month _day] (rest (first (re-seq #"(\d\d\d\d)(\d\d)(\d\d).+\.xml.*$" corpus-dir)))
-        wikipedia-metadata #:metadata{:year (Integer/parseInt year)}
-        lines (line-seq (utils/xz-reader corpus-dir))]
-    (sequence
-      (comp
-        (partition-by is-open?)
-        (partition-all 2)
-        (filter is-japanese?)
-        (map (partial process-doc wikipedia-metadata)))
-      lines)))
+  (let [cache-dir-path (utils/hash-file-path (fs/file corpus-dir))]
+    (if (fs/exists? cache-dir-path)
+      (map utils/read-cached-file (fs/glob cache-dir-path "*.transit"))
+      (let [[year _month _day] (rest (first (re-seq #"(\d\d\d\d)(\d\d)(\d\d).+\.xml.*$" corpus-dir)))
+            wikipedia-metadata #:metadata{:year (Integer/parseInt year)}
+            lines (line-seq (utils/xz-reader corpus-dir))]
+        (fs/mkdirs cache-dir-path)
+        (sequence
+          (comp
+            (partition-by is-open?)
+            (partition-all 2)
+            (filter is-japanese?)
+            (xf/pmap (partial process-doc wikipedia-metadata))
+            (map (fn [doc]
+                       (future (utils/cache-processed-file! cache-dir-path (:metadata/basename (:document/metadata doc)) doc))
+                       doc)))
+          lines)))))

 (s/fdef document-seq
   :args (s/cat :options (s/keys :req-un [::corpus-dir string?]))


Default size

Default size

--- src/dactyl_keyboard/dactyl.clj
+++ src/dactyl_keyboard/dactyl.clj
@@ -19,7 +19,7 @@
 (def α (/ π 12))                        ; curvature of the columns
 (def β (/ π 36))                        ; curvature of the rows
 (def centerrow (- nrows 3))             ; controls front-back tilt
-(def centercol 3)                       ; controls left-right tilt / tenting (higher number is more tenting)
+(def centercol 2)                       ; controls left-right tilt / tenting (higher number is more tenting)
 (def tenting-angle (/ π 12))            ; or, change this for more precise tenting control
 (def column-style
   (if (> nrows 5) :orthographic :standard))  ; options include :standard, :orthographic, and :fixed


CMR-2884: Fixing collection validation test.

--- system-int-test/test/cmr/system_int_test/ingest/collection_validation_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/collection_validation_test.clj
@@ -338,14 +338,14 @@
 ;; namespaces.
 ;; Currently in the process of moving validation too UMM Spec Lib. Some validation tests
 ;; are in cmr.umm-spec.test.validation
-(deftest collection-umm-validation-test
+(deftest collection-umm-spec-validation-test
   (testing "UMM-C JSON-Schema validation"
     ;; enable return of schema validation errors from API
     (side/eval-form `(icfg/set-return-umm-json-validation-errors! true))
     ;; create collection valid against echo10 but invalid against schema
     (let [response (d/ingest "PROV1" (dc/collection {:product-specific-attributes
-                                                     [(dc/psa {:name "bool1" :data-type :boolean :value true})
-                                                      (dc/psa {:name "bool2" :data-type :boolean :value true})]})
+                                                      [(dc/psa {:name "bool1" :data-type :boolean :value true})
+                                                       (dc/psa {:name "bool2" :data-type :boolean :value true})]})
                              {:allow-failure? true})]
       (is (= {:status 422
               :errors ["object has missing required properties ([\"Platforms\",\"ProcessingLevel\",\"RelatedUrls\",\"ScienceKeywords\",\"SpatialExtent\",\"TemporalExtents\"])"]}
@@ -354,37 +354,40 @@
     (side/eval-form `(icfg/set-return-umm-json-validation-errors! false))
     (assert-valid {:product-specific-attributes [(dc/psa {:name "bool1" :data-type :boolean :value true})
                                                  (dc/psa {:name "bool2" :data-type :boolean :value true})]}))
+
+  (side/eval-form `(icfg/set-return-umm-spec-validation-errors! true))
+
   (testing "Additional Attribute validation"
     (assert-invalid
-      {:product-specific-attributes
+     {:product-specific-attributes
        [(dc/psa {:name "bool" :data-type :boolean :value true})
         (dc/psa {:name "bool" :data-type :boolean :value true})]}
-      ["AdditionalAttributes"]
-      ["Additional Attributes must be unique. This contains duplicates named [bool]."]))
+     ["AdditionalAttributes"]
+     ["Additional Attributes must be unique. This contains duplicates named [bool]."]))
   (testing "Nested Path Validation"
     (assert-invalid
-      {:platforms [(dc/platform {:instruments [(dc/instrument {:short-name "I1"})
-                                               (dc/instrument {:short-name "I1"})]})]}
-      ["Platforms" 0 "Instruments"]
-      ["Instruments must be unique. This contains duplicates named [I1]."]))
+     {:platforms [(dc/platform {:instruments [(dc/instrument {:short-name "I1"})
+                                              (dc/instrument {:short-name "I1"})]})]}
+     ["Platforms" 0 "Instruments"]
+     ["Instruments must be unique. This contains duplicates named [I1]."]))
   (testing "Spatial validation"
     (testing "geodetic polygon"
       ;; Invalid points are caught in the schema validation
       (assert-invalid-spatial
-        :geodetic
-        [(polygon 180 90, -180 90, -180 -90, 180 -90, 180 90)]
-        ["SpatialExtent" "HorizontalSpatialDomain" "Geometry" "GPolygons" 0]
-        ["Spatial validation error: The shape contained duplicate points. Points 1 [lon=180 lat=90] and 2 [lon=-180 lat=90] were considered equivalent or very close."
-         "Spatial validation error: The shape contained duplicate points. Points 3 [lon=-180 lat=-90] and 4 [lon=180 lat=-90] were considered equivalent or very close."
-         "Spatial validation error: The shape contained consecutive antipodal points. Points 2 [lon=-180 lat=90] and 3 [lon=-180 lat=-90] are antipodal."
-         "Spatial validation error: The shape contained consecutive antipodal points. Points 4 [lon=180 lat=-90] and 5 [lon=180 lat=90] are antipodal."]))
+       :geodetic
+       [(polygon 180 90, -180 90, -180 -90, 180 -90, 180 90)]
+       ["SpatialExtent" "HorizontalSpatialDomain" "Geometry" "GPolygons" 0]
+       ["Spatial validation error: The shape contained duplicate points. Points 1 [lon=180 lat=90] and 2 [lon=-180 lat=90] were considered equivalent or very close."
+        "Spatial validation error: The shape contained duplicate points. Points 3 [lon=-180 lat=-90] and 4 [lon=180 lat=-90] were considered equivalent or very close."
+        "Spatial validation error: The shape contained consecutive antipodal points. Points 2 [lon=-180 lat=90] and 3 [lon=-180 lat=-90] are antipodal."
+        "Spatial validation error: The shape contained consecutive antipodal points. Points 4 [lon=180 lat=-90] and 5 [lon=180 lat=90] are antipodal."]))
     (testing "geodetic polygon with holes"
       ;; Hole validation is not supported yet. See CMR-1173.
       ;; Holes are ignored during validation for now.
       (assert-valid-spatial
-        :geodetic
-        [(poly/polygon [(umm-s/ords->ring 1 1, -1 1, -1 -1, 1 -1, 1 1)
-                        (umm-s/ords->ring 0,0, 0.00004,0, 0.00006,0.00005, 0.00002,0.00005, 0,0)])]))
+       :geodetic
+       [(poly/polygon [(umm-s/ords->ring 1 1, -1 1, -1 -1, 1 -1, 1 1)
+                       (umm-s/ords->ring 0,0, 0.00004,0, 0.00006,0.00005, 0.00002,0.00005, 0,0)])]))
     (testing "cartesian polygon"
       ;; The same shape from geodetic is valid as a cartesian.
       ;; Cartesian validation is not supported yet. See CMR-1172
@@ -393,23 +396,24 @@

     (testing "geodetic line"
       (assert-invalid-spatial
-        :geodetic
-        [(l/ords->line-string :geodetic [0,0,1,1,2,2,1,1])]
-        ["SpatialExtent" "HorizontalSpatialDomain" "Geometry" "Lines" 0]
-        ["Spatial validation error: The shape contained duplicate points. Points 2 [lon=1 lat=1] and 4 [lon=1 lat=1] were considered equivalent or very close."]))
+       :geodetic
+       [(l/ords->line-string :geodetic [0,0,1,1,2,2,1,1])]
+       ["SpatialExtent" "HorizontalSpatialDomain" "Geometry" "Lines" 0]
+       ["Spatial validation error: The shape contained duplicate points. Points 2 [lon=1 lat=1] and 4 [lon=1 lat=1] were considered equivalent or very close."]))

     (testing "cartesian line"
       ;; Cartesian line validation isn't supported yet. See CMR-1172
       (assert-valid-spatial
-        :cartesian
-        [(l/ords->line-string :cartesian [180 0, -180 0])]))
+       :cartesian
+       [(l/ords->line-string :cartesian [180 0, -180 0])]))

     (testing "bounding box"
       (assert-invalid-spatial
-        :geodetic
-        [(m/mbr -180 45 180 46)]
-        ["SpatialExtent" "HorizontalSpatialDomain" "Geometry" "BoundingRectangles" 0]
-        ["Spatial validation error: The bounding rectangle north value [45] was less than the south value [46]"]))))
+       :geodetic
+       [(m/mbr -180 45 180 46)]
+       ["SpatialExtent" "HorizontalSpatialDomain" "Geometry" "BoundingRectangles" 0]
+       ["Spatial validation error: The bounding rectangle north value [45] was less than the south value [46]"])))
+  (side/eval-form `(icfg/set-return-umm-spec-validation-errors! false)))

 (deftest duplicate-entry-title-test
   (testing "same entry-title and native-id across providers is valid"


Re-add :standard-out appender which has been renamed to :println in timbre 4. Fixes #248

--- src/onyx/static/logging_configuration.clj
+++ src/onyx/static/logging_configuration.clj
@@ -20,7 +20,10 @@
                                   :min-level :info)]
         (timbre/merge-config!
           {:appenders
-           {:rotor rotor-appender}})))
+           {:println
+            {:min-level :error
+             :enabled? true}
+            :rotor rotor-appender}})))

     (info "Starting Logging Configuration")
     component)


fix typo

fix typo

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1290,14 +1290,10 @@
                           :past "listened to"
                           :present {:3sing "listens to"}}}

-   "live" {:synsem {:cat :verb
-                    :sem {:pred :live-somewhere}
-                    :subcat {:2 '()}}}
-
-
-     "live" {:synsem {:cat :verb
-                    :sem {:pred :live}
-                    :subcat {:2 '()}}}
+   "live" [{:synsem {:cat :verb
+                     :sem {:pred :live-somewhere}}}
+           {:synsem {:cat :verb
+                     :sem {:pred :live}}}]

     "look" {:share-sem :obj
            :synsem {:cat :verb


eliminated caerse, wrong

eliminated caerse, wrong

--- src/babel/espanol/lexicon.cljc
+++ src/babel/espanol/lexicon.cljc
@@ -152,20 +152,7 @@
              {:synsem {:cat :verb
                        :sem {:pred :look-up}}}]
    "caber" {}
-   "caerse" (let [subject-semantics (atom {:human true})
-         subject-agr (atom :top)]
-     {:espanol {:boot-stem "diviert"}
-      :synsem {:cat :verb
-               :sem {:pred :have-fun
-                     :reflexive true
-                     :subj subject-semantics
-                     :obj subject-semantics}
-               :subcat {:1 {:agr subject-agr
-                            :sem subject-semantics}
-                        :2 {:agr subject-agr
-                            :pronoun true
-                            :reflexive true
-                            :sem subject-semantics}}}})
+   "caer"

    "cambiar" {:synsem {:cat :verb
                        :sem {:pred :change}}}


entered manually future and conditional of tener

--- src/babel/espanol/lexicon.cljc
+++ src/babel/espanol/lexicon.cljc
@@ -780,7 +780,18 @@
                         :number :sing}
                   :subcat '()}}

-    "tener" {:espanol {:futuro-stem "tendr"
+    "tener" {:espanol {:futuro {:1sing "tendré"
+                             :2sing "tendras"
+                             :3sing "tendrà"
+                             :1plur "tendremos"
+                             :2plur "tendréis"
+                             :3plur "tendràn"}
+                   :condicional {:1sing "tendrìa"
+                             :2sing "tendrìas"
+                             :3sing "tendrìa"
+                             :1plur "tendrìamos"
+                             :2plur "tendrìais"
+                             :3plur "tendrìan"}
                    :present {:1sing "tengo"
                              :2sing "tienes"
                              :3sing "tiene"


Remove old code

Remove old code

--- src/braid/ui/views/header.cljs
+++ src/braid/ui/views/header.cljs
@@ -1,49 +1,8 @@
 (ns braid.ui.views.header
-  (:require [chat.client.dispatcher :refer [dispatch!]]
-            [chat.client.routes :as routes]
+  (:require [chat.client.routes :as routes]
             [chat.client.views.helpers :refer [id->color]]
             [chat.client.reagent-adapter :refer [subscribe]]
-            [braid.ui.views.pills :refer [tag-pill-view user-pill-view]]
             [braid.ui.views.search-bar :refer [search-bar-view]]))
-
-
-(defn users-online-pane-view []
-  (let [open-group-id (subscribe [:open-group-id])
-        user-id (subscribe [:user-id])
-        users (subscribe [:users-in-open-group :online])]
-    (fn []
-      (let [users (->> @users
-                       (remove (fn [user]
-                                   (= @user-id
-                                      (user :id)))))
-            path (routes/users-page-path {:group-id @open-group-id})]
-        [:div.users.shortcut {:class (when (routes/current-path? path) "active")}
-          [:a.title {:href path
-                     :title "Users"}
-                  (count users)]
-                 [:div.modal
-                  [:h2 "Online"]
-                  (for [user users]
-                    ^{:key (user :id)}
-                    [user-pill-view (user :id)])]]))))
-
-
-
-
-
-#_(defn header-view []
-  (let [group-id (subscribe [:open-group-id])
-        admin? (subscribe [:current-user-is-group-admin?] [group-id])]
-    (fn []
-    [:div.header
-     [clear-inbox-button-view]
-     [inbox-page-button-view]
-     [recent-page-button-view]
-     [users-online-pane-view]
-     [tags-pane-view]
-     [group-settings-view]
-     [search-bar-view]
-     [current-user-button-view]])))

 (defn inbox-page-button-view []
   (let [open-group-id (subscribe [:open-group-id])]


Updated breadcrumbs

Updated breadcrumbs

--- src/hurvinek/html_renderer.clj
+++ src/hurvinek/html_renderer.clj
@@ -97,7 +97,7 @@
         [:body
             [:div {:class "container"}
                 (render-navigation-bar-section url-prefix title)
-                (render-breadcrumb url-prefix)
+                (render-breadcrumb url-prefix "help" "Help")
                 [:div {:class "container-fluid"}
                     [:h2 "Help"]
                 ]
@@ -114,7 +114,7 @@
         [:body
             [:div {:class "container"}
                 (render-navigation-bar-section url-prefix title)
-                (render-breadcrumb url-prefix)
+                (render-breadcrumb url-prefix "database-statistic" "Database statistic")
                 [:div {:class "container-fluid"}
                     [:h2 "Database statistic"]
                 ]
@@ -131,7 +131,7 @@
         [:body
             [:div {:class "container"}
                 (render-navigation-bar-section url-prefix title)
-                (render-breadcrumb url-prefix)
+                (render-breadcrumb url-prefix "export-database" "Export database")
                 [:div {:class "container-fluid"}
                     [:h2 "Export database"]
                 ]


Record data into mongoDB as well as postgres.

--- src/circle/web/views/index.clj
+++ src/circle/web/views/index.clj
@@ -7,17 +7,16 @@
         ring.util.response)
   (:use [circle.db :only (with-conn)])
   (:use [ring.util.response :only (redirect)])
+  (:require [somnium.congomongo :as mongo])
   (:require [circle.model.beta-notify :as beta])
   (:require [noir.session :as session]))

-(defpage [:post "/"] {:as request}
-  (with-conn
-    (beta/insert {:email (:email request)
-                  :contact (= "true" (:contact request))
-                  :environment ""
-                  :features ""
-                  :session_key nil})
+(defpage [:post "/"] {:keys [email contact]}
+  (let [bool-contact (= "true" contact)]
+    (mongo/insert! :signups
+                   {:email email :contact bool-contact})
+    (with-conn (beta/insert {:email email :contact bool-contact}))
     (session/flash-put! true)
     (redirect "/")))


Pull simple-link->map into manga-fox closure

--- src/clj/comic_reader/sites.clj
+++ src/clj/comic_reader/sites.clj
@@ -8,24 +8,23 @@
     {:name (process-name name)
      :url (process-url url)}))

-(def simple-link->map (gen-link->map identity identity))
-
 (def list
   [(let [canonical-url "http://mangafox.me"
          manga-url (format "%s/manga/" canonical-url)
-         manga-pattern (re-pattern (str manga-url "(.*?)/"))]
+         manga-pattern (re-pattern (str manga-url "(.*?)/"))
+         link->map (gen-link->map identity identity)]
      {:id :manga-fox
       :name "Manga Fox"

       :comic-list-data {:url manga-url
                         :selector [:div.manga_list :ul :li :a]
-                        :normalize simple-link->map}
+                        :normalize link->map}
       :chapter-list-data-for-comic
       (fn [comic-url]
         {:url comic-url
          :selector [:div#chapters :ul.chlist
                     :li :div :h3 :a]
-         :normalize simple-link->map})
+         :normalize link->map})
       :url->feed (fn [url]
                    (some->> url
                             (re-matches manga-pattern)


All aboard the hype train!

All aboard the hype train!

--- src/clj/mokkameister/train.clj
+++ src/clj/mokkameister/train.clj
@@ -51,6 +51,7 @@
    (train-coffee :heart)
    (train-coffee :heart)
    (train-coffee :heartpulse)
+   (train-coffee :blockchain)
    (train-coffee :syringe)
    (train-coffee :mushroom)
    (train-coffee :coffeepot)
@@ -83,6 +84,7 @@
    (train-coffee :badger :mushroom)
    (train-coffee :coffeepot :heart)
    (train-coffee :simply_overcaffeinated :coffeespin)
+   (train :blockchain)
    (train :coffeealarm)
    (train :nespresso :ali)
    (train :ali :gruff)


Make svg->png conversion route public

Make svg->png conversion route public

--- src/clj/salava/file/routes.clj
+++ src/clj/salava/file/routes.clj
@@ -45,8 +45,6 @@
              (GET "/as-png" []
                   :query-params [image :- s/Str]
                   :summary "Convert svg image to png"
-                  :auth-rules access/authenticated
-                  :current-user current-user
                   (let [bytes (f/svg->png ctx image)]
                     (if bytes
                       {:status 200


only push gmark text to component when entering edit mode

this didn't cause any bugs but it doesn't seem like a good idea and/or
necessary to be copying from app state to local state when we /close/
the edit box.

--- src/cljs/greffe/doc_comps.cljs
+++ src/cljs/greffe/doc_comps.cljs
@@ -113,8 +113,9 @@
              (dom/div #js {:className "controls"}
                (dom/a #js {:onClick
                            (fn [ev]
-                             (om/set-state! owner
-                               :editContent (gm/to-gmark @elem tei))
+                             (when-not (om/get-state owner :editText)
+                               (om/set-state! owner
+                                 :editContent (gm/to-gmark @elem tei)))
                              (om/set-state!
                                owner
                                :editText


Update rfc links on sign/jws ns.

Update rfc links on sign/jws ns.

--- src/clojure/buddy/sign/jws.clj
+++ src/clojure/buddy/sign/jws.clj
@@ -13,8 +13,9 @@
 ;; limitations under the License.

 ;; Links to rfcs:
-;; - http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-19
-;; - http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-25
+;; - http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32
+;; - http://tools.ietf.org/html/draft-ietf-jose-json-web-signature-40
+;; - https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40

 (ns buddy.sign.jws
   "Json Web Signature implementation."


Fixed typo.

Fixed typo.

--- src/clojure/freactive/dom.cljs
+++ src/clojure/freactive/dom.cljs
@@ -671,7 +671,7 @@
     (let [id (new-reactive-id)
           state (ReactiveElement. id parent nil false false false nil  nil)

-          ref-meta (meta ref)
+          ref-meta (meta child-ref)

           get-new-elem (fn []
                          (set! (.-dirty state) false)


Fixed bug in cond parenthesis

Fixed bug in cond parenthesis

--- src/compojure/http/servlet.clj
+++ src/compojure/http/servlet.clj
@@ -98,10 +98,10 @@
       (with-open [out (.getOutputStream response)]
         (copy-stream body out)
         (.close body)
-        (.flush out)))
+        (.flush out))
     (instance? File body)
       (with-open [stream (FileInputStream. body)]
-        (set-body stream)))
+        (set-body stream))))

 (defn update-response
   "Update the HttpServletResponse using a response map."


Update docstring for «explore-attributes»

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

--- src/conexp/fca/exploration.clj
+++ src/conexp/fca/exploration.clj
@@ -78,6 +78,10 @@
       object has, and «negative-attributes» is a sequence of attributes the new object
       does not have.  Note that «positive-attributes» and «negative-attributes» must be
       disjoint.
+
+    Note that it is the responsibility of the handler to ensure that the counterexample is
+    correct.  If this is not the case, the exploration algorithm will just ask the same
+    question in the next iteration again.

   - :background-knowledge «set of implications»


removed debug stmt

removed debug stmt

--- src/corpus_utils/wikipedia.clj
+++ src/corpus_utils/wikipedia.clj
@@ -62,7 +62,6 @@
          :or   {hiragana 0 katakana 0 kanji 0}}
         (into {} (x/by-key identity x/count)
               (sequence (comp (map str) (map char-writing-system)) text))]
-    (println hiragana katakana kanji text)
     (if (and
           (> length 50)
           (> (/


filtered non-japanese docs and added :title tags

--- src/corpus_utils/wikipedia.clj
+++ src/corpus_utils/wikipedia.clj
@@ -4,7 +4,8 @@
             [corpus-utils.document :refer :all]
             [schema.core :as s]
             [clojure.java.io :as io]
-            [corpus-utils.utils :as utils]))
+            [corpus-utils.utils :as utils]
+            [clojure.string :as str]))

 (defn is-open? [s]
   (re-seq #"^<doc id" s))
@@ -31,23 +32,75 @@
    :corpus    "Wikipedia"
    :category  ["Wikipedia" "百科事典"]})

+(defn char-writing-system
+  "Return writing system type of char.
+  To get codepoint of char: `(.codePointAt char 0)`.
+  Converting code point into char: `(char 0x3041)`."
+  [^String ch]
+  (let [code-point (.codePointAt ch 0)]
+    (cond
+     (and (>= code-point 0x3041) (<= code-point 0x309f)) :hiragana
+     (and (>= code-point 0x4e00) (<= code-point 0x9fff)) :kanji
+     (and (>= code-point 0x30a0) (<= code-point 0x30ff)) :katakana
+     (or (and (>= code-point 65)    (<= code-point 122))    ; half-width alphabet (A-Za-z)
+         (and (>= code-point 65313) (<= code-point 65370))  ; full-width alphabet (Ａ-Ｚａ-ｚ)
+         (and (>= code-point 48)    (<= code-point 57))     ; half-width numbers  (0-9)
+         (and (>= code-point 65296) (<= code-point 65305))) ; full-width numbers  (０-９)
+     :romaji
+     (or (= code-point 12289) (= code-point 65291) (= code-point 44)) :commas ; [、，,] <- CHECK
+     :else :symbols)))
+
+(s/defn is-japanese? :- s/Bool
+  [doc :- [[s/Str] s/Str]]
+  (let [[_ lines] doc
+        text (str/join lines)
+        length (count text)
+        {:keys [hiragana katakana kanji]
+         :or {hiragana 0 katakana 0 kanji 0}}
+        (->> text (map str) (map char-writing-system) frequencies)]
+    (println length)
+    (if (and
+         (> length 50)
+         (> (/
+             (+ hiragana katakana kanji)
+             length)
+            0.5))
+      true)))
+
 (s/defn process-doc :- DocumentSchema
-  [metadata
-   doc]
-  (let [[[header] lines] doc]
+  [metadata :- {:year s/Num :month s/Num :day s/Num}
+   doc :- [[s/Str] s/Str]]
+  (let [[[header] lines] doc
+        paragraphs (-> lines
+                       drop-last ; Drop closing </doc> and split into paragraphs and lines.
+                       (text/lines->paragraph-sentences identity))]
     {:metadata (let [[id title] (extract-header header)]
                  (make-sources-record title (:year metadata) id))
-     :paragraphs (-> lines drop-last text/lines->paragraph-sentences text/add-tags)})) ; Drop closing </doc>, split and add (dummy) tags.
+     :paragraphs (update-in
+                  (mapv (fn [sentences]
+                          {:tags (if (and (= 1 (count sentences))
+                                          (= \. (last (first sentences))))
+                                   #{:title} ; Also subsumes subtitles.
+                                   #{})
+                           :sentences sentences})
+                        paragraphs)
+                  [0 :tags] conj :title)}))

 (s/defn document-seq :- [DocumentSchema]
   "Given a suitable (quasi)XML file generated from a Wikipedia dump, returns a lazy sequence of maps containing sources meta-information and parsed paragraphs."
   [filename :- s/Str]
-  (let [metadata (->> (utils/read-tsv (str filename ".metadata.tsv") true) first (map #(try (Integer/parseInt %) (catch Exception e))) (zipmap [:year :month :day]))
+  (let [metadata (->> (utils/read-tsv (str filename ".metadata.tsv") true)
+                      first
+                      (map #(try (Integer/parseInt %) (catch Exception e)))
+                      (zipmap [:year :month :day]))
         lines (line-seq (io/reader filename))]
-    (->> lines
-         (partition-by is-open?)
-         (partition-all 2)
-         (map (partial process-doc metadata)))))
+    (sequence
+     (comp
+      (partition-by is-open?)
+      (partition-all 2)
+      (filter is-japanese?)
+      (map (partial process-doc metadata)))
+     lines)))

 (comment
   (s/with-fn-validation (document-seq "/data/Wikipedia/jawiki-20160113-text-small.xml")))


Fix NamespaceOfFile

Fix NamespaceOfFile

--- src/de/kotka/gorilla/nails.clj
+++ src/de/kotka/gorilla/nails.clj
@@ -91,20 +91,19 @@
                  *in*)
         eof    (Object.)
         of-interest '#{in-ns ns clojure.core/in-ns clojure.core/ns}
-        in-seq (repeatedly #(read in false eof))]
-    (let [candidate
-          (drop-while #(and (not= % eof)
-                            (or (not (instance? clojure.lang.ISeq %))
-                                (not (contains? of-interest (first %)))))
-                      in-seq)]
-      (when (not= candidate eof)
-        (let [candidate (first candidate)]
-          (cond
-            ('#{ns clojure.core/ns} (first candidate))
-            (println (second candidate))
-
-            ('#{in-ns clojure.core/in-ns} (first candidate))
-            (println (second (second candidate)))))))))
+        in-seq (repeatedly #(read in false eof))
+        candidate (first
+                    (drop-while #(and (not= % eof)
+                                      (or (not (instance? clojure.lang.ISeq %))
+                                          (not (contains? of-interest
+                                                          (first %)))))
+                                in-seq))]
+    (println
+      (cond
+        (= candidate eof)                                "user"
+        ('#{ns clojure.core/ns} (first candidate))       (second candidate)
+        ('#{in-ns clojure.core/in-ns} (first candidate)) (second (second candidate))
+        :else                                            (println "user")))))

 (defnail NamespaceInfo
   "Usage: ng de.kotka.gorilla.nails.NamespaceInfo [--] namespace ..."


add clj-logging-config logger by default

Adds a default log setup through clj-logging-config.
a log4j dependency is no longer is shipped with the newer version of
ring.middleware.logger, so we need to explicitly include it.

closes #218

--- src/leiningen/new/chestnut.clj
+++ src/leiningen/new/chestnut.clj
@@ -16,6 +16,7 @@
                             [ring/ring-defaults "0.3.1"]
                             [bk/ring-gzip "0.2.1"]
                             [radicalzephyr/ring.middleware.logger "0.6.0"]
+                            [clj-logging-config "1.9.12"]
                             [compojure "1.6.0"]
                             [environ "1.1.0"]
                             [com.stuartsierra/component "0.3.2"]


fixed a bug with dashes not being replaced with

underscores

--- src/leiningen/new/onyx_app.clj
+++ src/leiningen/new/onyx_app.clj
@@ -34,8 +34,10 @@
                          "docker-compose.yml")))

 (defn render-files [files name data]
-  (mapv (juxt (fn [path] (clojure.string/replace path #"onyx_app" name)) (fn [file-path] (render file-path data)))
-       files))
+  (let [name (clojure.string/replace name #"-" "_")]
+    (mapv (juxt (fn [path] (clojure.string/replace path #"onyx_app" name))
+                (fn [file-path] (render file-path data)))
+          files)))

 (defn onyx-app
   "Creates a new Onyx application template"


Don't import utils twice in auth.models.

--- src/lunchlotto/auth/models.clj
+++ src/lunchlotto/auth/models.clj
@@ -2,8 +2,7 @@
   (:require [clj-time.coerce :as coerce]
             [clj-time.core :as time]
             [clojure.java.jdbc :as jdbc])
-  (:require [lunchlotto.auth.utils :as utils]
-            [lunchlotto.auth.utils :as auth-utils]))
+  (:require [lunchlotto.auth.utils :as utils]))

 (defn register-user
   "Register a new user in the database. Assumes that the email address has
@@ -79,5 +78,5 @@
                                      WHERE is_confirmed=true
                                        AND email=?" email]))]
     (when (and user
-               (auth-utils/check-password password (:password user)))
+               (utils/check-password password (:password user)))
       user)))


Function to render breadcrumb and updated front page style

--- src/hurvinek/html_renderer.clj
+++ src/hurvinek/html_renderer.clj
@@ -51,6 +51,17 @@
         ] ; </div .container-fluid>
 ]); </nav>

+(defn render-breadcrumb
+    "Render the breadcumb at the top of page."
+    [url-prefix
+     product-id product-name
+     chapter-id chapter-name
+     group-id group-name]
+    [:ol {:class "breadcrumb"}
+         [:li [:a {:href url-prefix} "Hurvinek"]]
+         [:li product-name]]
+         )
+
 (defn render-front-page
     "Render front page of this application."
     [url-prefix title]
@@ -59,8 +70,15 @@
         [:body
             [:div {:class "container"}
                 (render-navigation-bar-section url-prefix title)
+                (render-breadcrumb url-prefix nil nil nil nil nil nil)
                 [:div {:class "container-fluid"}
-                [:p 42]
+                    [:h1 "Main menu"]
+                    [:table {:class "table table-hover"}
+                        [:tr [:td [:a {:href "select-product"} "Select product"]]]
+                        [:tr [:td [:a {:href "database-statistic"} "Database statistic"]]]
+                        [:tr [:td [:a {:href "export-database"} "Export database"]]]
+                        [:tr [:td [:a {:href "help"} "Help"]]]
+                    ]
                 ]
                 (render-html-footer)
             ] ; </div class="container">
@@ -75,6 +93,7 @@
         [:body
             [:div {:class "container"}
                 (render-navigation-bar-section url-prefix title)
+                (render-breadcrumb url-prefix nil nil nil nil nil nil)
                 [:div {:class "container-fluid"}
                 [:h2 "Product list"]
                 [:table {:style "border-collapse: separate; border-spacing: 10px;"}
@@ -119,7 +138,7 @@
             [:div {:class "container"}
                 (render-navigation-bar-section url-prefix title)
                 [:div {:class "container-fluid"}
-                [:h2 (str "Chapters for product " product-name " and chapter " chapter-name)]
+                [:h2 (str "Chapters ▶ for product " product-name " and chapter " chapter-name)]
                 [:table {:style "border-collapse: separate; border-spacing: 10px;"}
                     (for [group group-list]
                         [:tr


minor; can't keywordize type

minor; can't keywordize type

--- src/onyx/compression/nippy.clj
+++ src/onyx/compression/nippy.clj
@@ -25,7 +25,7 @@
           {:tag (keyword tag)
            :value value
            :deserialize-attempted? true
-           :deserialize-exception-type (keyword (type ex))})))))
+           :deserialize-exception-type (type ex)})))))

 (nippy/extend-thaw :onyx/exception-info
                    [data-input]


core - rename effect and supporting fns to :http-xhrio to reflect explicit API. Remove imposing response-format default

--- src/re_frame_http_fx/core.cljs
+++ src/re_frame_http_fx/core.cljs
@@ -5,11 +5,11 @@
     [ajax.core          :as ajax]
     [cljs.spec          :as s]))

-;; I provide the :http effect handler leveraging cljs-ajax lib
+;; I provide the :http-xhrio effect handler leveraging cljs-ajax lib
 ;; see API docs https://github.com/JulianBirch/cljs-ajax
 ;; Note we use the ajax-request.
 ;;
-;; Deviation from cljs-ajax options in http-spec
+;; Deviation from cljs-ajax options in request
 ;; :handler       - not supported, see :on-success and :on-failure
 ;; :on-success    - event vector dispatched with result
 ;; :on-failure    - event vector dispatched with result
@@ -20,7 +20,7 @@
 ;;       [:success-event "my-token" result]

-(defn ajax-handler
+(defn ajax-xhrio-handler
   "ajax-request only provides a single handler for success and errors"
   [on-success on-failure xhrio [success? response]]
   ; see http://docs.closure-library.googlecode.com/git/class_goog_net_XhrIo.html
@@ -36,35 +36,32 @@
       (on-failure details))))

-
-(defn spec->ajax-options
+(defn request->xhrio-options
   [{:as   request
-    :keys [on-success on-failure api response-format]
+    :keys [on-success on-failure]
     :or   {on-success      [:http-no-on-success]
-           on-failure      [:http-no-on-failure]
-           api             (new js/goog.net.XhrIo)
-           response-format (ajax/detect-response-format)}}]
-  ; wrap events in cljs-ajax callbacks
+           on-failure      [:http-no-on-failure]}}]
+  ; wrap events in cljs-ajax callback
+  (let [api (new js/goog.net.XhrIo)]
   (-> request
       (assoc
-        :api             api
-        :response-format response-format
-        :handler        (partial ajax-handler
-                                 #(dispatch (conj on-success %))
-                                 #(dispatch (conj on-failure %))
-                                 api))
-      (dissoc :on-success :on-failure)))
+        :api     api
+        :handler (partial ajax-xhrio-handler
+                          #(dispatch (conj on-success %))
+                          #(dispatch (conj on-failure %))
+                          api))
+      (dissoc :on-success :on-failure))))

 (s/def ::sequential-or-map (s/or :list-or-vector sequential? :map map?))

 (def-fx
-  :http
+  :http-xhrio
   (fn http-effect [request]
     (when (= :cljs.spec/invalid (s/conform ::sequential-or-map request))
       (console :error (s/explain-str ::sequential-or-map request)))
     ;;TODO verify detail request(s) using spec for ajax-request api
     (cond
       (sequential? request) (doseq [each request] (http-effect each))
-      (map? request)        (-> request spec->ajax-options ajax/ajax-request)
+      (map? request)        (-> request request->xhrio-options ajax/ajax-request)
       :else
       (console :error "re-frame-http-fx: expected request to be a list or vector or map, but got: " request))))


Allow users to toggle containers while running (#1814)

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -228,6 +228,9 @@
                                        (or current-tab (build-utils/default-tab build scopes))
                                        container-id)
            :on-click #(when (not= container-id selected-container-id)
+                        (when (or (= status-class :status-class/running)
+                                  (= status-class :status-class/waiting))
+                          (raise! owner [:container-selected {:container-id container-id}]))
                         ((om/get-shared owner :track-event) {:event-type :container-selected
                                                              :properties {:old-container-id selected-container-id
                                                                           :new-container-id container-id}}))


Use smaller objects as React keys

Use smaller objects as React keys

--- src/sinusoides/components.cljs
+++ src/sinusoides/components.cljs
@@ -207,7 +207,7 @@

     [:div.programs
      (for [p @entries]
-       ^{:key p}
+       ^{:key (:slug p)}
        [:a {:href (routes/do- {:id (:slug p)})
             :style {:background-image
                     (str "url(\"/static/screens/" ((:imgs p) 0) "\")")}}
@@ -274,12 +274,12 @@
                        :transition-enter-timeout 3000
                        :transition-leave-timeout 3000}
       (match [(:view @app)]
-        [[:am]]    ^{:key am-view}   [am-view sin am]
-        [[:do]]    ^{:key do-view}   [do-view sin do]
-        [[:init]]  ^{:key init-view} [init-view]
-        [[:main]]  ^{:key main-view} [main-view sin]
-        [[:todo]]  ^{:key todo-view} [todo-view sin]
-        :else      ^{:key not-found-view} [not-found-view sin])]]))
+        [[:am]]    ^{:key :am-view}   [am-view sin am]
+        [[:do]]    ^{:key :do-view}   [do-view sin do]
+        [[:init]]  ^{:key :init-view} [init-view]
+        [[:main]]  ^{:key :main-view} [main-view sin]
+        [[:todo]]  ^{:key :todo-view} [todo-view sin]
+        :else      ^{:key :not-found-view} [not-found-view sin])]]))

 (defn init-components! [state]
   (r/render-component


change name of 2nd nav to menu for clarity

--- frontend/components/aside.cljs
+++ frontend/components/aside.cljs
@@ -138,7 +138,7 @@
             settings (get-in app state/settings-path)
             controls-ch (om/get-shared owner [:comms :controls])]
         (html
-         [:nav.aside-left-nav.context
+         [:nav.aside-left-menu
           (om/build context-menu app)
           [:div.aside-activity.open
            [:div.wrapper


:art: Use relative path for default Viewer URL

--- frontend/src/uxbox/config.cljs
+++ frontend/src/uxbox/config.cljs
@@ -7,5 +7,5 @@
 (ns uxbox.config)

 (goog-define url "http://127.0.0.1:6060/api")
-(goog-define viewurl "http://127.0.0.1:3449/view/index.html")
+(goog-define viewurl "/view/index.html")
 (goog-define isdemo false)


cleanup str->sym aliases on source reset

--- src/main/shadow/build/data.clj
+++ src/main/shadow/build/data.clj
@@ -235,13 +235,14 @@
           ))))

 (defn remove-source-by-id [state resource-id]
-  (let [rc (get-in state [:sources resource-id])]
+  (let [{:keys [ns] :as rc} (get-in state [:sources resource-id])]
     (if-not rc
       state
       (-> state
           (remove-output-by-id resource-id)
           (update :immediate-deps dissoc resource-id)
           (remove-provides rc)
+          (update :str->sym dissoc ns)
           (update :sources dissoc resource-id)
           ))))


Don't re-sort the spaces, to ensure that the integration tests are last

--- src/test/clojure/all_tests.clj
+++ src/test/clojure/all_tests.clj
@@ -1,4 +1,4 @@
-; Copyright 2009 Howard M. Lewis Ship
+; Copyright 2009, 2010 Howard M. Lewis Ship
 ;
 ; Licensed under the Apache License, Version 2.0 (the "License");
 ; you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@

 (println "Loading code ...")

-(time (apply use (sort spaces)))
+(time (apply use spaces))

 (println "Executing tests ...")


util/hadoop.clj: require log, remove old commented-out fns

--- src/org/altlaw/util/hadoop.clj
+++ src/org/altlaw/util/hadoop.clj
@@ -1,4 +1,5 @@
-(ns org.altlaw.util.hadoop)
+(ns org.altlaw.util.hadoop
+  (:require [org.altlaw.util.log :as log]))

 (defn import-hadoop
   []
@@ -102,29 +103,3 @@
                   (Text. (pr-str value)))))))

-
-;; (defmulti conf [job key value]
-;;           (fn [job key value] key))
-
-;; (defmethod conf :in [job key value]
-;;   (FileInputFormat/setInputPaths job value))
-
-;; (defmethod conf :out [job key value]
-;;   (FileInputFormat/setOutputPaths job (Path. value)))
-
-;; (defmethod conf :mapper [job key value]
-;;   (.setMapperClass job value))
-
-;; (defmethod conf :reducer [job key value]
-;;   (.setReducerClass job value))
-
-;; (defmethod conf :reducers [job key value]
-;;   (.setNumReduceTasks job value))
-
-;; (defmethod conf :input-format [job key value]
-;;   (.setInputFormat job
-;;                    (cond
-;;                     (= value :seq) SequenceFileInputFormat
-;;                     (= value :text) TextInputFormat
-;;                     (= value :keyval) KeyValueTextInputFormat
-;;                     )))


rename for clarity

rename for clarity

--- src/clj/lambdacd/internal/execution.clj
+++ src/clj/lambdacd/internal/execution.clj
@@ -178,8 +178,8 @@
          cur-args args]
     (if (empty? remaining-steps-with-id)
       result
-      (let [step (first remaining-steps-with-id)
-            step-result (execute-step cur-args step)
+      (let [ctx-and-step (first remaining-steps-with-id)
+            step-result (execute-step cur-args ctx-and-step)
             step-output (first (vals (:outputs step-result)))
             new-result (cons step-result result)
             new-args (-> step-output


Remove comment, no longer valid as we removed the deprecated namespace it was referring to

--- src/clj/lambdacd/stepsupport/output.clj
+++ src/clj/lambdacd/stepsupport/output.clj
@@ -74,8 +74,6 @@
   ```
   "
   [ctx & body]
-  ; CODE DUPLICATED in `lambdacd.steps.support` because it's tricky delegating it to this macro.
-  ; Get rid of the deprecated code the next time you feel like changing it
   `(let [{x#      :writer
           buffer# :buffer} (writer-to-ctx ~ctx)
          body-result# (binding [*out* x#]


don't auto-reload clj files from cljs-build

--- src/clj/rksm/cloxp_cljs/compilation.clj
+++ src/clj/rksm/cloxp_cljs/compilation.clj
@@ -57,6 +57,16 @@
         (swap! builds assoc project-dir build)
         build))))

+; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+; cljs build related
+
+(defonce cljsbuild-reload-lib-orig clojurescript-build.core/reload-lib)
+
+(defn patch-cljs-build-reload
+  []
+  (alter-var-root
+   #'clojurescript-build.core/reload-lib
+   (fn [_] (fn [resource]))))

 ; -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 ; DEPRECATED (?)


Removed channels from state management

Removed channels from state management

--- src/clj_bots/pin_ctrl/state_wrapper.clj
+++ src/clj_bots/pin_ctrl/state_wrapper.clj
@@ -45,13 +45,6 @@
     (pcp/read-value impl-board (get (pcp/pin-modes board) pin-n) pin-n))
   (stateful-write-value! [board pin-n val]
     (pcp/write-value! impl-board (get (pcp/pin-modes board) pin-n) pin-n val))
-  (get-edge-chan [board pin-n]
-    (get-in @state-atom [:edge-channels pin-n]))
-  (set-edge-chan! [board pin-n ch]
-    (swap!
-      @state-atom
-      update-in
-      (fn [old-chan] (async/close! old-chan) ch)))

   pcp/PEdgeDetectablePin
   (set-edge! [_ pin-n edge f]


Remove rendering ctx: only basic rendering needed.

--- src/clojure/ch/hood/odpg/impl/expdp.clj
+++ src/clojure/ch/hood/odpg/impl/expdp.clj
@@ -19,7 +19,7 @@
 	 :directory                    s/Str
 	 (s/optional-key :remote-link) s/Str})

-(defn render-schema-metadatafilter [ctx schemas]
+(defn render-schema-metadatafilter [schemas]
 	(let [schema-names (keys schemas)
 				schema-names (map double-quote schema-names)
 				schema-names (str/join ", " schema-names)]
@@ -35,7 +35,7 @@
 		:exclude-tables "NOT IN"))

 (defn render-table-metadatafile
-	([ctx filter-type table-names]
+	([filter-type table-names]
 	 (let [table-names (map double-quote table-names)
 				 table-names (str/join ", " table-names)]
 		 (str "dbms_datapump.metadata_filter("
@@ -44,15 +44,15 @@
 					"value => '" (filter-type-operator filter-type) " (" table-names ")', "
 					"object_type => 'TABLE'"
 					");")))
-	([ctx schemas]
+	([schemas]
 		;; if we come here, we have the guarantee of a single schema mode. see validate.
 	 (let [filter-types [:include-tables :exclude-tables]
 				 tables ((apply juxt filter-types) (get schemas (-> schemas keys first)))
-				 tables (map #(when (not (nil? %2)) (render-table-metadatafile ctx %1 %2)) filter-types tables)
+				 tables (map #(when (not (nil? %2)) (render-table-metadatafile %1 %2)) filter-types tables)
 				 tables (filter (comp not nil?) tables)]
 		 (str/join "\n" tables))))

-(defn render-subquery-datafilter [ctx schema-name table-name subquery]
+(defn render-subquery-datafilter [schema-name table-name subquery]
 	(str "dbms_datapump.data_filter("
 			 "handle => handle, "
 			 "name => 'SUBQUERY', "
@@ -61,16 +61,16 @@
 			 "schema_name => '" schema-name "'"
 			 ");"))

-(defn render-subqueries-datafilter [ctx schema-name tables]
+(defn render-subqueries-datafilter [schema-name tables]
 	(->> tables
-			 (map #(render-subquery-datafilter ctx schema-name (first %) (second %)))
+			 (map #(render-subquery-datafilter schema-name (first %) (second %)))
 			 (str/join "\n")))

-(defn render-schemas [ctx {:keys [schemas]}]
-	(let [metadata-schema-filter (render-schema-metadatafilter ctx schemas)
-				table-metadata-filter (render-table-metadatafile ctx schemas)
+(defn render-schemas [{:keys [schemas]}]
+	(let [metadata-schema-filter (render-schema-metadatafilter schemas)
+				table-metadata-filter (render-table-metadatafile schemas)
 				subquery-filters (into {} (map #(vector (first %) (:subquery-filters (second %))) schemas))
-				data-filters (map #(render-subqueries-datafilter ctx (first %) (second %)) subquery-filters)]
+				data-filters (map #(render-subqueries-datafilter (first %) (second %)) subquery-filters)]
 		(str metadata-schema-filter "\n" table-metadata-filter "\n"
 				 (str/join "\n" data-filters))))

@@ -85,7 +85,7 @@
 		:log-file "dbms_datapump.KU$_FILE_TYPE_LOG_FILE"
 		:dump-file "dbms_datapump.KU$_FILE_TYPE_DUMP_FILE"))

-(defn render-add-file [ctx directory file-type file-basename]
+(defn render-add-file [directory file-type file-basename]
 	(str "dbms_datapump.add_file("
 			 "handle => handle, "
 			 "filename => '" (str file-basename (file-type-suffix file-type)) "', "
@@ -99,7 +99,7 @@
 				 (.get cal Calendar/MONTH) "_"
 				 (.get cal Calendar/DAY_OF_MONTH))))

-(defn render-header [ctx {:keys [remote-link file-prefix directory]}]
+(defn render-header [{:keys [remote-link file-prefix directory]}]
 	(let [file-basename (str file-prefix "_" (render-today))]
 		(str/join "\n"
 							["declare"
@@ -108,8 +108,8 @@
 							 "begin"
 							 (str "handle := dbms_datapump.open('EXPORT', 'SCHEMA'"
 										(if (nil? remote-link) "" (str ", remote_link => " (single-quote remote-link))) ");")
-							 (render-add-file ctx directory :dump-file file-basename)
-							 (render-add-file ctx directory :log-file (str file-basename "_exp"))
+							 (render-add-file directory :dump-file file-basename)
+							 (render-add-file directory :log-file (str file-basename "_exp"))
 							 ])))

 (defn validate [exp-data]
@@ -124,11 +124,10 @@
 (s/defn render-exp-script
 	([exp-data :- ExpData]
 		(validate exp-data)
-		(let [ctx nil]
-			(str/join "\n"
-								[(render-header ctx exp-data)
-								 (render-schemas ctx exp-data)
-								 (c/render-footer)])))
+		(str/join "\n"
+							[(render-header exp-data)
+							 (render-schemas exp-data)
+							 (c/render-footer)]))
 	([file exp-data :- ExpData]
 		(let [script (render-exp-script exp-data)]
 			(spit file script))))
@@ -146,9 +145,9 @@

 	(println (render-exp-script input))

-	(render-subqueries-datafilter nil "PERGO" {
-																						 "BOOKING_SETTER" "WHERE POINT_OF_SALE in ('2001', '200')"
-																						 "BOOKING_DELTA"  "WHERE Pth = 231"
-																						 })
+	(render-subqueries-datafilter "PERGO" {
+																				 "BOOKING_SETTER" "WHERE POINT_OF_SALE in ('2001', '200')"
+																				 "BOOKING_DELTA"  "WHERE Pth = 231"
+																				 })

-	(render-schema-metadatafilter nil (:schemas input)))
+	(render-schema-metadatafilter (:schemas input)))


improve lex.clj

improve lex.clj

--- src/clojure/org/mobileink/antlr/lex.clj
+++ src/clojure/org/mobileink/antlr/lex.clj
@@ -26,7 +26,7 @@
 (def ^:dynamic *rulemap* (atom nil))

 (defn- settoks [^String grammar]
-  (let [lexname (str grammar "Lexer")
+  (let [lexname grammar ;;  (str grammar "Lexer")
         lxr (eval `(new ~(Class/forName lexname) nil))
         toks (.getTokenNames lxr)
         tokmap (.getTokenTypeMap lxr)]
@@ -45,8 +45,11 @@
     (doseq [[k v] (sort @*tokmap*)]
       (println k ": " v))))

+(defn tok [^long i]
+  (@*tokmap* i))
+
 (defn- setrules [^String grammar]
-  (let [lexname (str grammar "Lexer")
+  (let [lexname grammar ;; (str grammar "Lexer")
         lxr (eval `(new ~(Class/forName lexname) nil))
         rules (.getRuleNames lxr)
         rulemap (.getRuleIndexMap lxr)]
@@ -72,7 +75,7 @@
    ^String file ;; file to parse
    ]
   (let [
-        lexname (str grammar "Lexer")
+        lexname grammar ;; (str grammar "Lexer")
         infile (ANTLRFileStream. file)
         lxr (eval `(new ~(Class/forName lexname) nil))
         devnull (.setInputStream lxr infile)
@@ -93,7 +96,7 @@
   [^String grammar ;; e.g. "org.mobileink.antlr.sym"
    ^String the-string ;; file to scan
    ]
-  (let [lexname (str grammar "Lexer")
+  (let [lexname grammar ; (str grammar "Lexer")
         strinput (ANTLRInputStream. the-string)
         lxr (eval `(new ~(Class/forName lexname) nil))
         devnull (.setInputStream lxr strinput)


Added a few more reps.

Added a few more reps.

--- src/overtunes/songs/at_all.clj
+++ src/overtunes/songs/at_all.clj
@@ -100,6 +100,12 @@
   (at (timing 0)
       (chord# (update-in I [:i] raise))))

-(defn play# [] (-> (bpm 160) (from 2) intro# first-bit# (speed-up 3/2) variation# final-chord#))
+(defn play# [] (->
+                 (bpm 160) (from 2)
+                 intro# intro#
+                 first-bit#
+                 (speed-up 3/2)
+                 first-bit# variation#
+                 final-chord#))

-; (play#)
+(play#)


Describe room on story start.

Describe room on story start.

--- src/tryclojure/models/eval.clj
+++ src/tryclojure/models/eval.clj
@@ -10,6 +10,7 @@
   (:require [clojure.string :as str])
   (:require [isla.story :as story])
   (:require [isla.library :as library])
+  (:require [isla.talk :as t])

   (:import java.io.File)
   (:import java.io.StringWriter
@@ -52,7 +53,7 @@
     (let [file-path (str/lower-case (str "stories/" story-name ".is"))
           story-str (slurp file-path)]
       (dosync (ref-set story (story/init-story story-str)))
-      "Are you sitting comfortably? Then, we shall begin.")
+      (t/room-intro (:room (:player (deref story)))))
     (throw (Exception. "You must specify the name of the story you want to load."))))

 (defmethod run-story-command :default [command expr] ;; normal command


Removed uneeded queued-agent

Removed uneeded queued-agent

--- src/polismath/queued_agent.clj
+++ src/polismath/queued_agent.clj
@@ -1,45 +0,0 @@
-(ns polismath.queued-agent
-  (:require [clojure.core.async :as async :refer [>!! <!! >! <! chan go]]))
-
-
-(defprotocol IQueuedAgent
-  (enqueue [this message])
-  (ping [this]))
-
-
-(defrecord QueuedAgent [agent queue]
-  IQueuedAgent
-  (enqueue [_ message]
-    (go (>! queue message)))
-  (ping [_]
-    (send agent identity)))
-
-
-(defn drain! [c]
-  (let [cc (chan 1)]
-    (go (>! cc ::queue-empty))
-    (letfn
-      ; This fn does all the hard work, but closes over cc to avoid reconstruction
-      [(drainer! [c]
-         (let [[v _] (<!! (go (async/alts! [c cc] :priority true)))]
-           (if (= v ::queue-empty)
-             (lazy-seq [])
-             (lazy-seq (cons v (drainer! c))))))]
-      (drainer! c))))
-
-
-(defn queued-agent [& {:keys [buffer update-fn init-fn error-handler-builder] :or {:buffer 1000000}}]
-  (let [q                (chan buffer)
-        a                (agent (if init-fn (init-fn) {}))
-        error-handler-fn (error-handler-builder q a)]
-    ; Set up the queue
-    (add-watch
-      a
-      :update-conv
-      (fn [k r o n]
-        (let [queued (drain! q)]
-          (when-not (empty? queued)
-            (send a update-fn queued error-handler-fn)))))
-    (QueuedAgent. a q)))
-
-


[fix 6501] sort chats by timestamps of last incoming message

Signed-off-by: yenda <96f164ad4d9b2b0dacf8ebee2bb1eeb3aa69adf1@status.im>

--- src/status_im/search/subs.cljs
+++ src/status_im/search/subs.cljs
@@ -31,4 +31,4 @@
  :search/filtered-home-items
  :<- [:search/filtered-active-chats]
  (fn [active-chats]
-   active-chats))
+   (sort-by #(-> % second :timestamp) > active-chats)))


working compare-triplets

working compare-triplets

--- src/hackerrank/compare_the_triplets.clj
+++ src/hackerrank/compare_the_triplets.clj
@@ -1,6 +1,6 @@
 (ns hackerrank.compare-the-triplets
-	(:require [clojure.java.io :as io]
-            [hackerrank.save-the-prisoner :refer :all])
+	(:require [clojure.java.io :as io])
+;;             [hackerrank.save-the-prisoner :refer :all])
   (:use [clojure.string :only (split join)]))

 ; https://www.hackerrank.com/challenges/compare-the-triplets
@@ -22,6 +22,8 @@
         b2 (parseInt (b0_t 2))

         max-points 100
+;;         http://stackoverflow.com/questions/940712/redefining-a-letd-variable-in-clojure-loop
+;;         locals never change, but you could use atom
         alice (atom 0)
         bob (atom 0)]

@@ -31,8 +33,8 @@
         (swap! person inc))

       ;; https://clojuredocs.org/clojure.core/swap!
-      (cond (and (> (compare a b) 0) (< @alice max-points)) (swap! alice inc)
-            (and (< (compare a b) 0) (< @bob max-points)) (swap! bob inc)))
+      (cond (and (> (compare a b) 0) (< @alice max-points)) (inc-points alice)
+            (and (< (compare a b) 0) (< @bob max-points)) (inc-points bob)))

     ;; https://clojuredocs.org/clojure.string/join
     (println (join " " [a0 a1 a2]))


Remove unnecessary `set-config!` destructuring

--- src/taoensso/carmine/locks.clj
+++ src/taoensso/carmine/locks.clj
@@ -15,7 +15,7 @@
   (atom {:conns {:pool (car/make-conn-pool)
                  :spec (car/make-conn-spec)}}))

-(defn set-config! [[k & ks] val] (swap! config assoc-in (cons k ks) val))
+(defn set-config! [ks val] (swap! config assoc-in ks val))

 (defmacro ^:private wcar
   [& body]


Adding minor fix

Adding minor fix

--- src/hasta_la_vista/core.clj
+++ src/hasta_la_vista/core.clj
@@ -125,8 +125,8 @@

   https://forums.couchbase.com/t/how-does-stale-query-work/870"
   [& args]
-  (let [  ^clojure.core.async.impl.channels.ManyToManyChannel chan                  (chan 5)
-          ^clojure.lang.PersistentHashMap                     config                (read-config "conf/app.edn") ]
+  (let [  ^clojure.core.async.impl.channels.ManyToManyChannel chan    (chan 5)
+          ^clojure.lang.PersistentHashMap                     config  (read-config "conf/app.edn") ]
     ;; INIT
     (log/info "init :: start")
     (log/info "checking config...")
@@ -146,11 +146,9 @@
                                                       thread-count          (get-in config [:ok :hasta-la-vista :thread-count])
                                                       thread-wait           (get-in config [:ok :hasta-la-vista :thread-wait]) ]
     (log/info (client/get-available-servers client))
-    (log/info "client-config" client-config "view-config" view-config)
     ;; creating N async threads
     (dotimes [i thread-count]
       (thread
-        (log/info "client-config" client-config "view-config" view-config)
         ;; inside a thread we usually process something
         ;; blocking like this thread sleeps for random(1000) ms
         ;; after the blocking part you send the message


Added call to goog.ui.Zippy.

Added call to goog.ui.Zippy.

--- src/tutorial/notepad/core.cljs
+++ src/tutorial/notepad/core.cljs
@@ -1,6 +1,6 @@
 (ns ^:figwheel-always tutorial.notepad.core
     (:require [goog.dom :as dom]
-              [goog.ui.Zippy :as zippy]))
+              [goog.ui.Zippy]))

 (enable-console-print!)

@@ -19,7 +19,8 @@
         content-element (dom/createDom "div" nil (.-content note))
         new-note-dom (dom/createDom "div" nil
                                     header-element content-element)]
-    (dom/appendChild (.-parent note) new-note-dom)))
+    (dom/appendChild (.-parent note) new-note-dom)
+    (goog.ui.Zippy. header-element content-element)))

 ;;"Main" function for page.


Add missing group component (stolen in shapes refactor).

--- src/uxbox/ui/shapes/group.cljs
+++ src/uxbox/ui/shapes/group.cljs
@@ -74,3 +74,9 @@
      [:g attrs
       (for [item (reverse (into [] xf items))]
         (rum/with-key item (str (:id item))))])))
+
+(def group-shape
+  (mx/component
+   {:render group-shape-render
+    :name "group-shape"
+    :mixins [mx/static]}))


Help by filling in assign-watermark-fn.

Help by filling in assign-watermark-fn.

--- src/workshop/challenge_6_3.clj
+++ src/workshop/challenge_6_3.clj
@@ -5,6 +5,10 @@

 (def workflow
   [[:read-segments :bucket-page-views]])
+
+(defn watermark-fn [segment]
+  ;;  <<< FILL ME IN >>>
+  )

 ;;; Catalogs ;;;

@@ -15,6 +19,7 @@
        :onyx/plugin :onyx.plugin.core-async/input
        :onyx/type :input
        :onyx/medium :core.async
+       :onyx/assign-watermark-fn ::watermark-fn
        :onyx/batch-size batch-size
        :onyx/batch-timeout batch-timeout
        :onyx/max-peers 1
@@ -42,7 +47,7 @@
     :onyx/doc "core.async plugin base lifecycle"}])

 ;; <<< BEGIN FILL ME IN PART 1 >>>
-
+;; Use an :onyx.triggers/watermark trigger.
 (def windows
   [])


Implement java static method lookup and fn application for :onyx/fn

--- src/onyx/peer/operation.clj
+++ src/onyx/peer/operation.clj
@@ -7,15 +7,32 @@
 (defn apply-function [f params segment]
   ((reduce #(partial %1 %2) f params) segment))

+(defn get-method-java [class-name method-name]
+  (let [ms (filter #(= (.getName %) method-name)
+                   (.getMethods (Class/forName class-name)))]
+    (if (= 1 (count ms))
+      (first ms)
+      (throw (Exception. (format "Multiple methods found for %s/%s. Only one method may be defined." class-name method-name))))))
+
+(defn build-fn-java
+  "Builds a clojure fn from a static java method.
+  Note, may be slower than it should be because of varargs, and the many
+  (unnecessary) calls to partial in apply-function above."
+  [method]
+  (fn [& args]
+    (.invoke ^java.lang.reflect.Method method nil #^"[Ljava.lang.Object;" (into-array Object args))))

 (defn kw->fn [kw]
   (try
-    (let [user-ns (symbol (name (namespace kw)))
-          user-fn (symbol (name kw))]
-      (or (ns-resolve user-ns user-fn)
+    (let [user-ns (name (namespace kw))
+          user-fn (name kw)]
+      (or (try (ns-resolve (symbol user-ns) (symbol user-fn))
+               (catch Throwable _))
+          (build-fn-java (get-method-java user-ns user-fn))
           (throw (Exception.))))
     (catch Throwable e
-      (throw (ex-info "Could not resolve symbol on the classpath, did you require the file that contains this symbol?" {:symbol kw})))))
+      (throw (ex-info "Could not resolve symbol on the classpath, did you require the file that contains this symbol?"
+                      {:symbol kw :exception e})))))

 (defn resolve-fn [task-map]
   (kw->fn (:onyx/fn task-map)))


Add event-debug-on and event-debug-off fns to print all event info to the REPL for easy monitoring.

--- src/overtone/libs/event.clj
+++ src/overtone/libs/event.clj
@@ -6,6 +6,7 @@
             [overtone.libs.handlers :as handlers]))

 (defonce handler-pool (handlers/mk-handler-pool "Overtone Event Handlers"))
+(defonce event-debug* (atom false))

 (defn on-event
   "Asynchronously runs handler whenever events of event-type are
@@ -101,6 +102,8 @@
   (event ::filter-sweep-done :instrument :phat-bass)"
   [event-type & args]
   (log/debug "event: " event-type " " args)
+  (when @event-debug*
+    (println "event: " event-type " " args "\n"))
   (binding [overtone.libs.handlers/*log-fn* log/error]
     (let [event-info (if (and (= 1 (count args))
                               (map? (first args)))
@@ -114,7 +117,17 @@
   new threads which generate events, these will revert back to the
   default behaviour of event (i.e. not forced sync). See event."
   [event-type & args]
-  (log/debug "sync-event: " event-type args)
+  (log/debug "sync-event: " event-type " " args)
+  (when @event-debug*
+    (println "sync-event: " event-type " " args "\n"))
   (binding [overtone.libs.handlers/*log-fn* log/error]
     (let [event-info (apply hash-map args)]
       (apply handlers/sync-event handler-pool event-type event-info))))
+
+(defn event-debug-on
+  []
+  (reset! event-debug* true))
+
+(defn event-debug-off
+  []
+  (reset! event-debug* false))


Make father drum louder.

Make father drum louder.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -290,7 +290,7 @@
   (drum 150 :pan -0.75))

 (defmethod live/play-note :father [_]
-  (drum 75 :pan 0))
+  (drum 75 :pan 0 :vol 1.0))

 (definst horn [freq 440 vol 0.5 pan 0]
   (-> (sin-osc freq)


Change a description of an option

Change a description of an option

--- src/whisper2cyanite/cli.clj
+++ src/whisper2cyanite/cli.clj
@@ -207,7 +207,7 @@
     (str "Cassandra batch size. Default: " mstore/default-cassandra-batch-size)
     :parse-fn #(Integer/parseInt %)
     :validate [#(< 0 %) "Must be a number > 0"]]
-   [nil "--cassandra-batch-rate RATE" "Cassandra batch rate (batches per second)"
+   [nil "--cassandra-batch-rate RATE" "Cassandra batch rate (batches per second, 1-100)"
     :parse-fn #(Integer/parseInt %)
     :validate [#(< 0 % 101) "Must be a number between 1-100"]]
    [nil "--disable-metric-store" "Disable writing to metric store"]


sort task list by priority

sort task list by priority

--- src/cljs/iwaswhere_web/ui/entry/briefing.cljs
+++ src/cljs/iwaswhere_web/ui/entry/briefing.cljs
@@ -105,7 +105,9 @@
                              (filter (u/pvt-filter conf @entries-map) linked-entries))
             current-filter (get linked-filters (:filter @local))
             filter-fn (u/linked-filter-fn @entries-map current-filter put-fn)
-            linked-entries (filter filter-fn linked-entries)]
+            linked-entries (->> linked-entries
+                                (filter filter-fn)
+                                (sort-by #(-> % :task :priority)))]
         [:div.linked-tasks
          [:div
           [:strong "Tasks:"]
@@ -117,13 +119,12 @@
           (for [linked linked-entries]
             (let [ts (:timestamp linked)]
               ^{:key ts}
-              [:li
-               {:on-click (up/add-search ts tab-group put-fn)}
+              [:li {:on-click (up/add-search ts tab-group put-fn)}
                (when-let [prio (-> linked :task :priority)]
                  [:span.prio {:class prio} prio])
                [:strong (some-> linked
                                 :md
-                                (s/replace "#habit" "")
+                                (s/replace "#task" "")
                                 (s/replace "##" "")
                                 s/trim
                                 s/split-lines


Simplified schema

Simplified schema

--- src/main/clojure/stl_collector/transforms.clj
+++ src/main/clojure/stl_collector/transforms.clj
@@ -18,7 +18,7 @@
   [[p0 p1 p2] :- m/Face]
   (mp/cross-product (x/- p1 p0) (x/- p2 p0)))

-(s/defn normalize :- [m/Facet]
+(s/defn normalize :- m/STL
   [vertices :- [m/Face]]
   (for [face vertices]
     {:normal (normal face)


Use new hmac ns on tests.

Use new hmac ns on tests.

--- test/buddy/test_buddy_sign.clj
+++ test/buddy/test_buddy_sign.clj
@@ -2,7 +2,7 @@
   (:require [clojure.test :refer :all]
             [buddy.core.codecs :refer :all]
             [buddy.core.sign :as sign]
-            [buddy.core.hmac :as hmac]
+            [buddy.core.mac.hmac :as hmac]
             [buddy.sign.generic :as gsign]
             [buddy.core.keys :refer :all]
             [clojure.java.io :as io])
@@ -125,9 +125,7 @@

     (testing "Sign/Verify salted hmac with string"
       (let [sig (hmac/shmac-sha256 "foo" secretkey "salt")]
-        (is (true? (hmac/shmac-sha256-verify "foo" sig secretkey "salt")))))
-
-))
+        (is (true? (hmac/shmac-sha256-verify "foo" sig secretkey "salt")))))))

 (deftest high-level-sign-tests
   (testing "Signing/Unsigning with default keys"


Simple test for broadcast variables.

Simple test for broadcast variables.

--- test/flambo/broadcast_test.clj
+++ test/flambo/broadcast_test.clj
@@ -1,6 +1,18 @@
 (ns flambo.broadcast-test
-  (:use midje.sweet))
+  (:use midje.sweet)
+  (:require [flambo.api :as f]
+            [flambo.conf :as conf]
+            [flambo.broadcast :as b]))
+

 (facts
  "about broadcast"
- (future-fact "some tests"))
+  (let [conf (-> (conf/spark-conf)
+                 (conf/master "local[*]")
+                 (conf/app-name "broadcast-test"))]
+    (f/with-context c conf
+      (let [bc (b/broadcast c {:one "foo"})]
+        (-> (f/parallelize c [1 2 3 4 5])
+            (f/foreach
+             (f/fn [x]
+               (fact "foo" (b/value bc) => {:one "foo"}))))))))


allow scheme to be specified for http connections

--- joplin.elasticsearch/src/joplin/elasticsearch/database.clj
+++ joplin.elasticsearch/src/joplin/elasticsearch/database.clj
@@ -107,8 +107,8 @@
 ;; ============================================================================
 ;; Functions for use within migrations

-(defn client [{:keys [host port]}]
-  (es/connect (str "http://" host ":" port)))
+(defn client [{:keys [scheme host port] :or {scheme "http"}}]
+  (es/connect (str scheme "://" host ":" port)))

 (defn native-client [{:keys [host port native-port cluster]}]
   (let [es-port (or native-port port)]


added agent, derefs and wait. Currently our agents are failing and we have no clue why

--- src/simple_symbolic_regression_clojure/gp.clj
+++ src/simple_symbolic_regression_clojure/gp.clj
@@ -68,7 +68,9 @@
   (assoc individual :score score))

 (defn get-score [individual]
-  (:score individual))
+  (when-not (deref (:score individual))
+    (await (:score individual)))
+  (deref (:score individual)))

 ;;; Generating random scripts, individuals, etc.
@@ -99,9 +101,8 @@
 (defn score-using-rubrics
   "assigns the score value of an Individual by invoking `total-score-on` a set of Rubrics"
   [individual rubrics]
-  (let [my-atom (atom nil)
-        my-agent (agent 0)]
-  (set-score individual @(send my-agent total-score-on (:script individual) rubrics))))
+  (let [my-agent (agent nil)]
+  (set-score individual (send my-agent total-score-on (:script individual) rubrics))))

 (defn score-population


Tap on bubble to enable command input

Tap on bubble to enable command input

Former-commit-id: 5e38d5589a73678b7749b48b720b708616fe798a

--- src/syng_im/components/chat/chat_message.cljs
+++ src/syng_im/components/chat/chat_message.cljs
@@ -92,34 +92,35 @@

 (defn message-content-command-request [content outgoing text-color background-color]
   (let [{:keys [command content]} (commands/parse-command-request-msg-content content)]
-    [view {:style {:marginTop 10}}
-     [view {:style (merge {:borderRadius      6
-                           :paddingVertical   12
-                           :paddingHorizontal 16}
-                          (if outgoing
-                            {:backgroundColor "#D3EEEF"}
-                            {:backgroundColor background-color}))}
-      [text {:style (merge {:fontSize   14
-                            :fontFamily "Avenir-Roman"}
+    [touchable-highlight {:onPress (fn []
+                                     (set-chat-command command))}
+     [view {}
+      [view {:style (merge {:marginTop         15
+                            :borderRadius      6
+                            :paddingVertical   12
+                            :paddingHorizontal 16}
                            (if outgoing
-                             {:color "#4A5258"}
-                             {:color text-color}))}
-       content]]
-     [touchable-highlight {:style {:position    "absolute"
-                                   :top         -15
-                                   :left        20}
-                           :onPress (fn []
-                                      (set-chat-command command))}
-      [view {:style {:width           30
+                             {:backgroundColor "#D3EEEF"}
+                             {:backgroundColor background-color}))}
+       [text {:style (merge {:fontSize   14
+                             :fontFamily "Avenir-Roman"}
+                            (if outgoing
+                              {:color "#4A5258"}
+                              {:color text-color}))}
+        content]]
+      [view {:style {:position        "absolute"
+                     :top             0
+                     :left            20
+                     :width           30
                      :height          30
                      :borderRadius    50
                      :backgroundColor (:color command)}}
        [image {:source res/att
-               :style  {:width  17
-                        :height 14
+               :style  {:width    17
+                        :height   14
                         :position "absolute"
-                        :top 8
-                        :left 6}}]]]]))
+                        :top      8
+                        :left     6}}]]]]))

 (defn message-content [{:keys [content-type content outgoing text-color background-color]}]
   (if (= content-type content-type-command-request)


add docstring to and cleanup reported-elements function

--- src/vip/data_processor/db/tree_statistics.clj
+++ src/vip/data_processor/db/tree_statistics.clj
@@ -7,16 +7,23 @@
             [vip.data-processor.db.translations.util :as t-util]))

 (defn reported-elements []
+  "Function to generate elements to use in the error-query; starting with the
+   column names from the v5_statistics table we have to manipulate the headings
+   where necessary to remove polling locations (i.e. starts-with PollingLocation)
+   and ev_polling_locations and db_polling_locations
+   (i.e. ends with PollingLocation) as their stats are all calculated by the
+   v5_statistics.polling_locations_by_type function"
   (->> postgres/v5-statistics
        postgres/column-names
        (filter #(str/ends-with? % "_count"))
-       (remove #(str/starts-with? % "polling_location"))
        (map #(str/replace % #"_count" ""))
        (map t-util/column->xml-elment)
-       (remove #(str/starts-with? % "PollingLocation"))))
+       (remove #(str/starts-with? % "PollingLocation"))
+       (remove #(str/ends-with? % "PollingLocation"))))

 (defn error-query []
   (let [element-paths (str/join "|" (reported-elements))]
+    (log/info element-paths)
     (str
      "WITH errors AS (SELECT element_type(errors.path) AS element_type,
                          COUNT(errors.severity) AS error_count


Validate instead of conform

Validate instead of conform

--- test/spec_tools/core_test.cljc
+++ test/spec_tools/core_test.cljc
@@ -146,7 +146,7 @@
                  :spec-tools.core-test$my-map$address/zip
                  :spec-tools.core-test$my-map$address/street}
                generated-keys))))
-    (testing "conforming"
+    (testing "validating"
       (let [value {::id 1
                    ::age 63
                    :boss true
@@ -157,4 +157,4 @@
                    :description "Liisa is a valid boss"
                    :address {:street "Amurinkatu 2"
                              :zip "33210"}}]
-        (is (= value (st/conform st-map value)))))))
+        (is (true? (s/valid? st-map value)))))))


(PDB-1031) Verify gc behavior in update race test

--- test/com/puppetlabs/puppetdb/test/command.clj
+++ test/com/puppetlabs/puppetdb/test/command.clj
@@ -1105,7 +1105,17 @@
         ;; that fact path, when the mytimestamp 1 value is still in
         ;; there.
         (test-msg-handler command-2c publish discard-dir
-          (is (not (extract-error-message publish))))))))
+          (is (not (extract-error-message publish))))
+
+        ;; Can we see the orphaned value '1', and does the global gc remove it.
+        (is (= 1 (count
+                  (query-to-vec
+                   "select id from fact_values where value_string = '1'"))))
+        (scf-store/garbage-collect! *db*)
+        (is (zero?
+             (count
+              (query-to-vec
+               "select id from fact_values where value_string = '1'"))))))))

 (deftest concurrent-catalog-updates
   (testing "Should allow only one replace catalogs update for a given cert at a time"


Stop 'boot show -u' from displaying "LATEST" dependencies as out of date

--- boot/pod/src/boot/pod.clj
+++ boot/pod/src/boot/pod.clj
@@ -255,7 +255,8 @@
   [env & {:keys [snapshots]}]
   (with-call-worker (boot.aether/update-always!))
   (let [v+ (if snapshots "(0,)" "RELEASE")]
-    (->> (for [[p v & _ :as coord] (->> env :dependencies (map canonical-coord))]
+    (->> (for [[p v & _ :as coord] (->> env :dependencies (map canonical-coord))
+                                   :when (not (= v "LATEST"))]
            (util/guard
              (let [env' (-> env (assoc :dependencies [(assoc coord 1 v+)]))
                    [p' v' & _ :as coord'] (->> (map :dep (resolve-dependencies env'))


Reformat docstring for parse-config-data

Reformat the docstring for parse-config-data so that there are
no more than 80 characters per line.

--- src/puppetlabs/trapperkeeper/config.clj
+++ src/puppetlabs/trapperkeeper/config.clj
@@ -87,8 +87,10 @@
            (get-in-config [this ks default] (get-in config ks default))))

 (defn parse-config-data
-  "Parses the .ini, .edn, .conf, .json, or .properties configuration file(s) and returns a map of configuration data.
-   If no configuration file is explicitly specified, will act as if it was given an empty configuration file."
+  "Parses the .ini, .edn, .conf, .json, or .properties configuration file(s)
+   and returns a map of configuration data. If no configuration file is
+   explicitly specified, will act as if it was given an empty configuration
+   file."
   [cli-data]
   {:post [(map? %)]}
   (let [debug? (or (:debug cli-data) false)]


(SERVER-246) Improve Error handling after timeout

Improve the error handling in the `with-jruby-puppet` macro
when borrowing an instance from the pool times out.

--- src/clj/puppetlabs/services/jruby/jruby_puppet_service.clj
+++ src/clj/puppetlabs/services/jruby/jruby_puppet_service.clj
@@ -81,9 +81,15 @@
     (with-jruby-puppet
       jruby-puppet
       jruby-service
-      (do-something-with-a-jruby-puppet-instance jruby-puppet)))"
+      (do-something-with-a-jruby-puppet-instance jruby-puppet)))
+
+  Will throw an IllegalStateException if borrowing an instance of
+  JRubyPuppet times out."
   [jruby-puppet jruby-service & body]
   `(loop [pool-instance# (jruby/borrow-instance ~jruby-service)]
+     (if (nil? pool-instance#)
+       (throw (IllegalStateException.
+                "Error: Attempt to borrow a JRuby instance from the pool timed out")))
      (if (core/retry-poison-pill? pool-instance#)
        (do
          (jruby-core/return-to-pool pool-instance#)


Small style fix.

Small style fix.

--- src/clojure/uncomplicate/neanderthal/internal/host/mkl.clj
+++ src/clojure/uncomplicate/neanderthal/internal/host/mkl.clj
@@ -361,12 +361,16 @@
     (throw (UnsupportedOperationException. INTEGER_UNSUPPORTED_MSG))))

 ;; ============ Real Vector Engines ============================================
-(def ^:private ones-double (->RealBlockVector nil nil nil true
-                                              (initialize double-accessor (create-data-source double-accessor 1024) 1.0)
-                                              1024 0 1))
-(def ^:private ones-float (->RealBlockVector nil nil nil true
-                                             (initialize float-accessor (create-data-source float-accessor 1024) 1.0)
-                                             1024 0 1))
+
+(def ^:private ones-double
+  (->RealBlockVector nil nil nil true
+                     (initialize double-accessor (create-data-source double-accessor 1024) 1.0)
+                     1024 0 1))
+
+(def ^:private ones-float
+  (->RealBlockVector nil nil nil true
+                     (initialize float-accessor (create-data-source float-accessor 1024) 1.0)
+                     1024 0 1))

 (deftype DoubleVectorEngine []
   Blas


Considering bad indexed for history-since

--- src/amindblowingworld/views.clj
+++ src/amindblowingworld/views.clj
@@ -42,7 +42,9 @@
     (response-png-image-from-bytes bytes)))

 (defn- get-history-since [event-id]
-  [(.length @events) (subvec @events event-id)])
+  (if (nil? @events)
+    [0 []]
+    [(.length @events) (if (>= event-id (.length @events)) [] (subvec @events event-id))]))

 (defn history-since [event-id]
   (json/write-str (get-history-since event-id)))


+TODOs

+TODOs

--- src/babel/italiano/grammar.cljc
+++ src/babel/italiano/grammar.cljc
@@ -103,6 +103,7 @@
    ug/h11
    head-first))

+;; <TODO: move most of the content to babel.ug as the above examples (c10,c21,h11) do.>
 (def c11-comp-subcat-1
   (let [subcat (atom :top)]
     (unify
@@ -194,7 +195,7 @@
     :comp {:synsem {:subcat '()}}
     :head {:synsem {:subcat '()}}}))

-;; </TODO: move to ug>
+;; </TODO: move most of the content to babel.ug>
 ;; -- END SCHEMA DEFINITIONS

 (def vp-non-pronoun


remove {:tense :past}: should be in lexical entries itself, not complication process

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -200,8 +200,7 @@
              ;; auxiliary to form its past form:
              essere-binary-categorization (atom :top)
              pred (atom :top)
-             sem (atom {:tense :past
-                        :pred pred})
+             sem (atom :top)
              subject (atom :top)
              infl (atom :top)]
          {:italiano {:infl infl}


remove incorrect entry for "nascere"

remove incorrect entry for "nascere"

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -1568,23 +1568,14 @@

     "muovere" {:synsem {:cat :verb
                         :sem {:pred :move}}}
-
-    "nascere"
-   {:italiano {:passato "nato"}
-    :synsem {:cat :verb
-             :essere true
-             :sem {:discrete false
-                   :pred :be-born
-                   :subj {:human true}
-                   :obj {:legible true}}}}
-
-   ;; non-comparative
-   ;; TODO: add comparative
+
    "nascere" {:synsem {:cat :verb
                       :essere true
                       :sem {:pred :be-born}}
              :italiano {:passato "nato"}}

+   ;; non-comparative
+   ;; TODO: add comparative
    "nero"
    (unify adjective
           {:synsem {:cat :adjective


Minor fixes on impl.handlers

Minor fixes on impl.handlers

--- src/catacumba/impl/handlers.clj
+++ src/catacumba/impl/handlers.clj
@@ -159,6 +159,8 @@
           (.set headersmap (name key) vals)
           (recur (rest headers)))))))

+(declare get-body)
+
 (extend-protocol io/IOFactory
   TypedData
   (make-reader [d opts]
@@ -188,7 +190,7 @@
   (make-input-stream [req opts]
     (io/make-input-stream (get-body req) opts))
   (make-output-stream [req opts]
-    (io/make-output-stream (get-body req) opts))
+    (io/make-output-stream (get-body req) opts)))

 (defn- build-request


Make the server namespace properly run jetty

--- src/clj/comic_reader/server.clj
+++ src/clj/comic_reader/server.clj
@@ -6,7 +6,8 @@
             [ring.middleware.params :refer [wrap-params]]
             [compojure.core  :as c]
             [compojure.route :as route]
-            [hiccup.page :as hp]))
+            [hiccup.page :as hp]
+            [ring.adapter.jetty :refer [run-jetty]]))

 (defn edn-response [data & [status]]
   {:status (or status 200)
@@ -48,3 +49,11 @@
   (route/resources "/"))

 (def app (wrap-params routes))
+
+(defn run-web-server [& [port]]
+  (let [port (Integer. (or port 10555))]
+    (print "Starting web server on port" port ".\n")
+    (run-jetty app {:port port :join? false})))
+
+(defn -main [& [port]]
+  (run-web-server port))


updated docs

updated docs

--- src/clj/forma/trends/filter.clj
+++ src/clj/forma/trends/filter.clj
@@ -19,8 +19,9 @@
   (i/matrix (take n (cycle (i/identity-matrix freq)))))

 (defn deseasonalize
-  "returns a deseasonalized vector based on the frequency `freq` of
-  the measurements in the supplied timeseries `ts`
+  "accepts a timeseries `ts` with frequency `freq` and returns a
+  vector with the seasonal component removed; the returned vector is
+  only the trend component and the idiosyncratic disturbance.

   Example:
     (deseasonalize 23 (s/sample-uniform 200))"


Only spawn jack-o-lanterns on Halloween

Only spawn jack-o-lanterns on Halloween

--- src/cljc/robinson/worldgen.cljc
+++ src/cljc/robinson/worldgen.cljc
@@ -28,6 +28,12 @@
      (:require-macros [robinson.macros :as rm]
                       [cljs.core.async.macros :refer [go go-loop]])))

+(defn halloween? []
+  (let [calendar (java.util.Calendar/getInstance)
+        month    (.get calendar java.util.Calendar/MONTH)
+        day-of-month (.get calendar java.util.Calendar/DAY_OF_MONTH)]
+    (and (= month 10)
+         (= day-of-month 31))))

 (defn rand-xy-in-circle
   [x y max-r]
@@ -254,7 +260,9 @@
                            :meadow        (rr/rand-nth [
                                             {:type :dirt}
                                             {:type :tall-grass}
-                                            {:type :tall-grass :items [(ig/gen-item :jack-o-lantern)]}
+                                            (if (halloween?)
+                                              {:type :tall-grass :items [(ig/gen-item :jack-o-lantern)]}
+                                              {:type :tall-grass})
                                             {:type :short-grass}
                                             {:type :short-grass}])
                            :jungle        (if (< t 0.1)


select-query-fn : Use Clojure data structures as much as possible

The code is slightly cleaner now (imho)

Signed-off-by: Pang Yan Han <22594c345857f664c61cd411f607c4d40a9d4af9@gmail.com>

--- src/cljs/cljs_nusmods/main.cljs
+++ src/cljs/cljs_nusmods/main.cljs
@@ -152,39 +152,36 @@
     (if (nil? (aget options "context"))
         (let [nrModules    (count ModulesMap)
               searchTerm   (.toUpperCase (aget options "term"))
+              ; vector of initial search results
               firstResults
                 (reduce
-                  (fn [resultsArray [moduleCode module]]
+                  (fn [resultsVec [moduleCode module]]
                     (let [moduleName (get module "name")
                           haystack   (str (.toUpperCase moduleCode)
                                           " "
                                           (.toUpperCase moduleName))]
                       (if (not= -1 (.indexOf haystack searchTerm))
-                          (.push resultsArray
-                                 (js-obj "id"   moduleCode
-                                         "text" (str moduleCode " "
-                                                     moduleName))))
-                      resultsArray))
-                  (array)
-                  ModulesMap)]
+                          (conj resultsVec
+                                {:id   moduleCode
+                                 :text (str moduleCode " " moduleName)})
+                          resultsVec)))
+                  []
+                  ModulesMap)
+              sortedSearchResults
+                (sort (fn [modA modB] (< (:id modA) (:id modB))) firstResults)]
           (aset options "context"
-                (js-obj "searchResults"
-                        (sort (fn [modA modB]
-                                (< (aget modA "id") (aget modB "id")))
-                              firstResults),
-                        "nrResults"
-                        (.-length firstResults)))))
-    ; options.page starts counting from 1
-    (if (< (* resultsPerPage (- (aget options "page") 1))
-           (aget (aget options "context") "nrResults"))
-        (let [i     (* resultsPerPage (- (aget options "page") 1))
-              limit (min (+ i resultsPerPage)
-                         (aget (aget options "context") "nrResults"))]
-          (aset result "more" true)
-          (doseq [k (range i limit)]
-            (.push (aget result "results")
-                   (nth (aget (aget options "context") "searchResults") k))))
-        (aset result "more" false))
+                (js-obj "searchResults" sortedSearchResults))))
+
+    (let [ctx           (aget options "context")
+          searchResults (aget ctx "searchResults")]
+      (if (not (empty? searchResults))
+          (let [resultsForCurrentPage (take resultsPerPage searchResults)
+                remSearchResults      (drop resultsPerPage searchResults)]
+            (aset result "more" true)
+            (aset (aget options "context") "searchResults" remSearchResults)
+            (doseq [r resultsForCurrentPage]
+              (.push (aget result "results")
+                     (js-obj "id" (:id r), "text" (:text r)))))))
     (aset result "context" (aget options "context"))
     ((aget options "callback") result)))


Extract the code allowing to add several cards to the card-list

--- src/cljs/clojure_rest/core.cljs
+++ src/cljs/clojure_rest/core.cljs
@@ -68,6 +68,14 @@
   (swap! app-state
     #(assoc-in % [:cards (:card-id card)] card)
   ))
+
+(defn add-cards!
+  "Add several cards to the application state"
+  [cards]
+  (let [to-id-pair #(vector (:card-id %) %)]
+    (swap! app-state
+     #(update-in % [:cards] merge (map to-id-pair cards))
+  )))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@@ -153,12 +161,8 @@

 (def fetch-and-render-app
   "Render the app - adding a fetching of data when the DOM is mounted"
-  (let [to-id-pair #(vector (:card-id %) %)
-        add-cards #(update-in %1 [:cards] merge (map to-id-pair %2))
-        add-cards! (fn [cards] (swap! app-state #(add-cards % cards)))]
-    (with-meta render-app
-     {:component-did-mount #(fake/fake-fetch! add-cards!)})
-  ))
+  (with-meta render-app
+    {:component-did-mount #(fake/fake-fetch! add-cards!)}))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;