add experimental unsafe cast

add experimental unsafe cast

--- src/main/clojure/cljs/core.cljc
+++ src/main/clojure/cljs/core.cljc
@@ -40,7 +40,8 @@
                                        unsafe-bit-and bit-shift-right-zero-fill mask bitpos caching-hash
                                        defcurried rfn specify! js-this this-as implements? array js-obj
                                        simple-benchmark gen-apply-to js-str es6-iterable load-file* undefined?
-                                       specify copy-arguments goog-define js-comment js-inline-comment])])
+                                       specify copy-arguments goog-define js-comment js-inline-comment
+                                       unsafe-cast])])
   #?(:cljs (:require-macros [cljs.core :as core]))
   (:require clojure.walk
             clojure.set
@@ -878,6 +879,12 @@
           (map #(core/str " * " (string/replace % #"^   " "") "\n"))
           (reduce core/str ""))
         " */"))))
+
+(core/defmacro unsafe-cast
+  "EXPERIMENTAL: Subject to change. Unsafely cast a value to a different type."
+  [t x]
+  (core/let [cast-expr (core/str "~{} = /** @type {" t "} */ (~{})")]
+    (core/list 'js* cast-expr x x)))

 (core/defmacro js-inline-comment
   "Emit an inline JavaScript comment."


Make event loop shutdown (probably).

Make event loop shutdown (probably).

--- src-cljs/kixi/hecuba/navigation.cljs
+++ src-cljs/kixi/hecuba/navigation.cljs
@@ -1,5 +1,5 @@
 (ns kixi.hecuba.navigation
-  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require-macros [cljs.core.async.macros :refer [go-loop]])
   (:require
    [om.core :as om :include-macros true]
    [om.dom :as dom :include-macros true]
@@ -23,7 +23,10 @@
     (reify
       om/IWillMount
       (will-mount [_]
-        (go (while true (let [n (<! in)] (.log js/console "Got an event!" n)))))
+        (go-loop []
+          (let [n (<! in)] (.log js/console "Got an event!" n)
+               (when (not= "stop" n)
+                 (recur)))))
       om/IWillUnmount ;; TODO requires go block to be terminate-able.
       (will-unmount [_]
         (put! in "stop"))


Remove term by setting to nil

Remove term by setting to nil

--- src/cljs/cglossa/search_inputs/cwb/extended.cljs
+++ src/cljs/cglossa/search_inputs/cwb/extended.cljs
@@ -76,29 +76,32 @@
             []
             parts)))

-(defn- construct-cqp-query [terms]
-  (let [parts (for [{:keys [interval word lemma? phonetic? start? end? features]} terms]
-                (let [attr   (cond
-                               lemma? "lemma"
-                               phonetic? "phon"
-                               :else "word")
-                      form   (if (empty? word)
-                               ".*"
-                               (cond-> word
-                                       start? (str word ".+")
-                                       end? (str ".+" word)))
-                      main   (str "(" attr "=\"" form "\" %c)")
-                      feats  (for [[name value] features]
-                               (str name "=\"" value "\""))
-                      [min max] interval
-                      interv (if (or min max)
-                               (str "[]{" (or min 0) "," (or max "") "} ")
-                               "")]
-                  (str interv "[" (str/join " & " (cons main feats)) "]")))]
+(defn- construct-cqp-query [terms query-term-ids]
+  (let [;; Remove ids whose corresponding terms have been set to nil
+        _      (swap! query-term-ids #(keep-indexed (fn [index id] (when (nth terms index) id)) %))
+        terms* (filter identity terms)                      ; nil means term should be removed
+        parts  (for [{:keys [interval word lemma? phonetic? start? end? features]} terms*]
+                 (let [attr   (cond
+                                lemma? "lemma"
+                                phonetic? "phon"
+                                :else "word")
+                       form   (if (empty? word)
+                                ".*"
+                                (cond-> word
+                                        start? (str word ".+")
+                                        end? (str ".+" word)))
+                       main   (str "(" attr "=\"" form "\" %c)")
+                       feats  (for [[name value] features]
+                                (str name "=\"" value "\""))
+                       [min max] interval
+                       interv (if (or min max)
+                                (str "[]{" (or min 0) "," (or max "") "} ")
+                                "")]
+                   (str interv "[" (str/join " & " (cons main feats)) "]")))]
     (str/join \space parts)))

-(defn wrapped-term-changed [wrapped-query terms index term]
-  (swap! wrapped-query assoc :query (construct-cqp-query (assoc terms index term))))
+(defn wrapped-term-changed [wrapped-query terms index query-term-ids term]
+  (swap! wrapped-query assoc :query (construct-cqp-query (assoc terms index term) query-term-ids)))

 (defn- interval-input [wrapped-query wrapped-term index]
   [:input.form-control.interval {:type        "text"
@@ -114,7 +117,7 @@
    [interval-input wrapped-query wrapped-term 1] "max"])

 (defn multiword-term [wrapped-query wrapped-term first? last? has-phonetic?
-                      show-remove-row-btn? show-remove-term-btn? remove-term-handler]
+                      show-remove-row-btn? show-remove-term-btn?]
   (let [term-val @wrapped-term]
     [:div.table-cell
      [:div
@@ -138,10 +141,9 @@
                                                   ;:on-change     #(on-text-changed)
                                                   :on-key-down   #(on-key-down % wrapped-query)}]
             (when show-remove-term-btn?
-              [:span.input-group-addon {:title " Remove word "
-                                        :style {:cursor "pointer"}
-                                        ;:on-click #(on-remove-term)
-                                        }
+              [:span.input-group-addon {:title    " Remove word "
+                                        :style    {:cursor "pointer"}
+                                        :on-click #(reset! wrapped-term nil)}
                [:span.glyphicon.glyphicon-minus]])
             (when last?
               [:div.add-search-word
@@ -189,31 +191,52 @@
   "Search view component with text inputs, checkboxes and menus
   for easily building complex and grammatically specified queries."
   [corpus wrapped-query show-remove-row-btn?]
-  (let [parts           (split-query (:query @wrapped-query))
-        terms           (construct-query-terms parts)
-        last-term-index (dec (count terms))]
-    (.log js/console (str terms))
-    [:div.multiword-container
-     [:form.form-inline.multiword-search-form {:style {:margin-left -30}}
-      [:div {:style {:display "table"}}
-       [:div {:style {:display "table-row"}}
-        (map-indexed (fn [index term]
-                       (let [wrapped-term          (reagent/wrap term
-                                                                 wrapped-term-changed
-                                                                 wrapped-query terms index)
-                             first?                (zero? index)
-                             last?                 (= index last-term-index)
-                             ;; Show buttons to remove terms if there is more than one term
-                             show-remove-term-btn? (pos? last-term-index)
-                             has-phonetic?         (:has-phonetic corpus)
-                             remove-term-handler   #()]
-                         (list (when-not first?
-                                 ^{:key (str "interval" index)}
-                                 [interval wrapped-query wrapped-term])
-                               ^{:key (str "term" index)}
-                               [multiword-term wrapped-query wrapped-term first? last?
-                                has-phonetic? show-remove-row-btn?
-                                show-remove-term-btn? remove-term-handler])))
-                     terms)]
-       (when (:has-headword-search corpus)
-         [headword-search-checkbox wrapped-query])]]]))
+  (let [;; This will hold a unique ID for each query term component. React wants a
+        ;; unique key for each component in a sequence, such as the set of search inputs
+        ;; in the multiword interface, and it will mess up the text in the search boxes
+        ;; when we remove a term from the query if we don't provide this. Using the index
+        ;; of the term is meaningless, since it does not provide any more information
+        ;; than the order of the term itself. What we need is a way to uniquely identify
+        ;; each term irrespective of ordering.
+        ;;
+        ;; Normally, the items in a list have some kind of database ID that we can use,
+        ;; but query terms don't. Also, we cannot just use a hash code created from the
+        ;; term object, since we may have several identical terms in a query. Hence, we
+        ;; need to provide this list of query term IDs containing a unique ID number for
+        ;; each term in the initial query (i.e., the one provided in the props when this
+        ;; component is mounted), and then we add a newly created ID when adding a query
+        ;; term in the multiword interface and remove the ID from the list when the term is
+        ;; removed. This is the kind of ugly state manipulation that React normally saves
+        ;; us from, but in cases like this it seems unavoidable...
+        query-term-ids (atom nil)]
+    (fn [corpus wrapped-query show-remove-row-btn?]
+      (let [parts           (split-query (:query @wrapped-query))
+            terms           (construct-query-terms parts)
+            last-term-index (dec (count terms))]
+        (when (nil? @query-term-ids)
+          (reset! query-term-ids (range (count terms))))
+        [:div.multiword-container
+         [:form.form-inline.multiword-search-form {:style {:margin-left -30}}
+          [:div {:style {:display "table"}}
+           [:div {:style {:display "table-row"}}
+            (map-indexed (fn [index term]
+                           (let [wrapped-term          (reagent/wrap term
+                                                                     wrapped-term-changed
+                                                                     wrapped-query terms index
+                                                                     query-term-ids)
+                                 term-id               (nth @query-term-ids index)
+                                 first?                (zero? index)
+                                 last?                 (= index last-term-index)
+                                 ;; Show buttons to remove terms if there is more than one term
+                                 show-remove-term-btn? (pos? last-term-index)
+                                 has-phonetic?         (:has-phonetic corpus)]
+                             (list (when-not first?
+                                     ^{:key (str "interval" term-id)}
+                                     [interval wrapped-query wrapped-term])
+                                   ^{:key (str "term" term-id)}
+                                   [multiword-term wrapped-query wrapped-term first? last?
+                                    has-phonetic? show-remove-row-btn?
+                                    show-remove-term-btn?])))
+                         terms)]
+           (when (:has-headword-search corpus)
+             [headword-search-checkbox wrapped-query])]]]))))


GAWB-1747: if ws has no entities of a type, mc's with that root ent. type will open their launch modals to no ent. selected

--- src/cljs/main/broadfcui/common/entity_table.cljs
+++ src/cljs/main/broadfcui/common/entity_table.cljs
@@ -131,7 +131,9 @@
        (fn [{:keys [current-page rows-per-page filter-text sort-column sort-order filter-group-index]} callback]
          (if (empty? entity-types)
            (callback {:group-count 0 :filtered-count 0 :rows []})
-           (let [type (nth entity-types filter-group-index)]
+           (let [type (if (clojure.string/blank? filter-group-index)
+                        (:initial-entity-type props)
+                        (nth entity-types filter-group-index))]
              (endpoints/call-ajax-orch
               {:endpoint (endpoints/get-entities-paginated (:workspace-id props) (name type)
                                                            {"page" current-page


fix multiplier to 0 crash bug

fix multiplier to 0 crash bug

--- Assets/game/board.clj
+++ Assets/game/board.clj
@@ -102,7 +102,7 @@
     (swap! CRASH-COUNT inc)
     (reset! TRICK-STREAK [])
     (reset! game.data/trick-score 0)
-    (reset! game.data/trick-multiplier 0)
+    (reset! game.data/trick-multiplier 1)
     (cmpt- legr UnityEngine.FixedJoint)
     (cmpt- legl UnityEngine.FixedJoint)
     (reset! STANDING false)


(defn sentences): allow for an optional spec argument

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -80,10 +80,13 @@
    (parse/parse (preprocess input) model)))

-(defn sentences []
-  (let [model (medium)]
-    (repeatedly #(println (str (let [expr (generate {:modified false
-                                                     :synsem {:cat :verb}}
+(defn sentences [ & [spec]]
+  (let [model (medium)
+        spec (if spec
+               (unifyc spec {:modified false})
+               {:modified false
+                :synsem {:cat :verb}})]
+    (repeatedly #(println (str (let [expr (generate spec
                                                     :model model)
                                      fo (fo expr :show-notes false)]
                                  (str (string/capitalize (nth fo 0))


More visibility for dev-db-in-file option

--- src/name_bazaar/server/dev.cljs
+++ src/name_bazaar/server/dev.cljs
@@ -73,6 +73,7 @@
                             :endpoints {:port 6200
                                         :middlewares [logging-middlewares]}
                             :web3 {:port 8549}
+                            :db {:opts {:memory true}}
                             :emailer {:print-mode? true
                                       :private-key "25677d268904ea651f84e37cfd580696c5c793dcd9730c415bf03b96003c09e9ef8"}
                             :ui {:public-key "2564e15aaf9593acfdc633bd08f1fc5c089aa43972dd7e8a36d67825cd0154602da47d02f30e1f74e7e72c81ba5f0b3dd20d4d4f0cc6652a2e719a0e9d4c7f10943"


clean out some old comments

clean out some old comments

--- src/block_chain/db.clj
+++ src/block_chain/db.clj
@@ -7,29 +7,7 @@
             [clj-leveldb :as ldb]
             ))

-;; DB namespace
-;; * collect various atom / ref types from project
-;; * remove implicit local references to stateful atoms
-;;   in varous namespaces
-;; * rewrite any atom-dependent functions to take data types
-;;   as explicit inputs
-;; * return matching data structure as output? OR take actual
-;;   atom and perform the transaction within the function
-
-;; Data Atoms:
-;; * chain.clj block-chain - (atom [])
-;; * peers.clj - peers - (atom #{})
-;; * transactions.clj - transactions -  (atom #{})
-
-;; Config / Switches
-;; * core.clj - running? - (atom true) (clean this out)
-;; * miner.clj - mine? (atom true)
-;; * net.clj - server - (atom nil)
-
 (def genesis-block (read-json (slurp (io/resource "genesis.json"))))
-
-(def chain-path (str (System/getProperty "user.home")
-                     "/.block_chain.json"))

 (defn json->bytes [val]
   (-> val


Fix :window/session-key doc error.

Fix :window/session-key doc error.

--- src/onyx/information_model.cljc
+++ src/onyx/information_model.cljc
@@ -353,7 +353,7 @@
              :added "0.8.0"}

             :window/session-key
-            {:doc "The key of the incoming segments to calculate a session window over. This key can represent any totally ordered domain, e.g. `:event-time`"
+            {:doc "The key of the incoming segments to calculate a session window over."
              :type :any
              :optional? true
              :added "0.8.0"}


fix baked jars

fix baked jars

--- src/cake/tasks/jar.clj
+++ src/cake/tasks/jar.clj
@@ -60,7 +60,9 @@

 (defn add-source-files [task & [opts]]
   (when-not (:omit-source *project*)
-    (add-path task :source-path {:includes "**/*.clj, **/*.java"})))
+    (add-path task :source-path {:includes "**/*.clj, **/*.java"}))
+  (when (:bake *project*)
+    (add-zipfileset task (bakepath opts :excludes "cake.clj"))))

 (defn build-context []
   (ant Copy {:todir "build/jar" :overwrite true}


Parallelize loading of datasets based off each file

* Trying parallelizing within each file first, which had good success
* Success when using pmap, which seems wrong
* Using agents, ran into issues on large datasets
* But agents worked well with multiple files

Idea for future:

* Parallelize by file if multiple files
* Else parallelize within file

--- src/cfpb/qu/loader.clj
+++ src/cfpb/qu/loader.clj
@@ -133,3 +133,50 @@
           (doseq [file sources]
             (load-csv-file table (str dir "/" file) columns)))))))

+(defn- pload-csv-file
+  "Given a table and CSV file name and the definitions of the table's
+columns, read the data from the CSV file, transform it, and insert it
+into the table."
+  [table file columns]
+  (with-open [in-file (io/reader (io/resource file))]
+    (let [data (parse-csv in-file)
+          headers (map keyword (first data))
+          data (map #(zipmap headers %) (rest data))
+          data (partition 1000 data)
+          agents (map agent data)]
+      (doseq [agent agents]
+        (send-off agent (fn [data]
+                          (doseq [datum data]
+                            (coll/insert table (cast-data datum columns))))))
+      (apply await-for 100000 agents))))
+
+(defn pload-dataset
+  "Given the name of a dataset, load that dataset from disk into the
+database. The dataset must be under the datasets/ directory as a
+directory containing a definition.json and a set of CSV files."
+  [name]
+  (let [dir (str "datasets/" name)
+        definition (-> (str dir "/definition.json")
+                       io/resource
+                       slurp
+                       (json/parse-string true))
+        tables (:tables definition)
+        slices (:slices definition)]
+    (save-dataset-definition name definition)
+    (with-db (get-db name)
+      (doseq [table (keys tables)]
+        (coll/remove table)
+        (let [tabledef (table tables)
+              indexes (get-indexes slices table)
+              sources (:sources tabledef)
+              columns (:columns tabledef)
+              agents (map agent sources)]
+          (set-indexes table indexes)
+          (doseq [agent agents]
+            (send-off agent (fn [file]
+                              (load-csv-file table (str dir "/" file) columns))))
+          (apply await-for 100000 agents))))))
+
+; (ensure-mongo-connection)
+; (with-out-str (time (load-dataset "county_taxes")))
+; (with-out-str (time (pload-dataset "county_taxes")))


Remove docsite generator. It moved to quil-site.

--- dev-resources/utils/docsite.clj
+++ dev-resources/utils/docsite.clj
@@ -1,217 +0,0 @@
-(ns utils.docsite
-  (:require [quil.helpers.docs :refer :all]
-            quil.core
-            [hiccup
-             [core :as h]
-             [page :as p]
-             [element :as e]
-             [util :as u]]
-            garden.core
-            [garden.units :refer [px]]
-            [garden.arithmetic :as ga]
-            [clojure.string :as string]
-            [clojure.java.io :as io]))
-
-(def fn-width (px 700))
-(def gray-background "#FAFAFA")
-(def column-width (px 200))
-
-(def index-page-columns [["Color" "Data" "Environment"]
-                         ["Image" "Transform" "Output" "Rendering" ]
-                         ["Math" "Typography"]
-                         ["Shape" "State" "Structure"]
-                         ["Lights, Camera" "Input"]])
-
-(def css
-  (garden.core/css
-
-   [[:body {:color "#333"}]
-    [:a {:color "#333"}]
-    [:p {:margin "0px"}]
-    [:.category-div :#toc
-     [:.category {:margin "0px 0px 7px 0px"}
-      [:a {:color "#D53E07"}]]
-     [:.subcategory {:margin "15px 0px 0px 0px"}
-      [:a {:color "#009900"}]]
-     [:.function {:margin-top "2px"}]]
-
-    [:.index-page
-     [:.wrapper {:margin "auto"
-                 :width (ga/* (count index-page-columns) column-width)}]
-
-     [:#title {:text-align "center"}]
-
-     [:.column {:display "inline-block"
-                :width column-width
-                :float "left"}]
-     [:.category-div {:background gray-background
-                      :margin "10px"
-                      :padding "10px"}]
-     [:#description {:font-size "18px"
-                     :text-align "center"}]]
-
-    [:.fn-page
-     [:.fns-wrapper {:width fn-width
-                     :margin "auto"}
-
-      [:h2 {:margin "10px 0px"}]
-
-      [:div.function {:background gray-background
-                      :margin "10px auto"
-                      :padding "10px"}
-       [:code {:margin-right "10px"}]
-       [:h3 {:margin "2px 0px"}]]
-
-      [:pre {:margin "0px"}]
-
-      [:dt {:margin-top "10px"}]
-
-      [:dl {:margin "0px"}]
-
-      [:.subcategory {:margin "30px auto 0px auto"}]]
-
-     [:#toc {:position "fixed"
-             :width column-width
-             :overflow-y "scroll"
-             :bottom "20px"
-             :top "0px"}]]]))
-
-(defn- get-page
-  "Converts hiccup-style body to full-blown page and returns it as string.
-class is string that will be used as class of body element in the page."
-  [class title body]
- (let [head [:head
-             [:meta {:name "description"
-                     :content (str "Quil is a clojure animation library for "
-                                   "creating interactive sketches. Quil is based on Processing.")}]
-             [:title title]
-             [:style css]]]
-   (p/html5 (list head [:body {:class class}
-                        body]))))
-
-(defn- as-url [str]
-  (-> str
-      (string/lower-case)
-      (string/replace  #"[ &,]" {" " "-"
-                                 "," ""
-                                 "&" "and"})))
-
-(defn- as-id [str]
-  (-> str
-      (string/lower-case)
-      (string/replace "?" "_q")))
-
-(defn- as-filename [& path]
-  (->> path (map as-url) (string/join "/")))
-
-(defn- as-filename-ext [& path]
-  (str (apply as-filename path) ".html"))
-
-(defn- link
-  ([to]
-    (link to to))
-  ([text to]
-     (link text to nil))
-  ([text to anchor]
-     (let [page (if to (as-filename-ext to) "")]
-      (e/link-to (if anchor
-                   (str page "#" (as-url (as-id anchor)))
-                   page)
-                 (u/escape-html text)))))
-
-(defn trim-docstring
-  "Removes extra spaces in the begginning of dostringing lines."
-  [dostringing]
-  (->> (string/split dostringing #"\n")
-       (map #(string/replace % #"^  " ""))
-       (string/join "\n")))
-
-(defn- function->html [fn-meta]
-  (let [{:keys [name arglists subcategory added doc
-                processing-name requires-bindings category]} fn-meta
-        fields (array-map
-                "Arguments" (map #(vector :code (pr-str %)) arglists)
-                "Docstring" [:pre (trim-docstring doc)]
-                "Works only inside sketch functions?" (if requires-bindings "Yes" "No")
-                "Original Processing method" (if processing-name
-                                               (if-let [link (link-to-processing-reference fn-meta)]
-                                                 [:code (e/link-to link processing-name)]
-                                                 [:code processing-name])
-                                               "None. It is present only in Quil.")
-                "Added in" added)]
-    [:div.function {:id (as-id name)}
-     [:h3 name]
-     [:dl (for [[key val] fields]
-            (list [:dt key] [:dd val]))]]))
-
-(defn- category->html [category fn-metas]
-  (let [{:keys [name fns subcategories]} category
-        subcat-id #(-> % :name (str "-subcategory") as-url)
-        fn-metas (reduce #(assoc %1 (:name %2) %2) {} fn-metas)
-        function->html (comp function->html fn-metas)
-        subcat->html (fn [subcat]
-                       (cons [:h3.subcategory
-                              {:id (as-id (subcat-id subcat))}
-                              (u/escape-html (:name subcat))]
-                             (map function->html (:fns subcat))))
-        subcat->toc (fn [subcat]
-                      (cons [:h4.subcategory (link (:name subcat) nil (subcat-id subcat))]
-                            (map #(vector :p.function (link % nil %)) (:fns subcat))))]
-    (list
-     [:div#toc
-      [:h3 (link "Back to index" "index")]
-      [:h3.category (link name name)]
-      (map #(vector :p.function (link % nil %)) fns)
-      (map subcat->toc (vals subcategories))]
-
-     [:div.fns-wrapper
-      [:h2 name]
-      (map function->html fns)
-      (mapcat subcat->html (vals subcategories))])))
-
-(defn generate-index-page [categories-map]
-  (letfn [(fns->html [fns page]
-            (map #(vector :p.function (link % page %)) fns))
-
-          (subcat->html [subcat page]
-            (cons [:h4.subcategory (link (:name subcat) page
-                                         (str (:name subcat) "-subcategory"))]
-                  (fns->html (:fns subcat) page)))
-
-          (category->html [category]
-            (let [{:keys [name fns subcategories]} category]
-              [:div.category-div
-               [:h3.category (link name)]
-               (fns->html fns name)
-               (map #(subcat->html % name) (vals subcategories))]))
-
-          (find-category [name]
-            (->> (vals categories-map)
-                 (filter #(= (:name %) name))
-                 (first)))
-
-          (column->html [column]
-            [:div.column (map (comp category->html find-category) column)])]
-    [:div.wrapper
-     [:h1#title "Quil 2.2.2 API"]
-     [:div#description
-      [:p "Quil is a clojure animation library for creating interactive sketches. "]
-      [:p
-       "Quil is based on " (e/link-to "http://processing.org" "Processing")
-       ". Check " (e/link-to "https://github.com/quil/quil" "Github repo") "."]]
-     (map column->html index-page-columns)]))
-
-(defn- generate-all [fn-metas folder]
-  (let [category-map (sorted-category-map fn-metas)]
-    (doseq [category (vals category-map)]
-      (let [html (get-page "fn-page" (str "Quil - " (:name category))
-                           (category->html category fn-metas))
-            file (as-filename-ext folder (:name category))]
-        (spit file html)))
-    (->> (generate-index-page category-map)
-         (get-page "index-page" "Quil API")
-         (spit (as-filename-ext folder "index")))))
-
-(generate-all @(resolve 'quil.core/fn-metas) "out")
-
-


remove REST export

remove REST export

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -8,7 +8,7 @@
             [org.httpkit.server :refer [with-channel on-close on-receive run-server send!]]
             [net.cgrand.enlive-html :refer [deftemplate set-attr append html substitute content]]
             [ceres.collector :refer [store] :as collector]
-            [ceres.curator :refer [get-recent-articles get-articles-count export-tweets get-news-diffusion get-news-frequencies get-month-distribution] :as curator]
+            [ceres.curator :refer [get-recent-articles get-articles-count get-news-diffusion get-news-frequencies] :as curator]
             [ceres.executor :refer [start-executor]]
             [gezwitscher.core :refer [start-filter-stream]]
             [clojure.java.io :as io]
@@ -109,27 +109,11 @@
        (assoc-in [:app :recent-articles] []))))

-(defn handle-export
-  "Parse date from query and create edn-string"
-  [query type]
-  (let [[y m d] (mapv read-string (clojure.string/split (get query "date") #"-" ))]
-    (case type
-      :tweets (export-tweets y m d)
-      :articles (str (curator/export-articles y m d true)
-                     (curator/export-articles y m d false))
-      "N/A")))
-

 (defroutes all-routes
   (resources "/")

   (GET "/tweets/ws" [] tweet-handler)
-
-  (GET "/tweets/export" request (let [query-params (-> request :query-params)]
-                                  (handle-export query-params :tweets)))
-
-  (GET "/articles/export" request (let [query-params (-> request :query-params)]
-                                    (handle-export query-params :articles)))

   (GET "/*" [] (if (= (:build @server-state) :prod)
                  (static-page)
@@ -171,7 +155,5 @@

   (stop-server)

-  @server-state
-

   )


make the Corp click directly on targeted Resource

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -350,8 +350,7 @@
              {:optional
               {:prompt "Trash 1 resource?"
                :effect (effect (resolve-ability
-                                 {:prompt "Choose a resource to trash"
-                                  :choices (req (get-in runner [:rig :resource]))
+                                 {:choices {:req #(and (= (:type %) "Resource"))}
                                   :msg (msg "trash " (:title target))
                                   :effect (effect (trash target))}))}}}}


Fixes for Project Atlas and Geist

Fixes for Project Atlas and Geist

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -8,7 +8,7 @@
 (def trash-hardware {:prompt "Choose a piece of hardware to trash" :label "Trash a piece of hardware"
                      :msg (msg "trash " (:title target))
                      :choices {:req #(= (:type %) "Hardware")}
-                     :effect (effect (trash target {:cause :subroutine}))})
+                     :effect (effect (trash target {:cause :subrprojectoutine}))})

 (def cards
   {"Accelerated Beta Test"
@@ -125,7 +125,7 @@
    "Armand \"Geist\" Walker"
    {:effect (effect (gain :link 1))
     :events {:trash {:optional {:req (req (and (= side :runner) (= (second targets) :ability-cost)))
-                                :prompt "Draw a card?" :msg (msg "draw a card" targets) :effect (effect (draw 1))}}}}
+                                :prompt "Draw a card?" :msg (msg "draw a card") :effect (effect (draw 1))}}}}

    "Armitage Codebusting"
    {:data {:counter 12}
@@ -1766,7 +1766,7 @@
                  :msg "do 1 meat damage"}]}

    "Project Atlas"
-   {:effect (effect (set-prop card :counter (- (:advance-counter card) 3)))
+   {:effect (effect (set-prop card :counter (max 0 (- (:advance-counter card) 3))))
     :abilities [{:counter-cost 1 :prompt "Choose a card" :label "Search R&D and add 1 card to HQ"
                  :msg (msg "add " (:title target) " to HQ from R&D")
                  :choices (req (:deck corp)) :effect (effect (move target :hand) (shuffle! :deck))}]}


Remove some unnecessary private docstrings

--- src/compojure/core.clj
+++ src/compojure/core.clj
@@ -11,9 +11,7 @@
             [clout.core :as clout]
             [ring.util.codec :as codec]))

-(defn- method-matches?
-  "True if this request matches the supplied request method."
-  [method request]
+(defn- method-matches? [method request]
   (let [request-method (request :request-method)
         form-method    (or (get-in request [:form-params "_method"])
                            (get-in request [:multipart-params "_method"]))]
@@ -21,9 +19,7 @@
       (.equalsIgnoreCase (name method) form-method)
       (= method request-method))))

-(defn- if-method
-  "Evaluate the handler if the request method matches."
-  [method handler]
+(defn- if-method [method handler]
   (fn [request]
     (cond
       (or (nil? method) (method-matches? method request))
@@ -35,21 +31,15 @@
 (defn- decode-route-params [params]
   (into {} (for [[k v] params] [k (codec/url-decode v)])))

-(defn- assoc-route-params
-  "Associate route parameters with the request map."
-  [request params]
+(defn- assoc-route-params [request params]
   (merge-with merge request {:route-params params, :params params}))

-(defn- if-route
-  "Evaluate the handler if the route matches the request."
-  [route handler]
+(defn- if-route [route handler]
   (fn [request]
     (if-let [params (clout/route-matches route request)]
       (handler (assoc-route-params request (decode-route-params params))))))

-(defn- prepare-route
-  "Pre-compile the route."
-  [route]
+(defn- prepare-route [route]
   (cond
     (string? route)
       `(clout/route-compile ~route)
@@ -71,9 +61,7 @@
   (assoc binds sym `(get-in ~req [:params ~(keyword sym)]
                       (get-in ~req [:params ~(str sym)]))))

-(defn- vector-bindings
-  "Create the bindings for a vector of parameters."
-  [args req]
+(defn- vector-bindings [args req]
   (loop [args args, binds {}]
     (if-let [sym (first args)]
       (cond


Richer error JSON-LD

Richer error JSON-LD

--- src/rdf_path_examples/views.clj
+++ src/rdf_path_examples/views.clj
@@ -8,8 +8,13 @@

 (defn error
   "Render JSON-LD description of the error."
-  [{:keys [error-msg status]}]
-  {"@context" "http://www.w3.org/ns/hydra/context.jsonld"
-   "@type" "Error"
-   "statusCode" status
-   "description" error-msg})
+  [{:keys [error-msg status see-also]}]
+  (let [hydra-error (cond-> {"@type" "Error"
+                             "statusCode" status
+                             "description" error-msg}
+                      see-also
+                      (assoc "rdfs:seeAlso" see-also))
+        graph (cond-> [hydra-error] see-also (conj see-also))]
+    {"@context" {"@vocab" "http://www.w3.org/ns/hydra/core#"
+                 "rdfs" "http://www.w3.org/2000/01/rdf-schema#"}
+     "@graph" graph}))


Strengthen `refactor-nrepl.analyzer`

Strengthen `refactor-nrepl.analyzer`

Now it uses locks and `invalid-fqn?`

--- src/refactor_nrepl/analyzer.clj
+++ src/refactor_nrepl/analyzer.clj
@@ -9,7 +9,9 @@
             [clojure.tools.namespace.parse :refer [read-ns-decl]]
             [clojure.walk :as walk]
             [refactor-nrepl
-             [config :as config]]
+             [config :as config]
+             [core :as core]
+             [util :as util]]
             [refactor-nrepl.ns.tracker :as tracker])
   (:import java.io.PushbackReader
            java.util.regex.Pattern))
@@ -71,14 +73,18 @@

 (defn- build-ast
   [ns aliases]
-  (when (ns-on-cp? ns)
-    (let [opts {:passes-opts
-                {:validate/unresolvable-symbol-handler shadow-unresolvable-symbol-handler
-                 :validate/throw-on-arity-mismatch false
-                 :validate/wrong-tag-handler shadow-wrong-tag-handler}}]
-      (binding [ana/macroexpand-1 noop-macroexpand-1
-                reader/*data-readers* *data-readers*]
-        (assoc-in (aj/analyze-ns ns (aj/empty-env) opts) [0 :alias-info] aliases)))))
+  (when (and (ns-on-cp? ns)
+             (not (util/invalid-fqn? ns)))
+    ;; Use `locking`, because AST analysis can perform arbitrary evaluation.
+    ;; Parallel analysis is not safe, especially as it can perform `require` calls.
+    (locking core/require-lock
+      (let [opts {:passes-opts
+                  {:validate/unresolvable-symbol-handler shadow-unresolvable-symbol-handler
+                   :validate/throw-on-arity-mismatch     false
+                   :validate/wrong-tag-handler           shadow-wrong-tag-handler}}]
+        (binding [ana/macroexpand-1 noop-macroexpand-1
+                  reader/*data-readers* *data-readers*]
+          (assoc-in (aj/analyze-ns ns (aj/empty-env) opts) [0 :alias-info] aliases))))))

 (defn- cachable-ast [file-content]
   (let [[ns aliases] (parse-ns file-content)]


Fix another minor error

Fix another minor error

--- src/rsvp_backend/db/invitee.clj
+++ src/rsvp_backend/db/invitee.clj
@@ -142,7 +142,8 @@
   [email]
   (try (ddb/put-item
         client-opts
-        {:code (+ 9999000000 (rand-int 999) (rand-int 999))
+        db-name
+        {:code (+ 9000000 (rand-int 999) (rand-int 999))
          :email email
          :status "INVALID_USER"})
        (catch Exception e "AWS_ERROR")))


Rewriting my dfs code, completely.

Rewriting my dfs code, completely.

My DFS code is terrible! It is horrible, terrible, no good very bad. The
issue is that if you look closely at what the "queue" was doing, it was
storing the entire sequence up to that point, basically walking down the
tree expanding one level out from a strict dfs.

I'm rewriting it to be a better, less memory-intensive dfs. Not that
it's strictly necessary (I mean, I'm not hurting for memory or anything)
but The Algorithm Is Totally Wrong!

--- wysitutwyg/src-clj/wysitutwyg/markov/builder.clj
+++ wysitutwyg/src-clj/wysitutwyg/markov/builder.clj
@@ -3,10 +3,15 @@

 ;; Fixes seed for reproducability
 (def ^:dynamic ^java.util.Random *rnd* (java.util.Random. 1))
-(defn get-rand [x]
+(defn- get-rand [x]
   (.nextInt *rnd* x))
-
-(defn pick-word
+
+(defmacro with-seed
+  [seed & code]
+  `(binding [*rnd* (java.util.Random. ~seed)]
+    ~@code))
+
+(defn- pick-word
   "Takes a map of counts in the form of {'sad' 2, 'mad' 3} (values from the
   n-gram map) and picks a word, by the ratio of the counts."
   [words]
@@ -19,7 +24,7 @@
             (nth keys i)
             (recur (inc i) (+ (counts i) sum)))))))

-(defn pick-words
+(defn- pick-words
   "Returns a lazy sequence of the next states from the start state, generated
   by repeatedly picking words."
   [counts]
@@ -29,18 +34,18 @@
               nil))]
     (lazy-seq (step counts))))

-(defn find-first-end
+(defn- find-first-end
   "Returns the first end node following the specified state, nil if none."
   [state {:keys [counts end] :as datamap}]
   (first (filter end (pick-words (counts state)))))

-(defn words-to-states
+(defn- words-to-states
   "Takes a state and a collection of words, and maps it to the next set of
   states."
   [state words]
   (map #(conj (vec (rest state)) %) words))

-(defn gen-next-continuations
+(defn- gen-next-continuations
   [{:keys [counts end] :as datamap} {:keys [depth queue state]}]
   (->> (counts state)
        (pick-words)
@@ -49,12 +54,12 @@
        (map #(hash-map :depth (inc depth)
                        :queue (conj queue state)
                        :state %1))))
-
+
 ;; cont consists of: {:depth depth, :queue string, :state state}
 ;;   Works for 2-3 tuples with caveats - many fewer viable paths, so drops to
 ;; dive a lot more! Also - it has n too many words, where n is one less than
 ;; the size of the tuple.
-(defn dfs-cont
+(defn- dfs-cont
   [{:keys [counts end] :as datamap} n continuations]
   (if-let [{:keys [depth queue state] :as cont} (first continuations)]
     (if (>= (+ depth (count state)) n)
@@ -65,7 +70,37 @@
           (recur datamap n (apply conj (rest continuations) new-conts))
           (recur datamap n (rest continuations))))))

-(defn dfs-begin
+(defn gen-next-info
+  [{:keys [counts end] :as datamap} {:keys [depth node edges]}]
+  (let [next-node (conj (vec (rest node)) (first edges))]
+    {:depth (inc depth)
+     :node next-node
+     :edges (->> (counts next-node)
+                 (pick-words))}))
+
+;; More true implementation of dfs
+(defn dfs-true
+  [{:keys [counts end] :as datamap} n stack]
+  (if-let [{:keys [depth node edges] :as node-info} (first stack)]
+    (cond
+      (and (= (+ depth (dec (count node))) n) ; TODO: lol
+           (end (last node)))
+        (reverse (map #(% :node) stack))
+      (or (= depth n) (empty? edges)) (recur datamap n (rest stack))
+      :else
+        (let [next-info (gen-next-info datamap node-info)
+              new-node-info (update-in node-info [:edges] rest)]
+          (recur datamap n (conj (cons new-node-info (rest stack)) next-info))))))
+
+(defn- dfs-true-begin
+  [{:keys [start counts] :as datamap} n]
+  {:pre [(pos? n)]}
+  (->> (pick-words start)
+       (map #(dfs-true datamap n [{:depth 0 :node % :edges (pick-words (counts %))}]))
+       (remove nil?)
+       (first)))
+
+(defn- dfs-begin
   [{:keys [start counts] :as datamap} n]
   {:pre [(pos? n)]}
   (->> (pick-words start)
@@ -74,16 +109,17 @@
        (first)))

 ;; Tail-recursive
-(defn dive
+(defn- dive
   [state {:keys [counts] :as datamap} n depth cont]
   (if (>= (+ depth (count state)) n)
       (conj cont state)
       (let [result (conj (vec (rest state)) (pick-word (counts state)))]
         (recur result datamap n (inc depth) (conj cont state)))))

-(defn dfs-single
+(defn- dfs-single
   [{:keys [start counts] :as datamap} n]
   {:pre [(pos? n)]}
+  (prn "Diving!")
   (dive (pick-word start) datamap n 0 []))

 (defn gen-sentence
@@ -96,4 +132,45 @@
          (concat (first coll))
          (reduce #(if (end %2)
                       (str %1 %2)
-                      (str %1 \space %2))))))+                      (str %1 \space %2))))))
+
+(defn gen-sentence-true-dfs
+  [{:keys [end] :as datamap} n]
+  {:pre [(pos? n)]}
+  (let [coll (if-let [s (dfs-true-begin datamap n)] s (dfs-single datamap n))]
+    (->> coll
+         (rest)
+         (map last)
+         (concat (first coll))
+         (reduce #(if (end %2)
+                      (str %1 %2)
+                      (str %1 \space %2))))))
+
+(def map-loc "resources/public/corpora/loremipsum/2.json")
+(use 'wysitutwyg.markov.textgen)
+(def dmap (read-into-datamap map-loc))
+
+;; TODO: Okay, it doesn't generate the currect length if you have 2-tuples.
+;; I thought I fixed that, but I didn't.
+;; This is why tests are good.
+
+(defn test-both [n]
+  (do
+    (prn "LENGTH: " n)
+    (binding [*rnd* (java.util.Random. 1)]
+      (prn "Psdo: " (gen-sentence dmap n)))
+    (binding [*rnd* (java.util.Random. 1)]
+      (prn "True: " (gen-sentence-true-dfs dmap n)))))
+
+; (test-both 2)
+(test-both 10) ; lol that tricked me into thinking it was length 9!
+;;; TODO: Issue: punctuation has its own depth in dives
+(test-both 20)
+(test-both 40) ;; Issue: 39 not 40!
+(test-both 30) ;; Issue: 39 not 40!
+
+#_(binding [*rnd* (java.util.Random. 1)]
+  (prn (gen-sentence dmap 500)))
+
+#_(binding [*rnd* (java.util.Random. 1)]
+  (prn (gen-sentence-true-dfs dmap 500)))


Pull out and name default extension lists

--- src/afrey/boot_asset_fingerprint.clj
+++ src/afrey/boot_asset_fingerprint.clj
@@ -15,6 +15,9 @@

 (defn- add-fingerprint-to-filenames [fileset sources]
   (reduce (fn [fs [source dest]] (core/mv fs source dest)) fileset sources))
+
+(def default-source-extensions [".html"])
+(def default-asset-extensions [".js" ".css"])

 (core/deftask asset-fingerprint
   "Replace asset references with a URL query-parameter based on the hash contents.
@@ -34,10 +37,10 @@
       (let [sources     (->> fileset
                           (core/fileset-diff @prev)
                           (core/output-files)
-                          (core/by-ext (or extensions [".html"])))
+                          (core/by-ext (or extensions default-source-extensions)))
             file-hashes (into {}
                               (map (juxt :path :hash))
-                              (core/by-ext (or rename-extensions [".js" ".css"]) (core/output-files fileset)))
+                              (core/by-ext (or rename-extensions default-asset-extensions) (core/output-files fileset)))
             file-rename-hash (into {} (map fingerprint-file file-hashes))]
         (reset! prev fileset)


Add support for whole-device mapping.

Add support for whole-device mapping.

Previously to get all of the messages sent by a given device, you needed
to register a global handler which received all messages sent by
everything. It's more efficient to let device mapping implementations
register interest in only events from their device, which this change
enables.

--- src/afterglow/midi.clj
+++ src/afterglow/midi.clj
@@ -469,6 +469,7 @@
   (let [device-key (@midi-device-key vanished)]
     (swap! midi-inputs dissoc device-key)
     (swap! synced-metronomes dissoc device-key)
+    (swap! device-mappings dissoc device-key)
     (swap! control-mappings dissoc device-key)
     (swap! note-mappings dissoc device-key)
     (swap! aftertouch-mappings dissoc device-key)
@@ -541,8 +542,10 @@
               (when @running
                 (run-message-handler handler msg running)))

-            ;; Then call any registered port listeners for the port on which
-            ;; it arrived
+            ;; Then call any registered port listeners for the port on which it arrived
+            (doseq [handler (get-in @device-mappings [(@midi-device-key (:device msg))])]
+              (when @running
+                (run-message-handler handler msg running)))

             ;; Then call specific message handlers that match
             (when @running
@@ -973,7 +976,33 @@
                   :device (select-keys (:device found) [:name :description]))))
        (finally (remove-global-handler! message-finder))))))

-;; TODO: apply to all matching input sources? Along with remove, and note & aftertouch messages?
+;; TODO: apply to all matching input sources? Along with remove, and control, note & aftertouch messages?
+(defn add-device-mapping
+  "Register a handler function `f` to be called whenever any MIDI
+  message is received from the specified device. Any subsequent MIDI
+  message which matches will be passed to `f` as its single argument.
+
+  The first MIDI input source whose device matches the
+  `device-filter` (using [[filter-devices]]) will be chosen."
+  [device-filter f]
+  {:pre [(fn? f)]}
+  (let [result (filter-devices device-filter (open-inputs-if-needed!))]
+    (when (empty? result)
+      (throw (IllegalArgumentException. (str "No MIDI sources " (describe-device-filter device-filter) "were found."))))
+    (swap! device-mappings #(update-in % [(@midi-device-key (first result))] clojure.set/union #{f}))))
+
+(defn remove-device-mapping
+  "Unregister a handler previously registered with
+  [[add-device-mapping]].
+
+  The first MIDI input source whose device matches the
+  `device-filter` (using [[filter-devices]]) will be chosen."
+  [device-filter f]
+  (let [result (filter-devices device-filter (open-inputs-if-needed!))]
+    (when (empty? result)
+      (throw (IllegalArgumentException. (str "No MIDI sources " (describe-device-filter device-filter) "were found."))))
+    (swap! device-mappings #(update-in % [(@midi-device-key (first result))] disj f))))
+
 (defn add-control-mapping
   "Register a handler function `f` to be called whenever a MIDI
   controller change message is received from the specified device, on


detecting empty usernames.

detecting empty usernames.

--- src/ancient_clj/io.clj
+++ src/ancient_clj/io.clj
@@ -7,12 +7,14 @@
 (defn fetch-url!
   "Fetch the given URL using `slurp` or `clj-http.client/get`."
   [url username password]
-  (let [msg (format "  Trying to retrieve '%s' ..." url)]
+  (let [msg (format "  Trying to retrieve '%s' ..." url)
+        username (when (seq username) username)]
     (if username
       (verbose msg)
       (verbose msg "(with authentication)"))
     (if-not username
-      (slurp url) (try
+      (slurp url)
+      (try
         (when-let [response (client/get url {:basic-auth [username password] :as :stream})]
           (with-open [data-stream (:body response)]
             (slurp data-stream)))


Allow set custom headers on jwe module.

Allow set custom headers on jwe module.

With additional consistency improvements related
to special treatment of headers.

--- src/buddy/sign/jwe.clj
+++ src/buddy/sign/jwe.clj
@@ -40,24 +40,22 @@
 ;; --- Implementation details

 (defn- encode-header
-  [{:keys [alg typ enc zip]}]
-  (let [alg (if (= alg :dir) "dir" (str/upper-case (name alg)))
-        typ (.toUpperCase (name typ))
-        enc (.toUpperCase (name enc))
-        header (merge {:alg alg :typ typ :enc enc}
-                      (when zip {:zip "DEF"}))]
-    (-> (json/generate-string header)
-        (b64/encode true))))
+  [header]
+  (-> header
+      (update :alg #(if (= % :dir) "dir" (str/upper-case (name %))))
+      (update :enc #(str/upper-case (name %)))
+      (json/generate-string)
+      (b64/encode true)))

 (defn- parse-header
   [^String data]
-  (let [{:keys [alg typ enc zip] :as header} (-> (b64/decode data)
-                                                 (codecs/bytes->str)
-                                                 (json/parse-string true))]
+  (let [{:keys [alg enc] :as header} (-> (b64/decode data)
+                                         (codecs/bytes->str)
+                                         (json/parse-string true))]
     (when-not (map? header)
       (throw (ex-info "Message seems corrupt or manipulated."
                       {:type :validation :cause :header})))
-    (cond-> {:typ typ :zip (= zip "DEF")}
+    (cond-> header
       alg (assoc :alg (keyword (str/lower-case alg)))
       enc (assoc :enc (keyword (str/lower-case enc))))))

@@ -213,13 +211,15 @@
 (defn encrypt
   "Encrypt then sign arbitrary length string/byte array using
   json web encryption."
-  [payload key & [{:keys [alg enc zip typ]
-                  :or {alg :dir enc :a128cbc-hs256 zip false typ :jwe}
+  [payload key & [{:keys [alg enc zip header]
+                  :or {alg :dir enc :a128cbc-hs256 zip false}
                   :as opts}]]
   (let [scek (cek/generate {:key key :alg alg :enc enc})
         ecek (cek/encrypt {:key key :cek scek :alg alg :enc enc})
         iv (generate-iv {:enc enc})
-        header (encode-header {:alg alg :enc enc :zip zip :typ typ})
+        header (cond-> (merge {:alg alg :enc enc} header)
+                 zip (assoc :zip "DEF"))
+        header (encode-header header)
         payload (encode-payload payload zip)
         [ciphertext authtag] (aead-encrypt {:alg enc
                                             :plaintext payload


Improve docstrings on monad based function on jws.

--- src/buddy/sign/jws.clj
+++ src/buddy/sign/jws.clj
@@ -175,12 +175,14 @@

 (defn encode
   "Sign arbitrary length string/byte array using
-  json web token/signature."
+  json web token/signature and return data wrapped
+  in a Success instance of the Exception monad."
   [& args]
   (exc/try-on (apply sign args)))

 (defn decode
   "Given a signed message, verify it and return
-  the decoded claims."
+  the decoded claims wrapped in a Success instance
+  of the Exception monad."
   [& args]
   (exc/try-on (apply unsign args)))


Cosmetic changes.

Cosmetic changes.

--- src/buddy/sign/jws.clj
+++ src/buddy/sign/jws.clj
@@ -28,22 +28,23 @@

 (def ^{:doc "List of supported signing algorithms"
        :dynamic true}
-  *signers-map* {:hs256 {:signer   #(mac/hash %1 {:alg :hmac+sha256 :key %2})
-                         :verifier #(mac/verify %1 %2 {:alg :hmac+sha256 :key %3})}
-                 :hs512 {:signer   #(mac/hash %1 {:alg :hmac+sha512 :key %2})
-                         :verifier #(mac/verify %1 %2 {:alg :hmac+sha512 :key %3})}
-                 :rs256 {:signer   #(dsa/sign %1 {:alg :rsassa-pkcs15+sha256 :key %2})
+  *signers-map*
+  {:hs256 {:signer   #(mac/hash %1 {:alg :hmac+sha256 :key %2})
+           :verifier #(mac/verify %1 %2 {:alg :hmac+sha256 :key %3})}
+   :hs512 {:signer   #(mac/hash %1 {:alg :hmac+sha512 :key %2})
+           :verifier #(mac/verify %1 %2 {:alg :hmac+sha512 :key %3})}
+   :rs256 {:signer   #(dsa/sign %1 {:alg :rsassa-pkcs15+sha256 :key %2})
                          :verifier #(dsa/verify %1 %2 {:alg :rsassa-pkcs15+sha256 :key %3})}
-                 :rs512 {:signer   #(dsa/sign %1 {:alg :rsassa-pkcs15+sha512 :key %2})
-                         :verifier #(dsa/verify %1 %2 {:alg :rsassa-pkcs15+sha512 :key %3})}
-                 :ps256 {:signer   #(dsa/sign %1 {:alg :rsassa-pss+sha256 :key %2})
-                         :verifier #(dsa/verify %1 %2 {:alg :rsassa-pss+sha256 :key %3})}
-                 :ps512 {:signer   #(dsa/sign %1 {:alg :rsassa-pss+sha512 :key %2})
-                         :verifier #(dsa/verify %1 %2 {:alg :rsassa-pss+sha512 :key %3})}
-                 :es256 {:signer   #(dsa/sign %1 {:alg :ecdsa+sha256 :key %2})
-                         :verifier #(dsa/verify %1 %2 {:alg :ecdsa+sha256 :key %3 })}
-                 :es512 {:signer   #(dsa/sign %1 {:alg :ecdsa+sha512 :key %2})
-                         :verifier #(dsa/verify %1 %2 {:alg :ecdsa+sha512 :key %3})}})
+   :rs512 {:signer   #(dsa/sign %1 {:alg :rsassa-pkcs15+sha512 :key %2})
+           :verifier #(dsa/verify %1 %2 {:alg :rsassa-pkcs15+sha512 :key %3})}
+   :ps256 {:signer   #(dsa/sign %1 {:alg :rsassa-pss+sha256 :key %2})
+           :verifier #(dsa/verify %1 %2 {:alg :rsassa-pss+sha256 :key %3})}
+   :ps512 {:signer   #(dsa/sign %1 {:alg :rsassa-pss+sha512 :key %2})
+           :verifier #(dsa/verify %1 %2 {:alg :rsassa-pss+sha512 :key %3})}
+   :es256 {:signer   #(dsa/sign %1 {:alg :ecdsa+sha256 :key %2})
+           :verifier #(dsa/verify %1 %2 {:alg :ecdsa+sha256 :key %3 })}
+   :es512 {:signer   #(dsa/sign %1 {:alg :ecdsa+sha512 :key %2})
+           :verifier #(dsa/verify %1 %2 {:alg :ecdsa+sha512 :key %3})}})

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Helpers


Added doc strings to functions in server.

--- src/cadence/server.clj
+++ src/cadence/server.clj
@@ -5,20 +5,24 @@

 (server/load-views "src/cadence/views/")

-(defn https-url [request-url]
+(defn https-url
+  "Creates string from request with scheme as https."
+  [request-url]
   (str "https://"
        (:server-name request-url)
        (let [port (:server-port request-url)]
          (if (nil?  port) (str ":" port)))
        (:uri request-url)))

-(defn require-https [handler]
+(defn require-https
+  "Function generates ring handler to redirect to https."
+  [handler]
   (fn [request]
     (if (= (:scheme request) :http)
       (ring.util.response/redirect (https-url request))
       (handler request))))

-(defn -main [& m]
+(defn -main "Main function to launch the Cadence application" [& m]
   (let [mode (keyword (or (first m) :dev))
         port (Integer. (get (System/getenv) "PORT" "5000"))
         url "cadence.herokuapp.com"]


better CLJS compatibility

better CLJS compatibility

--- src/calfpath/core.cljc
+++ src/calfpath/core.cljc
@@ -24,7 +24,8 @@
   (when-not (#{0 1} (rem (count clauses) 3))
     (i/expected "clauses in sets of 3 with an optional default expression" clauses))
   (doseq [[uri-template dav _] (partition 3 clauses)]
-    (i/expected string? "a uri-template string" (eval uri-template))
+    (i/expected string? "a uri-template string" #?(:cljs uri-template
+                                                    :clj (eval uri-template)))
     (when-not (and (vector? dav) (every? symbol? dav))
       (i/expected "destructuring argument vector with symbols" dav)))
   (let [response-400 {:status 400
@@ -35,7 +36,8 @@
         (if (= 1 (count clauses))
           (first clauses)
           (let [[uri-pattern dav expr] clauses
-                [uri-template partial?] (i/parse-uri-template \: (eval uri-pattern))]
+                [uri-template partial?] (i/parse-uri-template \: #?(:cljs uri-pattern
+                                                                     :clj (eval uri-pattern)))]
             `(if-let [match-result# (i/match-uri (:uri ~request)
                                       (int (i/get-uri-match-end-index ~request))
                                       ~uri-template ~partial?)]


stringify-rid can be used for db recs in general

--- src/clj/cglossa/db.clj
+++ src/clj/cglossa/db.clj
@@ -15,15 +15,16 @@
 (defn db-record? [o]
   (instance? OIdentifiable o))

-(defn stringify-rid [rid]
-  "When we ask for @rid in an SQL query, the value we get for the 'rid'
-  property is actually the entire record object. This function converts it into
-  the string representation of the record's @rid (e.g. 12:0)"
-  (.. rid getIdentity toString))
+(defn stringify-rid [record]
+  "Returns the ID of record as a string."
+  (.. record getIdentity toString))

 (defn- xform-val [val]
   "Transform the values of vertex properties retrieved via SQL as needed."
   (cond
+    ;; When we ask for @rid in an SQL query, the value we get for the 'rid'
+    ;; property is actually the entire record object. Convert it into
+    ;; the string representation of the record's @rid (e.g. 12:0).
     (db-record? val) (stringify-rid val)
     (instance? Iterable val) (map xform-val val)
     :else val))


add filter

add filter

--- src/clj/flambo/api.clj
+++ src/clj/flambo/api.clj
@@ -14,7 +14,7 @@

 (u/hail-flambo)

-(System/setProperty "spark.serializer" "flambo.kryo.FlamboKryoSerializer")
+(System/setProperty "spark.serializer" "org.apache.spark.serializer.KryoSerializer")

 (defmacro sparkop [& body]
   `(sfn/fn ~@body))
@@ -66,6 +66,9 @@

 (defn flat-map [rdd f]
   (.map rdd (flat-map-function f)))
+
+(defn filter [rdd f]
+  (.filter rdd (function (ftruthy? f))))

 (defn foreach [rdd f]
   (.foreach rdd (void-function f)))


Fix hidden hosted operations when trashed

--- src/clj/game/cards.clj
+++ src/clj/game/cards.clj
@@ -184,7 +184,7 @@
    {:choices {:req #(and (= (:type %) "ICE") (has? % :subtype "Bioroid") (not (:rezzed %)))}
     :msg (msg "rez " (:title target) " at no cost")
     :effect (effect (rez target {:no-cost true})
-                    (host (get-card state target) (assoc card :zone [:discard])))}
+                    (host (get-card state target) (assoc card :zone [:discard] :seen true)))}

    "Blue Level Clearance"
    {:effect (effect (gain :credit 5) (draw 2))}
@@ -1543,14 +1543,14 @@
    {:choices {:req #(and (= (:type %) "ICE") (not (:rezzed %)))}
     :msg (msg "rez " (:title target) " at no cost")
     :effect (effect (rez target {:no-cost true})
-                    (host (get-card state target) (assoc card :zone [:discard])))}
+                    (host (get-card state target) (assoc card :zone [:discard] :seen true)))}

    "PAD Campaign"
    {:events {:corp-turn-begins {:msg "gain 1 [Credits]" :effect (effect (gain :credit 1))}}}

    "Patch"
    {:choices {:req #(and (= (:type %) "ICE") (:rezzed %))}
-    :effect (effect (host target (assoc card :zone [:discard]))
+    :effect (effect (host target (assoc card :zone [:discard] :seen true))
                     (update-ice-strength (get-card state target)))
     :events {:pre-ice-strength {:req (req (= (:cid target) (:cid (:host card))))
                                 :effect (effect (ice-strength-bonus 2))}}}
@@ -2271,7 +2271,7 @@

    "Sub Boost"
    {:choices {:req #(and (= (:type %) "ICE") (:rezzed %))}
-    :effect (effect (host target (assoc card :zone [:discard])))}
+    :effect (effect (host target (assoc card :zone [:discard] :seen true)))}

    "Subliminal Messaging"
    {:effect (effect (gain :credit 1)


Use 'a gist' instead of 'a private gist'

--- src/clj/inky/entry.clj
+++ src/clj/inky/entry.clj
@@ -209,7 +209,7 @@
            "Compiled "
            (if public-gist
              ($link-gist login gist-id gist-id)
-             "a private gist")
+             "a gist")
            " " (util/timeago (:started job)) " ago."
            " Took " (compile-duration job) " s."]

@@ -219,7 +219,7 @@
            "Failed compiling "
            (if public-gist
              ($link-gist login gist-id gist-id)
-             "a private gist")
+             "a gist")
            " "(util/timeago (:started job)) " ago."]

           :else


add safe-read-string

add safe-read-string

--- src/clj_money/util.clj
+++ src/clj_money/util.clj
@@ -95,3 +95,7 @@

                        :else v)])
                   m))))
+
+(defn safe-read-string
+  [string]
+  (read-string (or string "{}")))


ClojureScript angry with ns :rename; use :require for now.

--- src/cljx/c2/scale.cljx
+++ src/cljx/c2/scale.cljx
@@ -1,9 +1,11 @@
 ^:clj (ns c2.scale
         (:use [c2.util :only [c2-obj]]
-              [c2.maths :only [log expt] :rename {log logg}]))
+              [c2.maths :only [expt]])
+        (:require [c2.maths :as maths]))
 ^:cljs (ns c2.scale
          (:use-macros [c2.util :only [c2-obj]])
-         (:use [c2.maths :only [log expt] :rename {log logg}]))
+         (:use [c2.maths :only [expt]])
+         (:require [c2.maths :as maths]))

 (defprotocol IInvertable
   (invert [scale] "Inverted scale"))
@@ -60,7 +62,7 @@

         clojure.lang.IFn
         (invoke [_ x]
-                ((comp (linear :domain (map logg domain)
+                ((comp (linear :domain (map maths/log domain)
                                :range range)
-                       logg) x)))
+                       maths/log) x)))


Minor refactoring

Minor refactoring

--- src/compojure/core.clj
+++ src/compojure/core.clj
@@ -1,8 +1,9 @@
 (ns compojure.core
   "A concise syntax for generating Ring handlers."
-  (:use [clojure.contrib.def :only (name-with-attributes)]
-        clout.core
-        compojure.response))
+  (:require [clojure.string :as str])
+  (:use clout.core
+        compojure.response
+        [clojure.contrib.def :only (name-with-attributes)]))

 (defn- method-matches
   "True if this request matches the supplied method."
@@ -11,7 +12,7 @@
         form-method    (get-in request [:form-params "_method"])]
     (or (nil? method)
         (if (and form-method (= request-method :post))
-          (= (.toUpperCase (name method)) form-method)
+          (= (str/upper-case (name method)) form-method)
           (= method request-method)))))

 (defn- prepare-route
@@ -117,20 +118,21 @@
   [path args & body]
   (compile-route nil path args body))

-(defn- keyword->middleware
+(defn- middleware-sym [x]
+  (symbol (namespace x) (str "wrap-" (name x))))
+
+(defn- ->middleware
   "Turn a keyword into a wrapper function symbol.
   e.g. :test => wrap-test
        (:test x) => (wrap-test x)"
   [kw]
-  (letfn [(mw-sym [x]
-            (symbol (namespace x) (str "wrap-" (name x))))]
-    (cond
-      (keyword? kw)
-        (mw-sym kw)
-      (and (seq? kw) (keyword? (first kw)))
-        (cons (mw-sym (first kw)) (rest kw))
-      :else
-        kw)))
+  (cond
+    (keyword? kw)
+      (middleware-sym kw)
+    (and (seq? kw) (keyword? (first kw)))
+      (cons (middleware-sym (first kw)) (rest kw))
+    :else
+      kw))

 (defmacro wrap!
   "DEPRECATED: Use '->' instead.
@@ -142,7 +144,7 @@
     => (def foo (wrap-session foo cookie-store))"
   {:deprecated "0.6.0"}
   [handler & funcs]
-  (let [funcs (map keyword->middleware funcs)]
+  (let [funcs (map ->middleware funcs)]
     `(alter-var-root
        (var ~handler)
        (constantly (-> ~handler ~@funcs)))))


[dataset/comment] Typo.

[dataset/comment] Typo.

--- src/cortex/dataset.clj
+++ src/cortex/dataset.clj
@@ -22,7 +22,7 @@

   Serialization to various formats is simple:
   For each format, two functions are necessary.
-  (1) A function to take a sequence of maps and serializes it.
+  (1) A function to take a sequence of maps and serialize it.
   (2) A function that takes serialized data and returns a sequence of maps."
   (:require [clojure.core.matrix :as m]))


Complete exercise test suite (#416)

Complete exercise test suite (#416)

* add learning-list-test

* test learning-list function

--- exercises/concept/tracks-on-tracks-on-tracks/test/tracks_on_tracks_on_tracks_test.clj
+++ exercises/concept/tracks-on-tracks-on-tracks/test/tracks_on_tracks_on_tracks_test.clj
@@ -21,3 +21,6 @@

 (deftest list-count-test
   (is (= 3 (tracks-on-tracks-on-tracks/count-languages '("JavaScript" "Java" "Clojure")))))
+
+(deftest learning-list-test
+  (is (= 3 (tracks-on-tracks-on-tracks/learning-list))))


Make use of fail function, and minor formatting change

--- src/cascade/internal/viewbuilder.clj
+++ src/cascade/internal/viewbuilder.clj
@@ -28,23 +28,23 @@
    (dom-node? any) any
    (string? any) (text-node any)
    (number? any) (raw-node (str any))
-   true (throw (RuntimeException.
-                (format "A rendering function returned %s. Rendering functions should return nil, a string, a number, a DOM node or a seq of such values."
-                        (pr-str any))))))
+   :else (fail
+          "A rendering function returned %s. Rendering functions should return nil, a string, a number, a DOM node or a seq of such values."
+          (pr-str any))))

 (defn explode-element-name
-  "Explodes an element name string into a seq of three-element vectors. Each vector
+     "Explodes an element name string into a seq of three-element vectors. Each vector
 consists of the portion of the name prior to the match, the match character, and
 the match term. \"div.alpha#beta\" would split to [[\"div\" \".\" \"alpha\"] [\"div.alpha\" \"#\" \"beta\"]]."
-  [^String element-name]
+     [^String element-name]
                                         ; match sequences of word characters prefixed with '.' or '#' within the overall name
-  (loop [matcher (re-matcher #"([.#])([\w-]+)" element-name)
-         result []]
-    (if (.find matcher)
-      (recur matcher (conj result [(.substring element-name 0 (.start matcher))
-                                   (.group matcher 1)
-                                   (.group matcher 2)]))
-      result)))
+     (loop [matcher (re-matcher #"([.#])([\w-]+)" element-name)
+            result []]
+       (if (.find matcher)
+         (recur matcher (conj result [(.substring element-name 0 (.start matcher))
+                                      (.group matcher 1)
+                                      (.group matcher 2)]))
+         result)))

 (defn extract-attributes
   [exploded match key attributes]


registry www-auth header realm validation before fallback

--- src/clj/swarmpit/registry/client.clj
+++ src/clj/swarmpit/registry/client.clj
@@ -3,7 +3,8 @@
   (:require [clojure.walk :refer [keywordize-keys stringify-keys]]
             [clojure.string :as str]
             [swarmpit.http :refer :all]
-            [swarmpit.token :as token]))
+            [swarmpit.token :as token]
+            [swarmpit.ip :as ip]))

 (defn- build-url
   [registry api]
@@ -38,10 +39,8 @@
                      :error-handler #(-> % :errors (first) :message)}))

 (defn- fallback-options
-  [www-auth-header options]
-  (let [www-auth-url (:realm www-auth-header)
-        www-auth-params (dissoc www-auth-header :realm)
-        query-params (merge {:client_id "swarmpit"} www-auth-params)
+  [www-auth-url www-auth-params options]
+  (let [query-params (merge {:client_id "swarmpit"} www-auth-params)
         options (assoc-in options [:query-params] query-params)
         token (-> (execute {:method  :GET
                             :url     www-auth-url
@@ -53,14 +52,20 @@
 (defn- execute-with-fallback
   [{:keys [method url options] :as request}]
   (try
+    (print request)
     (execute request)
     (catch ExceptionInfo e
       (let [status (:status (ex-data e))
             headers (:headers (ex-data e))
-            www-auth-header (authenticate-header headers)]
+            www-auth-header (authenticate-header headers)
+            www-auth-url (:realm www-auth-header)
+            www-auth-params (dissoc www-auth-header :realm)]
         (if (and (= status 401)
-                 (some? www-auth-header))
-          (execute (assoc request :options (fallback-options www-auth-header options)))
+                 (some? www-auth-url)
+                 (ip/is-valid-url www-auth-url))
+          (-> request
+              (assoc :options (fallback-options www-auth-url www-auth-params options))
+              (execute))
           (throw e))))))

 (defn repositories


Add resolution recommendation to admin page

--- src/cljs-admin/sbsk_admin/views.cljs
+++ src/cljs-admin/sbsk_admin/views.cljs
@@ -202,7 +202,7 @@
               [re-com/throbber
                :color "#000"]])]
           [re-com/label
-           :label "Select a Replacement Picture (6x4):"]
+           :label "Select a Replacement Picture (MUST BE 6x4 RATIO, e.g. resolution approx. 2048 × 1365):"]
           [:input {:type "file"
                    :id "additional-picture-input"
                    :on-change


[CODESTYLE] Place closing '}' on final line of metadata

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

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -242,8 +242,7 @@
                              :endTime   -> 0-indexed end time of lesson}
               }
        }"
-  :private true
-  }
+  :private true}
   ModulesSelected {})

 (defn is-module-selected?


Fix a few more problems with reader rendering/events

--- src/cljs/comic_reader/ui/reader.cljs
+++ src/cljs/comic_reader/ui/reader.cljs
@@ -15,6 +15,12 @@
     (if (number? n)
       (concat (take-last n before) current (take n after))
       [])))
+
+(defn add-locations-before [app-db locations]
+  (update app-db :locations #(concat locations %)))
+
+(defn add-locations-after [app-db locations]
+  (update app-db :locations #(concat % locations)))

 (defn setup! []
   (re-frame/reg-sub
@@ -107,6 +113,11 @@
                                {:on-success #(re-frame/dispatch [:add-locations-before %])})
        true)))

+  (re-frame/reg-event-db
+   :add-locations-before
+   (fn [app-db [_ locations]]
+     (add-locations-before app-db locations)))
+
   (re-frame/reg-sub
    :loading-after-buffer
    :<- [:comic-coordinates]
@@ -121,6 +132,11 @@
                                buffer-size
                                {:on-success #(re-frame/dispatch [:add-locations-after %])})
        true)))
+
+  (re-frame/reg-event-db
+   :add-locations-after
+   (fn [app-db [_ locations]]
+     (add-locations-after app-db locations)))

   (re-frame/reg-sub
    :current-locations
@@ -149,4 +165,6 @@
   (let [current-locations (re-frame/subscribe [:current-locations])
         loading-before (re-frame/subscribe [:loading-before-buffer])
         loading-after  (re-frame/subscribe [:loading-after-buffer])]
+    @loading-before
+    @loading-after
     [reader #(re-frame/dispatch [:set-current-location %]) @current-locations]))


Allow construction of abstract association rules

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

--- src/conexp/fca/association_rules.clj
+++ src/conexp/fca/association_rules.clj
@@ -66,7 +66,9 @@
                     1
                     (/ (support (union premise conclusion) context)
                        (support premise context)))]
-         (Association-Rule. premise (difference conclusion premise) supp conf)))))
+         (make-association-rule premise (difference conclusion premise) supp conf))))
+  ([premise conclusion support confidence]
+     (Association-Rule. premise conclusion support confidence)))

 ;;;


fix suggestions flickering

fix suggestions flickering

Former-commit-id: 3e7bd39ed3856b95312ef9268bf7d022ae30b03a

--- src/status_im/chat/views/suggestions.cljs
+++ src/status_im/chat/views/suggestions.cljs
@@ -119,8 +119,10 @@
          (into [animated-view {:style (st/container h)}] elements))})))

 (defn suggestion-container []
-  (let [h (anim/create-value 0.1)]
-    [container h
-     [header h]
-     [suggestions-view]
-     [view {:height c/input-height}]]))
+  (let [h (anim/create-value 0.1)
+        command? (subscribe [:command?])]
+    (when-not @command?
+      [container h
+       [header h]
+       [suggestions-view]
+       [view {:height c/input-height}]])))


Function to read list of all jobs from the database

--- src/emender_service/db_interface.clj
+++ src/emender_service/db_interface.clj
@@ -42,6 +42,15 @@
         (catch Exception e
             (println e))))

+(defn read-job-list
+    []
+    (try
+        (jdbc/query db-spec/emender-service-db
+                    ["select id, job from results order by id,job"])
+        (catch Exception e
+            (println e)
+            [])))
+
 (defn record-error
     [job-name repo-url branch datetime message stacktrace]
     (try


ns doc fix

ns doc fix

--- src/jamesmacaulay/zelkova/mouse.cljs
+++ src/jamesmacaulay/zelkova/mouse.cljs
@@ -1,6 +1,6 @@
 (ns jamesmacaulay.zelkova.mouse
-  "This namespace provides keyboard-related signals."
-  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
+  "This namespace provides mouse-related signals."
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
   (:require [jamesmacaulay.zelkova.signal :as z]
             [goog.events :as events]
             [cljs.core.async :as async :refer [>! <!]]))


Fix typo in docstring

Fix typo in docstring

--- src/main/cljs/cljs/tools/reader.cljs
+++ src/main/cljs/cljs/tools/reader.cljs
@@ -905,7 +905,7 @@
 (defn read
   "Reads the first object from an IPushbackReader.
    Returns the object read. If EOF, throws if eof-error? is true.
-   Otherwise returns sentinel. If no stream is providen, *in* will be used.
+   Otherwise returns sentinel. If no stream is provided, *in* will be used.

    Opts is a persistent map with valid keys:
     :read-cond - :allow to process reader conditionals, or


Attach interns new vars instead of using a single var

--- src/main/clojure/lazytest/attach.clj
+++ src/main/clojure/lazytest/attach.clj
@@ -1,27 +1,23 @@
-(ns lazytest.attach
-  (:use [lazytest.groups :only (group?)]))
-
-(defn groups-var
-  "Creates or returns the Var storing Groups in namespace n."
-  [n]
-  (or (ns-resolve n '*lazytest-groups*)
-      (intern n (with-meta '*lazytest-groups* {:private true}) #{})))
+(ns lazytest.attach)

 (defn groups
   "Returns the Groups for namespace n"
   [n]
-  (var-get (groups-var n)))
+  (map var-get (filter #(::group (meta %)) (vals (ns-interns n)))))

 (defn all-groups
   "Returns a sequence of all Groups in all namespaces."
   []
-  (mapcat (comp seq groups) (all-ns)))
+  (mapcat groups (all-ns)))

 (defn add-group
   "Adds Group g to namespace n."
   [n g]
-  {:pre [(group? g)
-	 (the-ns n)]}
-  {:post [(some #{g} (seq (groups n)))]}
-  (alter-var-root (groups-var (the-ns n)) conj g))
+  (intern n (with-meta (gensym "lazytest-group-") {::group true}) g))

+(defn clear-groups
+  "Removes all test groups from namespace n."
+  [n]
+  (doseq [[sym v] (ns-interns n)]
+    (when (::group (meta v))
+      (ns-unmap n sym))))


Fix soundcloud links

Fix soundcloud links

--- src/reddio_frontend/screens/player/player.cljs
+++ src/reddio_frontend/screens/player/player.cljs
@@ -20,7 +20,9 @@
               :on-pause #(rf/dispatch [:player-pause])
               :on-buffer #(rf/dispatch [:player-buffer])
               :on-ended #(rf/dispatch [:player-ended])
-              :on-error #(rf/dispatch [:player-error])}]
+              :on-error #(rf/dispatch [:player-error])
+              :soundcloud-config #js {:clientId nil
+                                      :showArtwork true}}]
     (when current-post
       [:div
        [:div.player


Refactor out part of track* function as checkpoint macro and checkpoint* function

Improve documentation

--- src/io/aviso/tracker.clj
+++ src/io/aviso/tracker.clj
@@ -1,12 +1,14 @@
 (ns io.aviso.tracker
-  "Code for tracking operations so that a history can be presented when an exception is thrown."
+  "Code for tracking operations so that a history can be presented when an exception is thrown.
+
+  The main entrypoint is the [[track]] macro."
   (:require [clojure.string :as str]
             [clojure.tools.logging :as l]
             [clojure.tools.logging.impl :as impl]
             [io.aviso.writer :as writer]
             [io.aviso.exception :as exception]
             [io.aviso.toolchest.exceptions :refer [to-message]])
-  (:import (java.util WeakHashMap Map)))
+  (:import [java.util WeakHashMap Map]))

 ;;; Contains a vector of messages (or functions that return messages) used to log the route to the exception.
 (def ^:private ^:dynamic *operation-labels*
@@ -18,6 +20,11 @@
   "Controls whether operation labels are logged on entry to the [[track]] macro. By default (nil), no
   logging takes places.  Otherwise, this is a logging level (such as :debug or :info) to be used."
   nil)
+
+(defn get-logger
+  "Determines the logger instance for a namespace (by leveraging some clojure.tools.logging internals)."
+  [namespace]
+  (impl/get-logger l/*logger-factory* namespace))

 (def ^:private ^Map log-exceptions?
   (WeakHashMap.))
@@ -35,7 +42,6 @@
     (.get log-exceptions? (Thread/currentThread))))

 (defn- label-to-string
-  "Converts a trace to a string; a trace may be a function which is invoked, a string, or any object that can be converted to a string."
   [message]
   (str (if (fn? message) (message) message)))

@@ -59,15 +65,59 @@
          (str/join writer/eol)
          (error logger))))

+(defn checkpoint*
+  "The main implementation of [[checkpoint]], using a specific logger.
+
+  :logger
+  : logger to use when logging the operation trace.
+
+  :f
+  : function to evaluate.
+
+  The result of the function is returned.
+
+  If the function throws an exception, it may be logged (and rethrown).  When the exception is logged,
+  it includes the operation trace (the sequence of active operation labels), then the formatted exception.
+
+  In the logging case, the exception is rethrown, wrapped as a new ex-info exception, with :operation-trace
+  as the vector of operation label strings."
+  {:added "0.1.5"}
+  [logger f]
+  (try
+    (set-should-log-operations! true)
+    (f)
+    (catch Throwable t
+      (if (should-log-operations?)
+        (let [trace-label-strings (operation-labels)]
+          (log-trace-label-stack logger trace-label-strings t)
+          (set-should-log-operations! false)
+          (throw (ex-info (to-message t)
+                          {:operation-trace trace-label-strings}
+                          t)))
+        (throw t)))))
+
+(defmacro checkpoint
+  "Establishes a checkpoint, a point at which a thrown exception results in
+  logging of the operation trace.
+
+  checkpoint is useful when flow of control passes from one thread to another, such as
+  when using clojure.core.async. Although the operation trace, being stored in a dynamic var,
+  will be conveyed to the new thread, the exception handler necessary to report an exception
+  is not. checkpoint provides that exception handler."
+  {:added "0.1.5"}
+  [& body]
+  `(checkpoint* (get-logger ~*ns*) (fn [] ~@body)))
+
 (defn track*
-  "Tracks the execution of a function of no arguments. The trace macro converts into a call to track*.
+  "Tracks the execution of a function of no arguments. The [[track]] macro converts into a call to track*.
+  Uses [[checkpoint]].

   logger
   : Logger where logging should occur (as defined by the clojure.tools.logging Logger protocol)

   label
   : String, object, or function. If a function, the function will only be evaluated if the message
-    needs to be printed (when an exception occurs, or when logging traces via [[*log-traces*]]).
+    needs to be printed (when an exception occurs, or when logging traces via [[*log-trace-level*]]).

   f
   : function to invoke. track* returns the result from this function."
@@ -81,41 +131,35 @@
                  (label-to-string label)
                  label)]
     (binding [*operation-labels* (conj *operation-labels* label')]
-      (set-should-log-operations! true)
-      (try
-        (when level'
-          (l/log* logger *log-trace-level* nil label'))
-        (f)
-        (catch Throwable t
-          (if (should-log-operations?)
-            (let [trace-label-strings (operation-labels)]
-              (log-trace-label-stack logger trace-label-strings t)
-              (set-should-log-operations! false)
-              (throw (ex-info (to-message t)
-                              {:operation-trace trace-label-strings}
-                              t)))
-            (throw t)))))))
-
-(defn get-logger
-  "Determines the logger instance for a namespace (by leveraging some clojure.tools.logging internals)."
-  [namespace]
-  (impl/get-logger l/*logger-factory* namespace))
+      (when level'
+        (l/log* logger *log-trace-level* nil label'))
+      (checkpoint* logger f))))

 (defmacro track
   "Tracks the execution of an operation, associating the label (which describes the operation) with the execution of the body.

-  If an exception occurs inside the body, then all labels leading up to the
-  point of the exception will be logged (the logger is determined from the current namespace); thus logging only occurs at the
-  most deeply nested label. The exception thrown is formatted and logged as well.  The actual exception will be rethrown, wrapped in a
-  new `ex-info` exception, with key `:operation-trace` set to the vector of operation trace strings.
+  track is intended to be nested; each block of work that does something interesting can be wrapped as a track block.

-  label may be a string, an object, or a function that returns a string; execution of the function is deferred until
-  an operation trace label is needed.
+  track is particularly useful when operations span across multiple threads.
+
+  track does *not* do anything magic with respect to lazy evaluation.
+
+  The provided label may be:
+
+  * a simple string
+  * a no-arguments function which is invoked, returning a string
+  * any other object, which is converted to a string
+
+  If an exception occurs inside the body, then all operation labels leading up to the
+  point of the exception will be logged. See [[checkpoint*]] for the details.

   The operation trace is stored in a dynamic var; if you make use of Clojure's bound-fn macro to execute code in a new thread
   with the same bindings, then operations in a new thread will log as successors to operations in the current thread.

-  Note that the clojure.core.async thead and go macros *do* propogate bindings to new threads."
+  Note that the clojure.core.async thread and go macros *do* propogate bindings to new threads, but it will be necessary
+  to use the [[checkpoint]] macro to get the full benefit of operation tracking.
+
+  See also: [[*log-trace-level*]]."
   [label & body]
   `(track* (get-logger ~*ns*) ~label #(do ~@body)))


Print out file encoding

Print out file encoding

--- src/lambda_demo/core.clj
+++ src/lambda_demo/core.clj
@@ -8,4 +8,5 @@
   [in out ctx]
   (let [input (parse-stream (io/reader in) true)]
     (println "Hello from Lambda with input" input)
+    (println "Running with encoding" (System/getProperty "file.encoding"))
     (process input)))


Fix format related tests.

Fix format related tests.

--- src/suricatta/format.clj
+++ src/suricatta/format.clj
@@ -59,7 +59,7 @@
       (when dialect
         (.set conf (impl/translate-dialect dialect)))
     (condp = type
-      nil      (.renderInlined ctx q)
+      nil      (.render ctx q)
       :named   (.renderNamedParams ctx q)
       :indexed (.render ctx q)
       :inlined (.renderInlined ctx q))))
@@ -91,5 +91,5 @@
   "Get sql with bind values in a `sqlvec` format."
   [q]
   (apply vector
-         (get-sql q {type :indexed})
+         (get-sql q {:type :indexed})
          (get-bind-values q)))


Faster `key` fn

Faster `key` fn

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -102,14 +102,17 @@

 (comment (wcar {} (parse-suppress (ping)) (ping) (ping)))

+(enc/compile-if enc/str-join
+  (defn key* [parts] (enc/str-join ":" (map #(if (keyword? %) (enc/as-qname %) (str %))) parts))
+  (defn key* [parts] (str/join     ":" (map #(if (keyword? %) (enc/as-qname %) (str %))  parts))))
+
 (defn key
   "Joins parts to form an idiomatic compound Redis key name. Suggested style:
     * \"category:subcategory:id:field\" basic form.
     * Singular category names (\"account\" rather than \"accounts\").
     * Plural _field_ names when appropriate (\"account:friends\").
     * Dashes for long names (\"email-address\" rather than \"emailAddress\", etc.)."
-  [& parts] (str/join ":" (mapv #(if (keyword? %) (enc/fq-name %) (str %))
-                                parts)))
+  [& parts] (key* parts))

 (comment (key :foo/bar :baz "qux" nil 10))


opponent plays nowssh 025!

opponent plays nowssh 025!

--- src/tic_tac_toe/core.clj
+++ src/tic_tac_toe/core.clj
@@ -114,7 +114,8 @@

 (defn get-board [board]
   (let [rows (partition 3 board)
-        piece (toggle)
+        ;;piece (toggle)
+        piece :x
         game-state (get-game-state board)]
     (hiccup/html [:center
                   [:table {:border "1px solid black"}
@@ -141,6 +142,8 @@
   (GET "/place-piece/:pos/:piece" [pos piece]
        (do
          (swap! board place-piece (keyword piece) (Integer/parseInt pos))
+         (when (= :ongoing (get-game-state @board))
+           (swap! board place-piece :o (rand-nth (available-squares @board ))))
          (resp/redirect "/")))
   (POST "/post" [] (do
                      (reset! board blank-board)


Minor adjustments to Sign In page left out in last update

--- src-cljs/rmfu_ui/sign_in.cljs
+++ src-cljs/rmfu_ui/sign_in.cljs
@@ -92,7 +92,7 @@
             [:br]
             [:div.checkbox
              [:label
-              [:input {:type "checkbox"}] "remember me?"]
+              [:input {:type "checkbox"}] "Remember me?"]
              [:p.pull-right
               [:button.btn.btn-link
                {:type     "button"
@@ -108,4 +108,9 @@
             [:div.text-center
             [:button.btn.btn-primary
              {:type     "button"
-              :on-click #(secretary/dispatch! "/sign-up")} "Sign Up Here"]]]]])})))
+              :on-click #(secretary/dispatch! "/sign-up")} "Sign Up Here"]]
+              [:br]
+              [:p.text-center [:small "Hatched with "
+                [:a {:target "blank" :href "http://www.codefordenver.org/"} "Code for Denver"]
+              " in 2015"]]
+              ]]])})))


Expand test coverage with name-filter-fn. (#769)

--- scheduler/test/cook/test/mesos/util.clj
+++ scheduler/test/cook/test/mesos/util.clj
@@ -398,21 +398,49 @@
             _ (Thread/sleep 5)
             end-time (Date.)
             states [(name state)]
-            name (constantly true)]
+            match-any-name-fn (constantly true)
+            match-no-name-fn (constantly false)]
         (testing (str "get " state " jobs")
-          (is (= 2 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 10 name nil))))
-          (is (= 1 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 name nil))))
-          (is (= (map :db/id (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 name nil))
+          (is (= 2 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 10 match-any-name-fn false))))
+          (is (= 1 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 match-any-name-fn false))))
+          (is (= (map :db/id (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 match-any-name-fn false))
                  [job1]))
-          (is (= 3 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 10 name nil))))
-          (is (= 2 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 name nil))))
-          (is (= (map :db/id (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 name nil))
+          (is (= 3 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 10 match-any-name-fn false))))
+          (is (= 2 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 match-any-name-fn false))))
+          (is (= (map :db/id (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 match-any-name-fn false))
                  [job1 job2]))

-          (is (= 1 (count (util/get-jobs-by-user-and-states (d/db conn) "u2" states start-time end-time 10 name nil))))
-          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u3" states start-time end-time 10 name nil))))
+          (is (= 1 (count (util/get-jobs-by-user-and-states (d/db conn) "u2" states start-time end-time 10 match-any-name-fn false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u3" states start-time end-time 10 match-any-name-fn false))))
           (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states
-                                                            #inst "2017-06-01" #inst "2017-06-02" 10 name nil)))))))))
+                                                            #inst "2017-06-01" #inst "2017-06-02" 10 match-any-name-fn false)))))
+        ; Nil means the same as always true.
+        (testing (str "get " state " jobs ; name = nil")
+          (is (= 2 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 10 nil false))))
+          (is (= 1 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 nil false))))
+          (is (= (map :db/id (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 nil false))
+                 [job1]))
+          (is (= 3 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 10 nil false))))
+          (is (= 2 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 nil false))))
+          (is (= (map :db/id (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 nil false))
+                 [job1 job2]))
+
+          (is (= 1 (count (util/get-jobs-by-user-and-states (d/db conn) "u2" states start-time end-time 10 nil false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u3" states start-time end-time 10 nil false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states
+                                                            #inst "2017-06-01" #inst "2017-06-02" 10 nil false)))))
+        ; Never true, so should match nothing.
+        (testing (str "get " state " jobs ; name = false")
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 10 match-no-name-fn false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time half-way-time 1 match-no-name-fn false))))
+
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 10 match-no-name-fn false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states start-time end-time 2 match-no-name-fn false))))
+
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u2" states start-time end-time 10 match-no-name-fn false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u3" states start-time end-time 10 match-no-name-fn false))))
+          (is (= 0 (count (util/get-jobs-by-user-and-states (d/db conn) "u1" states
+                                                            #inst "2017-06-01" #inst "2017-06-02" 10 match-no-name-fn false)))))))))

 (deftest test-reducing-pipe
   (testing "basic piping"


Add new approach for images page initialization.

--- src/uxbox/main/data/images.cljs
+++ src/uxbox/main/data/images.cljs
@@ -10,6 +10,7 @@
             [beicon.core :as rx]
             [uxbox.util.uuid :as uuid]
             [uxbox.util.rstore :as rs]
+            [uxbox.util.router :as r]
             [uxbox.main.state :as st]
             [uxbox.main.repo :as rp]))

@@ -18,23 +19,30 @@
 (declare fetch-collections)
 (declare collections-fetched?)

-(defrecord Initialize []
+(defrecord Initialize [type id]
+  rs/UpdateEvent
+  (-apply-update [_ state]
+    (let [type (or type :builtin)
+          id (or id (if (= type :builtin) 1 nil))
+          data {:type type :id id :selected #{}
+                :section :dashboard/images}]
+      (assoc state :dashboard data)))
+
   rs/EffectEvent
   (-apply-effect [_ state]
-    (when-not (seq (:images-by-id state))
+    (when (nil? (:images-by-id state))
       (reset! st/loader true)))

   rs/WatchEvent
   (-apply-watch [_ state s]
-    (let [images (seq (:images-by-id state))]
-      (if images
-        (rx/empty)
-        (rx/merge
-         (rx/of (fetch-collections))
+    (if (nil? (:images-by-id state))
+      (rx/merge
+       (rx/of (fetch-collections))
          (->> (rx/filter collections-fetched? s)
               (rx/take 1)
               (rx/do #(reset! st/loader false))
-              (rx/ignore)))))))
+              (rx/ignore)))
+      (rx/empty))))

 (defn initialize
   []


Upsert reimplemented to exclude upsert values from exploded map

--- src/datascript/db.cljc
+++ src/datascript/db.cljc
@@ -1069,64 +1069,80 @@
     (raise "Bad attribute type: " attr ", expected keyword or string"
            {:error :transact/syntax, :attribute attr})))

-
-(defn- check-upsert-conflict [entity acc]
-  (let [[e a v] acc
-        _e (:db/id entity)]
-    (if (or (nil? _e)
-            (tempid? _e)
-            (nil? acc)
-            (== _e e))
-      acc
-      (raise "Conflicting upsert: " [a v] " resolves to " e
-             ", but entity already has :db/id " _e
-             { :error :transact/upsert
-               :entity entity
-               :assertion acc }))))
-
-(defn- upsert-reduce-fn [db eav a v]
-  (let [e (:e (first (-datoms db :avet [a v])))]
-    (cond
-      (nil? e) ;; value not yet in db
-      eav
-
-      (nil? eav) ;; first upsert
-      [e a v]
-
-      (= (get eav 0) e) ;; second+ upsert, but does not conflict
-      eav
-
-      :else
-      (let [[_e _a _v] eav]
-        (raise "Conflicting upserts: " [_a _v] " resolves to " _e
-               ", but " [a v] " resolves to " e
-               { :error     :transact/upsert
-                 :assertion [e a v]
-                 :conflict  [_e _a _v] })))))
-
-(defn- upsert-eid [db entity]
-  (when-some [idents (not-empty (-attrs-by db :db.unique/identity))]
-    (->>
+(defn- resolve-upserts
+  "Returns [entity' upserts]. Upsert attributes that resolve to existing entities
+   are removed from entity, rest are kept in entity for insertion. No validation is performed.
+
+   upserts :: {:name  {\"Ivan\"  1}
+               :email {\"ivan@\" 2}
+               :alias {\"abc\"   3
+                       \"def\"   4}}}"
+  [db entity]
+  (if-some [idents (not-empty (-attrs-by db :db.unique/identity))]
+    (let [resolve (fn [a v]
+                    (:e (first (-datoms db :avet [a v]))))
+          split   (fn [a vs]
+                    (reduce
+                      (fn [acc v]
+                        (if-some [e (resolve a v)]
+                          (update acc 0 assoc v e)
+                          (update acc 1 conj v)))
+                      [{} []] vs))]
       (reduce-kv
-        (fn [eav a v] ;; eav = [e a v]
+        (fn [[entity upserts] a v]
           (cond
             (not (contains? idents a))
-            eav
+            [(assoc entity a v) upserts]

             (and
               (multival? db a)
               (or
                 (arrays/array? v)
                 (and (coll? v) (not (map? v)))))
-            (reduce #(upsert-reduce-fn db %1 a %2) eav v)
+            (let [[upsert insert] (split a v)]
+              [(cond-> entity
+                 (not (empty? insert)) (assoc a insert))
+               (cond-> upserts
+                 (not (empty? upsert)) (assoc a upsert))])

             :else
-            (upsert-reduce-fn db eav a v)))
-        nil
-        entity)
-     (check-upsert-conflict entity)
-     first))) ;; getting eid from eav
-
+            (if-some [e (resolve a v)]
+              [entity (assoc upserts a {v e})]
+              [(assoc entity a v) upserts])))
+        [entity {}]
+        entity))
+    [entity nil]))
+
+(defn validate-upserts
+  "Throws if not all upserts point to the same entity.
+   Returns single eid that all upserts point to, or null."
+  [entity upserts]
+  (let [upsert-ids (reduce-kv
+                     (fn [m a v->e]
+                       (reduce-kv
+                         (fn [m v e]
+                           (assoc m e [a v]))
+                         m v->e))
+                     {} upserts)]
+    (if (<= 2 (count upsert-ids))
+      (let [[e1 [a1 v1]] (first upsert-ids)
+            [e2 [a2 v2]] (second upsert-ids)]
+        (raise "Conflicting upserts: " [a1 v1] " resolves to " e1 ", but " [a2 v2] " resolves to " e2
+          {:error     :transact/upsert
+           :assertion [e1 a1 v1]
+           :conflict  [e2 a2 v2]}))
+      (let [[upsert-id [a v]] (first upsert-ids)
+            eid (:db/id entity)]
+        (when (and
+                (some? upsert-id)
+                (some? eid)
+                (not (tempid? eid))
+                (not= upsert-id eid))
+          (raise "Conflicting upsert: " [a v] " resolves to " upsert-id ", but entity already has :db/id " eid
+            {:error     :transact/upsert
+             :assertion [upsert-id a v]
+             :conflict  {:db/id eid}}))
+        upsert-id))))

 ;; multivals/reverse can be specified as coll or as a single value, trying to guess
 (defn- maybe-wrap-multival [db a vs]
@@ -1147,7 +1163,6 @@
     [vs]

     :else vs))
-

 (defn- explode [db entity]
   (let [eid (:db/id entity)]
@@ -1281,7 +1296,8 @@
                      (cons (assoc entity :db/id id) entities)))

             ;; upserted => explode | error
-            :let [upserted-eid (upsert-eid db entity)]
+            :let [[entity' upserts] (resolve-upserts db entity)
+                  upserted-eid      (validate-upserts entity upserts)]

             (some? upserted-eid)
             (if (and (tempid? old-eid)
@@ -1289,7 +1305,7 @@
                      (not= upserted-eid (get tempids old-eid)))
               (retry-with-tempid initial-report report initial-es old-eid upserted-eid)
               (recur (allocate-eid report old-eid upserted-eid)
-                     (concat (explode db (assoc entity :db/id upserted-eid)) entities)))
+                     (concat (explode db (assoc entity' :db/id upserted-eid)) entities)))

             ;; resolved | allocated-tempid | tempid | nil => explode
             (or (number? old-eid)