Update buttons after parinfer is run

Update buttons after parinfer is run

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -589,10 +589,6 @@
           shortcuts/create-hints!
           (shortcuts/create-mappings! actions)
           (update-buttons! text-area)))
-      ; update buttons every time a key is typed
-      (s/listen text-area
-                :key-released
-                (fn [e] (update-buttons! editor-pane text-area)))
       ; install completer if it exists
       (some->> completer (completions/install-completer! text-area))
       ; add watchers
@@ -610,6 +606,10 @@
       ; initialize parinfer
       (init-parinfer! text-area extension edit-history true)
       (update-buttons! editor-pane text-area)
+      ; update buttons every time a key is typed
+      (s/listen text-area
+                :key-released
+                (fn [e] (update-buttons! editor-pane text-area)))
       ; return a map describing the editor
       {:view editor-pane
        :text-area text-area


Update tests to reflect actual content.

Update tests to reflect actual content.

--- test/flatland/handler_test.clj
+++ test/flatland/handler_test.clj
@@ -17,7 +17,7 @@

 (deftest posts-test
   (testing "Markdown conversion results in HTML."
-    (let [body (:body (app (request :get "/posts/sample_post")))]
+    (let [body (:body (app (request :get "/posts/vladimir")))]
       (is (re-find #"<h1>" body))
       (is (re-find #"<em>" body))
       (is (re-find #"<strong>" body))


Fixed flakiness in redis test

Fixed flakiness in redis test

--- test/hitchhiker/redis_test.clj
+++ test/hitchhiker/redis_test.clj
@@ -47,9 +47,11 @@
                                      [(core/b-tree (core/->Config 3 3 2)) nil #{}]
                                      ops)]
                   #_(println "Make it to the end of a test, tree has" (count (lookup-fwd-iter b-tree -1)) "keys left")
-                  (let [res (= (lookup-fwd-iter b-tree -1) (sort set))]
+                  (let [b-tree-order (lookup-fwd-iter b-tree -1)
+                        res (= b-tree-order (seq (sort set)))]
                     (wcar {} (redis/drop-ref root))
                     (assert (= ["refcount:expiry"] (wcar {} (car/keys "*"))) "End with no keys")
+                    (assert res (str "These are unequal: " (pr-str b-tree-order) " " (pr-str (seq (sort set)))))
                     res))))

 (defspec test-many-keys-bigger-trees


Move `extra-types` def to a more sensible place.

--- test/isla/test/interpreter.clj
+++ test/isla/test/interpreter.clj
@@ -5,6 +5,13 @@
   (:require [isla.library :as library])
   (:use [clojure.test])
   (:use [clojure.pprint]))
+
+(def extra-types
+  {"person"
+   {:type (defrecord Person [age name friend])
+    :defaults [0 "" :undefined]}})
+
+;; non-slot assignment

 (deftest integer-assignment
   (let [result (interpret (parse "isla is 1"))]
@@ -30,11 +37,6 @@
 (deftest test-write-assigned-value
   (let [result (interpret (parse "name is 'mary'\nwrite name"))]
     (is (= (:ret result) "mary"))))
-
-(def extra-types
-  {"person"
-   {:type (defrecord Person [age name friend])
-    :defaults [0 "" :undefined]}})

 ;; type assignment


Add scm integration test.

Add scm integration test.

--- test/runbld/test/main_test.clj
+++ test/runbld/test/main_test.clj
@@ -1,6 +1,8 @@
 (ns runbld.test.main-test
   (:require [schema.test :as s])
-  (:require [clojure.test :refer :all]
+  (:require [clj-git.core :refer [git-branch git-log load-repo]]
+            [clojure.java.io :as jio]
+            [clojure.test :refer :all]
             [clojure.walk :refer [keywordize-keys]]
             [runbld.build :as build]
             [runbld.notifications.email :as email]
@@ -216,3 +218,55 @@
               (finally
                 (io/rmdir-r periodic-dir)
                 (io/rmdir-r intake-dir)))))))))
+
+(s/deftest ^:integration execution-with-scm
+  (testing "real execution all the way through with cloning via scm config"
+    (let [wipe-workspace-orig main/wipe-workspace
+          workspace "tmp/git/elastic+foo+master"]
+      (with-redefs [io/log (fn [& x] (prn x))
+                    email/send* (fn [& args]
+                                  (swap! email concat args)
+                                  ;; to satisfy schema
+                                  {})
+                    slack/send (fn [opts ctx]
+                                 (let [f (-> opts :slack :template)
+                                       tmpl (-> f io/resolve-resource slurp)
+                                       color (if (-> ctx :process :failed)
+                                               "danger"
+                                               "good")
+                                       js (mustache/render-string
+                                           tmpl (assoc ctx :color color))]
+                                   (reset! slack js)))
+                    main/wipe-workspace (fn [workspace] nil)]
+        (try
+          (let [[opts res] (run
+                             (conj
+                              ["-c" "test/config/scm.yml"
+                               "-j" "elastic+foo+master"
+                               "-d" workspace]
+                              (if (opts/windows?)
+                                "test/fail.bat"
+                                "test/fail.bash")))]
+            (testing "the elasticsearch repo was cloned correctly"
+              (let [branch (-> opts :scm :branch)
+                    depth (-> opts :scm :depth)
+                    repo (load-repo workspace)]
+                (is (= branch (git-branch repo)))
+                (is (= depth (count (git-log repo)))))
+              (testing "scm doesn't break anything else"
+                (is (= 1 (:exit-code res)))
+                (is (= 1 (-> (store/get (-> opts :es :conn)
+                                        (-> res :store-result :addr :index)
+                                        (-> res :store-result :addr :type)
+                                        (-> res :store-result :addr :id))
+                             :process
+                             :exit-code)))
+                (is (.startsWith
+                     (let [[_ _ _ subj _ _] @email] subj) "FAILURE"))
+                (is (.contains (slack-msg) "FAILURE")))
+              (testing "wiping the workspace"
+                (wipe-workspace-orig workspace)
+                ;; Should only have the top-level workspace dir left
+                (is (= [workspace] (map str (file-seq (jio/file workspace))))))))
+          (finally
+            (io/rmdir-r workspace)))))))


adding support for variance

adding support for variance

--- src/anyviz/views.clj
+++ src/anyviz/views.clj
@@ -34,7 +34,7 @@

 (def match-operators ["=","!=","<","<=",">",">="])
 (def group-times ["year","month","day","hour","minute"])
-(def reduce-operators ["count","min","max","sum","avg","stdev","range"])
+(def reduce-operators ["count","min","max","sum","avg","stdev","range","variance"])
 (def date-periods ["all time","last year","last 6 months","last 30 days","last 7 days","last day","last hour"])
 (def graph-types ["spline","column","line","area","bar","areaspline","scatter"])
 (def bs-columns ["col-sm-1","col-sm-2","col-sm-3","col-sm-4","col-sm-5","col-sm-6","col-sm-7","col-sm-8","col-sm-9","col-sm-10","col-sm-11","col-sm-12"])


Spec register-mappings and more completely spec register.

--- spec/incise/parsers/core_spec.clj
+++ spec/incise/parsers/core_spec.clj
@@ -1,14 +1,35 @@
 (ns incise.parsers.core-spec
   (:require [speclj.core :refer :all]
-            (incise [load :refer [load-parsers-and-layouts]]
-                    [config :as conf])
+            [incise.config :as conf]
+            (incise [load :refer [load-parsers-and-layouts]])
             [clojure.java.io :refer [file resource]]
             [incise.parsers.core :refer :all]))

 (describe "register"
   (before (reset! parsers {}))
+  (with parser (fn []))
   (it "can register parsers to extensions"
-    (should-not-throw (register ["markdown"] (fn [_])))))
+    (should-not-throw (register [:mkd "markdown"] @parser))
+    (should-contain "markdown" @parsers)
+    (should-contain "mkd" @parsers))
+  (it "can register parsers to extensions"
+    (should-not-throw (register ["markdown"] @parser)))
+  (it "can register parser to extension"
+    (should-not-throw (register "markdown" @parser)))
+  (it "can register parsers to keyword extensions"
+    (should-not-throw (register [:markdown] @parser))))
+
+(describe "register-mappings"
+  (before (reset! parsers {}))
+  (with parser (fn []))
+  (with mappings {:markdown :mkd
+                  :txt [:rst :thing]})
+  (before (register :markdown @parser))
+  (before (register :txt @parser))
+  (it "register mappings copies parsers to new extensions"
+    (register-mappings @mappings)
+    (doseq [parser-key (map name [:mkd :thing :rst])]
+      (should-contain parser-key @parsers))))

 (describe "parsers"
   (before-all (reset! parsers {}))


Process reader on pathom async

Process reader on pathom async

--- src/com/wsscode/pathom/async.cljc
+++ src/com/wsscode/pathom/async.cljc
@@ -76,18 +76,17 @@
 ;; PARSER READER

 (defn parser-error [env err]
-  err
-  (ex-info (str "Parser: " (.-message err)) {:path (pr-str (::p/path env))}))
+  (ex-info (str "Parser Error: " (.-message err)) {:path (pr-str (::p/path env))}))

 (defn error? [e]
   #?(:clj  (instance? Throwable e)
      :cljs (instance? js/Error e)))

-(defn async-pathom-read [{::p/keys [reader] :as env} _ _]
+(defn async-pathom-read [{::p/keys [reader process-reader] :as env} _ _]
   {:value
    (let [env (p/normalize-env env)]
      (try
-       (let [value (p/read-from env reader)]
+       (let [value (p/read-from env (if process-reader (process-reader reader) reader))]
          (if (chan? value)
            (go
              (let [v (<! value)]


Use buffered channels with size 100

Use buffered channels with size 100

--- exercise3/src/de/haw/vs/core.clj
+++ exercise3/src/de/haw/vs/core.clj
@@ -12,16 +12,15 @@
   (:gen-class))

 (defn station-system [runtime-config]
-  (let [station->message-writer (async/chan)
-        payload-source->station (async/chan)]
+  (let [station->message-writer (async/chan 100)
+        payload-source->station (async/chan 100)]

     (-> (system/base-system (merge {:name "exercise3"} runtime-config))
         (assoc
           :payload-source (c/using (payload-source/new-payload-source payload-source->station) [:config])
           :message-writer (c/using (message-writer/new-message-writer station->message-writer) [:config])
           :connector (c/using (connector/new-connector) [:config :app-status])
-          :station (c/using (station/new-station payload-source->station station->message-writer) [:config :app-status :connector])
-          )
+          :station (c/using (station/new-station payload-source->station station->message-writer) [:config :app-status :connector]))
         (httpkit/add-server))))

 (defn display-help []


Fixes CSS validation complaints for keyframes.

When slide? is false, empty left rules are generated. This will ensure the generated CSS adheres to syntax rules.

--- src/day8/re_frame_10x/styles.cljs
+++ src/day8/re_frame_10x/styles.cljs
@@ -518,13 +518,13 @@
 (def at-keyframes-styles
   (let [slide? false]
     [(at-keyframes :pulse-previous-re-frame-10x
-                   [:from {:color "white"
-                           :left  (when slide? "-100%")}]
-                   [:to {:left (when slide? "0%")}])
+                   [:from (merge {:color "white"}
+                                 (when slide? :left "-100%"))]
+                   [:to (when slide? {:left  "0%"})])
      (at-keyframes :pulse-next-re-frame-10x
-                   [:from {:color "white"
-                           :left  (when slide? "100%")}]
-                   [:to {:left (when slide? "0%")}])
+                   [:from (merge {:color "white"}
+                                 (when slide? {:left "100%"}))]
+                   [:to (when slide? {:left "0%"})])
      (at-keyframes :fade-clipboard-msg-re-frame-10x
                    [:0% {:margin-left "100px"}]
                    [:5% {:margin-left "0px"


we don't need these anymore

we don't need these anymore

--- src/desdemona/ui/sample-data.cljs
+++ src/desdemona/ui/sample-data.cljs
@@ -912,6 +912,4 @@
     :critical true
     :created-at "2005-03-30T11:49:32-02:00"}])

-(def sample-state {:results example-results
-                   :table-sort-key :id
-                   :table-sort-order :asc})
+(def sample-state {:results example-results})


fix docstring typo

fix docstring typo

--- src/asphalt/core.clj
+++ src/asphalt/core.clj
@@ -56,7 +56,7 @@

 (defn fetch-rows
-  "Given a java.sql.ResultSet and asphalt.internal.ISql instances fetch a vector of rows using ISql."
+  "Given java.sql.ResultSet and asphalt.type.ISql instances fetch a vector of rows using ISql."
   ([isql ^ResultSet result-set]
     (fetch-rows t/read-row isql result-set))
   ([row-maker isql ^ResultSet result-set]
@@ -69,7 +69,7 @@

 (defn fetch-single-row
-  "Given java.sql.ResultSet and asphalt.internal.ISql instances ensure result has exactly one row and fetch it using
+  "Given java.sql.ResultSet and asphalt.type.ISql instances ensure result has exactly one row and fetch it using
   ISql."
   ([isql ^ResultSet result-set]
     (fetch-single-row t/read-row isql result-set))
@@ -89,7 +89,7 @@

 (defn fetch-single-value
-  "Given java.sql.ResultSet and asphalt.internal.ISql instances, ensure result has exactly one row and one column, and
+  "Given java.sql.ResultSet and asphalt.type.ISql instances, ensure result has exactly one row and one column, and
   fetch it using ISql."
   ([isql ^ResultSet result-set]
     (fetch-single-value t/read-col isql result-set))


Flow conditions post transformation tests.

--- test/onyx/generative/flow_conditions_gen_test.clj
+++ test/onyx/generative/flow_conditions_gen_test.clj
@@ -78,6 +78,13 @@
               :flow/post-transform (gen/one-of
                                     [(gen/return nil)
                                      (gen/return ::post-transform)]))]
+       (gen/fmap #(merge v %) g)))))
+
+(defn post-transformation-flow-gen [base-gen]
+  (gen/bind
+   base-gen
+   (fn [v]
+     (let [g (gen/hash-map :flow/transform (gen/return ::post-transform))]
        (gen/fmap #(merge v %) g)))))

 (defn retry-flow-condition-gen [base-gen]
@@ -318,3 +325,36 @@
          results (t/route-data event nil nil fcs downstream)]
      (is (not (seq (:flow/to results))))
      (is (nil? (:action results))))))
+
+(deftest post-transformation
+  (checking
+   "A :flow/post-transform is returned for exception predicates that define it"
+   (times 30)
+   [false-xform
+    (gen/vector (->> :a
+                     (flow-condition-gen)
+                     (flow-to-tasks-gen)
+                     (exception-flow-condition-gen)
+                     (post-transformation-flow-gen)
+                     (false-flow-condition-gen)))
+    true-xform
+    (gen/not-empty
+     (gen/vector (->> :a
+                      (flow-condition-gen)
+                      (flow-to-tasks-gen)
+                      (exception-flow-condition-gen)
+                      (post-transformation-flow-gen)
+                      (true-flow-condition-gen))))
+    mixed
+    (gen/vector (->> :a
+                     (flow-condition-gen)
+                     (flow-to-tasks-gen)
+                     (maybe-predicate)))]
+   (let [fcs [false-xform true-xform mixed]
+         downstream (mapcat :flow/to fcs)
+         compiled (c/compile-fc-norms fcs :a)
+         event {:onyx.core/compiled-norm-fcs compiled}
+         results (t/route-data event nil nil fcs downstream)
+         xform (:flow/post-transformation (first true-xform))]
+     (is (= xform (:post-transformation results)))
+     (is (nil? (:action results))))))


Add and update ClojureDocs for processing_fn_utils.clj.

--- src/dsbdp/processing_fn_utils.clj
+++ src/dsbdp/processing_fn_utils.clj
@@ -15,6 +15,10 @@
     [clojure.pprint :refer :all]))

 (defn create-proc-fn-vec-from-template
+  "Create a vector with n processing functions based on the two given \"template\" functions fn-1 and fn-n.
+   fn-1 is the function that will be put as first function in the resulting vector.
+   Subsequently, fn-n will be repeated n-1 times to fill the vector with n instances.
+   All occurrences of :_idx_ in the supplied functions will be replaced with the numerical index value of the corresponding function in the resulting vector."
   [fn-1 fn-n n]
   (loop [fns (prewalk-replace {:_idx_ 0} [fn-1])]
     (if (< (count fns) n)
@@ -27,6 +31,7 @@
           (map eval fns))))))

 (defn combine-proc-fns
+  "Based on the given vector of processing functions, combine the functions starting at start-idx, inclusive, up to end-idx, non inclusive, into a single combined function."
   [fn-vec start-idx end-idx]
   (fn [in out]
     (loop [fns (subvec fn-vec start-idx end-idx) o out]
@@ -35,6 +40,9 @@
         (recur (rest fns) ((first fns) in o))))))

 (defn combine-proc-fns-vec
+  "Map a vector of processing functions, fn-vec, to a vector of combined functions.
+   The mapping definition fn-mapping, is a vector of integer values that define how many processing functions are combined in each combined function.
+   For a vector of processing functions [a b c d e f] a mapping definition [1 2 3] will result in the following association of processing rules to combined functions f_x: [f_1(a), f_2(b, c), f_3(d e f)]."
   [fn-mapping fn-vec]
   (reduce
     (fn [v m]
@@ -45,6 +53,8 @@
     (rest fn-mapping)))

 (defn calculate-distribution-mapping
+  "Based on an input sequence, in-seq, and a vector of ratios, calculate a mapping such that the input sequence will be distributed according to the given ratios.
+   The resulting mapping can be used, e.g., with combine-proc-fns-vec."
   ([in-seq ratios]
     (calculate-distribution-mapping in-seq ratios {}))
   ([in-seq ratios opts]


Log the stack trace.

Log the stack trace.

--- src/kixi/hecuba/data/entities.clj
+++ src/kixi/hecuba/data/entities.clj
@@ -91,7 +91,7 @@
         (try
           (json/parse-string (:property_data entity) keyword)
           (catch Throwable t
-            (log/errorf "Could not parse property_data %s for entity %s" (:property_data entity) entity)))
+            (log/errorf t "Could not parse property_data %s for entity %s" (:property_data entity) entity)))
              {})
       (decode-tech-icons)))


Adding children to HTML output and fixing application/edn representation for item resource

--- src/kixi/hecuba/web/resources.clj
+++ src/kixi/hecuba/web/resources.clj
@@ -8,6 +8,7 @@
    [clojure.edn :as edn]
    [clojure.java.io :as io]
    [clojure.string :as string]
+   [clojure.pprint :refer (pprint)]
    [camel-snake-kebab :as csk]))

 (def base-media-types ["text/html" "application/json" "application/edn"])
@@ -113,7 +114,9 @@
       [:ul
        (for [child children]
          [:li [:a {:href (:hecuba/href child)} (:hecuba/name child)]])])
-    [:pre (pr-str item)]]))
+    [:pre (with-out-str
+            (pprint {:item item
+                     :children children}))]]))

 ;; REST resource for individual items.

@@ -151,6 +154,8 @@
   (fn [{item ::item children ::children {mime :media-type} :representation}]
     (case mime
       "text/html" (render-item-html item children)
+      "application/edn" (pr-str {:item item
+                                 :children children})
       ;; The default is to let Liberator render our data
       {:item item
        :children children})))


注释报错的行，加入set接口相关知识

注释报错的行，加入set接口相关知识

--- src/learnclojure/chapt3/core5.clj
+++ src/learnclojure/chapt3/core5.clj
@@ -8,7 +8,7 @@
 (nth [:a :b :c] 2)
 (get [:a :b :c] 2)
 ;;nth在越界的时候会报IndexOutOfBoundsException
-(nth [:a :b :c] 3)
+;;(nth [:a :b :c] 3)
 ;;get返回nil，不报错
 (get [:a :b :c] 3)

@@ -18,7 +18,7 @@
 ;;它们另一个区别是，get对错误更容忍，当你传给它一个不支持的数据类型，它也返回nil而不是抛出异常
 (get 42 0)
 ;;用nth会报错
-(nth 42 0)
+;;(nth 42 0)
 ;;clojure中的vector本身就支持nth语义，比调用nth更方便
 (def v [1 2 3])
 (v 0)
@@ -47,4 +47,8 @@
 ;;对一个空栈调用pop会报错
 ;;(pop [])

+;;set接口
+;;从set中删除一个元素用disj
+(disj #{1 2 4} 1 2)
+;;clojure.set提供了一些有用的函数，如subset?、superset?、union、intersection、project等


s/DEBUG/INFO/ for index creation: should happen only rarely

--- src/babel/index.cljc
+++ src/babel/index.cljc
@@ -158,7 +158,7 @@
   (let [lexicon (if (map? lexicon)
                   (keys lexicon)
                   lexicon)]
-    (log/debug (str "create index with lexicon: " (count lexicon)))
+    (log/info (str "create index with lexicon: " (count lexicon)))
     (conj (build-lex-sch-index grammar
                                (map (fn [lexeme]
                                       (log/debug (str "trying(ci) lexeme: " lexeme))


debugging

debugging

--- src/babel/reader.clj
+++ src/babel/reader.clj
@@ -145,8 +145,7 @@
                       debug (log/debug (str "index of target result:" index-of-result))
                       target-expression (nth results index-of-result)
                       debug (log/debug (str "target-expression is nil? " (nil? target-expression)))
-                      debug (log/trace (str "target-expression is: " target-expression))
-                      ]
+                      debug (log/trace (str "target-expression is: " target-expression))]

                   ;; Now get all the target expressions that are semantically
                   ;; equivalent to this expression's semantics,
@@ -243,6 +242,7 @@
                                     retval)))

                                 )]
+                        (log/debug (str "generate-question-and-correct-set [target-spec:" target-spec "] => retval: " retval))
                         retval))))))))))

 (defn get-lexeme [canonical language & [ spec ]]


more logging and error diagnostic logging

--- src/babel/writer.clj
+++ src/babel/writer.clj
@@ -57,7 +57,9 @@
                                                   source-language-model :enrich true)

         semantics (strip-refs (get-in target-language-sentence [:synsem :sem] :top))
-        debug (log/debug (str "semantics: " semantics))
+        debug (log/debug (str "semantics of resulting expression: " semantics))
+        debug (log/trace (str "entire expression: " target-language-sentence))
+        debug (log/trace (str "french: " (get-in target-language-sentence [:français])))

         target-language-surface (target-fo target-language-sentence)
         debug (log/debug (str "target surface: " target-language-surface))
@@ -75,7 +77,14 @@
                   (if (= true mask-populate-errors)
                     (log/warn message)
                     ;; else
-                    (throw (Exception. message)))))
+                    (let [target-language-model (if (future? target-language-model)
+                                                  @target-language-model
+                                                  target-language-model)]
+                      (log/error message)
+                      (log/error "grammar: " (map :rule (:grammar target-language-model)))
+                      (log/error "lexicon: " (map (:morph target-language-model)
+                                                  (sort (keys (:lexicon target-language-model)))))
+                      (throw (Exception. message))))))
         source-language-sentence (engine/generate {:synsem {:sem semantics
                                                             :subcat '()}}
                                                   source-language-model
@@ -132,8 +141,8 @@
 (defn populate [num source-language-model target-language-model & [ spec table ]]
   (let [spec (if spec spec :top)
         debug (log/debug (str "populate spec(1): " spec))
-        debug (log/debug (str "type of source language model: " (type source-language-model)))
-        debug (log/debug (str "type of target language model: " (type target-language-model)))
+        debug (log/trace (str "type of source language model: " (type source-language-model)))
+        debug (log/trace (str "type of target language model: " (type target-language-model)))
         spec (cond
               (not (= :notfound (get-in spec [:synsem :sem :subj] :notfound)))
               (unify spec


Fixed a bug that postMessage() fails.

Fixed a bug that postMessage() fails.

- Null is not allowed for the 2nd argument of postMessage() in firefox.

--- src/butler/core.cljs
+++ src/butler/core.cljs
@@ -36,7 +36,7 @@
         serialized (serialize {:name name :data without-transferables})
         copying (clj->js {"serialized" serialized
                           "transferables" transferables})]
-    (.postMessage worker copying (clj->js (vals transferables)))))
+    (.postMessage worker copying (clj->js (or (vals transferables) [])))))

 (defn butler
   [script handlers]


Add props to vies

Add props to vies

--- frontend/src/cruncher/views.cljs
+++ frontend/src/cruncher/views.cljs
@@ -64,7 +64,7 @@
     (dom/div nil
              (dom/div #js {:className "page-header"}
                       (dom/div #js {:className "pull-right"}
-                               (vlib/login-indicator))
+                               (vlib/login-indicator (om/props this)))
                       (dom/h1 nil "Poké-Cruncher"))
              (dom/p nil "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.")
              (dom/hr nil))))
@@ -158,7 +158,7 @@
   Object
   (render [this]
     (dom/div nil
-             (dom/div nil (header))
+             (dom/div nil (header (om/props this)))
              (dom/div nil (error-message (om/props this)))
              (view-dispatcher)
              #_(dom/div nil (poketable (om/props this)))


placeholder: more thread-last macro in Clojure

--- clojure/thread-macros.clj
+++ clojure/thread-macros.clj
@@ -2,11 +2,11 @@
      (map #(* % %))
      (take 13)
      (reduce +)
-     (#(println "First 13 square pyramidal numbers:" % "(https://oeis.org/A000330)")))
+     (printf "First 13 square pyramidal numbers: %d (https://oeis.org/A000330)\n"))

 (->> (range)
      (map #(* % %))
      (filter even?)
      (take 13)
      (reduce +)
-     (#(println "Sum of the first 13 even squares:" % "(https://oeis.org/A002492)")))
+     (printf "Sum of the first 13 even squares: %d (https://oeis.org/A002492)\n"))


Refactor connect tests to use defresolver

--- test/com/wsscode/pathom/connect_test.cljc
+++ test/com/wsscode/pathom/connect_test.cljc
@@ -19,69 +19,69 @@
 (def user-addresses
   {1 "Live here somewhere"})

-(defn user-by-id [_ {:keys [user/id] :as input}]
-  (or (get users id) (throw (ex-info "user not found" {:input input}))))
-
-(defn user-by-login [_ {:keys [user/login]}]
-  (or (get users-login login) (throw (ex-info "user not found" {}))))
-
-(defn user-address [_ {:keys [user/id]}]
-  {:user/address (get user-addresses id)})
-
-(defn user-login-from-email [_ {:user/keys [email]}]
+(defresolver `user-by-id
+  {::pc/input  #{:user/id}
+   ::pc/output [:user/name :user/id :user/login :user/age]}
+  (fn  [_ {:keys [user/id] :as input}]
+  (or (get users id) (throw (ex-info "user not found" {:input input})))))
+
+(defresolver `user-by-login
+  {::pc/input  #{:user/login}
+   ::pc/output [:user/name :user/id :user/login :user/age]}
+  (fn  [_ {:keys [user/login]}]
+  (or (get users-login login) (throw (ex-info "user not found" {})))))
+
+(defresolver `user-login-from-email
+  {::pc/input  #{:user/email}
+   ::pc/output [:user/login]}
+  (fn  [_ {:user/keys [email]}]
   (if (= email "a@b.c")
-    {:user/login "meel"}))
-
-(defn user-network [_ {:user/keys [id]}]
+    {:user/login "meel"})))
+
+(defresolver `user-address
+  {::pc/input  #{:user/id}
+   ::pc/output [:user/address]}
+  (fn  [_ {:keys [user/id]}]
+  {:user/address (get user-addresses id)}))
+
+(defresolver `user-network
+  {::pc/input  #{:user/id}
+   ::pc/output [{:user/network [:network/id :network/name]}]}
+  (fn  [_ {:user/keys [id]}]
   (if (= 1 id)
-    {:user/network {:network/id "twitter" :network/name "mell"}}))
-
-(defn error-value [_ _]
-  {:some-error ::p/reader-error})
-
-(defn error-dependent [_ {:keys [some-error]}]
+    {:user/network {:network/id "twitter" :network/name "mell"}})))
+
+(defresolver `global-attr
+  {::pc/output [:color]}
+  (fn  [_ _]
+  {:color "purple"}))
+
+(defresolver `dont-cache-me
+  {::pc/output [:value]
+   ::pc/cache? false}
+  (fn  [_ _]
+  {:value 42}))
+
+(defresolver `change-env
+  {::pc/output [{::i-update-env [:foo]}]}
+  (fn  [env _]
+  {::i-update-env {:foo "bar"}
+   ::pc/env       (assoc env :new-info "vish")}))
+
+(defresolver `error-value
+  {::pc/output [:some-error]}
+  (fn  [_ _]
+  {:some-error ::p/reader-error}))
+
+(defresolver `error-dependent
+  {::pc/input  #{:some-error}
+   ::pc/output [:error-dep]}
+  (fn  [_ {:keys [some-error]}]
   ; ignore error, this should not run
-  {:error-dep :value})
-
-(defn dont-cache-me [_ _]
-  {:value 42})
-
-(defn global-attr [_ _]
-  {:color "purple"})
-
-(defn change-env [env _]
-  {::i-update-env {:foo "bar"}
-   ::pc/env       (assoc env :new-info "vish")})
-
-(def indexes
-  (-> {}
-      (pc/add `user-by-id
-        {::pc/input  #{:user/id}
-         ::pc/output [:user/name :user/id :user/login :user/age]})
-      (pc/add `user-by-login
-        {::pc/input  #{:user/login}
-         ::pc/output [:user/name :user/id :user/login :user/age]})
-      (pc/add `user-login-from-email
-        {::pc/input  #{:user/email}
-         ::pc/output [:user/login]})
-      (pc/add `user-address
-        {::pc/input  #{:user/id}
-         ::pc/output [:user/address]})
-      (pc/add `user-network
-        #::pc{:input  #{:user/id}
-              :output [{:user/network [:network/id :network/name]}]})
-      (pc/add `global-attr
-        #::pc{:output [:color]})
-      (pc/add `dont-cache-me
-        #::pc{:output [:value]
-              :cache? false})
-      (pc/add `change-env
-        {::pc/output [{::i-update-env [:foo]}]})
-      (pc/add `error-value
-        {::pc/output [:some-error]})
-      (pc/add `error-dependent
-        {::pc/input  #{:some-error}
-         ::pc/output [:error-dep]})))
+  {:error-dep :value}))
+
+
+(def indexes @base-indexes)

 (deftest test-resolver-data
   (is (= (pc/resolver-data indexes `user-by-id)
@@ -222,6 +222,7 @@
                                            {::env #(p/join % %)}
                                            pc/all-readers
                                            (p/placeholder-reader ">")]
+                             ::pc/resolver-dispatch resolver-fn
                              ::pc/indexes indexes})
               p/request-cache-plugin]}))

@@ -511,7 +512,7 @@
   (is (= (pc/data->shape {:foo [{:buz "baz"} {:it "nih"}]}) [{:foo [:buz :it]}]))
   (is (= (pc/data->shape {:foo [{:buz "baz"} "abc" {:it "nih"}]}) [{:foo [:buz :it]}])))

-(def regression-async-parser (p/async-parser {::p/plugins [#_p/error-handler-plugin]}))
+(def regression-async-parser (p/async-parser {::p/plugins [p/error-handler-plugin]}))
 (def async-env
   (assoc pct/parser-env
     ::p/reader [p/map-reader pc/all-async-readers]


set truthiness fix

set truthiness fix

--- src/atom_finder/location_dump.clj
+++ src/atom_finder/location_dump.clj
@@ -230,13 +230,13 @@

 (defn bin [bool] (if bool 1 0))

-(->> location-dump-data count)
-     (take 5000)
+(->> location-dump-data
+     ;(take 30000)
      (partition-by first) ; group data by filenames
      (map (fn [lst] [(first (first lst)) (map rest lst)])) ; remove the redundancy of repeated filenames
      (map last)
      ;(filter (fn [[_ s e _]] (and s e)))
-     (map
+     (pmap
       (fn [atom-positions]
         (let [comments  (filter (comp #{:comment} first) atom-positions)
               non-atoms (filter (fn [[t s e d]] (and (= :non-atom t) s e d)) atom-positions)
@@ -246,14 +246,17 @@
              (merge-with (partial merge-with +) hash
                          {depth {
                           :same-line (bin (comment-locs start))
-                          :1-line    (bin (set/intersection comment-locs (set (range (- start 1)  (inc start)))))
-                          :5-line    (bin (set/intersection comment-locs (set (range (- start 5)  (inc start)))))
-                          :10-line   (bin (set/intersection comment-locs (set (range (- start 10) (inc start)))))
+                          :1-line    (bin (not (empty? (set/intersection comment-locs (set (range (- start 1)  (inc start)))))))
+                          :5-line    (bin (not (empty? (set/intersection comment-locs (set (range (- start 5)  (inc start)))))))
+                          :10-line   (bin (not (empty? (set/intersection comment-locs (set (range (- start 10) (inc start)))))))
+                          :non-atoms 1
                           }})
             ) {} non-atoms))))
      (reduce (partial merge-with (partial merge-with +)))
      sort
-     pprint
-     time
-     )
-
+     (map (fn [[k v]] (str/join "," (cons k (vals v)))))
+     (take 100) ; depth >100 isn't super relevant
+     (map println)
+     time
+     )
+


use 10 as default benchmark run number

use 10 as default benchmark run number

--- src/babel/italiano/benchmark.cljc
+++ src/babel/italiano/benchmark.cljc
@@ -1,6 +1,7 @@
 (ns babel.italiano.benchmark
   (:refer-clojure :exclude [get-in])
-  (:require [babel.italiano.grammar :refer [small medium np-grammar]]
+  (:require [babel.engine :refer [generate-all]]
+            [babel.italiano.grammar :refer [small medium np-grammar]]
             [babel.italiano.lexicon :refer [lexicon]]
             [babel.italiano.morphology :as morph :refer [analyze-regular fo replace-patterns]]
             [babel.italiano.morphology.nouns :as nouns]
@@ -19,20 +20,24 @@
   #?(:cljs
      (throw (js/Error. error-string))))

-(defn run-benchmark [times]
-  (count (take (Integer/parseInt times)
-               (repeatedly #(let [debug (println "starting generation..")
-                                  expr (time (generate {:comp {:synsem {:agr {:person :3rd}}}
-                                                        :synsem {:cat :verb}}))]
-                              (println (str "generated: " (fo expr)))
-                              (println (str "starting parsing.."))
-                              (let [parsed (time (take 1 (parse (fo expr))))]
-                                (if (empty? parsed)
-                                  (throw (exception (str "could not parse: " (fo expr) " with semantics:"
-                                                         (strip-refs (get-in expr [:synsem :sem]))))))
-
-                                (println (str "parsed: " (fo (first parsed))))
-                                (println "")))))))
+(defn run-benchmark
+  ([]
+   (run-benchmark 10))
+
+  ([times]
+   (count (take (Integer/parseInt times)
+                (repeatedly #(let [debug (println "starting generation..")
+                                   expr (time (generate {:comp {:synsem {:agr {:person :3rd}}}
+                                                         :synsem {:cat :verb}}))]
+                               (println (str "generated: " (fo expr)))
+                               (println (str "starting parsing.."))
+                               (let [parsed (time (take 1 (parse (fo expr))))]
+                                 (if (empty? parsed)
+                                   (throw (exception (str "could not parse: " (fo expr) " with semantics:"
+                                                          (strip-refs (get-in expr [:synsem :sem]))))))
+
+                                 (println (str "parsed: " (fo (first parsed))))
+                                 (println ""))))))))
 (defn -main [times]
   (run-benchmark times))


version 0.5.6

version 0.5.6

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject cake "0.6.0-SNAPSHOT"
+(defproject cake "0.5.6"
   :description "Save your fork, there's cake!"
   :dependencies [[clojure "1.2.0"]
                  [clojure-contrib "1.2.0"]


upgrading deps

upgrading deps

--- project.clj
+++ project.clj
@@ -4,19 +4,17 @@
   :license  {:name "Apache License, Version 2.0" :url "http://www.apache.org/licenses/LICENSE-2.0.html"}

   :dependencies [[org.clojure/clojure "1.6.0"]
-                 [org.clojure/tools.cli "0.2.2"]
                  [clj-config "0.2.0" ]
                  [com.narkisr/gelfino-client "0.7.0"
                    :exclusions [com.fasterxml.jackson.core/jackson-core]]
                  ; utils
-                 [me.raynes/fs "1.4.5"]
-                 [org.clojure/tools.nrepl "0.2.3"]
+                 [me.raynes/fs "1.4.6"]
                  [robert/hooke "1.3.0"]
                  [org.clojure/core.incubator "0.1.3"]
                  [slingshot "0.10.3" ]
-                 [org.clojure/core.memoize "0.5.6"]
+                 [org.clojure/core.memoize "0.5.7"]
                  [org.flatland/useful "0.10.3"]
-                 [org.clojure/tools.macro "0.1.2"]
+                 [org.clojure/tools.macro "0.1.5"]
                  [org.clojure/java.data "0.1.1"]
                  ; templating
                  [selmer "0.3.4"]
@@ -38,8 +36,8 @@
                  ; ring
                  [ring-middleware-format "0.3.0"]
                  [ring/ring-jetty-adapter "1.2.0"]
-                 [ring "1.3.0"]
-                 [compojure "1.1.8" :exclusions  [ring/ring-core]]
+                 [ring "1.3.2"]
+                 [compojure "1.3.4" :exclusions  [ring/ring-core]]
                  ; ring security
                  [com.cemerick/friend "0.2.1"]
                  [ring/ring-session-timeout "0.1.0"]
@@ -59,6 +57,8 @@
                  ; scheduling
                  [jarohen/chime "0.1.6" :exclusions [org.clojure/core.async]]
                  [org.clojure/core.async "0.1.346.0-17112a-alpha"]
+                 ; remote managment
+                 [org.clojure/tools.nrepl "0.2.10"]
                ]

   :exclusions [org.clojure/clojure commons-codec]
@@ -80,7 +80,7 @@
         }

         :dependencies [[org.clojure/tools.namespace "0.2.10"] [midje "1.6.3"]
-                       [clojure-complete "0.2.3"] [redl "0.2.0"] [org.clojure/tools.trace "0.7.5"]]
+                       [redl "0.2.4"] [org.clojure/tools.trace "0.7.8"]]
         :injections  [(require '[redl core complete])]
         :resource-paths  ["src/main/resources/" "pkg/etc/celestial/"]
         :source-paths  ["dev"]
@@ -102,7 +102,7 @@
         :source-paths  ["dev"]
         :resource-paths  ["src/main/resources/" "pkg/etc/celestial/"]
         :dependencies [[ring-mock "0.1.5"] [midje "1.6.3"]
-                       [org.clojure/tools.trace "0.7.5"]
+                       [org.clojure/tools.trace "0.7.8"]
                        [org.clojure/test.check "0.7.0"]]
         :plugins [[lein-midje "3.1.3"]]
         :jvm-opts ~(into (vec (map (fn [[p v]] (str "-D" (name p) "=" v)) {:disable-conf "true" })) ["-XX:MaxPermSize=256m"])


:arrow_up: Upgraded dependencies

:arrow_up: Upgraded dependencies


Bump javac options to 1.7

Bump javac options to 1.7

--- project.clj
+++ project.clj
@@ -40,4 +40,4 @@
 ;;             "-XX:+UnlockDiagnosticVMOptions"
 ;;             "-XX:+PrintInlining"
              ]
-  :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"])
+  :javac-options ["-target" "1.7" "-source" "1.7" "-Xlint:-options"])


Changed where docs will be published.

Changed where docs will be published.


Bump tangle version to 0.1.7

Bump tangle version to 0.1.7


bump up cljs compiler version

bump up cljs compiler version


increment version

increment version


Java 1.5 is so last wednesday

Java 1.5 is so last wednesday


Update dependencies

Update dependencies


0.4.0


Upgrade clojure and libraries.

Upgrade clojure and libraries.


upgrade dag_unify to latest release

upgrade dag_unify to latest release


lein-release plugin: bumped version from 0.3 to 0.4-SNAPSHOT for next development cycle


Story ID: develop Merge branch 'release/0.4.3' into develop


bump Reitit version for perf tests

bump Reitit version for perf tests


lein-release plugin: preparing 0.111 release


Bump version

Bump version


Version 0.5.2-SNAPSHOT

Version 0.5.2-SNAPSHOT


Add description & URL to project.clj

Add description & URL to project.clj


Release version 0.9.0.0-beta3.

Release version 0.9.0.0-beta3.


Bumped version of friend.

Bumped version of friend.


Story ID: 0.4.2 Summary: - Removed snapshot from project name


moved oauth bits over to environ

moved oauth bits over to environ


Bump version to 0.1.3

Bump version to 0.1.3


fixed project.clj merge

fixed project.clj merge


Set clj-parent=5.2.9

Set clj-parent=5.2.9


(maint) Bump i18n to 0.9.0

(maint) Bump i18n to 0.9.0

This commit bumps i18n to 0.9.0, to match the version specified in clj-parent.
According to a comment in the pe-puppetdb-extensions repo (which I've copied
here), we need to specify this separately and it must match the version in
clj-parent.


shorten variables

shorten variables

--- src/euler/helper.clj
+++ src/euler/helper.clj
@@ -102,9 +102,10 @@
   "**primes :: [Int]**
   Lazy stream of prime numbers, generated by the
   sieve of Eratosthenes algorithm. Internally stores in a hastable the next
-  composite number corresponding to the prime number. Taken from
-  http://voidmainargs.blogspot.de/2010/12/lazy-sieve-eratosthenes-in-scala-and.html"
-  (letfn [(next-composite [x step sieve]
+  composite number corresponding to the prime number.
+  Taken from http://voidmainargs.blogspot.de/2010/12/
+  lazy-sieve-eratosthenes-in-scala-and.html"
+  (letfn [(next-comp [x step sieve]
             (if (sieve x)
             ;; the composite number has already been found previously
               (recur (+ x step) step sieve)
@@ -114,7 +115,7 @@
             (let [step (sieve x)]
               (if (sieve x)
             ;; found a composite
-                (recur (+ x 2) (next-composite (+ x step) step (dissoc sieve x)))
+                (recur (+ x 2) (next-comp (+ x step) step (dissoc sieve x)))
             ;; found a prime
                 (cons x
                       (lazy-seq


cleanups

cleanups

--- src/blog/hashobject/generator.clj
+++ src/blog/hashobject/generator.clj
@@ -2,8 +2,6 @@
   (:use clojure.java.io)
   (:require [markdown.core :as markdown]
             [endophile.core :as markdown-parser]
-;            [endophile.hiccup :as endophile-hiccup]
-;            [hiccup.core :only [html]]
             [sitemap.core :as sitemap]
             [blog.hashobject.views.index :as index-view]
             [blog.hashobject.views.post :as post-view]))
@@ -11,7 +9,6 @@

 (defn make-dir [path]
    (.mkdir (java.io.File. path)))
-

 (def sources-dir (file "./resources/posts/"))

@@ -66,11 +63,8 @@
         metadata (parse-post-defn lines)
         content (original-md-to-html-str file)]
     (println "post md ds" post)
-;    (println "post html" (html (to-hiccup past)))
-;    (println (markdown-parser/to-html post))
     (assoc metadata :filename filename
                     :content content)))
-

 (defn process-posts []
   (let [files (get-files-to-process)]
@@ -85,10 +79,8 @@

 (defn generate-index []
   (let [posts (reverse (process-posts))]
-    (println "posts" posts)
     (spit (str "./resources/public/index.html")
           (index-view/index posts))))
-

 (defn posts-sitemap-definitions []
   (let [posts (process-posts)]
@@ -106,7 +98,3 @@
                          :changefreq "daily"
                          :priority 1.0})]
         (sitemap/generate-sitemap-and-save "./resources/public/sitemap.xml" all-pages)))
-
-
-
-


Fix how multiple user-data-handlers compose

--- src/braid/client/core/events.cljs
+++ src/braid/client/core/events.cljs
@@ -547,29 +547,31 @@
 (reg-event-fx
   :set-init-data
   (fn [{state :db :as cofx} [_ data]]
-    (let [combined-data-handlers (apply comp @initial-user-data-handlers)]
-      {:dispatch-n (list [:set-login-state :app]
-                     [:add-users (data :users)])
-       :db (-> state
-               (assoc :session {:user-id (data :user-id)})
-               (assoc-in [:user :subscribed-tag-ids]
-                 (set (data :user-subscribed-tag-ids)))
-               (assoc :groups (key-by-id (data :user-groups)))
-               (assoc :invitations (data :invitations))
-               (assoc :threads (key-by-id (data :user-threads)))
-               (assoc :group-threads
-                 (into {}
-                       (map (fn [[g t]] [g (into #{} (map :id) t)]))
-                       (group-by :group-id (data :user-threads))))
-               (assoc-in [:user :open-thread-ids]
-                 (set (map :id (data :user-threads))))
-               (assoc :temp-threads (->> (data :user-groups)
-                                         (map :id)
-                                         (reduce (fn [memo group-id]
-                                                   (assoc memo group-id (schema/make-temp-thread group-id))) {})))
-               (helpers/add-tags (data :tags))
-               (helpers/set-preferences (data :user-preferences))
-               (combined-data-handlers data))})))
+    {:dispatch-n (list [:set-login-state :app]
+                       [:add-users (data :users)])
+     :db (-> state
+             (assoc :session {:user-id (data :user-id)})
+             (assoc-in [:user :subscribed-tag-ids]
+                       (set (data :user-subscribed-tag-ids)))
+             (assoc :groups (key-by-id (data :user-groups)))
+             (assoc :invitations (data :invitations))
+             (assoc :threads (key-by-id (data :user-threads)))
+             (assoc :group-threads
+                    (into {}
+                          (map (fn [[g t]] [g (into #{} (map :id) t)]))
+                          (group-by :group-id (data :user-threads))))
+             (assoc-in [:user :open-thread-ids]
+                       (set (map :id (data :user-threads))))
+             (assoc :temp-threads (->> (data :user-groups)
+                                      (map :id)
+                                      (reduce (fn [memo group-id]
+                                                (assoc memo group-id (schema/make-temp-thread group-id))) {})))
+             (helpers/add-tags (data :tags))
+             (helpers/set-preferences (data :user-preferences))
+             (as-> <>
+                 (reduce (fn [db f] (f db data))
+                         <>
+                         @initial-user-data-handlers)))}))

 (reg-event-fx
   :leave-group


schedule changed files to be imported again

currently we only compare the mtime.

--- src/brainbot/nozzle/esconnect.clj
+++ src/brainbot/nozzle/esconnect.clj
@@ -143,6 +143,23 @@
   [existing-map entries]
   (remove #(contains? existing-map (:id %)) entries))

+(defn entry-needs-update?
+  "compare es-entry with mq-entry and determine if we need to update it"
+  [es-entry mq-entry]
+  (not= (:mtime es-entry) (:mtime mq-entry)))
+
+(defn find-updates
+  "compare entries with those in es-file-map and return a seq of
+   entries that need to be updated"
+  [es-file-map entries]
+  (remove
+   nil?
+   (map (fn [mq-entry]
+          (if-let [es-entry (-> mq-entry :id es-file-map)]
+            (when (entry-needs-update? es-entry mq-entry)
+              mq-entry)))
+        entries)))
+
 (defn compare-directories
   [mq-entries es-entries]
   (let [mq-entries-by-type (group-by :type mq-entries)
@@ -159,7 +176,7 @@
      :delete-files (find-missing-entries mq-file-map (es-entries-by-type "file"))
      :create-directories (find-missing-entries es-directory-map (mq-entries-by-type "directory"))
      :create-files (find-missing-entries es-file-map (mq-entries-by-type "file"))
-     :update-files nil}))
+     :update-files (find-updates es-file-map (mq-entries-by-type "file"))}))

 (defn apply-diff-to-elasticsearch
@@ -223,7 +240,7 @@
         diff (compare-directories mq-entries es-entries)]
     (apply-diff-to-elasticsearch diff es-index parent-id)

-    (doseq [e (:create-files diff)]
+    (doseq [e (concat (:create-files diff) (:update-files diff))]
       (publish "extract_content"
                {:directory directory
                 :entry (select-keys e [:relpath :permissions :stat])}))))


update-wishlist-rem doesn't need wishlist parameter

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -77,9 +77,10 @@
   (letrem [neu (create-wishlist {:title "Default"})]
     (show-wishlist! neu)))

-(defn update-wishlist-rem [wishlist]
-  (letrem [neu (update-wishlist wishlist)]
-    (show-wishlist! neu)))
+(defn update-wishlist-rem []
+  (let [wishlist (wishlist-from-html)]
+    (letrem [neu (update-wishlist wishlist)]
+      (show-wishlist! neu))))

 ; DELEGATES


A smarter update-last! cljs

A smarter update-last! cljs

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -59,6 +59,11 @@
    :url (val (find $elem ".url"))
    :wishlist_code (get-path)})

+(defn update-last! [wish $elem]
+  (.attr $elem "id" (:id wish))
+  (.removeClass $elem "last")
+  (append ($ wish-ul) (wish-li-last)))
+
 (defn value-changed?! [$this]
   (if (= (data $this :old-val) (val $this))
     false
@@ -85,13 +90,8 @@
   (let [wish (wish-from-elem $elem)
         clean (dissoc wish :id)]
     (letrem [neu (create-wish clean)]
-      (fn [e] nil))))
-
-(defn create-wish-last-rem [$elem]
-  (let [wish (wish-from-elem $elem)
-        clean (dissoc wish :id)]
-    (letrem [neu (create-wish clean)]
-      (read-wishlist-rem (get-path)))))
+      (when (.hasClass $elem "last")
+        (update-last! neu $elem)))))

 (defn update-wish-rem [$elem]
   (let [wish (wish-from-elem $elem)]


Fix twitter link.

Fix twitter link.

--- src/circleci/web/views/common.clj
+++ src/circleci/web/views/common.clj
@@ -63,8 +63,7 @@
                  [:p#copyright "Copyright © 2011 Circle"]]
                 [:div#social_info.box_small.separator_r
                  [:ul
-                  [:li#twitter [:a {:href "#"} "follow us"] " on twitter"]
-                  [:li#facebook [:a {:href "#"} "follow us"] " on facebook"]]]
+                  [:li#twitter [:a {:href ""} "follow @circleci"] " on twitter"] ]]
                 [:div#contact_info.box_small
                  [:h5 "Contact"
                   (unordered-list


wire in search function

wire in search function

--- src/clj/ikea_clojure_cup/ikea.clj
+++ src/clj/ikea_clojure_cup/ikea.clj
@@ -1,6 +1,8 @@
 (ns ikea-clojure-cup.ikea
   (:require [compojure.api.sweet :refer :all]
-            [ring.util.http-response :refer :all]))
+            [schema.core :as s]
+            [ring.util.http-response :refer :all]
+            [ikea-clojure-cup.search :as search]))

 (defroutes* ikea-routes
@@ -8,10 +10,6 @@
         (ok [{:name "Australia"
               :code "au"}]))
   (GET* "/search" []
-        (ok [{:name "Test 1"
-              :url "/something/454543/"
-              :image "/something/45254325/small.jpg"}
-             {:name "Test 2"
-              :url "/something/454544/"
-              :image "/something/452544/small.jpg"}])))
+        :query-params [query :- s/Str]
+        (ok (search/search "au" query))))


Submit questions and save to fb

Submit questions and save to fb

--- src/clj/quiz_site/routes/quiz.clj
+++ src/clj/quiz_site/routes/quiz.clj
@@ -22,6 +22,16 @@
            (seq
              (char-array "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")))))))

+(defn push-quiz
+  [quiz host]
+  (let [quiz-id (generate-code)
+        result-id (generate-code)]
+    (m/reset-in! root [:quizzes (keyword quiz-id)] (merge quiz {:result-id result-id}))
+    (m/reset-in! root [:results (keyword result-id)] {:quiz-id quiz-id})
+    {:quiz-url (str host "/quiz/" quiz-id)
+     :result-url (str host "/quiz/" result-id)}
+    ))
+
 (defn get-quiz
   [& {:keys[quiz-id] :as args}]
   (log/debug "get-quiz")
@@ -35,10 +45,11 @@
   {:error "Implementation for this method not found."})

 (defn create-quiz
-  [& {:keys[quiz-id] :as args}]
+  [& {:keys[params headers] :as args}]
   (log/debug "create-quiz")
-  (log/debug "args:   " args)
-  {:error "Implementation for this method not found."})
+  (log/debug "params " params)
+  (push-quiz params (:host headers))
+  )

 (defn submit-answers
   [& {:keys[quiz-id] :as args}]
@@ -49,7 +60,7 @@
 (def quiz-routes
   (defroutes document-routes
     (context "/quiz" []
-             (POST "/" {params :params} (wrap-status (mapply create-quiz params)))
+             (POST "/" {:keys [headers params] :as request} (wrap-status (mapply create-quiz request)))
              (context "/:quiz-id" [quiz-id]
                       (GET  "/" {params :params} (wrap-status (mapply get-quiz       params)))
                       (POST "/" {params :params} (wrap-status (mapply submit-answers params)))))


Update initial page header text

Update initial page header text

--- src/cljs/gc_api_browser/core.cljs
+++ src/cljs/gc_api_browser/core.cljs
@@ -21,7 +21,7 @@
                        :method  "GET"
                        :body    nil
                        :headers {}}
-   :text              "Restman"
+   :text              "Explore"
    :selected-resource nil
    :selected-action   nil
    :schema            nil


set theme font

set theme font

--- src/cljs/material/components.cljs
+++ src/cljs/material/components.cljs
@@ -14,7 +14,8 @@
                              :light        "#957ed1"
                              :dark         "#362870"
                              :contrastText "#fff"}}
-   :typography  {:useNextVariants true}
+   :typography  {:fontSize 13}
+   :overrides   {}
    :breakpoints {:values {:xs 0
                           :sm 600
                           :md 1080
@@ -26,7 +27,6 @@
 (defn mui [component]
   (f/mui-theme-provider (clj->js {:theme theme}) (f/css-baseline) component))

-
 (defn md [props dialog]
   (let [md (f/with-mobile-dialog js/MaterialUI.Dialog)]
     (md props dialog)))


fix compare

fix compare

--- src/cljs/suurjako/view/index.cljs
+++ src/cljs/suurjako/view/index.cljs
@@ -11,7 +11,8 @@
 (defn all-valid? [{:keys [participant-count group-count]}]
   (and (not (:error participant-count))
        (not (:error group-count))
-       (>= (:value participant-count) (:value group-count))))
+       (>= (-> participant-count :value js/parseInt)
+           (-> group-count :value js/parseInt))))

 (defn input [form-data id]
   (let [data (id @form-data)]


now is dynamic

now is dynamic

--- src/grid/render.cljs
+++ src/grid/render.cljs
@@ -4,33 +4,38 @@

 (q/defcomponent User
-  [user]
-  (d/tr {}
-        (d/td {} (:name user))
-         (d/td {} (:email user))
-         (d/td {} (:country user))))
+  [header data]
+  (apply d/tr {}
+        (map (fn [key] (d/td {} (get data key))) (map :key header))))
+
+(defn render-header [header]
+  (d/thead {}
+           (apply d/tr {}
+                 (map (partial d/th {})  (map :title header)))))

 (q/defcomponent Grid
-  [data]
-  (d/div {:className "panel panel-default"}
-         (d/div {:className "panel-heading"} (str "SuperAmazing ClojureScript w/React grid"))
-         (d/table {:className "table"}
-                  (d/thead {}
-                           (d/tr {}
-                                 (d/th {} (str "Name"))
-                                 (d/th {} (str "Email"))
-                                 (d/th {} (str "Country"))))
-                  (apply d/tbody {}
-                         (map User (:users data))))))
+  [meta data]
+  (let [header (:header meta)]
+    (d/div {:className "panel panel-default"}
+           (d/div {:className "panel-heading"} (str "SuperAmazing ClojureScript w/React grid"))
+           (d/table {:className "table"}
+                    (render-header (:header meta))
+                    (apply d/tbody {}
+                           (map (partial User (:header meta)) (:data data)))))))

-(def my-data {:users [{:name "John Doe"
+(def my-data {:data [{:name "John Doe"
                           :email "user@email.com"
                           :country "USA" }
                          {:name "Frank Bølviken"
                           :email "frank.bolviken@gmail.com"
                           :country "Norway"}]})

+(def my-meta {:header [{:key :email :title "Email"}
+                       {:key :name :title "Name"}

-(q/render (Grid my-data)
+                    {:key :country :title "Country"}]})
+
+
+(q/render (Grid my-meta my-data)
           (.getElementById js/document "grid"))


Fix for the changed thing->relative-path contract

--- src/grimoire/api.clj
+++ src/grimoire/api.clj
@@ -187,7 +187,7 @@
                      e/result
                      (get :added "0.0.0")
                      util/normalize-version)
-        unv-path (t/thing->relative-path ::t/version thing)
+        unv-path (t/thing->relative-path t/version thing)
         versions (e/result (list-versions config (:parent currentv)))]
     (-> (for [v     versions
               :when (<= 0 (semver/version-compare (:name v) added))


working on keep-word?

working on keep-word?

--- src/hangman/core.clj
+++ src/hangman/core.clj
@@ -28,18 +28,12 @@
   "cat" "car" "can" "cob" "con" "cop" "cup"
   "work" "love" "hate" "jobs" "able" "ball" ] )

-(defn format-clue
-  "Format the clue vector into a nice-looking string."
-  [clue]
-  (str/join
-    (map  #(if (nil? %) "-" % )  clue) ))
-
 (defn make-clue
   "Generate a clue given the target word and a vec of guessed letters. The clue is a
   vector the length of the target word consisting of either letters (for correctly guessed
   letters) or nil (for incorrect guesses)."
   [tgt-word guessed-chars]
-  (vec (for [ letter tgt-word ] (guessed-chars letter)) ))
+  (vec (for [ letter tgt-word ] (get guessed-chars letter \- ))) )

 (defn complement-char-class
   "Generate the regex for the complement of a set of characters."
@@ -65,11 +59,11 @@
   indicates a wildcard that matches any character in the target word."
   [word clue guessed-chars]
   { :pre  [ (= (count word) (count clue))
-            (not-any? nil? word) ]
+            (not-any? #(= \- %) word) ]
     :post [] }
   (let [ pair-seq   (map vector clue word)  ; a sequence of pairs
          result     (every? #(or (=    (first %) (second %))
-                                 (nil? (first %)) )
+                                 (= \- (first %)) )
                       pair-seq) ]
     result ))

@@ -144,17 +138,17 @@

     ; Test if keep word
     (assert      (keep-word? "abcd" "abcd"             #{}            )  )
-    (assert      (keep-word? "abcd" [\a  nil nil nil]  #{}            )  )
-    (assert      (keep-word? "abcd" [\a  \b  nil nil]  #{}            )  )
-    (assert      (keep-word? "abcd" [nil nil nil nil]  #{}            )  )
-    (assert      (keep-word? "abcd" [\a  \b  nil nil]   guessed-chars )  )
-    (assert (not (keep-word? "abcd" [\a  nil nil nil]   guessed-chars ) ))
+    (assert      (keep-word? "abcd" "a---"  #{}            )  )
+    (assert      (keep-word? "abcd" "ab--"  #{}            )  )
+    (assert      (keep-word? "abcd" "----"  #{}            )  )
+    (assert      (keep-word? "abcd" "ab--"   guessed-chars )  )
+    (assert (not (keep-word? "abcd" "a---"   guessed-chars ) ))

   )
   (let [tst-words       [ "abcd" "xbcd" "xxcd" "xxxd" ]
         words-map       (group-by count tst-words)
         word-list       (words-map 4)
-        clue            [ nil \b  nil nil ]
+        clue            "-b--"
         keep-words      (filter #(keep-word? % clue #{} ) word-list)
   ]
     (assert (= words-map   {4 ["abcd" "xbcd" "xxcd" "xxxd"]} ))
@@ -181,7 +175,7 @@
         (println )
         (let [
           keep-words      (filter #(keep-word? % clue #{} ) word-list) ]
-            (print "clue: " (format-clue clue) "  ")
+            (print "clue: " clue "  ")
             (show-info "keep-words" keep-words)
             (if (= 1 (count keep-words))
               (let [final-guess (str/join (first keep-words)) ]
@@ -194,7 +188,7 @@
               ]
                 (println "  new-guess" new-guess
                   "  guessed-chars (" (count guessed-chars) ")" guessed-chars)
-                (when (some nil? new-clue)
+                (when (some #(= \- %) new-clue)
                   (recur  (conj guessed-chars new-guess)  new-clue ) )
               )
             )


CMR-5166: Fixed failing search tests.

CMR-5166: Fixed failing search tests.

--- search-app/src/cmr/search/validators/validation.clj
+++ search-app/src/cmr/search/validators/validation.clj
@@ -30,9 +30,7 @@

 (defmethod cqv/supported-result-formats :granule
   [_]
-  (into #{:xml, :json, :echo10, :atom, :iso19115, :csv, :kml, :native :timeline
-          :umm-json :umm-json-results}
-        (umm-versioned-result-formats :granule)))
+  #{:xml, :json, :echo10, :atom, :iso19115, :csv, :kml, :native :timeline})

 (defmethod cqv/supported-result-formats :variable
   [_]


fix type check

fix type check

--- plugin/src/leiningen/figwheel.clj
+++ plugin/src/leiningen/figwheel.clj
@@ -231,7 +231,8 @@
                (:builds data)
                (get-in (fuz/fuzzy-select-keys-and-fix data [:cljsbuild])
                        [:cljsbuild :builds]))]
-     (if (sequential? res) res []))))
+     (if (coll? res)
+       res []))))

 (defn figwheel-options [data]
   (let [res (if-let [data (figwheel-edn)]


some more work on getting postgres + heroku to work

--- src/lobos/config.clj
+++ src/lobos/config.clj
@@ -2,9 +2,15 @@
   (:use lobos.connectivity)
   (:require [heroku-database-url-to-jdbc.core :as heroku-url]))

-(def db (or (heroku-url/jdbc-connection-string (System/getenv "DATABASE_URL"))
-  {:classname "org.postgresql.Driver"
+(def db
+  {:classname   "org.postgresql.Driver"
    :subprotocol "postgresql"
-   :subname "//localhost:5432/barmap"}))
+   :dbname      (or (System/getenv "DB_DATABASE") "barmap")
+   :host        (or (System/getenv "DB_HOST") "localhost")
+   :port        (or (System/getenv "DB_PORT") 5432)
+   :user        (or (System/getenv "DB_USER") "")
+   :password    (or (System/getenv "DB_PASSWORD") "")
+   :sslfactory "org.postgresql.ssl.NonValidatingFactory"
+   :ssl true})

 (open-global db)


Use if instead of cond

Use if instead of cond

--- clojure/rna-transcription/dna.clj
+++ clojure/rna-transcription/dna.clj
@@ -1,10 +1,7 @@
 (ns dna)

 (defn- strand-convert [ch]
-    (cond
-        (= \T ch) \U
-        :else ch
-        )
+    (if (= \T ch) \U ch)
 )

 (defn to-rna [dna]


(SERVER-537) Update tests to return borrowed instances

Previously tests didn't need to return all of their borrowed instances
before ending a test, but now that holding onto a borrowed instance will
block the stop, they must. This commit updates the existing service
tests to return any borrowed instances before ending the test to ensure
the test completes.

--- test/unit/puppetlabs/services/jruby/jruby_puppet_service_test.clj
+++ test/unit/puppetlabs/services/jruby/jruby_puppet_service_test.clj
@@ -198,11 +198,13 @@
               pool-context (:pool-context context)]
           (let [jrubies (jruby-testutils/drain-pool pool-context pool-size)]
             (is (= 1 (count jrubies)))
-            (is (every? jruby-schemas/jruby-puppet-instance? jrubies)))
-          (let [test-start-in-millis (System/currentTimeMillis)]
-            (is (nil? (jruby-protocol/borrow-instance service :test-borrow-timeout-configuration)))
-            (is (>= (- (System/currentTimeMillis) test-start-in-millis) timeout))
-            (is (= (:borrow-timeout context) timeout)))))))
+            (is (every? jruby-schemas/jruby-puppet-instance? jrubies))
+            (let [test-start-in-millis (System/currentTimeMillis)]
+              (is (nil? (jruby-protocol/borrow-instance service :test-borrow-timeout-configuration)))
+              (is (>= (- (System/currentTimeMillis) test-start-in-millis) timeout))
+              (is (= (:borrow-timeout context) timeout)))
+            ; Test cleanup. This instance needs to be returned so that the stop can complete.
+            (doseq [inst jrubies] (jruby-protocol/return-instance service inst :test)))))))

   (testing (str ":borrow-timeout defaults to " jruby-core/default-borrow-timeout " milliseconds")
     (bootstrap/with-app-with-config


Provide the REPL a means of mangaing the component system.

--- dev-resources/src/dragon/dev.clj
+++ dev-resources/src/dragon/dev.clj
@@ -11,9 +11,11 @@
             [clojure.tools.namespace.repl :as repl]
             [clojure.walk :refer [macroexpand-all]]
             [clojusc.twig :as logger]
+            [com.stuartsierra.component :as component]
             [dragon.blog.content.rfc5322 :as rfc5322]
             [dragon.blog.generator :as generator]
             [dragon.cli.core :as cli]
+            [dragon.components.system :as components]
             [dragon.main :as main]
             [dragon.util :as util]
             [dragon.web.core :as web]
@@ -26,7 +28,95 @@

 (logger/set-level! '[dragon clojang] :debug)

+(def state :stopped)
+(def system nil)
+(def valid-stop-transitions #{:started :running})
+(def invalid-init-transitions #{:initialized :started :running})
+(def invalid-deinit-transitions #{:started :running})
+(def invalid-start-transitions #{:started :running})
+(def invalid-stop-transitions #{:stopped})
+(def invalid-run-transitions #{:running})
+
+(defn init
+  ([]
+    (init :default))
+  ([mode]
+    (if (contains? invalid-init-transitions state)
+      (log/error "System has aready been initialized.")
+      (do
+        (alter-var-root #'system
+          (constantly ((components/init mode)))
+        (alter-var-root #'state (fn [_] :initialized))))
+    state))
+
+(defn deinit
+  []
+  (if (contains? [] state)
+    (log/error "System is not stopped; please stop before deinitializing.")
+    (do
+      (alter-var-root #'system (fn [_] nil))
+      (alter-var-root #'state (fn [_] :uninitialized))))
+  state)
+
+(defn start
+  ([]
+    (start :repl))
+  ([mode]
+    (when (nil? system)
+      (init mode))
+    (if (contains? invalid-start-transitions state)
+      (log/error "System has already been started.")
+      (do
+        (alter-var-root #'system component/start)
+        (alter-var-root #'state (fn [_] :started))))
+    state))
+
+(defn stop
+  []
+  (if (contains? invalid-stop-transitions state)
+    (log/error "System already stopped.")
+    (do
+      (alter-var-root #'system
+        (fn [s] (when s (component/stop s))))
+      (alter-var-root #'state (fn [_] :stopped))))
+  state)
+
+(defn restart
+  []
+  (stop)
+  (start))
+
+(defn run
+  []
+  (if (contains? invalid-run-transitions state)
+    (log/error "System is already running.")
+    (do
+      (if (not (contains? invalid-init-transitions state))
+        (init))
+      (if (not (contains? invalid-start-transitions state))
+        (start))
+      (alter-var-root #'state (fn [_] :running))))
+  state)
+
+(defn -refresh
+  ([]
+    (repl/refresh))
+  ([& args]
+    (apply #'repl/refresh args)))
+
+(defn refresh
+  "This is essentially an alias for clojure.tools.namespace.repl/refresh."
+  [& args]
+  (if (contains? valid-stop-transitions state)
+    (stop))
+  (apply -refresh args))
+
+(defn reset
+  []
+  (stop)
+  (deinit)
+  (refresh :after 'dragon.dev/run))
+
 ;;; Aliases

-(def reload #'repl/refresh)
-(def reset #'repl/refresh)
+(def reload #'reset)


use-live-data? should default to true

use-live-data? should default to true

--- src/cljs/org/broadinstitute/firecloud_ui/utils.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/utils.cljs
@@ -107,7 +107,8 @@
   (reset! on-log-out-atom callback))

-(defonce use-live-data? (atom (or (local-storage-read ::use-live-data? true) false)))
+(defonce use-live-data? (atom (let [value (local-storage-read ::use-live-data? true)]
+                                (if (nil? value) true value))))
 (add-watch
  use-live-data? :save-to-local-storage
  (fn [k r os ns]


Use (comment ...) for commenting out new UTF-8 filename test

--- ring-core/test/ring/util/test/response.clj
+++ ring-core/test/ring/util/test/response.clj
@@ -110,19 +110,18 @@
       (is (= (slurp (:body resp))
              "Hello World\n"))))

-  ;; This test requires the ability to have file names in the source
-  ;; tree with non-ASCII characters in them encoded as UTF-8.  That
-  ;; may be platform-specific.  Comment out for now.
-
-  ;; If this fails on Mac OS X, try again with the command line:
-  ;; LC_CTYPE="UTF-8" lein test
-;;  (testing "resource is a file with UTF-8 characters in path"
-;;    (let [resp (resource-response "/ring/assets/abcíe.txt")]
-;;      (is (= (:body resp)
-;;             (.getAbsoluteFile (File. "test/ring/assets/abcíe.txt"))))
-;;      (is (.contains (slurp (:body resp))
-;;                     "UTF-8"))))
-  )
+  (comment
+    ;; This test requires the ability to have file names in the source
+    ;; tree with non-ASCII characters in them encoded as UTF-8.  That
+    ;; may be platform-specific.  Comment out for now.
+
+    ;; If this fails on Mac OS X, try again with the command line:
+    ;; LC_CTYPE="UTF-8" lein test
+    (testing "resource is a file with UTF-8 characters in path"
+      (let [resp (resource-response "/ring/assets/abcíe.txt")]
+        (is (= (:body resp)
+               (.getAbsoluteFile (File. "test/ring/assets/abcíe.txt"))))
+        (is (.contains (slurp (:body resp)) "UTF-8"))))))

 (deftest test-file-response
   (testing "response map"


[skip ci] Generate proper symbols for record fields starting with numbers

--- src/main/cljc/mikron/compiler/processor/common.cljc
+++ src/main/cljc/mikron/compiler/processor/common.cljc
@@ -18,7 +18,7 @@
     [schemas]
     (->> (keys schemas)
          (map (fn [key]
-                [key (gensym (name key))]))
+                [key (gensym (str "value'-" (name key)))]))
          (into (sorted-map))))

   (defn fields->record


optimize clojure.string

optimize clojure.string

--- src/main/cljs/clojure/string.cljs
+++ src/main/cljs/clojure/string.cljs
@@ -31,11 +31,14 @@
    string / string
    pattern / (string or function of match)."
   [s match replacement]
-  (cond (string? match)
-        (.replace s (js/RegExp. (gstring/regExpEscape match) "g") replacement)
-        (instance? js/RegExp match)
-        (.replace s (js/RegExp. (.-source match) "g") replacement)
-        :else (throw (str "Invalid match arg: " match))))
+  (cond
+    (string? match)
+    (.replace s (js/RegExp. (gstring/regExpEscape match) "g") replacement)
+
+    (instance? js/RegExp match)
+    (.replace s (js/RegExp. (.-source match) "g") replacement)
+
+    :else (throw (str "Invalid match arg: " match))))

 (defn replace-first
   "Replaces the first instance of match with replacement in s.
@@ -51,12 +54,12 @@
   separated by an optional separator."
   ([coll]
    (loop [sb (StringBuffer.) coll (seq coll)]
-     (if coll
+     (if-not (nil? coll)
        (recur (. sb (append (str (first coll)))) (next coll))
        (.toString sb))))
   ([separator coll]
    (loop [sb (StringBuffer.) coll (seq coll)]
-     (if coll
+     (if-not (nil? coll)
        (do
          (. sb (append (str (first coll))))
          (let [coll (next coll)]
@@ -96,13 +99,13 @@
 (defn- pop-last-while-empty
   [v]
   (loop [v v]
-    (if (= "" (peek v))
+    (if (identical? "" (peek v))
       (recur (pop v))
       v)))

 (defn- discard-trailing-if-needed
   [limit v]
-  (if (= 0 limit)
+  (if (== 0 limit)
     (pop-last-while-empty v)
     v))

@@ -110,7 +113,7 @@
   [s limit]
   (if (or (<= limit 0) (>= limit (+ 2 (count s))))
     (conj (vec (cons "" (map str (seq s)))) "")
-    (condp = limit
+    (condp == limit
       1 (vector s)
       2 (vector "" s)
       (let [c (- limit 2)]
@@ -123,21 +126,22 @@
      (split s re 0))
     ([s re limit]
      (discard-trailing-if-needed limit
-       (if (= (str re) "/(?:)/")
+       (if (identical? "/(?:)/" (str re))
          (split-with-empty-regex s limit)
          (if (< limit 1)
            (vec (.split (str s) re))
            (loop [s s
                   limit limit
                   parts []]
-             (if (= limit 1)
+             (if (== 1 limit)
                (conj parts s)
-               (if-let [m (re-find re s)]
-                 (let [index (.indexOf s m)]
-                   (recur (.substring s (+ index (count m)))
-                          (dec limit)
-                          (conj parts (.substring s 0 index))))
-                 (conj parts s)))))))))
+               (let [m (re-find re s)]
+                 (if-not (nil? m)
+                   (let [index (.indexOf s m)]
+                     (recur (.substring s (+ index (count m)))
+                       (dec limit)
+                       (conj parts (.substring s 0 index))))
+                   (conj parts s))))))))))

 (defn split-lines
   "Splits s on \n or \r\n."
@@ -145,19 +149,19 @@
   (split s #"\n|\r\n"))

 (defn trim
-    "Removes whitespace from both ends of string."
-    [s]
-    (gstring/trim s))
+  "Removes whitespace from both ends of string."
+  [s]
+  (gstring/trim s))

 (defn triml
-    "Removes whitespace from the left side of string."
-    [s]
-    (gstring/trimLeft s))
+  "Removes whitespace from the left side of string."
+  [s]
+  (gstring/trimLeft s))

 (defn trimr
-    "Removes whitespace from the right side of string."
-    [s]
-    (gstring/trimRight s))
+  "Removes whitespace from the right side of string."
+  [s]
+  (gstring/trimRight s))

 (defn trim-newline
   "Removes all trailing newline \\n or return \\r characters from
@@ -167,7 +171,8 @@
     (if (zero? index)
       ""
       (let [ch (get s (dec index))]
-        (if (or (= ch \newline) (= ch \return))
+        (if (or (identical? \newline ch)
+                (identical? \return ch))
           (recur (dec index))
           (.substring s 0 index))))))

@@ -186,10 +191,11 @@
   (let [buffer (StringBuffer.)
         length (.-length s)]
     (loop [index 0]
-      (if (= length index)
+      (if (== length index)
         (. buffer (toString))
-        (let [ch (.charAt s index)]
-          (if-let [replacement (get cmap ch)]
+        (let [ch (.charAt s index)
+              replacement (get cmap ch)]
+          (if-not (nil? replacement)
             (.append buffer (str replacement))
             (.append buffer ch))
           (recur (inc index)))))))


Enable fspec tests

Enable fspec tests

--- test/expound/alpha_test.cljc
+++ test/expound/alpha_test.cljc
@@ -1380,13 +1380,7 @@
       50
       [spec spec-gen
        form gen/any-printable]
-      (when-not (some
-                 #{"clojure.spec.alpha/fspec"}
-                 (->> spec
-                      inline-specs
-                      (tree-seq coll? identity)
-                      (map str)))
-        (is (string? (expound/expound-str spec form)))))))
+      (is (string? (expound/expound-str spec form))))))

 (deftest test-mutate
   (checking
@@ -1410,21 +1404,15 @@
       50
       [spec spec-gen
        mutate-path (gen/vector gen/pos-int)]
-      (when-not (some
-                 #{"clojure.spec.alpha/fspec"}
-                 (->> spec
-                      inline-specs
-                      (tree-seq coll? identity)
-                      (map str)))
-        (when (contains? (s/registry) spec)
-          (try
-            (let [valid-form (first (s/exercise spec 1))
-                  invalid-form (mutate valid-form mutate-path)]
-              (is (string? (expound/expound-str spec invalid-form))))
-            (catch clojure.lang.ExceptionInfo e
-              (when (not= :no-gen (::s/failure (ex-data e)))
-                (when (not= "Couldn't satisfy such-that predicate after 100 tries." (.getMessage e))
-                  (throw e))))))))))
+      (when (contains? (s/registry) spec)
+        (try
+          (let [valid-form (first (s/exercise spec 1))
+                invalid-form (mutate valid-form mutate-path)]
+            (is (string? (expound/expound-str spec invalid-form))))
+          (catch clojure.lang.ExceptionInfo e
+            (when (not= :no-gen (::s/failure (ex-data e)))
+              (when (not= "Couldn't satisfy such-that predicate after 100 tries." (.getMessage e))
+                (throw e)))))))))

 ;; Using conformers for transformation should not crash by default, or at least give useful error message.
 (defn numberify [s]


carry-reagent: remove provided scope from some deps, don't require react-with-addons, use newest alpha2 version of Reagent

--- contrib/reagent/project.clj
+++ contrib/reagent/project.clj
@@ -7,10 +7,9 @@
   :dependencies [[org.clojure/clojure "1.8.0" :scope "provided"]
                  [org.clojure/clojurescript "1.8.51" :scope "provided"]

-                 [carry "0.1.0" :scope "provided"]
+                 [carry "0.1.0"]

-                 [reagent "0.6.0-alpha" :exclusions [cljsjs/react] :scope "provided"]
-                 [cljsjs/react-with-addons "15.0.2-0" :scope "provided"]]
+                 [reagent "0.6.0-alpha2"]]

   :pedantic? :abort


Implemented lazy page generation as another zipmap pass (rather than conflating code-colouring and fn-wrapping in a single manipulation as done in the tutorial).

--- src/omhome/ssgen.clj
+++ src/omhome/ssgen.clj
@@ -41,8 +41,14 @@
   (zipmap (keys pages)
           (map #(highlight-code-blocks %) (vals pages))))

+(defn lazy-pages [pages]
+  (zipmap (keys pages)
+          (map #(fn [req] %) (vals pages))))
+
 (defn prepare-pages []
-  (highlight-code (get-basic-pages)))
+  (-> (get-basic-pages)
+      highlight-code
+      lazy-pages))

 (def app (stasis/serve-pages prepare-pages))


dangling parenthesis

dangling parenthesis

--- src/ontrail/core.clj
+++ src/ontrail/core.clj
@@ -90,8 +90,8 @@
     (webutil/json-response (ex/get-ex (user-from-cookie cookies) (:id params))))

   (GET "/rest/v1/ex-list-all/:page" {params :params cookies :cookies}
-    (webutil/json-response {:results (ex/get-latest-ex-list-default-order (user-from-cookie cookies) {} (webutil/get-page params))})
-)
+    (webutil/json-response {:results (ex/get-latest-ex-list-default-order (user-from-cookie cookies) {} (webutil/get-page params))}))
+
   (GET "/rest/v1/ex-list-filter" {params :params cookies :cookies}
     (webutil/json-response {:results
                     (ex/get-latest-ex-list (user-from-cookie cookies)


[Shafeeq|Abhi][#184] makes Gstin and PAN Optional

--- src/time_tracker/clients/spec.clj
+++ src/time_tracker/clients/spec.clj
@@ -15,5 +15,5 @@
                                   :opt-un [::phone ::email]))
 (s/def ::points-of-contact (s/coll-of ::point-of-contact))

-(s/def ::client (s/keys :req-un [::name ::address ::gstin ::pan]
-                        :opt-un [::points-of-contact]))
+(s/def ::client (s/keys :req-un [::name ::address]
+                        :opt-un [::points-of-contact ::gstin ::pan]))


Allow debug output during tests.

Allow debug output during tests.

if the env var TEST_DEBUG is set, debug output will be enabled during
the test runs.

--- test/matross/test/helper.clj
+++ test/matross/test/helper.clj
@@ -2,6 +2,7 @@
   "Helper functions for writing and running tests"
   (:require [me.raynes.conch :refer [with-programs]]
             [matross.connections.ssh :refer [translate-ssh-config ssh-connection]]
+            [matross.connections.debug :refer [debug-connection]]
             [matross.connections.core :refer [connect disconnect]]))

 (defn get-available-vms []
@@ -13,11 +14,17 @@
 (def vagrant-test-connection
   (memoize (fn [] (translate-ssh-config (slurp (System/getenv "TEST_SSH_CONF"))))))

+(defn test-connection []
+  (let [conn (ssh-connection (vagrant-test-connection))]
+    (if-let [debug (System/getenv "TEST_DEBUG")]
+      (debug-connection conn)
+      conn)))
+
 (defmacro task-tests
   "Evaluate the body against the test vm connection, exposed as conn"
   [conn & body]

-  `(let [~conn (ssh-connection (vagrant-test-connection))]
+  `(let [~conn (test-connection)]
      (connect ~conn)
      ~@body
      (disconnect ~conn)))


give each user a contact

give each user a contact

--- src/pc/analytics.clj
+++ src/pc/analytics.clj
@@ -27,7 +27,8 @@
                                                :verified_email (:cust/verified-email cust)
                                                ;; want ":_" to push it to top of list
                                                ":_admin_url" (admin-urls/cust-info-from-cust cust)
-                                               :occupation (:cust/occupation cust)}})
+                                               :occupation (:cust/occupation cust)
+                                               :precursor_contact (first (shuffle cust-model/admin-emails))}})
     (mailchimp/maybe-list-subscribe cust)))

 (defn track-create-team [team]


fix logic in default port

fix logic in default port

--- src/pronouns/web.clj
+++ src/pronouns/web.clj
@@ -40,8 +40,8 @@
       trace/wrap-stacktrace))

 (defn -main []
-  (let [port (or (Integer. (env :port))
-                 (:default-server-port config))]
+  (let [port (Integer. (env :port (:default-server-port config)))
+                 ]
     (jetty/run-jetty app {:port port})))

 ;; For interactive development:


Remove requirement that lifecycle functions must be passed as literal map

--- src/re_view/core.clj
+++ src/re_view/core.clj
@@ -7,11 +7,11 @@
 (defmacro defview
   ([view-name methods]
    `(def ~view-name
-      (~'re-view.core/view ~(assoc methods
-                              :display-name (str (last (string/split (name (ns-name *ns*)) #"\.")) "/" view-name)))))
+      (~'re-view.core/view (assoc ~methods
+                             :display-name ~(str (last (string/split (name (ns-name *ns*)) #"\.")) "/" view-name)))))
   ([view-name a1 a2 & body]
-   (let [[methods args body] (if (map? a1)
-                               [a1 a2 body]
-                               [{} a1 (cons a2 body)])]
+   (let [[methods args body] (if (vector? a1)
+                               [{} a1 (cons a2 body)]
+                               [a1 a2 body])]
      `(~'re-view.core/defview ~view-name
-        ~(assoc methods :render `(~'fn ~args (~'re-view.hiccup/element (do ~@body))))))))
+        (~'assoc ~methods :render (~'fn ~args (~'re-view.hiccup/element (do ~@body))))))))


Bring in the math library

Bring in the math library

--- minimal-3d/desktop/src-common/minimal_3d/core.clj
+++ minimal-3d/desktop/src-common/minimal_3d/core.clj
@@ -3,7 +3,7 @@
 (ns minimal-3d.core
   (:require [play-clj.core :refer :all]
             [play-clj.g3d :refer :all]
-            [play-clj.math :as m]
+            [play-clj.math :refer :all]
             [play-clj.ui :refer :all]))

 (defscreen main-screen
@@ -24,12 +24,12 @@
           model-attrs (bit-or (usage :position) (usage :normal))
           builder (model-builder)]
       (model (model-builder! builder :create-box 2 2 2 model-mat model-attrs)
-             (m/vector-3 0 0 0))))
+             (vector-3 0 0 0))))
   :on-render
   (fn [screen entities]
     (clear! 1 1 1 1)
     (doto screen
-      (perspective! :rotate-around (m/vector-3 0 0 0) (m/vector-3 0 1 0) 1)
+      (perspective! :rotate-around (vector-3 0 0 0) (vector-3 0 1 0) 1)
       (perspective! :update))
     (render! screen entities)))


SC Book, 3.5, translation

SC Book, 3.5, translation

--- docs/sc-book/sc-three.clj
+++ docs/sc-book/sc-three.clj
@@ -211,6 +211,7 @@
        #'task (rest p) (rest q) [])))

   (defn start-task []
+    (reset! cont true)
     (task p q))

   (defn stop-task []
@@ -240,3 +241,31 @@
 p = { rrand(64, 76) }; // to a Function: random notes from a chromatic octave
 t.stop; x.release(2);
 )
+
+(do
+  (def p (atom (fn [] 64)))
+  (def q (cycle [1000 2000 500]))
+
+  (def cont (atom true))
+  (def x (atom nil))
+
+  (defn task [q]
+    (when @x (release @x 2))
+    (when @cont
+      (reset! x (s :freq (midi->hz (@p))))
+      (apply-at
+       (+ (now) (first q))
+       #'task (rest q) [])))
+
+  (defn start-task []
+    (reset! cont true)
+    (task q))
+
+  (defn stop-task []
+    (reset! cont false))
+)
+(start-task)
+(reset! p (let [s (atom (cycle [64 66 68]))]
+            (fn [] (first (swap! s rest)))))
+(reset! p (fn [] (ranged-rand 64 77)))
+(stop-task)


update comment

update comment

--- src/revdiff/core.clj
+++ src/revdiff/core.clj
@@ -85,13 +85,13 @@
                           matching-line-in #(re-matches re %)]
                       (if (some matching-line-in changes) filename)))))))

-;; Run "svn diff" on the file/pathname in index. The format of the file/path name
-;; following "Index:" in diff's output depends on the argument: If the argument
-;; is a filesystem pathname, the index name is absolute, and we can simply use
-;; that. If the argument is a uri, the index name is relative to the base item
-;; name. If the base item name was the uri to a file (and therefore a complete
-;; pathname) we can use item; if it was the uri to a directory, we have to
-;; concatenate the item and index to form a complete pathname.
+;; Run "svn diff" on the file/pathname in index. The format of the file/path
+;; name following "Index:" in diff's output depends on the argument: If the
+;; argument is a filesystem pathname, the index name is absolute, and we can
+;; simply use that. If the argument is a uri, the index name is relative to the
+;; base item name. If the base item name was the uri to a file (and therefore a
+;; complete pathname) we can use item; if it was the uri to a directory, we have
+;; to concatenate the item and index to form a complete pathname.

 (defn svndiff [r1 r2 index item]
   (let [r (re-pattern (str "^.*/" index "$"))


Removed remaining reflection warnings on report.scheduler/filter-executing-jobs.

--- reports/src/reports/scheduler.clj
+++ reports/src/reports/scheduler.clj
@@ -1,6 +1,6 @@
 (ns reports.scheduler
   (:refer-clojure :exclude [key])
-  (:import [org.quartz Scheduler])
+  (:import [org.quartz JobExecutionContext Scheduler])
   (:require [clojure.string :as string :only (split join)]
             [clojurewerkz.quartzite [conversion :as conversion]
                                     [jobs :as jobs]
@@ -10,8 +10,8 @@

 (def cache (ref {}))

-(jobs/defjob ExportJob [context]
-  (let [{:strs [baseURL exportType surveyId opts reportId]} (conversion/from-job-data context)
+(jobs/defjob ExportJob [job-data]
+  (let [{:strs [baseURL exportType surveyId opts reportId]} (conversion/from-job-data job-data)
         report (export-report exportType baseURL surveyId opts)
         path (string/join "/" (take-last 2 (string/split (.getAbsolutePath report) #"/")))]
     (dosync
@@ -26,7 +26,7 @@

 (defn- filter-executing-jobs [key]
   "Filter the list of executing jobs by key (usually returns just 1 job)"
-  (filter #(= (.. % (getJobDetail) (getKey)) (jobs/key key))
+  (filter #(= (.. ^JobExecutionContext % (getJobDetail) (getKey)) (jobs/key key))
           (get-executing-jobs)))

 (defn- job-executing? [key]


Catch exceptions when processing expired events

--- src/riemann/core.clj
+++ src/riemann/core.clj
@@ -26,14 +26,17 @@
               streams (:streams core)]
           (when i
             (doseq [state (index/expire i)]
-              (let [e {:host (:host state)
-                       :service (:service state)
-                       :state "expired"
-                       :time (unix-time)}]
-                (when-let [registry (:pubsub core)]
-                  (ps/publish registry "index" e))
-                (doseq [stream streams]
-                  (stream e))))))))))
+              (try
+                (let [e {:host (:host state)
+                         :service (:service state)
+                         :state "expired"
+                         :time (unix-time)}]
+                  (when-let [registry (:pubsub core)]
+                    (ps/publish registry "index" e))
+                  (doseq [stream streams]
+                    (stream e)))
+                (catch Exception e
+                  (warn e "Caught exception while processing expired events"))))))))))

 (defn core
   "Create a new core."


core: false?

core: false?

--- core.clj
+++ core.clj
@@ -292,7 +292,7 @@
   "Returns true if x is nil, false otherwise."
   {:tag Bool
    :added "1.0"}
-  [x] (instance? Nil x))
+  [x] (=* x nil))

 (def

@@ -353,3 +353,9 @@
   {:added "1.0"}
   [test & body]
     (list 'if test nil (cons 'do body)))
+
+(defn false?
+  "Returns true if x is the value false, false otherwise."
+  {:tag Bool
+   :added "1.0"}
+  [x] (=* x false))


Use `require-lock` in the last remaining place

--- src/refactor_nrepl/middleware.clj
+++ src/refactor_nrepl/middleware.clj
@@ -11,7 +11,8 @@
             [nrepl.transport :as transport]))

 (defn- require-and-resolve [sym]
-  (require (symbol (namespace sym)))
+  (locking core/require-lock
+    (require (symbol (namespace sym))))
   (resolve sym))

 (defn err-info


fix typo

fix typo


Added a function to get facets map.

Added a function to get facets map.

--- scripts/extract-ipip-neo-pi-r.clj
+++ scripts/extract-ipip-neo-pi-r.clj
@@ -69,7 +69,7 @@
      :facet-name (get-facet table-data)
      :cronbach-alpha (Float. (string/replace cleaned #"[()]" "0"))
      :domain-key domain-key
-     :domain (bigfive/attributes domain-key)}))
+     :domain (bigfive/domains domain-key)}))

 (defn get-facet-id
   [table-data]
@@ -111,6 +111,16 @@
         facet-names (get-facet-names tables-data)]
     (flatten (map #(get-facet-questions % tables-data) facet-names))))

+(defn get-facets-map [url]
+  "This returns a data structure like what is in simulacrum.ipip/facets."
+  (let [tables-data (get-tables-data (util/fetch-url url))]
+    (into
+      (sorted-map)
+      (map (fn[x] [(keyword (x :facet-id)) (x :facet-name)])
+           (map get-facet-data
+                (map #(get-table % tables-data)
+                     (get-facet-names tables-data)))))))
+
 (spit export-file
       (json/write-str
         (get-data url)))


Rename headers to use document- instead of item-.

--- project/scrape-summitpost-data/src/scrape_summitpost_data/core.clj
+++ project/scrape-summitpost-data/src/scrape_summitpost_data/core.clj
@@ -40,7 +40,7 @@
   [file-name search-link]
   (with-open [out-file (io/writer file-name)]
     (csv/write-csv out-file
-                   (cons ["item-url", "item-name", "item-text"]
+                   (cons ["document-url", "document-name", "document-text"]
                          (get-item-texts search-link)))))

 (defn -main [& args]


Default touch strip to off/external.

Default touch strip to off/external.

Avoid the flicker back and forth between local pitch bend mode and
remote volume/discrete mode when adjusting a value; also don't let the
strip seem to be doing something when it actually isn't.

--- src/afterglow/controllers/ableton_push.clj
+++ src/afterglow/controllers/ableton_push.clj
@@ -904,7 +904,7 @@
       (Arrays/fill (get (:next-display controller) row) (byte 32)))
     (reset! (:next-text-buttons controller) {})
     (Arrays/fill (:next-top-pads controller) 0)
-    (reset! (:next-touch-strip controller) nil)
+    (reset! (:next-touch-strip controller) [0 1])

     (let [snapshot (rhythm/metro-snapshot (get-in controller [:show :metronome]))]
       (update-effect-list controller)


Add idempotence test for Aleph component

--- clstreams/test/clstreams/webapi/component_test.clj
+++ clstreams/test/clstreams/webapi/component_test.clj
@@ -8,7 +8,7 @@

 (def app-factory nil)

-(deftest test-aleph-component
+(deftest test-cycle-aleph-component
   (testing "Component starts and stops server"
     (let [config {:host "0.1.2.3" :port 1234}

@@ -38,3 +38,15 @@
           (mkto/verify-fn start-server-fn [handler config])
           (mkto/verify-> server-mock (.close))))))))

+(deftest test-idempotent-aleph-component
+  (testing "Component starts and stops server"
+    (let [config {:host "0.1.2.3" :port 1234}
+
+          handler (mkto/mock-fn)
+          app-factory (mkto/on-call (mkto/mock-fn) [(Mockito/any)] handler)
+
+          server-mock (mkto/mock java.io.Closeable)
+          start-server-fn (mkto/on-call (mkto/mock-fn) [handler config] server-mock)]
+
+      (with-redefs [aleph/start-server start-server-fn]
+        (tu-comp/check-idempotence (new-aleph app-factory config))))))


Replace base-url by request-url

Replace base-url by request-url

--- src/silly_image_store/handler.clj
+++ src/silly_image_store/handler.clj
@@ -13,14 +13,13 @@
 (defn- image-not-found [image]
   (route/not-found (str "No image '" image "' found")))

-(defn- base-url [{scheme :scheme, {host "host"} :headers}]
-  (str (name scheme) "://" host))
+(defn- request-url [{scheme :scheme, {host "host"} :headers, uri :uri}]
+  (str (name scheme) "://" host uri))

 (defn- list-images-route [request bucket]
-  (println request)
   (let [image-names (store/list-images images-dir bucket)
-        image-url (str (base-url request) (:uri request) "/")
-        to-json (fn [n] {:name n :url (str image-url n)})]
+        image-url (request-url request)
+        to-json (fn [n] {:name n :url (str image-url "/" n)})]
     (map to-json image-names)))

 (defn- serve-image-route [{{image :image} :params}]


Use a managed :input el instead of an :a element for the api-token creation form. Also, explicitly return false in the :on-submit callback to prevent the browser from refreshing on form submit.

--- frontend/components/account.cljs
+++ frontend/components/account.cljs
@@ -141,12 +141,15 @@
                             (om/set-state! owner :token-label v))}]
             [:label {:placeholder "Token name"}]
             (forms/managed-button
-             [:a
+             [:input
               {:data-loading-text "Creating...",
                :data-failed-text  "Failed to add token",
                :data-success-text "Created",
-               :on-click          #(create-token! (om/get-state owner :token-label))}
-              "Create"])]]
+               :on-click          #(do (create-token! (om/get-state owner :token-label))
+                                       (js/alert "Return false")
+                                       false)
+               :type "submit"
+               :value "Create"}])]]
           [:div.api-item
            {:data-bind "if: tokens().length"}
            (when (seq tokens)


Document differences between APIs

Document differences between APIs

--- src/caesium/crypto/secretbox.clj
+++ src/caesium/crypto/secretbox.clj
@@ -12,7 +12,9 @@
 (defn secretbox-easy
   "Encrypt with `crypto_secretbox_easy`.

-  Please note that this returns a (mutable!) byte array.
+  Please note that this returns a (mutable!) byte array. This is a
+  higher level API than [[secretbox-easy-to-buf!]] because it create
+  that output byte array for you.

   This API is marginally higher level than `secretbox`: it will
   automatically prepend the required `ZERO_BYTES` NUL bytes, verify
@@ -34,7 +36,9 @@
 (defn secretbox-open-easy
   "Decrypt with `crypto_secretbox_open_easy`.

-  Please note that this returns a (mutable!) byte array.
+  Please note that this returns a (mutable!) byte array. This is a
+  higher level API than [[secretbox-open-easy-to-buf!]] because it
+  create that output byte array for you.

   This API is marginally higher level than `secretbox_open`: it will
   automatically prepend the required `BOXZERO_BYTES` NUL bytes, verify


Fix the missing text from the checkbox.

Fix the missing text from the checkbox.

--- src/circleci/web/views/index.clj
+++ src/circleci/web/views/index.clj
@@ -87,12 +87,12 @@
                 (check-box {:id "contact"
                             :name "contact"
                             :checked true}
-                            "contact"
-                            [:div
-                              [:div
-                                (label {:id "contact-label"}
-                                       "contact"
-                                       "May we contact you to ask about your platform, stack, test suite, etc?")]])])]
+                            "contact")
+                [:div
+                  [:div
+                    (label {:id "contact-label"}
+                           "contact"
+                           "May we contact you to ask about your platform, stack, test suite, etc?")]]])]
            [:fieldset
              [:input.call_to_action {:type "submit"
                                      :value "Get Notified"}]]]]])


use toast with Gang Sign instead of printing to log

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -276,10 +276,11 @@
                                   " agenda point" (when (> (get-agenda-points state :runner c) 1) "s"))))}]}

    "Gang Sign"
-   {:events {:agenda-scored {:effect (req (system-msg state :runner (str "can access cards in HQ by clicking on Gang Sign"))
+   {:events {:agenda-scored {:effect (req (toast state :runner "Click on Gang Sign to access 1 card from HQ" "info")
                                           (update! state side (assoc card :access-hq true)))}}
     :abilities [{:req (req (:access-hq card))
-                 :msg (msg "access " (get-in @state [:runner :hq-access]) " card from HQ")
+                 :msg (msg "access " (get-in @state [:runner :hq-access]) " card"
+                           (when (< 1 (get-in @state [:runner :hq-access])) "s") " from HQ")
                  :effect (req (let [c (take (get-in @state [:runner :hq-access]) (shuffle (:hand corp)))]
                                 (resolve-ability state :runner (choose-access c '(:hq)) card nil)
                                 (update! state side (dissoc (get-card state card) :access-hq))))}]}