Three tests for function obj.endsWith (+NPE check)

--- test/emender_jenkins/utils_test.clj
+++ test/emender_jenkins/utils_test.clj
@@ -246,4 +246,29 @@
         (is (thrown? NullPointerException (startsWith "text" nil)))
         (is (thrown? NullPointerException (startsWith nil "text")))))

-
+(deftest test-ends-with-1 "Check the function emender-jenkins.utils/ends-with."
+    (testing "the function emender-jenkins.utils/ends-with."
+        (are [x y] (= x y)
+            true  (endsWith "Hello world!" "Hello world!")
+            false (endsWith "Hello world!" "hello world!")
+            true  (endsWith "Hello world!" "world!")
+            true  (endsWith "Hello world!" "!")
+            true  (endsWith "Hello world!" ""))))
+
+(deftest test-ends-with-2
+    "Check the function emender-jenkins.utils/ends-with."
+    (testing "the function emender-jenkins.utils/ends-with."
+        (are [x y] (= x y)
+            false (endsWith "" "hello")
+            false (endsWith "" "Hello")
+            false (endsWith "" "H")
+            true  (endsWith "" ""))))
+
+(deftest test-ends-with-NPE
+    "Check the function emender-jenkins.utils/ends-with."
+    (testing "the function emender-jenkins.utils/ends-with."
+        (is (thrown? NullPointerException (endsWith nil nil)))
+        (is (thrown? NullPointerException (endsWith "text" nil)))
+        (is (thrown? NullPointerException (endsWith nil "text")))))
+
+


Back to concurrent.

Back to concurrent.

--- test/onyx/peer/single_peer_test.clj
+++ test/onyx/peer/single_peer_test.clj
@@ -77,7 +77,7 @@
    {:onyx/name :inc
     :onyx/fn :onyx.peer.single-peer-test/my-inc
     :onyx/type :function
-    :onyx/consumption :sequential
+    :onyx/consumption :concurrent
     :onyx/batch-size batch-size}

    {:onyx/name :out


Fixed test

Fixed test

--- kuona-core/test/kuona_core/cloc_test.clj
+++ kuona-core/test/kuona_core/cloc_test.clj
@@ -75,5 +75,5 @@

                (each-commit (fn [path sha time]
                               (loc-collector
-                                (fn [a] store/put-document code-metric-store a (uuid-from sha "cloc")) path sha))
+                                (fn [a] store/put-document code-metric-store a (uuid-from sha "cloc")) path))
                             test-repo-path) => nil)))


Closes 45; Passing test for k-means on members with identical positions

--- test/cluster_tests.clj
+++ test/cluster_tests.clj
@@ -46,11 +46,21 @@
         (is (= 2 (count (kmeans real-nmat 2 :last-clusters clusts))))))))

 (deftest edge-cases
-  (testing "k-means on n < k items gives n clusters"
-    (let [data (named-matrix
-                 ["p1" "p2"]
-                 ["c1" "c2" "c3"]
-                 [[ 0  1  0 ]
-                  [-1  1  0 ]])]
-      (size-correct (kmeans data 3) 2))))
+  (testing "k-means on n < k items"
+    (testing "gives n clusters"
+      (let [data (named-matrix
+                   ["p1" "p2"]
+                   ["c1" "c2" "c3"]
+                   [[ 0  1  0 ]
+                    [-1  1  0 ]])]
+        (size-correct (kmeans data 3) 2)))
+    (testing "gives n-1 clusters when precisely 2 items have identical positions"
+      (let [data (named-matrix
+                   ["p1" "p2" "p3"]
+                   ["c1" "c2" "c3"]
+                   [[ 0  1  0 ]
+                    [ 0  1  0 ]
+                    [-1  1  0 ]])]
+        (size-correct (kmeans data 3) 2)))))

+


Add runboot in boot.task.built-in

Add runboot in boot.task.built-in

--- boot/core/src/boot/task/built_in.clj
+++ boot/core/src/boot/task/built_in.clj
@@ -823,3 +823,24 @@
                 (util/info "Tag %s already created for %s\n" tag commit)
                 (do (util/info "Creating tag %s...\n" v)
                     (git/tag v "release"))))))))))
+
+(core/deftask runboot
+  "Run boot in boot.
+
+  The args parameter is exactly the same kind of string you would write on the
+  command line (split in a vector). Runboot will execute the tasks in a brand
+  new pod every time it is invoked, isolating from the boot instance it is
+  launched from.
+
+  Data will be passed to the new pod (found in boot.pod/data). It has to be a
+  Java object (pods might not share the same Clojure version and therefore
+  Clojure objects won't work)."
+  [a args ARG        [str] "The boot cli arguments."
+   d data OBJECT ^:! code  "The data to pass the (new) boot environment"]
+  (let [core   (boot.App/newCore data)
+        worker (future pod/worker-pod)
+        args   (-> (vec (remove empty? args))
+                   (->> (into-array String)))]
+    (util/dbug "Runboot will run %s \n" (str "\"boot " (string/join " " args) "\""))
+    (core/with-pass-thru [fs]
+      (future (boot.App/runBoot core worker args)))))


add me.raynes/fs dep for copy-dir

add me.raynes/fs dep for copy-dir

--- tasklib/build.boot
+++ tasklib/build.boot
@@ -11,6 +11,7 @@
  :dependencies   '[[org.clojure/clojure "1.8.0" :scope "provided"]
                    [boot/core "2.6.0-SNAPSHOT" :scope "provided"]
                    [boot/pod "2.6.0-SNAPSHOT" :scope "provided"]
+                   [me.raynes/fs "1.4.6"]
                    [stencil "0.5.0"]
                    [adzerk/boot-test "1.0.7" :scope "test"]
                    ;; ;; we need this so we can import KickStart for the run task:


add utility fn 'stack-trace-str'

add utility fn 'stack-trace-str'

--- src/bract/core/util.clj
+++ src/bract/core/util.clj
@@ -12,6 +12,7 @@
   (:require
     [clojure.string :as string])
   (:import
+    [java.io PrintWriter StringWriter]
     [java.util UUID]))

@@ -73,3 +74,12 @@
   ^String
   []
   (.toString (UUID/randomUUID)))
+
+
+(defn stack-trace-str
+  "Given a throwable (generally an exception) return the stack trace string as it would be printed on a console."
+  ^String
+  [^Throwable e]
+  (let [^StringWriter sw (StringWriter.)]
+    (.printStackTrace e (PrintWriter. sw))
+    (.toString sw)))


lein-release plugin: preparing 0.3.0 release

--- backend/project.clj
+++ backend/project.clj
@@ -1,4 +1,4 @@
-(defproject lambdaui "0.3.0-SNAPSHOT"
+(defproject lambdaui "0.3.0"
   :description "LambdaCD-Plugin that provides a modern UI for your pipeline."
   :url "https://github.com/sroidl/lambda-ui"
   :license {:name "Apache License 2.0"


using threading macro

using threading macro

--- exercises/minesweeper/src/example.clj
+++ exercises/minesweeper/src/example.clj
@@ -1,12 +1,12 @@
 (ns minesweeper
-  (require [clojure.pprint :refer [cl-format]]
-           [clojure.string :refer [split-lines]]))
+  (:require [clojure.pprint :refer [cl-format]]
+            [clojure.string :refer [split-lines]]))

 (defn- windows [field]
-  (apply map vector
-         (apply map #(partition 3 1 `(nil ~@%& nil))
-                (map #(partition 3 1 `(nil ~@% nil))
-                     field))))
+  (->> field
+       (map #(partition 3 1 `(nil ~@% nil)))
+       (apply map #(partition 3 1 `(nil ~@%& nil)))
+       (apply map vector)))

 (defn- count-mines-around [[[a b c]
                             [d e f]


remove unnecessary :import

remove unnecessary :import

--- gae/src/gae/user.clj
+++ gae/src/gae/user.clj
@@ -1,9 +1,5 @@
 (ns gae.user
   (:gen-class :extends javax.servlet.http.HttpServlet)
-  (:import (javax.servlet.http HttpServlet
-                               HttpServletRequest
-                               HttpServletResponse)
-           (javax.servlet ServletConfig))
   (:require [gae.user-impl :as impl]
             [ring.util.servlet :as ring]))


retore schema that was accidentally deleted

--- src/clj/puppetlabs/master/certificate_authority.clj
+++ src/clj/puppetlabs/master/certificate_authority.clj
@@ -166,7 +166,7 @@
    ca-private-key :- (schema/pred utils/private-key?)
    ca-cert :- (schema/pred utils/certificate?)
    keylength :- schema/Int
-   serial-number-file]
+   serial-number-file :- String]
   {:post [(files-exist? ssldir-file-paths)]}
   (log/debug (str "Initializing SSL for the Master; file paths:\n"
                   (ks/pprint-to-string ssldir-file-paths)))


CMR-2014: Addressed review comments.

CMR-2014: Addressed review comments.

--- system-int-test/test/cmr/system_int_test/virtual_product_test.clj
+++ system-int-test/test/cmr/system_int_test/virtual_product_test.clj
@@ -372,6 +372,10 @@
            :concept-id virt-granule-id
            :granule-ur virt-granule-ur})))))

+
+;; This test tests the tranlsation end-point using all the sample granule-urs defined for virtual
+;; granules in the config file. All the virtual granule entries should be translated to corresponding
+;; source entries by the end-point.
 (deftest all-virtual-granules-translate-entries-test
    (let [source-collections (vp/ingest-source-collections)
         ;; Ingest the virtual collections. For each virtual collection associate it with the source


form mode port selectfield support #221

form mode port selectfield support
#221

--- src/cljs/swarmpit/component/service/form_ports.cljs
+++ src/cljs/swarmpit/component/service/form_ports.cljs
@@ -28,13 +28,16 @@
      :on-success (fn [{:keys [response]}]
                    (doseq [port response]
                      (if (not-suggested? port)
-                       (state/add-item port form-value-cursor))))
+                       (state/add-item (merge port
+                                              {:mode "ingress"}) form-value-cursor))))
      :on-error   (fn [_])}))

 (def headers [{:name  "Container port"
                :width "100px"}
               {:name  "Protocol"
                :width "100px"}
+              {:name  "Mode"
+               :width "150px"}
               {:name  "Host port"
                :width "100px"}])

@@ -67,6 +70,24 @@
        :value       "udp"
        :primaryText "UDP"})))

+(defn- form-mode [value index]
+  (list/selectfield
+    {:name     (str "form-mode-select-" index)
+     :key      (str "form-mode-select-" index)
+     :value    value
+     :onChange (fn [_ _ v]
+                 (state/update-item index :mode v form-value-cursor))}
+    (comp/menu-item
+      {:name        (str "form-mode-ingress-" index)
+       :key         (str "form-mode-ingress-" index)
+       :value       "ingress"
+       :primaryText "ingress"})
+    (comp/menu-item
+      {:name        (str "form-mode-host-" index)
+       :key         (str "form-mode-host-" index)
+       :value       "host"
+       :primaryText "host"})))
+
 (defn- form-host [value index]
   (list/textfield
     {:name     (str "form-host-text-" index)
@@ -82,9 +103,11 @@
   [item index _]
   (let [{:keys [containerPort
                 protocol
+                mode
                 hostPort]} item]
     [(form-container containerPort index)
      (form-protocol protocol index)
+     (form-mode mode index)
      (form-host hostPort index)]))

 (defn- form-table
@@ -101,6 +124,7 @@
   []
   (state/add-item {:containerPort 0
                    :protocol      "tcp"
+                   :mode          "ingress"
                    :hostPort      0} form-value-cursor))

 (rum/defc form < rum/reactive []


Changed DM parameters to match the best runs from paper.

--- src/clojush/problems/boolean/digital_multiplier.clj
+++ src/clojush/problems/boolean/digital_multiplier.clj
@@ -133,11 +133,12 @@
      :max-points-in-initial-program 200
      :evalpush-limit 400
      :epigenetic-markers []
-     :genetic-operator-probabilities {:reproduction 0.05
-                                      :alternation 0.80
-                                      :uniform-mutation 0.15}
-     :parent-selection :tournament
-     :tournament-size 7
+     :genetic-operator-probabilities {[:alternation :uniform-mutation] 1}
+     :alternation-rate 0.01
+     :alignment-deviation 10
+     :uniform-mutation-rate 0.01
+     :uniform-mutation-constant-tweak-rate 0
+     :parent-selection :lexicase
      :report-simplifications 0})
   )


[lein] Use Drip

[lein] Use Drip

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -6,5 +6,6 @@
                   [com.jakemccrary/lein-test-refresh "0.3.4"]
                   [lein-pprint                       "1.1.1"]
                   [cider/cider-nrepl                 "0.12.0"]
+                  [lein-drip                         "0.1.1-SNAPSHOT"]
                   [venantius/ultra                   "0.4.1"]]
         :signing {:gpg-key "E5B26621"}}}


:lipstick: Add event handler to main icon on viewer header.

--- frontend/src/uxbox/main/ui/viewer/header.cljs
+++ frontend/src/uxbox/main/ui/viewer/header.cljs
@@ -107,7 +107,7 @@
                                    {:page-id page-id}))]
     [:header.viewer-header
      [:div.main-icon
-      [:a i/logo-icon]]
+      [:a {:on-click on-edit} i/logo-icon]]

      [:div.sitemap-zone {:alt (tr "header.sitemap")
                          :on-click on-click}


Try to make "Current Plan" box less wrong w/ grandfathered plans.

--- frontend/components/org_settings.cljs
+++ frontend/components/org_settings.cljs
@@ -320,12 +320,14 @@
          [:p [:strong "PAID"]]
          [:ul
           [:li [:strong.old-plan-total (str (pm/usable-containers plan) " for $" plan-total "/ month")]]
+          (when (pm/grandfathered? plan)
+            [:li "Current price grandfathered in. Updates will be priced as:"])
           (when (pm/freemium? plan)
-            [:li "Includes " (pluralize (pm/freemium-containers plan) "container") " FREE!"])
-          (if (> (pm/paid-plan-min-containers plan) 0)
-            [:li (if (pm/freemium? plan) "Next " "First ")
-             (pluralize (pm/paid-plan-min-containers plan) "container") " at $"
-             (-> plan :paid :template :price)])
+            [:li "First " (pluralize (pm/freemium-containers plan) "container") " free!"])
+          (when (> (pm/paid-plan-min-containers plan) 0)
+            [:li (str (if (pm/freemium? plan) "Next " "First ")
+                      (pluralize (pm/paid-plan-min-containers plan) "container") " at $"
+                      (-> plan :paid :template :price))])
           [:li "Additional containers for $" (pm/per-container-cost plan) "/month"]
           [:li [:strong "No other limits"]]])

@@ -333,7 +335,11 @@
              (not (pm/in-trial? plan)))
         (list
          [:p [:strong "FREE"]]
-         [:ul [:li "Includes " (pluralize (:containers plan) "container") " free!"]
+         [:ul [:li "First " (pluralize (:containers plan) "container") " free!"]
+          (when (> (pm/paid-plan-min-containers plan) 0)
+            [:li (str (if (pm/freemium? plan) "Next " "First ")
+                      (pluralize (pm/paid-plan-min-containers plan) "container") " at $"
+                      (-> plan :paid :template :price))])
           [:li "Additional containers for $" container-cost "/month"]
           [:li [:strong "No other limits"]]])


CMR-662: Added tests for AQL query parameters.

--- test/cmr/system_int_test/search/aql_search_test.clj
+++ test/cmr/system_int_test/search/aql_search_test.clj
@@ -99,6 +99,37 @@
          "SH%RT" [coll1 coll2 coll3 coll4 coll5 coll6]
          "S%R_" [coll1 coll2 coll3 coll4 coll5 coll6])))

+(deftest aql-search-with-query-parameters
+  (let [make-coll (fn [n entry-title]
+                    (d/ingest "PROV1" (dc/collection {:short-name entry-title
+                                                      :entry-title (str "coll" n)})))
+        coll1 (make-coll 1 "SHORT")
+        coll2 (make-coll 2 "SHORT")
+        coll3 (make-coll 3 "SHORT")
+        coll4 (make-coll 4 "SHORT")]
+    (index/refresh-elastic-index)
+    ;; invalid query parameter
+    (is (= {:errors ["Parameter [foo] was not recognized."]
+            :status 422}
+           (search/find-refs-with-aql :collection
+                                      [{:shortName "SHORT"}]
+                                      {}
+                                      {:query-params {:foo true}})))
+    (are [search-str params items]
+         (let [refs (search/find-refs-with-aql :collection [{:shortName search-str}]
+                                               {} {:query-params params})
+               result (d/refs-match? items refs)]
+           (when-not result
+             (println "Expected:" (pr-str (map :entry-title items)))
+             (println "Actual:" (pr-str (map :name (:refs refs)))))
+           result)
+         ;; Exact matches
+         "SHORT" {:page-size 1} [coll1]
+         "SHORT" {:page-size 1 :page-num 3} [coll3]
+         ; TODO - enable this test when sort-key is supported
+         ;"SHORT" {:sort-key :entry-title} [coll2]
+         "SHORT" {} [coll1 coll2 coll3 coll4])))
+

 (deftest aql-search-with-multiple-conditions
   (let [coll1 (d/ingest "PROV1" (dc/collection {:entry-title "Dataset1"


override eval ignorer to install warning handlers and exception catchers

--- sidecar/src/figwheel_sidecar/repl.clj
+++ sidecar/src/figwheel_sidecar/repl.clj
@@ -6,7 +6,7 @@
    [cljs.stacktrace]
    [cljs.analyzer :as ana]
    [cljs.env :as env]
-
+   [cljs.util :refer [debug-prn]]
    [clojure.java.io :as io]
    [clojure.string :as string]
    [clojure.core.async :refer [chan <!! <! put! alts!! timeout close! go go-loop]]
@@ -155,14 +155,84 @@
 (defn in-nrepl-env? []
   (thread-bound? #'nrepl-eval/*msg*))

-(defn catch-exception [e repl-env opts]
-  (if (and (instance? IExceptionInfo e)
-           (#{:js-eval-error :js-eval-exception} (:type (ex-data e))))
-    (cljs.repl/repl-caught e repl-env opts)
-    ;; color is going to have to be configurable
-    (with-color
-        (cljs-ex/print-exception e {:environment :repl
-                                    :current-ns ana/*cljs-ns*}))))
+(defn catch-exception
+  ([e repl-env opts form env]
+   (if (and (instance? IExceptionInfo e)
+            (#{:js-eval-error :js-eval-exception} (:type (ex-data e))))
+     (cljs.repl/repl-caught e repl-env opts)
+     ;; color is going to have to be configurable
+     (with-color
+       (cljs-ex/print-exception e (cond-> {:environment :repl
+                                           :current-ns ana/*cljs-ns*}
+                                    form (assoc :source-form form)
+                                    env  (assoc :compile-env env))))))
+  ([e repl-env opts]
+   (catch-exception e repl-env opts nil nil)))
+
+;; this is copied because its private
+(defn wrap-fn [form]
+  (cond
+    (and (seq? form) (= 'ns (first form))) identity
+    ('#{*1 *2 *3 *e} form) (fn [x] `(cljs.core.pr-str ~x))
+    :else
+    (fn [x]
+      `(try
+         (cljs.core.pr-str
+           (let [ret# ~x]
+             (set! *3 *2)
+             (set! *2 *1)
+             (set! *1 ret#)
+             ret#))
+         (catch :default e#
+           (set! *e e#)
+           (throw e#))))))
+
+;; this is copied because it's private
+(defn eval-cljs
+  ([repl-env env form]
+    (eval-cljs repl-env env form cljs.repl/*repl-opts*))
+  ([repl-env env form opts]
+   (cljs.repl/evaluate-form repl-env
+     (assoc env :ns (ana/get-namespace ana/*cljs-ns*))
+     "<cljs repl>"
+     form
+     ;; the pluggability of :wrap is needed for older JS runtimes like Rhino
+     ;; where catching the error will swallow the original trace
+     ((or (:wrap opts) wrap-fn) form)
+     opts)))
+
+(defn warning-handler [form opts]
+  (fn [warning-type env extra]
+    (when (warning-type cljs.analyzer/*cljs-warnings*)
+      (when-let [s (cljs.analyzer/error-message warning-type extra)]
+        (let [warning-data {:line   (:line env)
+                            :column (:column env)
+                            :ns     (-> env :ns :name)
+                            :file (if (= (-> env :ns :name) 'cljs.core)
+                                    "cljs/core.cljs"
+                                    ana/*cljs-file*)
+                            :source-form   form
+                            :message s
+                            :extra   extra}
+              parsed-warning (cljs-ex/parse-warning warning-data)]
+          (debug-prn (with-color
+                       (cljs-ex/format-warning warning-data))))))))
+
+(defn catch-warnings-and-exceptions-eval-cljs
+  ([repl-env env form]
+   (catch-warnings-and-exceptions-eval-cljs
+    repl-env env form cljs.repl/*repl-opts*))
+  ([repl-env env form opts]
+   (try
+     (binding [cljs.analyzer/*cljs-warning-handlers*
+               [(warning-handler form opts)]]
+       (eval-cljs repl-env env form opts))
+     (catch Throwable e
+       (catch-exception e repl-env opts form env)
+       ;; when we are in an nREPL environment lets re-throw with a friendlier
+       ;; message maybe
+       #_(when (in-nrepl-env?)
+           (throw (ex-info "Hey" {})))))))

 (defn repl
   ([build figwheel-server]
@@ -170,7 +240,7 @@
   ([build figwheel-server opts]
    (let [opts (merge (assoc (or (:compiler build) (:build-options build))
                             :warn-on-undeclared true
-                            :caught #'catch-exception
+                            :eval #'catch-warnings-and-exceptions-eval-cljs
                             )
                      opts)
          figwheel-repl-env (repl-env figwheel-server build)


user.clj: System management functions return nil

The used to return the system object, but it's too large and makes
REPL output too noisy.

--- clstreams/dev/user.clj
+++ clstreams/dev/user.clj
@@ -20,14 +20,17 @@

 (defn init []
   (alter-var-root #'system
-                  (constantly (count-words-system))))
+                  (constantly (count-words-system)))
+  nil)

 (defn start []
-  (alter-var-root #'system component/start))
+  (alter-var-root #'system component/start)
+  nil)

 (defn stop []
   (alter-var-root #'system
-                  (fn [s] (when s (component/stop s)))))
+                  (fn [s] (when s (component/stop s))))
+  nil)

 (defn reset []
   (stop)


oops, hud not last element in app anymore

--- src-cljs/frontend/components/app.cljs
+++ src-cljs/frontend/components/app.cljs
@@ -114,7 +114,7 @@
                                               [:team]
                                               [:max-document-scope]
                                               (state/doc-tx-rejected-count-path (:document/id app))])
-                      {:react-key "hud"})])
+                      {:react-key "hud"})

             (when (:show-landing? app)
               (om/build outer/outer (select-in app [[:show-landing?]


Simplified interpreter using list form

Simplified interpreter using list form

--- extended/interpreter/interpreter.clj
+++ extended/interpreter/interpreter.clj
@@ -1,4 +1,3 @@

 (export eval (expressions)
-        (Cons 97 (Cons 98 Empty)))
-
+        (list 97 98))


CMR-2652: Fixed more PR issues.

CMR-2652: Fixed more PR issues.

--- system-int-test/test/cmr/system_int_test/search/collection_keyword_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_keyword_search_test.clj
@@ -526,36 +526,34 @@
 (deftest search-by-ancillary-keywords
   (let [c10-umm-json (d/ingest "PROV1"
                                (assoc exp-conv/example-collection-record
-                                      :AncillaryKeywords ["CMR-2652-AKW1" "CMR-2652-AKW2"])
+                                      :AncillaryKeywords ["CMR2652AKW1" "CMR2652AKW2"])
                                {:format :umm-json
                                 :accept-format :json})]
     (index/wait-until-indexed)
     (testing "parameter searches"
       (are3 [keyword-str items]
-        (let [parameter-refs (search/find-refs :collection {:keyword keyword-str})
-              parameter-matches? (d/refs-match? items parameter-refs)]
-          (is parameter-matches?))
+        (let [parameter-refs (search/find-refs :collection {:keyword keyword-str})]
+          (d/assert-refs-match items parameter-refs))

         "testing parameter search by existing ancillary keywords"
-        "CMR-2652-AKW1"
+        "CMR2652AKW1"
         [c10-umm-json]

         "testing parmaeter search by non-existing ancillary keywords"
-        "CMR-2652-NO-AKW"
+        "CMR2652NOAKW"
         []))

     (testing "json query searchs"
       (are3 [keyword-str items]
-        (let [json-refs (search/find-refs-with-json-query :collection {} {:keyword keyword-str})
-              json-matches? (d/refs-match? items json-refs)]
-          (is json-matches?))
+        (let [json-refs (search/find-refs-with-json-query :collection {} {:keyword keyword-str})]
+          (d/assert-refs-match items json-refs))

         "testing json query search by existing ancillary keywords"
-        "CMR-2652-AKW2"
+        "CMR2652AKW2"
         [c10-umm-json]

         "testing json query search by non-existing ancillary keywords"
-        "CMR-2652-NO-AKW"
+        "CMR2652NOAKW"
         []))))

 ;; This tests that when searching by relevancy that if the score is the same short name ascending is used for


Only process doc manifest on success

Only process doc manifest on success

--- frontend/controllers/navigation.cljs
+++ frontend/controllers/navigation.cljs
@@ -434,7 +434,8 @@
           docs (or (get-in current-state state/docs-data-path)
                    (let [api-result (<! (ajax/managed-ajax :get (get-in current-state [:render-context :doc_manifest_url])))]
                      (put! api-ch [:doc-manifest (:status api-result) api-result])
-                     (doc-utils/format-doc-manifest (:resp api-result))))
+                     (when (= :success (:status api-result))
+                       (doc-utils/format-doc-manifest (:resp api-result)))))
           doc (get docs subpage)]
       (cond
        (not subpage)


upgrades to jetty version 9.4.48.v20220622 (#1615)

--- waiter/project.clj
+++ waiter/project.clj
@@ -45,7 +45,7 @@
                  [io.grpc/grpc-core "1.20.0"
                   :exclusions [com.google.guava/guava]
                   :scope "test"]
-                 [twosigma/jet "0.7.10-20220407_144841-gd100014"
+                 [twosigma/jet "0.7.10-20220804_012742-g4f12016"
                   :exclusions [org.mortbay.jetty.alpn/alpn-boot]]
                  [twosigma/clj-http "1.0.2-20180124_201819-gcdf23e5"
                   :exclusions [commons-codec commons-io org.clojure/tools.reader potemkin slingshot]]


add breseq as a simple function for use by breseq-runs

--- src/aerobio/pgmgraph.clj
+++ src/aerobio/pgmgraph.clj
@@ -67,8 +67,8 @@
   []
   (programs bcl2fastq samtools
             bowtie bowtie2 bowtie-build bowtie2-build
-            featureCounts tophat
-            cufflinks cuffmerge cuffcompare cuffdiff
+            featureCounts breseq
+            tophat cufflinks cuffmerge cuffcompare cuffdiff
             Rscript python ruby perl
             bp_load_genbank
             ))


Kenny is now represented by the number 6


Re-add crypto dependency

Re-add crypto dependency

--- worker/project.clj
+++ worker/project.clj
@@ -21,7 +21,8 @@
                  [com.google.guava/guava "15.0"]
                  [me.raynes/fs "1.4.5"]
                  [org.rosuda/REngine "1.7.1-20130821.152906-1"]
-                 [com.novemberain/langohr "3.5.0"]]
+                 [com.novemberain/langohr "3.5.0"]
+                 [crypto-random "1.2.0"]]
   :env {:rserve-logs "log/rserve.log"}
   :profiles {:uberjar {:aot :all}
              :dev {:dependencies [[org.clojure/tools.namespace "0.2.4"]]}}


Add clojure.core.reducers ns. Fixes #136

--- src/clj/clojuredocs/search/static.clj
+++ src/clj/clojuredocs/search/static.clj
@@ -4,6 +4,7 @@
   '[clojure.core
     clojure.core.async
     clojure.core.logic
+    clojure.core.reducers
     clojure.data
     clojure.edn
     clojure.inspector


Test describing behavior for throwing exceptions from error handler.

As described in #52.
Fixes #52.

If error handler throws exception this exception is delivered in
:error slot of response.

--- src/clj/http/async/client/request.clj
+++ src/clj/http/async/client/request.clj
@@ -277,9 +277,12 @@
            (^{:tag void}
             onThrowable [this #^Throwable t]
             (do
-              (deliver (:error resp) ((or error
-                                          (:error *default-callbacks*))
-                                      resp t))
+              (deliver (:error resp) (try
+                                       ((or error
+                                            (:error *default-callbacks*))
+                                        resp t)
+                                       (catch Throwable e
+                                         e)))
               (when-not (realized? (:done resp))
                 (deliver (:done resp) true))))))]
     (with-meta resp {:started (System/currentTimeMillis)


map? for map handling instead of associative?

--- src/cljc/commos/delta/compscribe.cljc
+++ src/cljc/commos/delta/compscribe.cljc
@@ -80,7 +80,7 @@
   subscribed ids removed and subs has the extracted
   subscriptions/unsubscriptions merged onto it.

-  Pass nil a new-val to only get unsubscriptions."
+  Pass nil as new-val to only get unsubscriptions."
   [subs deep-hooks ks new-val]
   (reduce (fn [[subs new-val] [rks ks _]]
             (if-let [val (get-in new-val rks)]
@@ -123,7 +123,7 @@
                                        new-val)
                              (update-in [:unsubs] conj ks))
                          adjusted-deltas)
-                  (if (associative? new-val)
+                  (if (map? new-val)
                     (let [[subs new-val]
                           (nested-subs subs deep-hooks ks new-val)]
                       (recur deltas


Add docstring for the serializers namespace.

--- src/clojure/catacumba/serializers.clj
+++ src/clojure/catacumba/serializers.clj
@@ -23,7 +23,32 @@
 ;; THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 (ns catacumba.serializers
-  "A serializers abstraction layer."
+  "A friction-less and extensioble serializers abstraction layer.
+
+  The main public api consists in two functions:
+
+  - `encode`: that takes the clojure data and the serialization format
+    as keyword and returns serialized bytes.
+  - `decode`: just does the reverse operation. It takes the a byte array
+    and returns a deserialized data.
+
+  If something wrong is happens in the process, the underlying library
+  used for serialize or deserialize can raise exceptions.
+
+  Here an simple example serializing and deserializing a clojure
+  hash-map using json format:
+
+  ```
+  (require '[catacumba.serializers :as sz])
+
+  (-> (sz/encode {:foo 2} :json)
+      (sz/bytes->str))
+  ;; => \"{\\\"foo\\\": 2}\"
+
+  (sz/decode some-data :json)
+  ;; => {:foo 2}
+  ```
+  "
   (:require [cheshire.core :as json]
             [cognitect.transit :as transit]
             [buddy.core.codecs :as codecs])


Changing the metadata db job to run every 5 hours.

--- src/cmr/metadata_db/services/jobs.clj
+++ src/cmr/metadata_db/services/jobs.clj
@@ -15,7 +15,7 @@

 (def EXPIRED_CONCEPT_CLEANUP_INTERVAL
   "The number of seconds between jobs run to cleanup expired granules and collections"
-  3600)
+  (* 3600 5))

 (defn configure-quartz-system-properties
   [db]


A few minor simplifications

A few minor simplifications


Minor: remove useless code.

Minor: remove useless code.

--- ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/resources/common/std_crud.clj
+++ ssclj/jar/src/main/clojure/com/sixsq/slipstream/ssclj/resources/common/std_crud.clj
@@ -15,10 +15,10 @@

 (defn log-request
   [request]
-  (log/info (:request-method request)
-            (:uri request)
-            (get request :query-string "")
-            (get request :body "")))
+  (log/info (:request-method  request)
+            (:uri             request)
+            (:query-string    request)
+            (:body            request)))

 (defn add-fn
   [resource-name collection-acl resource-uri]


implement tests for the current future-facts in api-test

Added tests for group-untuple, repartition, and subtract.

--- test/flambo/api_test.clj
+++ test/flambo/api_test.clj
@@ -70,7 +70,10 @@
   (let [double-tuple2 (Tuple2. 1 (Tuple2. 2 "hi"))]
     (f/double-untuple double-tuple2) => [1 [2 "hi"]]))

- (future-fact "group-untuple"))
+(fact
+  "group untuple returns a vector with a key and a multiple value vector"
+  (let [group-untuple2 (Tuple2. 1 [2 3 4])]
+    (f/group-untuple group-untuple2) => [1 [2 3 4]])))

 (facts
  "about transformations"
@@ -270,9 +273,20 @@
             f/collect
             vec) => (just [[1 5] [1 6] [1 7] [2 5] [2 6] [2 7]] :in-any-order)))

-     (future-fact "repartition returns a new RDD with exactly n partitions")
-
-     (future-fact "subtract")
+     (fact "repartition returns a new RDD with exactly n partitions"
+       (let [rdd1 (f/parallelize c [1 2])
+             rdd2 (f/parallelize c [5 6 7])
+             rdd3 (f/parallelize c [8 9 10 11])
+             rdd4 (f/parallelize c [12 13])]
+         (-> (f/union c rdd1 rdd2 rdd3 rdd4)
+             (f/repartition 4)
+             f/partition-count) => 4))
+
+     (fact "subtract returns a new RDD with the elements from the second RDD removed from the first"
+       (-> (f/parallelize c [1 3 5 7 9])
+           (f/subtract (f/parallelize c [1 3 5]))
+           f/collect
+           vec) => (just [7 9] :in-any-order))

      )))


formatted comments, removed junk comments

--- possibledb/src/possibledb/core.cljs
+++ possibledb/src/possibledb/core.cljs
@@ -16,15 +16,19 @@
         (node/enable-util-print!)

         ;; needed for reading config files
+
         (def fs (node/require "fs"))

         ;; rethinkdb backs everything
+
         (def r (node/require "rethinkdb"))

         ;; net socket for requests
+
         (def net (node/require "net"))

         ;; altered, but not added kv pairs
+
         (def app
           (atom
            {:possibledb-table "databases"
@@ -34,6 +38,7 @@

         ;; each db is actually a single row in a single table
         ;; and this is the prefix for the main table
+
         (def possibledb-rethinkdb-prefix "possibledb_")

         (defn possibledb-table-name [name]
@@ -42,6 +47,7 @@
                      "_"))

         ;; prefix for all non-main tables within the db
+
         (def possibledb-db-prefix "possibledb_db_")

         (defn possibledb-db-name [name]
@@ -50,10 +56,12 @@
                      "_"))

         ;; returns main table
+
         (defn rethinkdb-possibledb-table []
           (-> @app :possibledb-table possibledb-table-name))

         ;; clj->js has a bug for datoms => workaround is used later
+
         (defn clj->json [x]
           (-> x
               clj->js
@@ -61,12 +69,15 @@
               JSON/parse))

         ;; used when the main-fn is ready to run
+
         (def ch-ready (chan))

         ;; owned by pub-main
+
         (def ch-main (chan))

-        ;; pub fn is key of single key hashmaps
+        ;; pub fn is key of single key hashmaps
+
         (def pub-main (pub ch-main (comp key first)))

         (def config-file (:config-file @app))
@@ -79,6 +90,7 @@
             (JSON/parse data)))

         ;; load config
+
         (let [c (chan)]
           (sub pub-main :load-config c)

@@ -86,12 +98,15 @@
             (println "Loading RethinkDB config from " config-file)

             ;; load configuration file
+
             (let [json (load-config! config-file)]

               ;; set configuration
+
               (swap! app assoc :reathinkdb-config json)

               ;; unsub and don't recur
+
               (unsub pub-main :load-config c)

               (>! ch-ready true))))
@@ -112,6 +127,7 @@
           (re-find #"already exists" (str err)))

         ;; make rethinkdb connection
+
         (let [c (chan)]
           (sub pub-main :rethinkdb-create-connection c)

@@ -119,6 +135,7 @@
             (println "Creating RethinkDB connection")

             ;; create connection for rethinkdb
+
             (doto r
               (.connect (rethinkdb-config)
                         (fn [err conn]
@@ -131,6 +148,7 @@
             (unsub pub-main :rethinkdb-create-connection c)))

         ;; check/create rethinkdb database
+
         (let [c (chan)]
           (sub pub-main :rethinkdb-create-db c)

@@ -154,9 +172,11 @@
               (catch js/Object ex (println ex)))

             ;; no recur
+
             (unsub pub-main :rethinkdb-create-db c)))

         ;; create rethink-db POSSIBLEDB table(s)
+
         (let [c (chan)]
           (sub pub-main :create-possibledb-tables c)

@@ -182,6 +202,7 @@
               (catch js/Object ex (println ex)))

             ;; no recur
+
             (unsub pub-main :create-possibledb-tables c)))

         (defn rethinkdb-insert-possibledb!
@@ -344,6 +365,7 @@
             (let [[socket data] (-> c <! :incoming)

                   ;; needed to be evaluated so must remove parens
+
                   safe (-> data
                            (.toString "utf8")
                            (s/replace #"\(" "")
@@ -362,15 +384,18 @@
                     (case (str action)

                       ;; get the entire database
+
                       "get"
                       (possibledb-get-db! db
                                           (fn [db]
                                             (let [conn @db

                                                   ;; remove type for reading
+
                                                   conn (zipmap (keys conn) (vals conn))

                                                   ;; remove children type
+
                                                   vs (mapv (fn [x]
                                                              (if-not (set? x)
                                                                x
@@ -412,20 +437,24 @@

         (go
           ;; load rethinkdb json config
+
           (>! ch-main
               {:load-config config-file})

           ;; park until ready, connect to rethink db
+
           (if (<! ch-ready)
             (>! ch-main
                 {:rethinkdb-create-connection true}))

           ;; park until ready, create main db
+
           (if (<! ch-ready)
             (>! ch-main
                 {:rethinkdb-create-db true}))

           ;; park until ready, create possibledb databases table
+
           (if (<! ch-ready)
             (>! ch-main
                 {:create-possibledb-tables true})))
@@ -443,15 +472,3 @@
                             (put! ch-main {:incoming [socket data]}))))))

               (.listen port)))))
-
-
-
-          ;; (when (<! ch-ready)
-          ;;   (possibledb-create-db! "example")
-          ;;   (<! (timeout 1000))
-          ;;   (possibledb-transact! "example"
-          ;;                   [{:db/id -1 :name "user1"}])
-          ;;   (<! (timeout 1000))
-          ;;   (possibledb-q "example"
-          ;;           '[:find ?n
-          ;;             :where [?e :name ?n]])))))


:wrench: LDAP authentication config with better default values

Co-authored-by: Mathieu Brunot <cbb78c9d6ecc8139b4697c3352cc1f1edbdf61d7@monogramm.io>

--- backend/src/uxbox/config.clj
+++ backend/src/uxbox/config.clj
@@ -43,22 +43,22 @@
    :allow-demo-users true
    :registration-enabled true
    :registration-domain-whitelist ""
-   :debug-humanize-transit true})
+   :debug-humanize-transit true

-   ;; LDAP auth disabled by default
+   ;; LDAP auth disabled by default. Set ldap-auth-host to enable
    ;:ldap-auth-host "ldap.mysupercompany.com"
-   ;:ldap-auth-port 636
-   ;:ldap-auth-version "3"
+   ;:ldap-auth-port 389
+   :ldap-auth-version "3"
    ;:ldap-bind-dn "cn=admin,dc=ldap,dc=mysupercompany,dc=com"
    ;:ldap-bind-password "verysecure"
    ;:ldap-auth-ssl false
-   ;:ldap-auth-starttls true
+   ;:ldap-auth-starttls false
    ;:ldap-auth-base-dn "ou=People,dc=ldap,dc=mysupercompany,dc=com"
-   ;:ldap-auth-user-query "(|(uid=$username)(mail=$username))"
-   ;:ldap-auth-username-attribute "uid"
-   ;:ldap-auth-email-attribute "mail"
-   ;:ldap-auth-fullname-attribute "displayname"
-   ;:ldap-auth-avatar-attribute "jpegPhoto"
+   :ldap-auth-user-query "(|(uid=$username)(mail=$username))"
+   :ldap-auth-username-attribute "uid"
+   :ldap-auth-email-attribute "mail"
+   :ldap-auth-fullname-attribute "displayName"
+   :ldap-auth-avatar-attribute "jpegPhoto"})

 (s/def ::http-server-port ::us/integer)
 (s/def ::http-server-debug ::us/boolean)


Revert optimisations to simple for now

Revert optimisations to simple for now

--- web-app/project.clj
+++ web-app/project.clj
@@ -72,7 +72,7 @@
                 :source-paths ["src/cljs" "env/prod/cljs"]
                 :compiler {:main          potato.main
                            :output-to     "resources/public/js/potato.js"
-                           :optimizations :advanced
+                           :optimizations :simple
                            :externs       ["externs-input.js"]
                            :elide-asserts false
                            :pseudo-names false


Simplify example implementation of robot-name

--- exercises/robot-name/src/example.clj
+++ exercises/robot-name/src/example.clj
@@ -1,19 +1,16 @@
 (ns robot-name)

-(defn robot []
-  {:name (atom "")})
-
-(def random (java.util.Random.))
-(def letters (map char (range 65 91)))
-(defn generate-name []
+(def ^:private random (java.util.Random.))
+(def ^:private letters (map char (range 65 91)))
+(defn- generate-name []
   (str (apply str (take 2 (shuffle letters)))
        (+ 100 (.nextInt random 899))))

+(defn robot []
+  {:name (atom (generate-name))})
+
 (defn robot-name [robot]
-  (let [n @(:name robot)]
-    (if (= "" n)
-        (swap! (:name robot) #(str %1 (generate-name)))
-        n)))
+  @(:name robot))

 (defn reset-name [robot]
-  (swap! (:name robot) (fn [_] "")))
+  (reset! (:name robot) (generate-name)))


Remove graphite host

Remove graphite host

--- src/leiningen/new/cljskel/project.clj
+++ src/leiningen/new/cljskel/project.clj
@@ -38,7 +38,7 @@
         :service-port "8080"
         :service-url "http://localhost:%s"
         :restdriver-port "8081"
-        :environment-entertainment-graphite-host "graphite.brislabs.com"
+        :environment-entertainment-graphite-host ""
         :environment-entertainment-graphite-port "8080"
         :service-graphite-post-interval "1"
         :service-graphite-post-unit "MINUTES"


Fixed bug in reading 24 bit integers

Fixed bug in reading 24 bit integers

Signed-off-by: Peter Schuck <4b8373d016f277527198385ba72fda0feb5da015@bendyworks.com>

--- src/longshi/fressian/byte_stream.cljs
+++ src/longshi/fressian/byte_stream.cljs
@@ -175,7 +175,8 @@
       (.getInt16 i32adv 0 little-endian)))
   (read-int24! [bis]
     (do
-      (bsp/read-bytes! bis i32a 0 3)
+      (bsp/read-bytes! bis (.subarray i32a 1 4) 0 3)
+      (aset i32a 0 0)
       (.getInt32 i32adv 0 little-endian)))
   (read-int32! [bis]
     (do
@@ -187,7 +188,8 @@
       (.getUint16 i32adv 0 little-endian)))
   (read-unsigned-int24! [bis]
     (do
-      (bsp/read-bytes! bis i32a 0 3)
+      (bsp/read-bytes! bis (.subarray i32a 1 4) 0 3)
+      (aset i32a 0 0)
       (.getUint32 i32adv 0 little-endian)))
   (read-unsigned-int32! [bis]
     (do


make-request debug

make-request debug

--- boot.clj
+++ boot.clj
@@ -13,3 +13,5 @@
  (interpolating
   (let [x (+ 1 1)]
     "1+1=#{x}")))
+
+(println (boot/make-request))


Fix a problem in creating updates w/o using the most recent section revision.

--- src/open_company/resources/common.clj
+++ src/open_company/resources/common.clj
@@ -271,10 +271,10 @@
 (defn read-resources-in-order
   "
   Given a table name, an index name and value, and a set of fields, retrieve
-  the resources from the database in updated-at property order.
+  the resources from the database in created-at property order.
   "
   [conn table-name index-name index-value fields]
-  (updated-at-order
+  (created-at-order
     (read-resources conn table-name index-name index-value fields)))

 (defn update-resource


Track logins from 404 pages

Track logins from 404 pages

--- src-cljs/frontend/components/errors.cljs
+++ src-cljs/frontend/components/errors.cljs
@@ -40,7 +40,12 @@
              404 (if (and (not logged-in?) maybe-login-page?)
                    [:div
                     [:p "We're sorry; either that page doesn't exist or you need to be logged in to view it."]
-                    [:p [:b [:a {:href (gh-utils/auth-url)} "Login here"] " to view this page with your GitHub permissions."]]]
+                    [:p [:b [:a {:href (gh-utils/auth-url)
+                                 :on-click #(raise! owner [:track-external-link-clicked
+                                                           {:event "login_click"
+                                                            :properties {:source "404"
+                                                                         :url js/window.location.pathname}
+                                                            :path (gh-utils/auth-url)}])} "Login here"] " to view this page with your GitHub permissions."]]]
                    [:p "We're sorry, but that page doesn't exist."])
              500 [:p "We're sorry, but something broke"]
              "Something completely unexpected happened")]])))))


fixed some formatting in header.cljs (put all ending parens on one line)

--- src-cljs/frontend/components/header.cljs
+++ src-cljs/frontend/components/header.cljs
@@ -223,9 +223,7 @@
                    "Log In"]]
                  [:li
                   [:a.signup-link.btn.btn-success.navbar-btn {:href "/signup" :on-mouse-up #(analytics/track-signup-click)}
-                   "Sign Up"]]])
-              ]
-             ]]
+                   "Sign Up"]]])]]]
            (outer-subheader
              [{:mobile {:path "/mobile"
                         :title "Mobile"}


Add webdriver test, make non-existent build pages fake 404.

--- frontend/controllers/navigation.cljs
+++ frontend/controllers/navigation.cljs
@@ -175,6 +175,8 @@
   [history-imp navigation-point {:keys [project-name build-num] :as args} previous-state current-state]
   (let [api-ch (get-in current-state [:comms :api])
         ws-ch (get-in current-state [:comms :ws])
+        nav-ch (get-in current-state [:comms :nav])
+        err-ch (get-in current-state [:comms :errors])
         projects-loaded? (seq (get-in current-state state/projects-path))
         current-user (get-in current-state state/user-path)]
     (mlog (str "post-navigated-to! :build current-user? " (not (empty? current-user))
@@ -186,7 +188,15 @@
               api-result (<! (ajax/managed-ajax :get build-url))
               scopes (:scopes api-result)]
           (mlog (str "post-navigated-to! :build, " build-url " scopes " scopes))
-          (put! api-ch [:build (:status api-result) (assoc api-result :context {:project-name project-name :build-num build-num})])
+          ;; Start 404'ing on non-existent builds, as well as when you
+          ;; try to go to a build page of a project which doesn't
+          ;; exist. This is different than current behaviour, where
+          ;; you see the "regular" inner page, with an error message
+          ;; where the build info would be. Thoughts?
+          (condp = (:status api-result)
+            :success (put! api-ch [:build (:status api-result) (assoc api-result :context {:project-name project-name :build-num build-num})])
+            :failed (put! nav-ch [:error {:status (:status-code api-result) :inner? false}])
+            (put! err-ch [:api-error api-result]))
           (when (= :success (:status api-result))
             (analytics/track-build (:resp api-result)))
           (when (and (not (get-in current-state state/project-path))


Use capitalised letters to make the music read more like the lyrics.

--- src/overtunes/songs/frere_jacques.clj
+++ src/overtunes/songs/frere_jacques.clj
@@ -3,18 +3,18 @@
   (:use [overtunes.core])
   (:use [overtunes.instruments.foo]))

-(def frère-jacques [:C4 :D4 :E4 :C4])
-(def dormez-vous [:E4 :F4 :G4 :rest])
-(def sonnez-les-matines [:G4 :G4 :E4 :C4])
-(def din-dan-don [:C4 :G3 :C4 :rest])
+(def Frère-Jacques [:C4 :D4 :E4 :C4])
+(def Dormez-vous? [:E4 :F4 :G4 :rest])
+(def Sonnez-les-matines! [:G4 :G4 :E4 :C4])
+(def Din-dan-don [:C4 :G3 :C4 :rest])

 (def melody (concat
-  frère-jacques frère-jacques
-  dormez-vous dormez-vous
-  sonnez-les-matines sonnez-les-matines
-  din-dan-don din-dan-don))
+  Frère-Jacques Frère-Jacques
+  Dormez-vous? Dormez-vous?
+  Sonnez-les-matines! Sonnez-les-matines!
+  Din-dan-don Din-dan-don))

-(defn frere-jacques-round []
+(defn frere-jacques []
   (let [metro (metronome 120)]
     (play-melody melody foo metro)
     (play-melody melody foo (metronome-from metro 8))


option load

option load

--- src/pl/fermich/invest_data/option.clj
+++ src/pl/fermich/invest_data/option.clj
@@ -17,7 +17,7 @@
            ))

 (defn last-month-diff []
-  (vec (load-quotes-starting-from 2017 05 01)))
+  (vec (load-quotes-starting-from 2017 05 26)))

 (defn load-from-dir [dir]


Watching appears to work!

Watching appears to work!

--- src/prod/clj/com/potetm/tire_iron.clj
+++ src/prod/clj/com/potetm/tire_iron.clj
@@ -10,7 +10,26 @@
             [cljs.closure :as closure]
             [cljs.compiler :as comp]
             [cljs.env :as env]
-            [cljs.repl :as repl]))
+            [cljs.repl :as repl])
+  (:import (com.sun.nio.file SensitivityWatchEventModifier)
+           (java.nio.file Files
+                          FileSystem
+                          FileSystems
+                          FileVisitResult
+                          LinkOption
+                          Path
+                          SimpleFileVisitor
+                          StandardWatchEventKinds
+                          WatchEvent
+                          WatchEvent$Kind
+                          WatchEvent$Modifier)
+           (java.io IOException)
+           (java.util.concurrent Executors
+                                 ExecutorService
+                                 ThreadFactory
+                                 TimeUnit)))
+
+(defonce ^ExecutorService watch-exec nil)

 (defprotocol IRefresh
   (-initialize [this opts])
@@ -219,7 +238,10 @@
                         before
                         after
                         state
-                        add-all?]}]
+                        add-all?
+                        compiler-env]
+                 :or
+                 {compiler-env env/*compiler*}}]
   (doseq [s (filter some? [before after state])]
     (assert (symbol? s) "value must be a symbol")
     (assert (namespace s)
@@ -236,7 +258,7 @@
       ;; Once we're here, no checks are needed.
       (closure/build (apply build/inputs source-dirs)
                      repl-opts
-                     env/*compiler*))
+                     compiler-env))
     (when (or (seq unload) (seq load))
       (prn :requesting-reload load)
       (-refresh refresher {:repl-env repl-env
@@ -250,6 +272,61 @@
                            :load-nss load})))
   (swap! tracker assoc ::track/load nil ::track/unload nil)
   (println :ok))
+
+(defn recursive-register [watcher root]
+  (Files/walkFileTree
+    root
+    (proxy [SimpleFileVisitor] []
+      (preVisitDirectory [^Path dir attrs]
+        (.register dir
+                   watcher
+                   (into-array WatchEvent$Kind
+                               [StandardWatchEventKinds/ENTRY_CREATE
+                                StandardWatchEventKinds/ENTRY_DELETE
+                                StandardWatchEventKinds/ENTRY_MODIFY])
+                   (into-array WatchEvent$Modifier
+                               [SensitivityWatchEventModifier/HIGH]))
+        FileVisitResult/CONTINUE))))
+
+(defn start-watch [^ExecutorService exec ^FileSystem fs refresh-opts]
+  (.submit exec
+           ^Callable
+           (fn []
+             (try
+               (with-open [ws (.newWatchService fs)]
+                 (doseq [^Path root (map #(.getPath fs % (make-array String 0))
+                                         (:source-dirs refresh-opts))]
+                   (recursive-register ws root))
+                 (while true
+                   (when-let [k (.poll ws 300 TimeUnit/MILLISECONDS)]
+                     (when-let [events (and (.reset k)
+                                            (seq (.pollEvents k)))]
+                       (doseq [^WatchEvent e events]
+                         (if (= (.kind e) StandardWatchEventKinds/ENTRY_CREATE)
+                           (let [f (.context e)]
+                             (if (Files/isDirectory f (make-array LinkOption 0))
+                               (recursive-register ws f)))))
+                       (when (some (comp #(or (.endsWith % ".cljs")
+                                              (.endsWith % ".cljc"))
+                                         str
+                                         #(.context %))
+                                   events)
+                         (println "Watcher Refreshing...")
+                         (refresh* refresh-opts))))))
+               (catch IOException io
+                 (comment (println "REPL shutdown detected.")))
+               (catch InterruptedException ie
+                 (comment (println "Interrupted")))
+               (catch Exception e
+                 (binding [*out* *err*]
+                   (println (.getMessage e))
+                   (println (.printStackTrace e *out*))))
+               (finally
+                 (println "Shutting down watcher.")
+                 (.shutdown exec))))))
+
+(defn stop-watch []
+  (.shutdownNow watch-exec))

 (defn maybe-quoted->symbol [symbol-or-list]
   (if (list? symbol-or-list)
@@ -316,12 +393,12 @@
       {source-dirs ["src"]}}]
   (let [refresher (atom refresher)
         tracker (atom (track/tracker))
+        initial-build-complete? (promise)
         disable-unload (atom (into #{} disable-unload))
         disable-load (atom (into #{'cljs.core
                                    'clojure.browser.repl
                                    'clojure.browser.net}
                                  disable-load))
-        initial-build-complete? (promise)
         closed-settings (select-keys closed-settings
                                      [:before
                                       :after
@@ -345,23 +422,55 @@
                  (binding [*out* *err*]
                    (println "tire-iron not initialized"))))))

+     'start-watch (wrap (fn [repl-env analyzer-env [_ & opts] repl-opts]
+                          (let [passed-settings (apply hash-map opts)
+                                exec (Executors/newSingleThreadExecutor
+                                       (reify ThreadFactory
+                                         (newThread [this runnable]
+                                           (doto (Thread. runnable
+                                                          "tire-iron-watcher-thread")
+                                             (.setDaemon true)))))]
+                            (if-let [r @refresher]
+                              (do @initial-build-complete?
+                                  (alter-var-root #'watch-exec (constantly exec))
+                                  (start-watch watch-exec
+                                               (FileSystems/getDefault)
+                                               (merge {:refresher r
+                                                       :tracker tracker
+                                                       :source-dirs source-dirs
+                                                       :disable-unload @disable-unload
+                                                       :disable-load @disable-load
+                                                       :repl-env repl-env
+                                                       :analyzer-env analyzer-env
+                                                       :repl-opts repl-opts
+                                                       :compiler-env env/*compiler*}
+                                                      closed-settings
+                                                      passed-settings)))
+                              (binding [*out* *err*]
+                                (println "tire-iron not initialized"))))))
+
+     'stop-watch (wrap (fn [_ _ _ _]
+                         (stop-watch)))
+
      'init
      (wrap (fn [repl-env analyzer-env _ repl-opts]
-             (let [refresher (or @refresher
+             (let [env env/*compiler*
+                   ^Runnable build #(try
+                                      (closure/build (apply build/inputs source-dirs)
+                                                     repl-opts
+                                                     env)
+                                      (finally
+                                        (deliver initial-build-complete? true)))
+                   ;; Kick off a build. That will speed up the first reload which
+                   ;; takes the longest to build.
+                   _ (.start (Thread. build))
+                   refresher (or @refresher
                                  (reset! refresher
-                                         (determine-refresher repl-env)))
-                   env env/*compiler*
-                   ^Runnable build #(do (closure/build (apply build/inputs source-dirs)
-                                                       repl-opts
-                                                       env)
-                                        (deliver initial-build-complete? true))]
+                                         (determine-refresher repl-env)))]
                (-initialize refresher
                             {:repl-env repl-env
                              :analyzer-env analyzer-env
-                             :repl-opts repl-opts})
-               ;; Kick off a build. That will speed up the first reload which
-               ;; takes the longest to build.
-               (.start (Thread. build)))))
+                             :repl-opts repl-opts}))))

      'print-disabled
      (wrap (fn [& _]


Remove inspects

Remove inspects

--- frontend/components/add_projects.cljs
+++ frontend/components/add_projects.cljs
@@ -52,7 +52,7 @@
     (render [_]
       (let [user (:user data)
             settings (:settings data)
-            org (inspect (:organizations user))]
+            org (:organizations user)]
         (html [:div
             [:div.overview
              [:span.big-number "1"]
@@ -197,7 +197,7 @@
            (om/build repo-filter settings)
            [:ul.proj-list
             (let [filtered-repos (sort-by :name (filter (fn [repo]
-                                           (inspect (and
+                                           (and
                                              (if show-forks
                                                true
                                                (not (:fork repo)))
@@ -205,7 +205,7 @@
                                                :name
                                                (.toLowerCase)
                                                (.indexOf (.toLowerCase repo-filter-string))
-                                               (not= -1)))))
+                                               (not= -1))))
                                          repos))]
               (map (fn [repo] (om/build repo-item {:repo repo
                                                    :settings settings}))


Add some sauce copy

Add some sauce copy

--- frontend/components/integrations.cljs
+++ frontend/components/integrations.cljs
@@ -35,6 +35,10 @@
             :fill "#054C64",
             :d "M30.3,64.2c0.2,0,0.4,0,0.6,0.1c-0.2,0.1-0.3,0.3-0.3,0.6\r\n\t\tc0,0.4,0.3,0.7,0.7,0.7c0.3,0,0.5-0.1,0.6-0.4c0.1,0.2,0.2,0.4,0.2,0.7c0,1-0.8,1.8-1.8,1.8c-1,0-1.7-0.8-1.7-1.8\r\n\t\tC28.6,64.9,29.4,64.2,30.3,64.2",
             :clip-rule "evenodd"}]]])
+
+(def selenium-logo
+  [:svg {:x "0" :y "0" :width "120px" :height "120px" :view-box "0 0 100 100"}
+   [:path {:d "M64.6,75.6c0,2.7-3.3,5.6-7.7,5.6 c-5.7,0-9.7-3-9.7-11.5c0-6.8,2.9-11.5,9.7-11.5c9.2,0,8,10.8,8,10.8H47.6 M15.9,73.9c0,4.1,5.2,6.8,10.9,6.8s9.6-3.1,9.6-8 s-3.7-6-9.6-7.8c-5.9-1.9-9.6-2.8-9.6-7.8s3.5-7.4,9.6-7.4c6.7,0,9.6,3.2,9.6,5.2 M44.3,33c0,0,12.7,12.7,12.7,12.7l38-38 M81.3,14.9c-2.3-2-5.4-3.3-8.7-3.3H18.9C11.5,11.7,5,17.9,5,25.2V79c0,7.4,6.5,13.3,13.9,13.3h53.8c7.4,0,13-5.9,13-13.3V25.2 c0-0.7,0.1-1.5,0-2.2" :stroke-width "3px" :stroke-linecap "round" :stroke "#2bb033" :fill "none"}]])

 (defn cta-form [app owner]
   (reify
@@ -175,8 +179,16 @@
             :bottom-header "Ready for world-class continuous delivery?"
             :secondary-cta [:span "Or see our " [:a {:href "/docs/continuous-deployment-with-heroku"} "docs on deploying to Heroku."]]}
    :saucelabs {:hero {:header [:span "Test with " [:img {:src (utils/cdn-path "/img/outer/integrations/sauce.png") :alt "Sauce Labs" :style {:width "300px"}}] " on CircleCI"]
-                      :text "Test with as many browsers as you want, in parallel."}
-               :bullets [{:title "Test against hundreds of mobile and desktop browsers"}]}})
+                      :text "Test against hundreds of mobile and desktop browsers."}
+               :bullets [{:title "Selenium WebDriver"
+                          :text "Sauce Labs supports automated browser tests using Selenium WebDriver, a widely-adopted browser driving standard. Selenium WebDriver provides a common API for programatically driving browsers implemented in several popular languages, including Java, Python, and Ruby. WebDriver can operate in two modes: local or remote. When run locally, your tests use the Selenium WebDriver library to communicate directly with a browser on the same machine. When run in remote mode, your tests interact with a Selenium Server, and it it is up to the server to drive the browsers. Sauce Labs essentially provides a Selenium Server as a service, with all kinds of browsers available to test. It provides some extra goodies like videos of all test runs as well."
+                          :graphic selenium-logo}
+                         {:title "All the browsers and platforms you need"
+                          :text "Sauce Labs provides a huge variety of browsers and operating systems. You can choose between combinations of Firefox, Chrome, Safari, and Internet Explorer browsers and OSX, Windows, and Linux operating systems. You can also test against mobile Safari and Android browsers."}
+                         {:title "No public test servers required"
+                          :text [:span "Sauce Labs operates browsers on a network separate from CircleCI build containers, but there needs to be a way for the browsers to access the web application you want to test. The easiest way to do this is to simply run your server during a CircleCI build and use Sauce Connect to setup a secure tunnel between Sauce Labs' browsers and your build containers on CircleCI. There is an in-depth example of this in " [:a {:href "/docs/browser-testing-with-sauce-labs"} "our docs."]]}]
+               :bottom-header "Want to get rid of browser bugs?"
+               :secondary-cta [:span "Or see our " [:a {:href "/docs/browser-testing-with-sauce-labs"} "docs on Sauce Labs."]]}})

 (defrender integration [app owner]
   (let [integration (get-in app [:navigation-data :integration])]


Add select-below-iv-threshold

Add select-below-iv-threshold

--- frontend/src/cruncher/selections.cljs
+++ frontend/src/cruncher/selections.cljs
@@ -30,22 +30,39 @@
 (defn select-all []
   (mass-selections "data-id" 0 < true))

+(defn select-below-iv-perfect [percentage]
+  (println "Select all below " percentage "%")
+  (mass-selections "data-iv-perfect" percentage > true))
+

 ;;;; Views
+(defui IVPercentage
+  Object
+  (render [this]
+    (let [percentage (om/get-state this :percentage)]
+      (dom/div #js {:className "form-group"}
+               (dom/label #js {:className "control-label"} "Select all below IV % Perfect Threshold")
+               (dom/div #js {:className "input-group"}
+                        (dom/input #js {:type        "text"
+                                        :className   "form-control"
+                                        :onChange    #(vlib/commit-component-state this :percentage %)
+                                        :value       percentage
+                                        :placeholder "42"})
+                        (dom/span #js {:className "input-group-addon"} "%")
+                        (dom/span #js {:className "input-group-btn"}
+                                  (dom/button #js {:className "btn btn-default"
+                                                   :onClick   #(select-below-iv-perfect percentage)} "Select"))
+                        )))))
+(def iv-percentage (om/factory IVPercentage))
+
 (defui SelectionButtons
-       Object
-       (render [this]
-               (dom/div nil
-                        (dom/p #js {:className "lead"} "Selections")
-                        (vlib/button-primary select-all "Select all")
-                        (vlib/button-primary unselect-all "Unselect all")
-                        (vlib/button-primary select-all-but-favorite "Select all but favorite")
-                        (dom/input #js {:type "range"})
-                        (dom/div #js {:className "input-group"
-                                      :style #js {:width "200px"}}
-                                 (dom/span #js {:className "input-group-addon"} "IV <")
-                                 (dom/input #js {:type "text", :className "form-control"})
-                                 (dom/span #js {:className "input-group-addon"} "%")
-                                 )
-                        )))
+  Object
+  (render [this]
+    (dom/div nil
+             (dom/p #js {:className "lead"} "Selections")
+             (vlib/button-primary select-all "Select all")
+             (vlib/button-primary unselect-all "Unselect all")
+             (vlib/button-primary select-all-but-favorite "Select all but favorite")
+             (dom/div nil (iv-percentage))
+             )))
 (def controls (om/factory SelectionButtons))


Remove unused MAC algorithm usage.

Remove unused MAC algorithm usage.

--- src/ruuvi_server/tracker_security.clj
+++ src/ruuvi_server/tracker_security.clj
@@ -15,18 +15,6 @@
     ;; concatenate keys, values and separators
     (apply str (for [k param-keys]
                  (str (name k) ":" (params k) "|")))))
-
-(defn compute-mac [params secret mac-field]
-  (let [mac-message (generate-mac-message params mac-field)
-        request-mac (params mac-field)]
-
-    (let [value-with-shared-secret (str mac-message secret)
-          messageDigester (MessageDigest/getInstance "SHA-1")]
-      (let [computed-mac (.digest messageDigester (.getBytes value-with-shared-secret "ASCII"))
-            computed-mac-hex (Hex/encodeHexString computed-mac)]
-        (debug (str "orig-mac "(str request-mac) " computed mac " (str computed-mac-hex)) )
-        computed-mac-hex
-        ))))

 (defn compute-hmac [params secret mac-field]
   (let [mac-message (generate-mac-message params mac-field)
@@ -85,6 +73,4 @@

      :else (do (debug "Tracker failed authentication")
                {:authentication-failed true})
-     )
-
-    ))+     ) ))


Adds all-nums

Adds all-nums

--- src/the_little_clojurian/chapter4.clj
+++ src/the_little_clojurian/chapter4.clj
@@ -212,3 +212,16 @@
   (is (= (no-nums '(1)) '()))
   (is (= (no-nums '(apple)) '(apple)))
   (is (= (no-nums '(5 pears 6 prunes 9 dates)) '(pears prunes dates))))
+
+(with-test
+  (def all-nums
+    (fn [lat]
+      (cond (null? lat) '()
+            (number? (car lat)) (cons (car lat)
+                                      (all-nums (cdr lat)))
+            :else (all-nums (cdr lat)))))
+
+  (is (= (all-nums '()) '()))
+  (is (= (all-nums '(1)) '(1)))
+  (is (= (all-nums '(apple)) '()))
+  (is (= (all-nums '(1 apple 2 pears 3 bananas)) '(1 2 3))))


Fix when actually logged in

Fix when actually logged in

--- src/braid/core/client/ui/views/main.cljs
+++ src/braid/core/client/ui/views/main.cljs
@@ -54,7 +54,6 @@
        [readonly-group-header])
      [readonly-inbox-page-view]]

-    :else
     [:div.main
      [error-banner-view]
      [reconnect-overlay-view]


aviary-figwheel: Normalize build-once output.

--- aviary-figwheel/src/main/clj/aviary/figwheel.clj
+++ aviary-figwheel/src/main/clj/aviary/figwheel.clj
@@ -18,21 +18,30 @@
                    line))))
          args))

+(defn- transform-cljs-builder-out-line [line]
+  (condp re-matches (decolor-string line)
+    #"Compiling \"(.*)\" from (\[.*\]).*" :>>
+    (fn [matches]
+      (console/info :cljs/build (matches 2) str))
+    #"notifying browser that file changed:  (.*)" :>>
+    (fn [matches]
+      (console/info :cljs/reload (matches 1) str))
+    #"Successfully compiled \"(.*)\" in (.*) seconds\." :>>
+    (fn [matches]
+      (console/info :cljs/build (str (matches 1) " [" (matches 2) "s]") str))
+    line))
+
 (defn make-figwheel-builder [state]
   (-> state
       figwheel-auto/builder
       cljs/make-conditional-builder
       (transform-out-lines
-        (fn [line]
-          (condp re-matches (decolor-string line)
-            #"Compiling .*" :>> (constantly nil)
-            #"notifying browser that file changed:  (.*)" :>>
-            (fn [matches]
-              (console/info :cljs/reload (matches 1) str))
-            #"Successfully compiled \"(.*)\" in (.*) seconds\." :>>
-            (fn [matches]
-              (console/info :cljs/build (matches 1) str))
-            line)))))
+        transform-cljs-builder-out-line)))
+
+(defn build-cljs-once [& args]
+  (apply (-> cljs/build-once
+             (transform-out-lines
+               transform-cljs-builder-out-line)) args))

 (system/defcomponent serve [config]
   ([_] (start-figwheel-server (assoc config :server-port (:port config))))
@@ -49,7 +58,7 @@
                  (builder ctx))}]))

 (defn build-cljs [config]
-  (cljs/build-once
+  (build-cljs-once
     (cljs/prep-build config)))

 (defn reload-css [fw files]


Replace bootstrap navbar and bg-dark classes with tailwind

--- src/cljs/my_money/components/navbar.cljs
+++ src/cljs/my_money/components/navbar.cljs
@@ -28,7 +28,7 @@
 (defn navbar [e!]
   (let [collapsed? (r/atom true)]
     (fn [e!]
-      [:nav#navbar.navbar.navbar-expand-lg.navbar-dark.bg-dark.mb-2
+      [:nav.navbar-expand-lg.navbar-dark.mb-2.relative.flex.items-center.px-4.py-2.bg-black.bg-opacity-75
        [:a.navbar-brand {:href "#"} "my-money"]
        [:button.navbar-toggler {:type "button"
                                 :on-click #(swap! collapsed? not)}


Removed debug lines

Removed debug lines

--- src/ardoq/swagger/api.clj
+++ src/ardoq/swagger/api.clj
@@ -110,10 +110,8 @@
          (let [client (c/client {:url (:base-url config)
                                  :org org
                                  :token token})]
-           (println notifier)
            (try
              (let [wid (get-spec client url wsname (read-headers headers) swag ignorer)]
-               (println (str "Already here\nNotifier is " notifier))
                (socket-close)
                (when notifier
                  (send-success-email! wid org session client))


* src/clj/cljs/compiler.clj: CLJS-315: resolve-var and resolve-existing-var should never emit :name as string

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -108,7 +108,7 @@

 (defn resolve-existing-var [env sym]
   (if (= (namespace sym) "js")
-    {:name (name sym) :ns 'js}
+    {:name sym :ns 'js}
     (let [s (str sym)
           lb (-> env :locals sym)]
       (cond
@@ -154,7 +154,7 @@

 (defn resolve-var [env sym]
   (if (= (namespace sym) "js")
-    {:name (name sym)}
+    {:name sym}
     (let [s (str sym)
           lb (-> env :locals sym)]
       (cond
@@ -343,7 +343,11 @@

 (defmethod emit :var
   [{:keys [info env] :as arg}]
-  (emit-wrap env (emits (munge (:name info)))))
+  (let [n (:name info)
+        n (if (= (namespace n) "js")
+            (name n)
+            n)]
+    (emit-wrap env (emits (munge n)))))

 (defmethod emit :meta
   [{:keys [expr meta env]}]


added filter requirement in time partitioning

--- src/clj/datasplash/bq.clj
+++ src/clj/datasplash/bq.clj
@@ -145,12 +145,13 @@
   ([defs] (->schema defs name)))

 (defn ^TimePartitioning ->time-partitioning
-  [{:keys [type expiration-ms field]
+  [{:keys [type expiration-ms field require-partition-filter]
     :or   {type :day}}]
   (let [tp (doto (TimePartitioning.) (.setType (-> type name .toUpperCase)))]
     (cond-> tp
-            (int? expiration-ms) (.setExpirationMs expiration-ms)
-            (string? field)      (.setField field))))
+            (int? expiration-ms)                   (.setExpirationMs expiration-ms)
+            (string? field)                        (.setField field)
+            (boolean? require-partition-filter)    (.setRequirePartitionFilter require-partition-filter))))

 (defn get-bq-table-schema
   "Beware, uses bq util to get the schema!"


Refactored to no longer use peek

Refactored to no longer use peek

--- src/cljs/cljs/reader.cljs
+++ src/cljs/cljs/reader.cljs
@@ -13,17 +13,16 @@
 (defprotocol PushbackReader
   (read-char [reader] "Returns the next char from the Reader,
 nil if the end of stream has been reached")
-  (unread [reader ch] "Push back a single character on to the stream")
-  (peek [reader] [reader n] "Returns the first (or nth) character of the reader without advancing the reader position"))
+  (unread [reader ch] "Push back a single character on to the stream"))

+;; This implementation is quite inefficient. It can be improved by using an index into the original string
+;; and using a seperate buffer to store pushed data.
 (deftype StringPushbackReader [state]
   PushbackReader
   (read-char [reader] (let [original @state]
                       (reset! state (subs 1 original))
                       (first original)))
-  (unread [reader ch] (reset! state (str ch @state)))
-  (peek [reader] (first @state))
-  (peek [reader n] (nth @state n)))
+  (unread [reader ch] (reset! state (str ch @state))))

 (defn push-back-reader [s]
   "Creates a StringPushbackReader from a given string"
@@ -48,17 +47,22 @@

 (defn- number-literal?
   "Checks whether the reader is at the start of a number literal"
-  [reader]
-  (let [ch (peek reader)]
-    (or (numeric? ch)
-        (and (or (= \+ ch) (= \- ch))
-             (numeric? (peek reader 2))))))
+  [reader ch]
+  (or (numeric? ch)
+      (and (or (= \+ ch) (= \- ch))
+           (numeric? (let [next-ch (read-char reader)]
+                       (unread next-ch)
+                       next-ch)))))

 (defn- string-prefix?
   "Checks whether the character starts a string"
   [ch])

-(defn- vector-prefix ?
+(defn- list-prefix?
+  "Checks whether the char is the start of a list literal"
+  [ch])
+
+(defn- vector-prefix?
   "Checks whether the char is the start of a vector literal"
   [ch])

@@ -72,39 +76,47 @@
   "Advances the reader to the end of a line. Returns the reader"
   [reader]
   (let [ch (read-char reader)]
-    (if (or (= ch \n) (= ch r) (nil? ch))
+    (if (or (= ch \n) (= ch \r) (nil? ch))
       reader
       (recur reader))))

 (defn read-number
-  [reader])
+  [reader initch])

 (defn read-string
-  [reader])
+  [reader initch])
+
+
+(defn read-list
+  [reader initch is-recursive])

 (defn read-vector
-  [reader])
+  [reader initch is-recursive])

 (defn read-map
-  [reader])
+  [reader initch is-recursive])

 (defn read-symbol
-  [reader])
+  [reader initch is-recursive])
+

 (defn read
   "Reads the first object from a PushbackReader. Returns the object read.
-Returns nil if the reader did not contain any forms."
-  [reader]
-  (let [ch (peek reader)]
+Returns sentinel if the reader did not contain any forms."
+  [reader eof-is-error sentinel is-recursive]
+  (let [ch read-char]
     (if (not (nil? ch))
       (cond
-       (whitespace? ch) (do (read-char reader) (recur reader))
+       (whitespace? ch) (recur reader)
        (comment-prefix? ch) (recur (skip-line reader))
-       (number-literal? reader) (read-number reader)
-       (string-prefix? ch) (read-string reader)
-       (vector-prefix? ch) (read-vector reader)
-       (map-prefix? ch) (read-map reader)
-       :default (read-symbol reader)))))
+       (number-literal? reader) (read-number reader ch)
+       (string-prefix? ch) (read-string reader ch)
+       (list-prefix? ch) (read-list reader ch is-recursive)
+       (vector-prefix? ch) (read-vector reader ch is-recursive)
+       (map-prefix? ch) (read-map reader ch is-recursive)
+       :default (read-symbol reader ch)))
+    sentinel))
+

 (defn read-all
   "Reads a lazy sequence of objects from a reader."


Display first-taker-actx.

Display first-taker-actx.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -141,7 +141,12 @@
 (defn vis-html-chs [vis]
   ["
channels...
"
    (map (fn [ch-info]
-          ["
" (:id ch-info) ": " (:msgs ch-info) "
"])
+          ["
"
+           (:id ch-info) ": " (:msgs ch-info)
+           (if-let [fta (:first-taker-actx ch-info)]
+             [" --> " (last fta)]
+             "")
+           "
"])
         (vals (:chs vis)))
    "

"])


a useless comment added

a useless comment added

--- src/crawler/extractor.clj
+++ src/crawler/extractor.clj
@@ -15,9 +15,9 @@

 (def *page-sim-thresh* 0.90)

-(def *xpath-hrefs* (atom {}))     ; hold the unique hrefs for each xpath
-(def *xpath-df* (atom {}))        ; hold the df score for each xpath
-(def *visited* (atom (set [])))
+(def *xpath-hrefs* (atom {}))       ; hold the unique hrefs for each xpath
+(def *xpath-df* (atom {}))          ; hold the df score for each xpath
+(def *visited* (atom (set [])))     ; set of visited documents
 (def *url-documents* (atom {}))
 (def *enum-candidates* (atom {}))

@@ -129,6 +129,7 @@
         (/ (Math/log (count (@*xpath-hrefs* xpath)))
            (@*xpath-df* xpath)))
       enum-xpath-candidates)))))
+
 (defn process-new-page
   "Store the page signature"
   [url body one-hop?]


Async update tested.  AWESOME.

Async update tested.  AWESOME.

--- src-cljs/tea_time/core.cljs
+++ src-cljs/tea_time/core.cljs
@@ -98,7 +98,26 @@
   (fn [app-db [_ id]]
     (ajax/GET (str "/api/teas/" id "/delete")
               :error-handler (fn [response] (println "DELETE-TEA ERROR" response))
-              :handler (fn [response] (println name " deleted") (re-frame/dispatch [:load-teas])(reset! edit-tea-snap nil)))))
+              :handler #(re-frame/dispatch [:process-delete]))
+    app-db))
+
+;(re-frame/register-handler
+  ;:update-tea
+  ;(fn [app-db [_ id new-name]]
+    ;(.setTimeout js/window #(ajax/GET (str "/api/teas/" id "/update/" new-name)
+                                  ;:error-handler (fn [response]
+                                                  ;(println "UPDATE-TEA ERROR" response))
+                                  ;:handler (fn [response] (println response))) 4000)
+    ;app-db))
+
+(re-frame/register-handler
+  :update-tea
+  (fn [app-db [_ id new-name]]
+    (ajax/GET (str "/api/teas/" id "/update/" new-name)
+      :error-handler (fn [response]
+                      (println "UPDATE-TEA ERROR" response))
+      :handler (fn [response] (println response)))
+    app-db))

 (re-frame/register-handler
@@ -124,7 +143,11 @@
 (re-frame/register-handler
   :replace-tea
   (fn [app-state [_ replaced-by edit-tea-input]]
-    (assoc-in app-state [:teas-list] (replace {replaced-by edit-tea-input} (:teas-list app-state)))))
+    (re-frame/dispatch [:update-tea (:id replaced-by) edit-tea-input])
+    (assoc-in app-state [:teas-list] (replace {replaced-by
+                                               {:id (:id replaced-by)
+                                                :name edit-tea-input}}
+                                      (:teas-list app-state)))))

 (re-frame/register-sub
   :teas
@@ -152,13 +175,6 @@
             :error-handler (fn [response] (println "DELETE-TEA ERROR" response))
             :handler (fn [response] (println name " deleted") (re-frame/dispatch [:load-teas])(reset! edit-tea-snap nil))))

-(defn update-tea
-  "Sends an update request to the API, which updates the tea in the db"
-  [id newname]
-  (ajax/GET (str "/api/teas/" id "/update/" newname)
-            :error-handler (fn [response] (println "UPDATE-TEA ERROR" response))
-            :handler (fn [response] (println newname " updated") (reset! edit-tea nil))))
-
 (defn post-to-teas-db
   "Sends an Ajax Request to the API route to post the tea from the form to the database"
   [tea-name]
@@ -180,27 +196,23 @@
   [event]
   (-> event .-target .-value))

-
-(defn edit-tea-form
-  [tea edit?]
-  (let [edit-tea (reagent/atom (:name tea))]
-    (fn [tea]
-      [:form.pull-left {:type "text"
-                        :value @edit-tea
-                        :on-change #(reset! edit-tea (value-event %))}]
-      [:button.btn.btn-success.pull-right {:on-click (fn [e]
-                                                      (re-frame/dispatch
-                                                        [:replace-tea tea @edit-tea])
-                                                      (swap! edit? not))}
-       "Finalize"])))
-
 (defn tea-edit-toggler
   [tea]
-  (let [edit? (reagent/atom false)]
+  (let [edit? (reagent/atom false)
+        tmp-edit (reagent/atom (:name tea))]
     (fn [tea]
       (if @edit?
         [:tr
-          [:td.pull-right [edit-tea-form tea edit?]]]
+          [:td
+            [:input.form-control {:type "text"
+                                  :value @tmp-edit
+                                  :on-change #(reset! tmp-edit (value-event %))}]
+            [:button.btn.btn-success.pull-right
+              {:on-click (fn [e]
+                          (re-frame/dispatch
+                            [:replace-tea tea @tmp-edit])
+                          (swap! edit? not))}
+              "Finalize"]]]
         [:tr
           [:td.pull-left {:on-click #(swap! edit? not)} (:name tea)]]))))

@@ -261,18 +273,18 @@
   []
   (fn []
     [:div.form-group
-     [:div.row [:div.col-md-12
+     [:div.row [:div.col-md-12]
        [:button.btn.btn-info {:on-click (fn [_] (swap! show-edit not))} "Show/Hide edit form"]
        [:div.p (str "Preview: " (or @edit-tea-snap "*no tea selected*") " -> " (or @edit-tea "*no tea selected*"))]
        [:div.p]
        [:form {:style {:visibility (if @show-edit
                                      "visible"
                                      "hidden")}}
-        [:input.form-control {:field :text :id :change-tea :value @edit-tea :on-change sync-edit-tea }]
-        [:input.btn.btn-info {:type "submit" :value "Update Tea Name" :on-click #((update-tea @edit-tea-id @edit-tea)
+        [:input.form-control {:field :text :id :change-tea :value @edit-tea :on-change sync-edit-tea
+        ; [:input.btn.btn-info {:type "submit" :value "Update Tea Name" :on-click #((update-tea @edit-tea-id @edit-tea)
                                                                                (reset! edit-tea nil)
-                                                                                (reset! edit-tea-snap nil))}]]
-       [:input.btn.btn-danger {:type "button" :value (str "Delete " @edit-tea-snap) :on-click #(delete-tea @edit-tea)}]]]]))
+                                                                                (reset! edit-tea-snap nil)}]]
+       [:input.btn.btn-danger {:type "button" :value (str "Delete " @edit-tea-snap) :on-click #(delete-tea @edit-tea)}]]]))

 ;; tea-edit can be re-written so that it will look like the tea is being
 ;; modified in place on the DOM -- as a sort of preview -- then once the
@@ -285,10 +297,10 @@
    [:div.row
     [:div.col-md-12
      "Here is a list of teas"]]
-   [:div.row {:style {:display "flex" :align-items "flex-end"}}
-    [:div.col-md-6
+   [:div.row
+    [:div.col-md-8
      [tealister]]
-    [:div.col-md-6
+    [:div.col-md-4
      [tea-edit]
      [tea-adder]]]])


Orchestrate the execution of a function exposed. Work for function with no argument.

--- src/fnx/views/welcome.clj
+++ src/fnx/views/welcome.clj
@@ -2,7 +2,8 @@
   (:require [fnx.views.common :as common])
   (:use [noir.core :only [defpage render]]
         [hiccup.core :only [html]]
-        [hiccup.form-helpers :only [form-to submit-button]]))
+        [hiccup.form-helpers :only [text-field label form-to submit-button]]
+        [fnx.meta.expose :only [ns-public-fn]]))

 (defpage "/welcome" []
   (common/layout
@@ -32,14 +33,29 @@
    [:p#wrapper (map #(str % "
")
                     (range (read-string start) (read-string end)))]))

-;; A page to expose some functions from a fixed namespace fnx.meta.example
+;; A page to execute function
+(defpage "/xfn" {:keys [fun] :as user}
+  (let [g (fnx.meta.expose/resolve-str fun)]
+    (common/site-layout
+     "eXecute"
+     [:h1 (str "eXecute " g)]
+     [:p:#wrapper (str (g))])))
+
+(defn input-fields-fn "Wrapper to expose an execute function button."
+  [fun]
+  (form-to [:get "/xfn"]
+           (text-field "fun" fun)
+           (submit-button (str fun))))
+
+;; A page to expose some functions from a namespace.
+;; fnx.meta.example is the default one is no other is supplied.
 (defpage "/expose" {:keys [ns] :as user}
   (let [n (if (empty? ns) 'fnx.meta.example (symbol ns))
         title (str "Exposed functions in " n)]
     (common/site-layout
      title
      [:h1 title]
-     [:p#wrapper (let [f (fnx.meta.expose/ns-public-fn n)]
+     [:p#wrapper (let [f (ns-public-fn n)]
                    (if f
-                     (map #(str "" % "
") f)
-                     (str "No function exposed in " n)))])))
+                     (map input-fields-fn f)
+                     (str "Huh? No function exposed in " n)))])))


fix sort by on users

fix sort by on users

--- src/foreclojure/users.clj
+++ src/foreclojure/users.clj
@@ -4,10 +4,11 @@
         compojure.core))

 (defn get-users []
-  (from-mongo
-   (fetch :users
-          :only [:user :solved]
-	  :sort {:solved -1})))
+  (let [users (from-mongo
+               (fetch :users
+                      :only [:user :solved]))
+        sortfn  #(compare (count (:solved %1)) (count (:solved %2)))]
+    (reverse (sort sortfn users))))

 (def-page users-page []
   [:table {:class "my-table" :width "50%"}


correct namespace

correct namespace

--- src/io/cyanite/config.clj
+++ src/io/cyanite/config.clj
@@ -7,7 +7,7 @@
 (def
   ^{:doc "handle logging configuration from the yaml file"}
   default-logging
-  {:use "io.spootnik.logconfig/start-logging!"
+  {:use "org.spootnik.logconfig/start-logging!"
    :pattern "%p [%d] %t - %c - %m%n"
    :external false
    :console true
@@ -100,7 +100,6 @@
   [{:keys [use] :as config} target]
   (debug "building " target " with " use)
   (instantiate (-> use name symbol) config))
-
 (defn load-path
   "Try to find a pathname, on the command line, in
    system properties or the environment and load it."


Fixed small route bug

Fixed small route bug

--- server/src/spira/service/routes.clj
+++ server/src/spira/service/routes.clj
@@ -42,7 +42,7 @@
 (defroutes app-routes
   (GET "/api/garden/:id" [id]
        (json-response (service/req-garden (util/parse-int id))))
-  (GET ["/api/garden"] []
+  (GET "/api/garden" []
        (json-response (service/req-garden-list)))
   (route/not-found "Page not found"))


allow nrepl to be disabled via :nrepl false in config

--- src/main/shadow/cljs/devtools/server.clj
+++ src/main/shadow/cljs/devtools/server.clj
@@ -121,7 +121,7 @@

   (do-shutdown (rt/stop-all app))

-  (discard-println "shutdown complete."))
+  #_ (discard-println "shutdown complete."))

 (defn make-port-files [cache-root ports]
   (io/make-parents (io/file cache-root "foo.txt"))
@@ -267,12 +267,13 @@
         (:socket-repl config)

         socket-repl
-        (try
-          (socket-repl/start socket-repl-config app-ref)
-          (catch Exception e
-            (log/warn-ex e ::socket-repl-ex)
-            nil
-            ))
+        (when-not (false? socket-repl-config)
+          (try
+            (socket-repl/start socket-repl-config app-ref)
+            (catch Exception e
+              (log/warn-ex e ::socket-repl-ex)
+              nil
+              )))

         cli-repl-config
         {:port 0 ;; random port, not for humans
@@ -291,43 +292,44 @@
             (create-cli-checker cli-port)))

         nrepl
-        (try
-          ;; problem child nrepl
-          ;; we need to start a 0.2 nrepl server
-          ;; if an older cider-nrepl version is used
-          ;; otherwise it should be fine to start 0.4
-          (let [use-old-nrepl?
-                (when (io/resource "cider/nrepl.clj")
-                  (require 'cider.nrepl)
-
-                  (when-let [the-ns (find-ns 'cider.nrepl)]
-                    (= 'clojure.tools.nrepl.server
-                      (-> (.getAliases the-ns)
-                          (.get 'nrepl-server)
-                          (.getName)))))
-
-                nrepl-ns
-                (if use-old-nrepl?
-                  (do (log/info ::nrepl-fallback)
-                      'shadow.cljs.devtools.server.nrepl)
-                  'shadow.cljs.devtools.server.nrepl04)
-
-                _ (require nrepl-ns)
-
-                nrepl-start
-                (ns-resolve nrepl-ns 'start)
-
-                nrepl-stop
-                (ns-resolve nrepl-ns 'stop)
-
-                server
-                (nrepl-start (:nrepl config))]
-
-            ;; return a generic stop fn
-            (assoc server ::stop #(nrepl-stop server)))
-          (catch Exception e
-            (log/warn-ex e ::nrepl-ex)
-            nil))
+        (when-not (false? (:nrepl config))
+          (try
+            ;; problem child nrepl
+            ;; we need to start a 0.2 nrepl server
+            ;; if an older cider-nrepl version is used
+            ;; otherwise it should be fine to start 0.4
+            (let [use-old-nrepl?
+                  (when (io/resource "cider/nrepl.clj")
+                    (require 'cider.nrepl)
+
+                    (when-let [the-ns (find-ns 'cider.nrepl)]
+                      (= 'clojure.tools.nrepl.server
+                        (-> (.getAliases the-ns)
+                            (.get 'nrepl-server)
+                            (.getName)))))
+
+                  nrepl-ns
+                  (if use-old-nrepl?
+                    (do (log/info ::nrepl-fallback)
+                        'shadow.cljs.devtools.server.nrepl)
+                    'shadow.cljs.devtools.server.nrepl04)
+
+                  _ (require nrepl-ns)
+
+                  nrepl-start
+                  (ns-resolve nrepl-ns 'start)
+
+                  nrepl-stop
+                  (ns-resolve nrepl-ns 'stop)
+
+                  server
+                  (nrepl-start (:nrepl config))]
+
+              ;; return a generic stop fn
+              (assoc server ::stop #(nrepl-stop server)))
+            (catch Exception e
+              (log/warn-ex e ::nrepl-ex)
+              nil)))

         port-files-ref
         (atom nil)
@@ -381,11 +383,12 @@
               (assoc :socket-repl (:port socket-repl)))
             )))

-    (let [nrepl-port-file (io/file ".nrepl-port")]
-      (when-not (.exists nrepl-port-file)
-        (spit nrepl-port-file (str (:port nrepl)))
-        (swap! port-files-ref assoc :nrepl-port nrepl-port-file)
-        (.deleteOnExit nrepl-port-file)))
+    (when nrepl
+      (let [nrepl-port-file (io/file ".nrepl-port")]
+        (when-not (.exists nrepl-port-file)
+          (spit nrepl-port-file (str (:port nrepl)))
+          (swap! port-files-ref assoc :nrepl-port nrepl-port-file)
+          (.deleteOnExit nrepl-port-file))))

     (. (Runtime/getRuntime) (addShutdownHook shutdown-hook))

@@ -499,7 +502,8 @@
                          " running at http" (when ssl-context "s") "://" http-host ":" (:port http)))
            #_ (println (str "shadow-cljs - socket REPL running on port " (:port socket-repl)))
            ;; must keep this message since cider looks for it
-           (println (str "shadow-cljs - nREPL server started on port " (:port nrepl)))
+           (when nrepl
+             (println (str "shadow-cljs - nREPL server started on port " (:port nrepl))))

            ::started
            )))))


fix demo

fix demo

--- src/babel/english/demo.cljc
+++ src/babel/english/demo.cljc
@@ -36,7 +36,7 @@
           :synsem {:cat :noun
                    :sem {:pred :cane
                          :number :plur
-                         :mod {:pred :first}
+                         :mod {:pred :second}
                          :spec {:def :genitive
                                 :of {:pred :luisa}}}}}


first pass of support for 'chiamarsi'

first pass of support for 'chiamarsi'

--- src/babel/italiano/lab.cljc
+++ src/babel/italiano/lab.cljc
@@ -294,6 +294,7 @@

 (def future-grammar
   #{"sentence-phrasal-head"
+    "vp-pronoun-phrasal"
     "vp-pronoun-nonphrasal"})

 (def present-perfect-grammar
@@ -368,29 +369,36 @@
 (defn arrabbiarsi-or-sedersi
   "generate arrabiarsi sentences with a grammar subset."
   []
-  (let [verb-set #{"arrabbiarsi" "fermarsi" "parlare" "sedersi"}
-        grammar (filter
-                 #(contains? verbcoach-grammar (u/get-in % [:rule]))
-                 (:grammar model))
-        specs [{:root {:italiano {:italiano "arrabbiarsi"}}
-                :synsem {:cat :verb
-                         :sem {:tense :present
-                               :aspect :perfect}
-                         :subcat []}}
-               {:root {:italiano {:italiano "sedersi"}}
-                :synsem {:cat :verb
-                         :sem {:tense :future}
-                         :subcat []}}]]
+  (let [verb-set #{"arrabbiarsi" "chiamarsi" "fermarsi" "parlare" "sedersi"}
+        verb-set #{"chiamarsi"}
+        specs
+        (map (fn [root]
+               {:root {:italiano {:italiano root}}})
+             verb-set)
+        tense-specs [{:synsem {:cat :verb
+                               :sem {:tense :present
+                                     :aspect :perfect}
+                               :subcat []}}
+                     {:synsem {:cat :verb
+                               :sem {:tense :future}
+                               :subcat []}}]]
     (repeatedly
      #(println
        (let [chosen-spec
-             (first (shuffle specs))]
+             (unify (first (shuffle specs))
+                    (first (shuffle tense-specs)))]
          (let [generate-with-grammar
-               (cond
+               (cond
                  (not (= :fail
-                         (unify (u/get-in chosen-spec [:synsem :sem])
-                                {:tense :present
-                                 :aspect :perfect})))
+                         (unify
+                          (u/get-in chosen-spec [:synsem :sem])
+                          {:root {:root "chiamarsi"}})))
+                 (do (log/warn "chiamarsi: gotta use everything.")
+                     (:grammar model))
+                 (not (= :fail
+                         (unify(u/get-in chosen-spec [:synsem :sem])
+                               {:tense :present
+                                :aspect :perfect})))
                  (filter (fn [rule-structure]
                            (contains? present-perfect-grammar
                                       (u/get-in rule-structure [:rule])))
@@ -409,10 +417,10 @@
                  (do
                    (log/warn "using entire model: will be slow.")
                    (:grammar model)))]
-           (morph (binding [babel.generate/println? false
-                            babel.generate/truncate? true
-                            babel.generate/grammar generate-with-grammar]
-                    (time (generate chosen-spec model))))))))))
+           (morph-ps (binding [babel.generate/println? false
+                               babel.generate/truncate? false
+                               babel.generate/grammar generate-with-grammar]
+                       (time (generate chosen-spec model))))))))))

 (defn stampare
   "generate arrabiarsi sentences with a grammar subset."


Use the same content for the cover page of the text output

as for the pdf output, i.e.

- current date
- Impressum

--- src/catalog/layout/text.clj
+++ src/catalog/layout/text.clj
@@ -1,7 +1,9 @@
 (ns catalog.layout.text
   "Render catalog items as plain textx"
   (:require [catalog.layout.common :as layout :refer [empty-or-blank? wrap]]
-            [clj-time.core :as time.core]
+            [clj-time
+             [core :as time.core]
+             [format :as time.format]]
             [clojure
              [set :as set]
              [string :as string]
@@ -211,38 +213,49 @@

 (defmulti document-str (fn [items _] (if (standard-catalog? items) :standard :custom)))

+(defn- impressum []
+  (let [creator (layout/translations :sbs)]
+    (string/join
+     "\n"
+     ["Herausgeber:"
+      creator
+      "Grubenstrasse 12"
+      "CH-8045 Zürich"
+      "Fon +41 43 333 32 32"
+      "Fax +41 43 333 32 33"
+      "www.sbs.ch"
+      "nutzerservice@sbs.ch"
+      (format "© %s" creator)])))
+
 (defmethod document-str :standard
   [items {:keys [year issue editorial recommendation]}]
   (let [title (layout/translations :catalog-all)
-        creator "SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte"
-        date (time.core/now)
-        language "de"
         items (cond-> items
                 (not (string/blank? editorial)) (assoc :editorial editorial)
                 (not (string/blank? recommendation)) (assoc :recommendation recommendation))
         path-to-numbers (layout/path-to-number items)]
-    (str
-     title
+    (string/join
      "\n\n"
-     (format "%s-%s" year issue)
-     "\n\n"
-     (string/join "\n\n" (map #(level-str (get items %) [%] path-to-numbers) (keys items))))))
+     (concat
+      [title
+       (format "%s-%s" year issue)
+       (impressum)]
+      (map #(level-str (get items %) [%] path-to-numbers) (keys items))))))
+
+(def ^:private date-formatter (time.format/formatter "dd.MM.YYYY"))

 (defmethod document-str :custom
   [items {:keys [query customer]}]
   (let [title (layout/translations :catalog-custom)
-        creator "SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte"
         date (time.core/now)
-        language "de"
         path-to-numbers (layout/path-to-number items)]
-    (str
-     title
-     "\n\n"
-     query
-     "\n\n"
-     (format "für %s" customer)
-     "\n\n"
-     (level-str items [] path-to-numbers))))
+    (string/join "\n\n"
+     [title
+      (format "Stand %s" (time.format/unparse date-formatter date))
+      query
+      (format "für %s" customer)
+      (impressum)
+      (level-str items [] path-to-numbers)])))

 (defn text
   [items options]