Fixes TODOs

Fixes TODOs

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -632,7 +632,6 @@
          (ansi/color (count problems) :footer)
          (ansi/color (if (= 1 (count problems)) "error" "errors") :footer)))))))

-;; TODO - move this up to top
 (defn minimal-fspec [form]
   (let [fspec-sp (s/cat
                   :sym qualified-symbol?
@@ -647,12 +646,9 @@
   (let [{:keys [sym spec failure]} check-result
         ret #?(:clj (:clojure.spec.test.check/ret check-result)
                :cljs (:clojure.test.check/ret check-result))
-        ;; TODO - should this be :clojure.spec.test.alpha/args (0 0) in explain-data
         bad-args (first (:fail ret))
         explain-data (ex-data failure)
         failure-reason (::s/failure explain-data)]
-    ;; TODO - remove this
-    (s/assert (s/nilable #{:check-failed :no-gen :no-fn :no-args-spec}) (-> explain-data ::s/failure))
     (str
      ;; CLJS does not contain symbol if function is undefined
      (if sym
@@ -679,7 +675,6 @@
           (printer/indent (str (s/form (:args (:spec check-result)))))
           "\n"))

-              ;; TODO - implement
        (= :no-args-spec failure-reason)
        (str
         "Failed to check function.\n\n"
@@ -687,7 +682,6 @@
                                      (minimal-fspec (s/form spec)))) :bad-value)
         "\n\nshould contain an :args spec\n")

-       ;; TODO - implement
        (= :no-fn failure-reason)
        (if (some? sym)
          (str
@@ -739,8 +733,7 @@
                     :clojure.spec.test.check/ret])
    data))

-;; TODO - rename explain-data
-(defn printer-str [opts explain-data]
+(defn printer-str [opts data]
   (let [opts' (merge {:show-valid-values? false
                       :print-specs? true}
                      opts)]
@@ -754,15 +747,15 @@
                                     {})]

       (cond
-        (or (explain-data? explain-data)
-            (nil? explain-data))
-        (print-explain-data opts' explain-data)
-
-        (check-result? explain-data)
-        (print-check-result explain-data)
+        (or (explain-data? data)
+            (nil? data))
+        (print-explain-data opts' data)
+
+        (check-result? data)
+        (print-check-result data)

         :else
-        (str "Unknown data:\n\n" explain-data)))))
+        (str "Unknown data:\n\n" data)))))

 ;;(s/def ::foo string?)


Cleanup

Cleanup

--- src/expound/alpha.cljc
+++ src/expound/alpha.cljc
@@ -275,9 +275,52 @@
    (header-label "Missing spec")
    (expected-str _type spec-name val path problems opts)))

-;; TODO - reorder to avoid this
-(declare sorted-and-grouped-problems)
-(declare problem-type)
+(defn safe-sort-by
+  "Same as sort-by, but if an error is raised, returns the original unsorted collection"
+  [key-fn comp coll]
+  (try
+    (sort-by key-fn comp coll)
+    (catch #?(:cljs :default
+              :clj Exception) e coll)))
+
+(defn problem-type [failure problem]
+  (cond
+    (insufficient-input? failure problem)
+    :problem/insufficient-input
+
+    (extra-input? failure problem)
+    :problem/extra-input
+
+    (not-in-set? failure problem)
+    :problem/not-in-set
+
+    (missing-key? failure problem)
+    :problem/missing-key
+
+    (missing-spec? failure problem)
+    :problem/missing-spec
+
+    (fspec-exception-failure? failure problem)
+    :problem/fspec-exception-failure
+
+    (fspec-ret-failure? failure problem)
+    :problem/fspec-ret-failure
+
+    (fspec-fn-failure? failure problem)
+    :problem/fspec-fn-failure
+
+    :else
+    :problem/unknown))
+
+(defn sorted-and-grouped-problems [explain-data]
+  (->> explain-data
+       :expound/problems
+       (problems/leaf-only)
+       (group-by (juxt :expound/in (partial problem-type (::s/failure explain-data))))
+       ;; We attempt to sort the problems by path, but it's not feasible to sort in
+       ;; all cases, since paths could contain arbitrary user-defined data structures.
+       ;; If there is an error, we just give up on sorting.
+       (safe-sort-by first paths/compare-paths)))

 (defmethod expected-str :problem/insufficient-input [_type spec-name val path problems opts]
   (s/assert ::singleton problems)
@@ -294,20 +337,16 @@
                 (and
                  (s/get-spec last-via)
                  (= pred (s/form (s/get-spec last-via)))) last-via)
-           non-matching-value #_:expound/value-that-should-never-match
-
-           [:expound/value-that-should-never-match]]
-       ;; TODO - convert back to if/then
-       (cond
-         (and (not (symbol? pred))
-              sp)
+           non-matching-value [:expound/value-that-should-never-match]]
+       (if
+        (and (not (symbol? pred))
+             sp)
          (let [explain-data (s/explain-data sp  non-matching-value)
                new-problems (sorted-and-grouped-problems (problems/annotate explain-data))]
            (apply str
                   (for [[[in type] problems'] new-problems]
                     (expected-str type :expound/no-spec-name non-matching-value in problems' opts))))

-         :else
          (let [ptype (problem-type nil (dissoc problem :reason))
                new-problems (map #(dissoc % :reason) problems)]
            (apply str
@@ -440,43 +479,6 @@
    (problem-group-str type spec-name val path problems opts)
    "\n\n"
    (if (:print-specs? opts) (relevant-specs problems) "")))
-
-(defn problem-type [failure problem]
-  (cond
-    (insufficient-input? failure problem)
-    :problem/insufficient-input
-
-    (extra-input? failure problem)
-    :problem/extra-input
-
-    (not-in-set? failure problem)
-    :problem/not-in-set
-
-    (missing-key? failure problem)
-    :problem/missing-key
-
-    (missing-spec? failure problem)
-    :problem/missing-spec
-
-    (fspec-exception-failure? failure problem)
-    :problem/fspec-exception-failure
-
-    (fspec-ret-failure? failure problem)
-    :problem/fspec-ret-failure
-
-    (fspec-fn-failure? failure problem)
-    :problem/fspec-fn-failure
-
-    :else
-    :problem/unknown))
-
-(defn safe-sort-by
-  "Same as sort-by, but if an error is raised, returns the original unsorted collection"
-  [key-fn comp coll]
-  (try
-    (sort-by key-fn comp coll)
-    (catch #?(:cljs :default
-              :clj Exception) e coll)))

 (defn instrumentation-info [failure caller]
   ;; As of version 1.9.562, Clojurescript does
@@ -493,16 +495,6 @@
   (if (#{:instrument} (::s/failure ed))
     (-> ed ::s/problems first :path first)
     nil))
-
-(defn sorted-and-grouped-problems [explain-data]
-  (->> explain-data
-       :expound/problems
-       (problems/leaf-only)
-       (group-by (juxt :expound/in (partial problem-type (::s/failure explain-data))))
-       ;; We attempt to sort the problems by path, but it's not feasible to sort in
-       ;; all cases, since paths could contain arbitrary user-defined data structures.
-       ;; If there is an error, we just give up on sorting.
-       (safe-sort-by first paths/compare-paths)))

 (defn printer-str [opts explain-data]
   (let [opts' (merge {:show-valid-values? false


Adds a nice layout for 500 errors.

Adds a nice layout for 500 errors.

--- src/cadence/views/response_codes.clj
+++ src/cadence/views/response_codes.clj
@@ -10,3 +10,10 @@
               [:p (str "Maybe it was just an accident, but we can't find that page"
                        " you requested.")]
               [:h2.response-code "404"]]))
+
+(set-page! 500
+           (common/base-layout
+             [:div.hero-unit
+              [:h1 "Oops! Something bad happened."]
+              [:p "An error has occured and I can't load a page or anything."]
+              [:h2.response-code "500"]]))


Disable button if previously pressed restart

--- src/discuss/views.cljs
+++ src/discuss/views.cljs
@@ -50,7 +50,11 @@
                (dom/hr nil)
                (dom/div #js {:className "row"}
                         (dom/div #js {:className "col-md-offset-4 col-md-4 text-center"}
-                                 (bs/button-default-sm history/back! (vlib/fa-icon "fa-step-backward") "Zurück"))
+                                 (dom/button #js {:className "btn btn-default btn-sm"
+                                                  :onClick   history/back!
+                                                  :disabled  (> 2 (count (re-seq #"/" (lib/get-last-api))))}
+                                             (vlib/fa-icon "fa-step-backward")
+                                             "Zurück"))
                         (dom/div #js {:className "col-md-4 text-right"}
                                  (bs/button-default-sm com/init! (vlib/fa-icon "fa-refresh") "Neustarten")))))))


Fix dispatching to executors which do not accept the repo

--- src/cider_ci/dispatcher/dispatch.clj
+++ src/cider_ci/dispatcher/dispatch.clj
@@ -115,7 +115,7 @@
            (hh/merge-join :branches_commits [:= :commits.id :branches_commits.commit_id])
            (hh/merge-join :branches [:= :branches_commits.branch_id :branches.id])
            (hh/merge-join :repositories [:= :branches.repository_id :repositories.id])
-           (hh/merge-join [:or
+           (hh/merge-where [:or
                            (hc/raw "(executors_with_load.accepted_repositories = '{}')")
                            (hc/raw " repositories.git_url = ANY(executors_with_load.accepted_repositories) ")])
            hc/format)


fix race condition in zookeeper#mkdirs

fix race condition in zookeeper#mkdirs

--- src/clj/backtype/storm/zookeeper.clj
+++ src/clj/backtype/storm/zookeeper.clj
@@ -1,7 +1,7 @@
 (ns backtype.storm.zookeeper
   (:import [org.apache.zookeeper ZooKeeper Watcher KeeperException$NoNodeException
             ZooDefs ZooDefs$Ids CreateMode WatchedEvent Watcher$Event Watcher$Event$KeeperState
-            Watcher$Event$EventType])
+            Watcher$Event$EventType KeeperException$NodeExistsException])
   (:import [org.apache.zookeeper.data Stat])
   (:import [org.apache.zookeeper.server ZooKeeperServer NIOServerCnxn$Factory])
   (:import [java.net InetSocketAddress])
@@ -66,7 +66,11 @@
   (let [path (normalize-path path)]
     (when-not (or (= path "/") (exists-node? zk path false))
       (mkdirs zk (parent-path path))
-      (create-node zk path (barr 7) :persistent)
+      (try
+        (create-node zk path (barr 7) :persistent)
+        (catch KeeperException$NodeExistsException e
+          ;; this can happen when multiple clients doing mkdir at same time
+          ))
       )))

 (defn get-data [^ZooKeeper zk ^String path watch?]


saving.

saving.

--- src/clj/forma/hadoop/jobs/update.clj
+++ src/clj/forma/hadoop/jobs/update.clj
@@ -156,7 +156,7 @@

      forma-tap
      ([:tmp-dirs forma-tap-output
-       :deps [preprocess-fires #_ merge-trends]]
+       :deps [preprocess-fires merge-trends]]
       (println "Prepping FORMA tap for neighbor analysis")
       (r/FormaTap (:spatial-res conf)
                   (:temporal-res conf)


Added docstring to mk-date-header

Added docstring to mk-date-header

--- src/clj/forma/postprocess/output.clj
+++ src/clj/forma/postprocess/output.clj
@@ -73,6 +73,9 @@
   (reduce str (split date-str #"-")))

 (defn mk-date-header
+  "(mk-date-header \"16\" \"p\" (s/timeseries-value 827 (range 141)))
+    63
++  => (\"p20051219\" \"p20060101\" \"p20060117\" ... \"p20120117\")"
   [tres prefix ts]
   (map (comp (partial str prefix)
              date-no-sep


Refactor - create `add-to-ModulesSelectedOrder!` function

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

--- src/cljs/cljs_nusmods/timetable.cljs
+++ src/cljs/cljs_nusmods/timetable.cljs
@@ -217,6 +217,11 @@
   "Determines if a module is in `ModulesSelectedOrder`"
   [moduleCode]
   (not-any? #{moduleCode} ModulesSelectedOrder))
+
+(defn- add-to-ModulesSelectedOrder!
+  "Appends a module to `ModulesSelectedOrder`"
+  [moduleCode]
+  (set! ModulesSelectedOrder (conj ModulesSelectedOrder moduleCode)))

 (defn is-module-selected?
   "Determines if a module has been selected"
@@ -788,8 +793,7 @@
               ; Add to ModulesSelectedOrder
               (if (module-not-in-ModulesSelectedOrder? moduleCode)
                   (do
-                    (set! ModulesSelectedOrder
-                          (conj ModulesSelectedOrder moduleCode))
+                    (add-to-ModulesSelectedOrder! moduleCode)
                     ; Update select2 box.
                     ; NOTE: This does a quadratic amount of work but I do not
                     ;       have a workaround.


Fix more build config tests to point at git SHAs that actually match the project, necessary after the git log changes

--- test/circle/backend/build/test_config.clj
+++ test/circle/backend/build/test_config.clj
@@ -43,20 +43,20 @@
   (circle.backend.build.template/find "build") => truthy)

 (fact "build-from-config works"
-  (let [project test/circle-project
-        config (get-config-for-url (-> test/circle-project :vcs_url))
-        vcs_revision "9538736fc7e853db8dac3a6d2f35d6dcad8ec917"
-        b (build-from-config config test/circle-project
+  (let [project test/test-project
+        config (get-config-for-url (-> test/test-project :vcs_url))
+        vcs_revision "78f58846a049bb6772dcb298163b52c4657c7d45"
+        b (build-from-config config test/test-project
                              :vcs-revision vcs_revision
                              :job-name :build)]
     (ref? b) => true
-    (-> @b :vcs_revision) => "9538736fc7e853db8dac3a6d2f35d6dcad8ec917"
+    (-> @b :vcs_revision) => "78f58846a049bb6772dcb298163b52c4657c7d45"
     (validate @b) => nil))

 (fact "build-from-json works"
-  (let [build (build-from-json test/circle-github-json)]
+  (let [build (build-from-json test/circle-dummy-project-json)]
     (ref? build) => true
-    (-> @build :vcs_revision) => "9538736fc7e853db8dac3a6d2f35d6dcad8ec917"))
+    (-> @build :vcs_revision) => "78f58846a049bb6772dcb298163b52c4657c7d45"))

 (fact "build loads the node and slurps the ssh keys"
   ;; The circle.yml contains :private-key, :public-key. Verify they were slurped.


Fix failing index watch test

Fix failing index watch test

--- test/clj_ravendb/client_watching_test.clj
+++ test/clj_ravendb/client_watching_test.clj
@@ -39,10 +39,6 @@
                         (put-index! client {:index index-name
                                             :where [[:== :name id]]
                                             :select [:name]})
-                        (bulk-operations! client [{:method "PUT"
-                                                   :id id
-                                                   :document {:test 1 :name id}
-                                                   :metadata {}}])
                         (f)
                         (delete-index! client index-name)
                         (bulk-operations! client [{:method "DELETE"


removed stream id check

removed stream id check

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -8,7 +8,6 @@
                           :upload-progress nil
                           :data-uploaded 0
                           :current-file-download nil
-                          :current-download-stream-id (new js/Blob)
                           :message-received false}))

 (enable-console-print!)
@@ -43,27 +42,23 @@

 (.on (new js/ss socket) "file-to-client"
   (fn [stream]
-    (if (= 0 (:current-file-download @app-state))
-      (swap! app-state assoc :current-download-stream-id (.-id stream)))
     (.on stream "data"
       (fn [blob-chunk]
-        (if (= (.-id stream) (:current-download-stream-id @app-state))
-          (println (.-id stream))
-          (swap! app-state assoc :current-file-download
-            (new js/Blob #js [(:current-file-download @app-state) blob-chunk])))))
+        (println "H")
+        (swap! app-state assoc :current-file-download
+          (new js/Blob #js [(:current-file-download @app-state) blob-chunk]))))
     (.on stream "end"
       (fn []
-        (if (= (.-id stream) (:current-download-stream-id @app-state))
-          (let [reader (new js/FileReader)
-                blob   (:current-file-download @app-state)]
-            (.readAsDataURL reader blob)
-            (set! (.-onloadend reader)
-              (fn []
-                (.attr (js/$ "#current-track") "src" (.-result reader))
-                (.load (.getElementById js/document "audio-tag"))
-                (.play (.getElementById js/document "audio-tag"))
-                (swap! app-state assoc :current-download-stream-id nil)
-                (swap! app-state assoc :current-file-download (new js/Blob))))))))))
+        (let [reader (new js/FileReader)
+              blob   (:current-file-download @app-state)]
+          (.readAsDataURL reader blob)
+          (set! (.-onloadend reader)
+            (fn []
+              (.attr (js/$ "#current-track") "src" (.-result reader))
+              (.load (.getElementById js/document "audio-tag"))
+              (.play (.getElementById js/document "audio-tag"))
+              (swap! app-state assoc :current-download-stream-id nil)
+              (swap! app-state assoc :current-file-download (new js/Blob)))))))))

 (.change (js/$ "#file_upload_input")
   (fn [e]


updates userlist

updates userlist

--- src/frontend/core.cljs
+++ src/frontend/core.cljs
@@ -5,18 +5,32 @@
 (defonce room-id (.getAttribute (. js/document (getElementById "roomid")) "data"))
 (defonce room (str "room:" room-id))
 (defonce socket (js/io "http://localhost:3001"))
-(defonce app-state (atom {}))
+(defonce app-state (atom {:users []}))

-(defn users-list-view [users owner]
+(defn user-view [user owner]
   (reify
     om/IRender
     (render [this]
-      (dom/h1 nil "Users"))))
+      (dom/li nil user))))
+
+(defn users-list-view [data owner]
+  (reify
+    om/IRender
+    (render [this]
+      (dom/div nil
+        (dom/h1 nil "Users")
+        (apply dom/h2 nil
+          (om/build-all user-view (:users data)))))))

 (om/root users-list-view app-state {:target (. js/document (getElementById "userslist"))})

 (.on socket "connect" #(.emit socket "join_room" room))
+
 (.submit (js/$ "#username_form")
   (fn []
     (.emit socket "set_username" room (.val (js/$ "#username")))
     false))
+
+(.on socket "userslist"
+  (fn [users]
+    (swap! app-state assoc :users users)))


Added a client setup lock

Added a client setup lock

--- src/atomix_jepsen/core.clj
+++ src/atomix_jepsen/core.clj
@@ -21,19 +21,13 @@
              [util :as net/util]]
             [jepsen.os.debian :as debian]
             [jepsen.checker.timeline :as timeline])
-
-  ;(:import (io.atomix Atomix AtomixClient AtomixReplica)
-  ;         )
   (:import (java.util.concurrent ExecutionException)))
-
-(defn- node-id [node]
-  (Integer/parseInt (subs (name node) 1)))

 ; Test lifecycle

 (defn install!
   "Installs atomix on the given node."
-  [node version]
+  [node]

   ; Setup for non atomix-jepsen Docker environments
   (when (nil? (debian/installed-version "oracle-java8-installer"))
@@ -65,7 +59,7 @@
 (defn start!
   "Starts atomix."
   [node test]
-  (let [nodes (into #{} (:nodes test))
+  (let [nodes (set (:nodes test))
         other-nodes (clojure.set/difference nodes (set [node]))
         local-node-arg "5555"
         other-node-args (doall (map #(str (name %) ":5555")
@@ -88,11 +82,11 @@

 (defn db
   "Atomix database"
-  [version]
+  []
   (reify db/DB
     (setup! [this test node]
       (doto node
-        (install! version)
+        (install!)
         (start! test)))

     (teardown! [this test node]
@@ -100,25 +94,29 @@

 ; Test clients

-(defrecord CasRegisterClient [client register nodes]
+(def setup-lock (Object.))
+
+(defrecord CasRegisterClient [client register]
   client/Client
   (setup! [this test node]
-    (let [node-set (map #(hash-map :host (name %)
-                                   :port 5555)
-                        nodes)]
-      (cutil/try-until-success
-        #(do
-          (info "Creating client connection to" node-set)
-          (let [atomix-client (trinity/client node-set)
-                _ (debug node "Client connected!")
-                test-name (:name test)
-                register (trinity/dist-atom atomix-client test-name)]
-            (debug node "Created atomix resource" test-name)
-            (assoc this :client atomix-client
-                        :register register)))
-        #(do
-          (debug node "Connection attempt failed. Retrying..." %)
-          (Thread/sleep 2000)))))
+    ; One client connection at a time
+    (locking setup-lock
+      (let [node-set (map #(hash-map :host (name %)
+                                     :port 5555)
+                          (:nodes test))]
+        (cutil/try-until-success
+          #(do
+            (info "Creating client connections to" node-set)
+            (let [atomix-client (trinity/client node-set)
+                  _ (debug node "Client connected!")
+                  test-name (:name test)
+                  register (trinity/dist-atom atomix-client test-name)]
+              (debug node "Created atomix resource" test-name)
+              (assoc this :client atomix-client
+                          :register register)))
+          #(do
+            (debug node "Connection attempt failed. Retrying..." %)
+            (Thread/sleep 2000))))))

   (invoke! [this test op]
     (try
@@ -143,8 +141,8 @@

 (defn cas-register-client
   "A basic CAS register client."
-  [nodes]
-  (CasRegisterClient. nil nil nodes))
+  []
+  (CasRegisterClient. nil nil))

 ; Generators

@@ -191,30 +189,29 @@

 ; Tests

-(defn- base-test
-  "Returns a map of base test settings"
+(defn- atomix-test
+  "Returns a map of atomix test settings"
   [name]
-  (let [base-test tests/noop-test]
-    (merge base-test
-           {:name     (str "atomix " name)
-            :os       debian/os
-            :db       (db "1.0")
-            :checker  (checker/compose {:linear checker/linearizable})
-            })))
+  (merge tests/noop-test
+         {:name (str "atomix " name)
+          :os   debian/os
+          :db   (db)
+          }))

 (defn- cas-register-test
   "Returns a map of jepsen test configuration for testing cas"
   [name opts]
-  (let [base-test (base-test (str "cas register " name))]
-    (merge base-test
-           {:client    (cas-register-client (:nodes base-test))
-            :model     (model/cas-register)
-            :checker   (checker/compose {:linear checker/linearizable
-                                         :latency (checker/latency-graph)})
-            :generator (->> gen/cas
-                            (gen/delay 1/2)
-                            std-gen)}
-           opts)))
+  (merge (atomix-test (str "cas register " name))
+         {:client    (cas-register-client)
+          :model     (model/cas-register)
+          :checker   (checker/compose {:html    timeline/html
+                                       :linear  checker/linearizable
+                                       :latency (checker/latency-graph)})
+          :generator (->> gen/cas
+                          (gen/delay 1/2)
+                          std-gen)}
+
+         opts))

 (def cas-bridge-test
   (cas-register-test "bridge"
@@ -231,3 +228,9 @@
 (def cas-crash-subset-test
   (cas-register-test "crash"
                      {:nemesis crash-nemesis}))
+
+(def cas-clock-drift-test
+  (cas-register-test "clock drift"
+                     {:nemesis (nemesis/clock-scrambler 10000)}))
+
+


working on generating with a static tree-structure rather than one created at generation-time

--- src/babel/english/lab.cljc
+++ src/babel/english/lab.cljc
@@ -94,18 +94,54 @@
       (u/assoc-in [:head :comp :head]
                   (-> model :grammar-map :nbar))))

-(def the-static-tree (create-the-static-tree))
-
-(def lexemes
-  (flatten (vals (:lexicon model))))
+(def semantics
+  {:synsem
+   {:subcat []
+    :cat :verb
+    :sem {:pred :see
+          :obj {:pred :chair
+                :spec {:def :def}
+                :mod {:first {:pred :red}}}
+          :subj {:pred :dog
+                 :mod {:first {:pred :small}}}}}})
+
+(def the-static-tree
+  (unify
+    (create-the-static-tree)
+    semantics
+    {:synsem
+     {:sem {:pred :see
+            :obj {:pred :chair
+                  :spec {:def :def}
+                  :mod {:first {:pred :red}}}
+            :subj {:pred :dog
+                   :mod {:first {:pred :small}}}}}}))
+
+;; can be used to determine
+(def tiny-lexicon
+  (filter #(or
+            true
+            (= "his" (u/get-in % [:english :english]))
+            (= "small" (u/get-in % [:english :english]))
+            (= "dog" (u/get-in % [:english :english]))
+            (= "see" (u/get-in % [:english :english]))
+            (= "those" (u/get-in % [:english :english]))
+            (= "red" (u/get-in % [:english :english]))
+            (= "chair" (u/get-in % [:english :english])))
+          (flatten (vals (:lexicon model)))))

 (def default-fn (:default-fn model))

+(def use-entire-lexicon true)
+
 (defn matching-lexemes [spec]
-  (take 1 (remove #(= :fail %)
-                  (map (fn [lexeme]
-                         (u/unify lexeme spec))
-                       lexemes))))
+  (let [lexemes (if use-entire-lexicon
+                  ((:index-fn model) spec)
+                  tiny-lexicon)]
+    (take 1 (remove #(= :fail %)
+                    (map (fn [lexeme]
+                           (u/unify lexeme spec))
+                         lexemes)))))

 (declare basecamp-at-spec)


cleanup

cleanup

--- src/metabase/api/common/throttle.clj
+++ src/metabase/api/common/throttle.clj
@@ -84,7 +84,7 @@
      (require '[metabase.api.common.throttle :as throttle])
      (def email-throttler (throttle/make-throttler :attempts-threshold 10))"
   [exception-field-key & {:as kwargs}]
-  (map->Throttler (merge throttler-defaults kwargs {:attempts   (atom '())
+  (map->Throttler (merge throttler-defaults kwargs {:attempts            (atom '())
                                                     :exception-field-key exception-field-key})))

 (defn check


add some try/catch logic to prevent an exception from killing the whole job.

--- src/metabase/task/sync_databases.clj
+++ src/metabase/task/sync_databases.clj
@@ -21,7 +21,11 @@
   [ctx]
   (dorun
     (for [database (db/sel :many Database)]
-      (future (driver/sync-database! database)))))
+      (try
+        ;; NOTE: this happens synchronously for now to avoid excessive load if there are lots of databases
+        (driver/sync-database! database)
+        (catch Exception e
+          (log/error "Error syncing database: " (:id database) e))))))

 ;; this is what actually adds our task to the scheduler
 (when (config/is-prod?)


Fix zero length interval issue in Junit emitter (#473)

* Update junit.clj

Fix zero length interval issue.

* Update junit.clj

--- src/midje/emission/plugins/junit.clj
+++ src/midje/emission/plugins/junit.clj
@@ -64,9 +64,12 @@
       (str (fact/file fact) ":" (fact/line fact))))

 (defn process-fact [fact]
-  (let [elapsed (/ (time/in-millis (time/interval (-> fact :attrs :start-time)
-                                                  (-> fact :attrs :stop-time)))
-                   1000.0)
+  (let [start-time (-> fact :attrs :start-time)
+        stop-time (-> fact :attrs :stop-time)
+        elapsed (if (time/before? start-time stop-time)
+                  (/ (time/in-millis (time/interval start-time stop-time))
+                     1000.0)
+                  0.0)
         dissoc-times (fn [attrs] (-> attrs
                                     (dissoc :start-time)
                                     (dissoc :stop-time)))]


CMR-3971 attempt build fix

CMR-3971 attempt build fix

--- system-int-test/test/cmr/system_int_test/ingest/bulk_update/bulk_update_flow_test.clj
+++ system-int-test/test/cmr/system_int_test/ingest/bulk_update/bulk_update_flow_test.clj
@@ -4,6 +4,7 @@
    [cheshire.core :as json]
    [clojure.test :refer :all]
    [cmr.common.util :as util :refer [are3]]
+   [cmr.message-queue.test.queue-broker-side-api :as qb-side-api]
    [cmr.mock-echo.client.echo-util :as e]
    [cmr.system-int-test.data2.umm-spec-collection :as data-umm-c]
    [cmr.system-int-test.system :as s]
@@ -37,6 +38,7 @@
       ;; Create another bulk update event with PROV2 to make sure we're just
       ;; getting PROV1 statuses
       (ingest/bulk-update-collections "PROV2" bulk-update-body)
+      (qb-side-api/wait-for-terminal-states)

       (are3 [accept-format]
         (let [response (ingest/bulk-update-provider-status "PROV1"


things

things

--- dev/user.clj
+++ dev/user.clj
@@ -126,4 +126,8 @@
 (defn testy []
   (reset)
   (Thread/sleep 200)
-  (set-value :a "a"))
+  (println "leader: " (first (find-leader)))
+  (assert (= :ok (set-value :a "a")))
+  (Thread/sleep 200)
+  (kill-random-follower)
+  (assert (= :ok (set-value :b "b"))))


Improve test

Improve test

--- test/obb_api/handlers/open_games_test.clj
+++ test/obb_api/handlers/open_games_test.clj
@@ -15,23 +15,14 @@
       (is game)
       (is (get game :starting-stash))
       (is (get-in game [:p1 :name]))
-      (is (nil? (get game :p2))))))
-
-(comment
-
-(deftest latest-games-smoke-p2
-  (let [[_ _] (create-friendly-test/create-dummy-game "donbonifacio" "Pyro")
-        [response status] (service/get-json "Pyro" (str "/player/latest-games"))]
-    (is (not (empty? response)))
-    (is (= 200 status))))
-
-(deftest latest-games-game-uri
-  (let [[_ _] (create-friendly-test/create-dummy-game "donbonifacio" "Pyro")
-        [response status] (service/get-json "donbonifacio" (str "/player/latest-games"))]
-    (is (not (empty? response)))
-    (is (= 200 status))
-    (let [sample-game (first response)
-          uri (sample-game :uri)]
-      (let [[response status] (service/get-json uri)]
-        (is (= 200 status))))))
-)
+      (is (nil? (get game :p2)))
+      (testing "if joining the game clears it from the lobby"
+        (let [game-id (game :_id)
+              join-url (str "/game/" game-id  "/join")
+              [response status] (service/put-json "Pyro" join-url "")]
+          (is (= 200 status))
+          (let [[response status] (service/get-json "donbonifacio" (str "/lobby/open-games"))]
+            (is (= 200 status))
+            (let [new-game (first response)]
+              (is new-game)
+              (is (not= (:_id game) (:_id new-game))))))))))


Reorder shutdown.

Reorder shutdown.

--- test/onyx/log/balanced_multi_job_test.clj
+++ test/onyx/log/balanced_multi_job_test.clj
@@ -122,10 +122,10 @@
   (fact "Peers balanced after job killed in multi-job test"
         (get-counts replica-2 [j1 j2]) => [[] [12 12 12]])

-  (finally
-    (doseq [v-peer v-peers]
-      (onyx.api/shutdown-peer v-peer))
+  (finally
+   (onyx.api/shutdown-peer-group peer-group)

-    (onyx.api/shutdown-env env)
+   (doseq [v-peer v-peers]
+     (onyx.api/shutdown-peer v-peer))

-    (onyx.api/shutdown-peer-group peer-group)))
+   (onyx.api/shutdown-env env)))


Add PDF roles to the toc

Add PDF roles to the toc

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -80,19 +80,19 @@

 (defn- toc-entry [items path to-depth]
   (let [depth (count path)]
-    [:fo:block (if (<= depth 2)
-                 {:text-align-last "justify"}
-                 {:text-align-last "justify" :start-indent "1em"})
+    [:fo:block (-> {:text-align-last "justify" :role "TOCI"}
+                   (cond-> (<= depth 2) (assoc :start-indent "1em")))
      [:fo:basic-link {:internal-destination (hash path)}
-      (layout/translations (last path))
-      " " [:fo:leader {:leader-pattern "dots"}] " "
-      [:fo:page-number-citation {:ref-id (hash path)}]]
+      (inline {:role "Reference"} (layout/translations (last path)))
+      " " [:fo:leader {:leader-pattern "dots" :role "NonStruct"}] " "
+      [:fo:page-number-citation {:ref-id (hash path) :role "Reference"}]]
      (when (and (map? items) (< depth to-depth))
        (keep #(toc-entry (% items) (conj path %) to-depth) (order (keys items))))]))

 (defn toc [items path to-depth & {:keys [heading?]}]
   (when (map? items)
-    [:fo:block {:line-height "150%"}
+    [:fo:block {:line-height "150%"
+                :role "TOC"}
      (when heading? (heading :h1 :inhalt []))
      (keep #(toc-entry (% items) (conj path %) to-depth) (order (keys items)))]))


The very first format should start on recto

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -394,6 +394,7 @@

     [:fo:flow {:flow-name "xsl-region-body"}
      (toc items [] 1 :heading? true)
+     (block {:break-before "odd-page"}) ;; the very first format should start on recto
      (mapcat #(format-sexp items %) (order (keys items)))]]])

 (defn document [items & args]


Simplify the prev/next navigation

Simplify the prev/next navigation

yet again

--- src/catalog/web/layout.clj
+++ src/catalog/web/layout.clj
@@ -68,14 +68,13 @@
                                    [(format "/%s/%s/editorial/hörbuch" year issue) "Hörbuch"]])
       (menu-item (format "/%s/%s/full" year issue) "Full")
       (menu-item (format "/%s/%s/custom" year issue) "Custom")
-      (dropdown-menu "Previous"
-                     [(let [[year issue] (issue/prev-issue year issue)]
-                        [(format "/%s/%s" year issue) "Previous"])
-                      ["/" "Current"]
-                      (let [[year issue] (issue/next-issue year issue)]
-                        [(format "/%s/%s" year issue) "Next"])])]
-     [:ul.nav.navbar-nav.navbar-right
-      [:li [:a (format "%s/%s" year issue)]]]]]])
+      ]
+     [:div.nav.navbar-nav.navbar-right
+      [:p.navbar-text (format "%s/%s" year issue)]
+      (let [[year issue] (issue/prev-issue year issue)]
+        [:a.btn.btn-default.btn-sm.navbar-btn {:href (format "/%s/%s" year issue)} (glyphicon "chevron-left" "Older catalogs")])
+      (let [[year issue] (issue/next-issue year issue)]
+        [:a.btn.btn-default.btn-sm.navbar-btn {:href (format "/%s/%s" year issue)} (glyphicon "chevron-right" "Newer catalogs")])]]]])

 (defn common
   "Display a page using the bootstrap css"


Update offset-date-time docstring

Update offset-date-time docstring

--- src/java_time/zone.clj
+++ src/java_time/zone.clj
@@ -94,6 +94,7 @@
     * no arguments - current date-time with the default offset
     * one argument
       + clock
+      + zone offset
       + another temporal entity
       + string representation
       + year


Shutdown agents for faster completion.

Shutdown agents for faster completion.

--- src/onyx_benchmark/submit_linear.clj
+++ src/onyx_benchmark/submit_linear.clj
@@ -81,4 +81,5 @@
                           :acker/percentage 20
                           :acker/exempt-input-tasks? true
                           :task-scheduler :onyx.task-scheduler/balanced})
-    (println "Job successfully submitted")))
+    (println "Job successfully submitted")
+    (shutdown-agents)))


adding jobs parent key

adding jobs parent key

--- src/celestial/api/jobs.clj
+++ src/celestial/api/jobs.clj
@@ -127,5 +127,5 @@
      (let [page* (Integer/valueOf page) offset* (Integer/valueOf offset)
         {:keys [username]} (friend/current-authentication)
         {:keys [envs] :as user} (u/get-user username)]
-       (success (es/paginate (* (- page* 1) offset*) (* page*  offset*) envs))))
+       (success {:jobs (es/paginate (* (- page* 1) offset*) (* page*  offset*) envs)})))
   )


CMR-6217 updated tests

CMR-6217 updated tests

--- access-control-app/int-test/cmr/access_control/int_test/access_control_group_crud_test.clj
+++ access-control-app/int-test/cmr/access_control/int_test/access_control_group_crud_test.clj
@@ -286,8 +286,8 @@
         {:keys [concept_id revision_id]} (test-util/create-group token group1)
         group2-concept-id (:concept_id (test-util/create-group token group2))]
     (testing "Delete without token"
-      (is (= :status 401
-             :errors ["Valid user token required."]
+      (is (= {:status 401
+              :errors ["Valid user token required."]}
              (test-util/delete-group nil concept_id))))

     (testing "Delete success"
@@ -383,33 +383,19 @@
       (is (empty? (set (:items (test-util/search-for-acls token {:permitted_group group-1-concept-id}))))))))

 (deftest update-group-test
-  (testing "successful update"
-    (let [group (test-util/make-group {:members ["user1" "user2"]})
-          token (echo-util/login (test-util/conn-context) "user1")
-          {:keys [concept_id]} (test-util/create-group token group)]
-
-      ;; Do not specify members in the update
-      (let [updated-group {:name "Updated Group Name"
-                           :description "Updated group description"}
-            token2 (echo-util/login (test-util/conn-context) "user2")
-            response (test-util/update-group token2 concept_id updated-group)]
-        (is (= {:status 200 :concept_id concept_id :revision_id 2}
-               response))
-        ;; Members should be intact
-        (test-util/assert-group-saved (assoc updated-group :members ["user1" "user2"]) "user2" concept_id 2))))
-
-  (testing "name collision updates should fail"
-    (let [group1 (test-util/make-group {:name "Group1" :members ["user1"]})
-          group2 (test-util/make-group {:name "Group2" :members ["user1"]})
-          updated-group2 {:name "Group1"
-                          :description "name collision expected"
-                          :members ["user1"]}
-          token (echo-util/login (test-util/conn-context) "user1")
-          {id1 :concept_id} (test-util/create-group token group1)
-          {id2 :concept_id} (test-util/create-group token group2)
-          _ (println token " " id1 " " id2)
-          response (test-util/update-group token id2 updated-group2)]
-      (is (= 400 (:status response))))))
+  (let [group (test-util/make-group {:members ["user1" "user2"]})
+        token (echo-util/login (test-util/conn-context) "user1")
+        {:keys [concept_id]} (test-util/create-group token group)]
+
+    ;; Do not specify members in the update
+    (let [updated-group {:name "Updated Group Name"
+                         :description "Updated group description"}
+          token2 (echo-util/login (test-util/conn-context) "user2")
+          response (test-util/update-group token2 concept_id updated-group)]
+      (is (= {:status 200 :concept_id concept_id :revision_id 2}
+             response))
+      ;; Members should be intact
+      (test-util/assert-group-saved (assoc updated-group :members ["user1" "user2"]) "user2" concept_id 2))))

 (deftest update-group-with-members-test
   (let [group (test-util/make-group {:members ["user1" "user2"]})
@@ -426,8 +412,10 @@

 (deftest update-group-failure-test
   (let [group (test-util/make-group)
-        token (echo-util/login (test-util/conn-context) "user1")
-        {:keys [concept_id revision_id]} (test-util/create-group token group)]
+        group2 (test-util/make-group {:name "Group2" :members ["user1"]})
+        token (echo-util/login (test-util/conn-context) "user1")
+        {:keys [concept_id revision_id]} (test-util/create-group token group)
+        {concept_id2 :concept_id} (test-util/create-group token group2)]

     (testing "Update group with invalid content type"
       (is (= {:status 400,
@@ -465,7 +453,15 @@
       (test-util/delete-group token concept_id)
       (is (= {:status 404
               :errors [(format "Group with concept id [%s] was deleted." concept_id)]}
-             (test-util/update-group token concept_id group))))))
+             (test-util/update-group token concept_id group))))
+
+    (testing "Update a group with conflicting name"
+      (test-util/wait-until-indexed)
+      (is (= {:status 409
+              :errors [(format "A system group with name [%s] already exists with concept id [%s]."
+                               (:name group)
+                               concept_id)]}
+             (test-util/update-group token concept_id2 (assoc group2 :name (:name group))))))))

 (deftest update-group-legacy-guid-test
   (let [group1 (test-util/make-group {:legacy_guid "legacy_guid_1" :name "group1"})


CMR-3410 remove debug code

CMR-3410 remove debug code

--- access-control-app/int_test/cmr/access_control/int_test/access_control_group_crud_test.clj
+++ access-control-app/int_test/cmr/access_control/int_test/access_control_group_crud_test.clj
@@ -342,7 +342,6 @@
     (testing "We should now successfully update groups with a legacy_guid, without specifying the legacy_guid in the updated group")
       (is (= {:status 200 :concept_id concept-id :revision_id 2}
              response-no-legacy))
-      (println response-no-legacy)
       (u/assert-group-saved (assoc no-legacy-group :legacy_guid "legacy_guid_1") "user1" concept-id 2)

     (testing "Specifying the same legacy_guid should also successfully update the group")


Normalize paths on changed-href? check fixes #23

--- src/adzerk/boot_reload/reload.cljs
+++ src/adzerk/boot_reload/reload.cljs
@@ -13,11 +13,14 @@
 (defn- reload-page! []
   (.reload (.-location js/window)))

+(defn- normalize-href-or-uri [href-or-uri]
+  (let [uri  (goog.Uri. href-or-uri)]
+    (.getPath (.resolve page-uri uri))))
+
 (defn- changed-href? [href-or-uri changed]
   (when href-or-uri
-    (let [uri  (goog.Uri. href-or-uri)
-          path (.getPath (.resolve page-uri uri))]
-      (when (not-empty (filter #(ends-with? % path) changed))
+    (let [path (normalize-href-or-uri href-or-uri)]
+      (when (not-empty (filter #(ends-with? (normalize-href-or-uri %) path) changed))
         uri))))

 (defn- reload-css [changed]


Remove fail banner completely for paid plans

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -60,7 +60,9 @@
   (let [build-id (build-model/id build)
         build-url (:build_url build)
         fail-reason (:fail_reason build)]
-    (when (:failed build)
+    (when (and (:failed build)
+               (not show-premium-content?)
+               (not (config/enterprise?)))
       [:div.alert.alert-danger.iconified
        [:div [:img.alert-icon {:src (common/icon-path "Info-Error")}]]
        (if (:infrastructure_fail build)
@@ -73,17 +75,7 @@
           [:a {:href "https://discuss.circleci.com/"}
            "community site"]
           "."
-          (let [support-link [:a (common/contact-support-a-info owner :tags [:report-build-clicked {:build-url build-url}])
-                              "contact engineering support"]]
-            (cond
-              (config/enterprise?) [:span "As an enterprise customer, you may also "
-                                    support-link
-                                    " to ask for help. Thanks!"]
-              show-premium-content? [:span
-                                     " As this project builds under a paid plan, you may also "
-                                     support-link
-                                     " to ask for help. Thanks!"]
-              :else [:span " Upgrading to a paid plan unlocks access to CircleCI engineering support, faster builds, and advanced features. Thanks!"]))])])))
+          [:span " Upgrading to a paid plan unlocks access to CircleCI engineering support, faster builds, and advanced features. Thanks!"]])])))

 (defn sticky [{:keys [wrapper-class content-class content]} owner]
   (reify


Binop is now handled by a multimethod dispatch in munch

--- src/clj/minijava/munch.clj
+++ src/clj/minijava/munch.clj
@@ -84,11 +84,9 @@
   				 d)) ;;Since Mem is an expression, it returns a temp.

 ;; Handles binop cases
-;(defmulti munchOp (fn [op r1 r2] op))
-;(defmulti munchOp [:+] [op rand1 rand2])
+(defmulti munchOp (fn [op r1 r2] op))

-(defmethod munchMap [:minijava.ir/BinaryOp clojure.lang.Keyword :minijava.exp/expression :minijava.exp/expression]
-  [exp op rand1 rand2]
+(defmethod munchOp :+ [op rand1 rand2]
   (cond (and (isit? rand1 :minijava.ir/Const)
              (isit? rand2 :minijava.ir/Const))
         (emit (addl (CONST (:val rand1))
@@ -100,6 +98,10 @@
         (emit (addl (CONST (:val rand2))
                     (munch rand1)))))

+(defmethod munchMap [:minijava.ir/BinaryOp clojure.lang.Keyword :minijava.exp/expression :minijava.exp/expression]
+  [exp op rand1 rand2]
+  (munchOp op rand1 rand2))
+
 (defmethod munchMap [:minijava.ir/Temp minijava.ir.temp.Temp]
   [exp temp]
   exp)


Minor optimizations.

Minor optimizations.

--- src/clojure_robby/core.clj
+++ src/clojure_robby/core.clj
@@ -78,8 +78,8 @@
         make-step
         (fn [[current-map pos score]]
           "Makes a single step on the map, according to the DNA sequence."
-          (let [situation (map (fn[v] (get-tile current-map (add-vec pos v))) dir-vects)
-                action-idx (reduce + (map * (map get-tile-index situation) multipliers))
+          (let [situation (map (fn[v] (get-tile-index (get-tile current-map (add-vec pos v)))) dir-vects)
+                action-idx (reduce + (map * situation multipliers))
                 action (nth dna action-idx)
                 step-to
                   (fn [the-pos]
@@ -98,7 +98,8 @@
               (if (= \g (get-tile current-map pos))
                 [(set-tile current-map pos \p) pos (+ score gold-value)]
                 [current-map pos (- score action-penalty)]))))
-        [_ final-pos final-score] (nth (iterate make-step [the-map '(1 1) 0]) simul-steps)]
+        iteration (iterate make-step [the-map '(1 1) 0])
+        [_ final-pos final-score] (nth iteration simul-steps)]
     final-score))


streamlines test

streamlines test

--- test/vip/data_processor/pipeline_test.clj
+++ test/vip/data_processor/pipeline_test.clj
@@ -59,7 +59,7 @@

 (deftest process-test
   (testing "Builds the context and executes the pipeline"
-    (let [intial-input {:input 0 :check-stop-flag-fn #(identity %)}
+    (let [intial-input {:input 0 :check-stop-flag-fn identity}
           pipeline [incrementor incrementor incrementor]
           result (process pipeline intial-input)]
       (is (= 3 (:input result)))


Fix find-relative-path for case where file is not found in dirs

Fixes e.g. jar urls

--- src/adzerk/boot_cljs/util.clj
+++ src/adzerk/boot_cljs/util.clj
@@ -32,9 +32,7 @@
     (let [parent (->> dirs
                       (map io/file)
                       (some (fn [x] (if (file/parent? x file) x))))]
-      (.getPath (if parent
-                  (file/relative-to parent file)
-                  file)))))
+      (if parent (.getPath (file/relative-to parent file))))))

 (defn find-original-path [source-paths dirs filepath]
   (if-let [rel-path (find-relative-path dirs filepath)]


ci [aeèiou] => c'

ci [aeèiou] => c'

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -1089,6 +1089,11 @@
                 (re-find #"^s[t]" b))
            (str "gli " b)

+           (and (= a "ci")
+                (string? b)
+                (re-find #"^[aeèiou]" b))
+           (str "c'" b)
+
            ;; handle e.g. "io lo ho visto" => "io l'ho visto"
            (and (string? a)
                 (re-find #"^l[ao]$" a)


light warn scrub boil

light warn scrub boil

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -177,6 +177,9 @@
                           :physical-object true
                           :human false}}})

+   "boil" {:synsem {:cat :verb
+                :sem {:pred :boil}}}
+
    "book"
    (unify agreement-noun
           common-noun
@@ -682,6 +685,9 @@
    "lift" {:synsem {:cat :verb
                     :sem {:pred :lift}}}

+   "light" {:synsem {:cat :verb
+                     :sem {:pred :light}}}
+
    "listen to" {:synsem {:cat :verb
                          :sem {:pred :listen-to}}
                 :english {:participle "listening to"
@@ -926,6 +932,11 @@
    ;; TODO: search _within_ or _on_: depends on the object.
    ;;   "search"  {:synsem {:sem {:pred :cercare}}})

+   "scrub"  {:synsem {:cat :verb
+                     :sem {:pred :prendere}}
+            :english {:participle "scrubbing"
+                      :past "scrubbed"}}
+
    "see"  {:synsem {:cat :verb
                     :sem {:pred :vedere}}
            :english {:past "saw"
@@ -1194,6 +1205,9 @@
    "warm" {:synsem {:cat :verb
                 :sem {:pred :warm}}}

+   "warn" {:synsem {:cat :verb
+                     :sem {:pred :warn}}}
+
    "wash" (let [subject-semantics (ref :top)]
             {:synsem {:cat :verb
                       :sem {:pred :wash
@@ -1396,6 +1410,13 @@
                          ;; if a verb has an object,
                          ;; and the object is not {:reflexive true}
                          ;; then the object is {:reflexive false}
+
                          (if-then {:synsem {:cat :verb
                                             :subcat {:2 {:reflexive false}}}}
                                   {:synsem {:subcat {:2 {:reflexive false}}}}))))
+
+
+
+
+
+


added contar

added contar

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -114,6 +114,10 @@

    "considerar" {:synsem {:cat :verb
                           :sem {:pred :consider}}}
+
+   "contar" {:espanol {:boot-stem "cuent"}
+             :synsem {:cat :verb
+                      :sem {:pred :count}}}

    "contestar" {:synsem {:cat :verb
                          :sem {:pred :answer}}}


changed pred conocer to know-c

changed pred conocer to know-c

--- src/babel/espanol/lexicon.clj
+++ src/babel/espanol/lexicon.clj
@@ -249,7 +249,7 @@

    "conocer" {:espanol {:present {:1sing "conozco"}}
               :synsem {:cat :verb
-                       :sem {:pred :know}}}
+                       :sem {:pred :know-c}}}

    "consentir" {:espanol {:boot-stem "consient"}
                 :synsem {:cat :verb


create test

create test

--- test/etcd_clojure/core_test.clj
+++ test/etcd_clojure/core_test.clj
@@ -19,6 +19,10 @@
   (testing "should set a value"
     (is (= "bar" (get (etcd/set "foo" "bar") "value")))))

+(deftest test-create
+  (testing "should set a value"
+    (is (= "bar" (get (etcd/create "foo" "bar") "value")))))
+
 (deftest test-delete
   (testing "should delete a value"
     (etcd/set "foo" "bar")


Write documents of some functions in jungerer.graph

--- src/jungerer/graph.clj
+++ src/jungerer/graph.clj
@@ -22,6 +22,8 @@
 ;; -----------

 (defn directed-graph
+  "Returns an edu.uci.ic.jung.graph.DirectedSparseGraph. If a list or vector
+  of edges is passed, returning graph including the edges."
   ([] (DirectedSparseGraph.))
   ([edges]
    (let [graph (DirectedSparseGraph.)]
@@ -33,6 +35,8 @@
      graph)))

 (defn directed-multigraph
+  "Returns an edu.uci.ic.jung.graph.DirectedSparseMultigraph. If a list or
+  vector of edges is passed, returning graph including the edges."
   ([] (DirectedSparseMultigraph.))
   ([edges]
    (let [graph (DirectedSparseMultigraph.)]
@@ -44,6 +48,8 @@
      graph)))

 (defn undirected-graph
+  "Returns an edu.uci.ic.jung.graph.UndirectedSparseGraph. If a list or vector
+  of edges is passed, returning graph including the edges."
   ([] (UndirectedSparseGraph.))
   ([edges]
    (let [graph (UndirectedSparseGraph.)]
@@ -55,6 +61,8 @@
      graph)))

 (defn undirected-multigraph
+  "Returns an edu.uci.ic.jung.graph.UndirectedSparseMultigraph. If a list or
+  vector of edges is passed, returning graph including the edges."
   ([] (UndirectedSparseMultigraph.))
   ([edges]
    (let [graph (UndirectedSparseMultigraph.)]
@@ -69,50 +77,68 @@
 ;; ------------

 (defn add-node!
+  "Adds node to graph. Returns true if the addition suceeded. Note that this
+  function is not immutable, changing the graph state."
   [^Hypergraph graph node]
   (.addVertex graph node))

 (defn remove-node!
+  "Removes node from graph. Returns true if the removal suceeded. As a side
+  effect, removes any edges incident to the node if the removal of the node
+  would cause the edge to be incident to an illegal number of nodes. Note that
+  this function is not immutable, changing the graph state."
   [^Hypergraph graph node]
   (.removeVertex graph node))

 (defn contains-node?
+  "Returns true if graph's node collection contains node."
   [^Hypergraph graph node]
   (.containsVertex graph node))

 (defn add-edge!
+  "Adds edge to graph. Returns true if the addition suceeded. Note that this
+  function is not immutable, changing the graph state."
   [^Graph graph edge]
   (let [[a b] edge]
     (.addEdge graph (edge->j-edge edge) a b)))

 (defn remove-edge!
+  "Removes edge from graph. Returns true if the removal suceeded. Note that this
+  function is not immutable, changing the graph state."
   [^Graph graph edge]
   (.removeEdge graph (edge->j-edge edge)))

 (defn contains-edge?
+  "Returns true if graph's edge collection contains edge."
   [^Hypergraph graph edge]
   (.containsEdge graph (edge->j-edge edge)))

 (defn nodes
+  "Returns all nodes in graph as set."
   [^Graph graph]
   (set (.getVertices graph)))

 (defn edges
+  "Returns all edges in graph."
   [^Graph graph]
   (map (partial j-edge->edge graph) (.getEdges graph)))

 (defn in-edges
+  "Returns incoming edges incident to node in graph."
   [^Graph graph node]
   (map (partial j-edge->edge graph) (.getInEdges graph node)))

 (defn degree
+  "Returns the number of edges incident to node."
   [^Hypergraph graph node]
   (.degree graph node))

 (defn in-degree
+  "Returns the number of incoming edges incident to node."
   [^Hypergraph graph node]
   (.inDegree graph node))

 (defn out-degree
+  "Returns the number of outgoing edges incident to node."
   [^Hypergraph graph node]
   (.outDegree graph node))


can make lists and vectors

can make lists and vectors

--- src/k_means/vector.clj
+++ src/k_means/vector.clj
@@ -28,3 +28,22 @@
       (<= n 0) c
       :else
         (recur (dec n) (conj c [])))))
+
+
+(defn make-list-rand
+  "create a vector containing n cols populated with random data"
+  ([n] (make-vector-rand n '()))
+  ([n c]
+  (cond
+    (<= n 0) c
+    :else
+      (recur (dec n) (conj c '((rand-int 50000) (rand-int 50000)))))))
+
+(defn make-list
+  "create a vector containing n cols"
+  ([n] (make-vector n []))
+  ([n c]
+    (cond
+      (<= n 0) c
+      :else
+        (recur (dec n) (conj c '())))))


Interchanged layout labeling

Interchanged layout labeling

fixed that.

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

--- src/conexp/layout/base.clj
+++ src/conexp/layout/base.clj
@@ -156,7 +156,9 @@
   (apply str (interpose ", " set)))

 (def-layout-fn annotation
-  "Returns the annotation of this layout."
+  "Returns the annotation of this layout as hash-map of nodes to
+  pairs, where the first entry is the upper label and second one is
+  the lower label."
   [layout]
   (if-not (concept-lattice-layout? layout)
     (hashmap-by-function (fn [x] [x ""]) (nodes layout))
@@ -164,9 +166,9 @@
 	  lowers (lower-neighbours layout)]
       (hashmap-by-function (fn [node]
 			     [(set-to-label
-			       (apply difference (first node) (map first (lowers node))))
+			       (apply difference (second node) (map second (uppers node))))
 			      (set-to-label
-			       (apply difference (second node) (map second (uppers node))))])
+			       (apply difference (first node) (map first (lowers node))))])
 			   (nodes layout)))))

 ;;;


Changed error message when missing required project.

--- src/leiningen/core.clj
+++ src/leiningen/core.clj
@@ -136,7 +136,9 @@
   (:arglists (meta (resolve-task task-name))))

 (defn- project-needed? [parameters]
-  (= 'project (first parameters)))
+  (if (vector? parameters)
+    (= 'project (first parameters))
+    (every? project-needed? parameters)))

 (defn- arg-count [parameters project]
   (if (and project (project-needed? parameters))
@@ -159,8 +161,11 @@
       (if (project-needed? parameters)
         (apply task project args)
         (apply task args))
-      (abort "Wrong number of arguments to" task-name "task."
-             "\nExpected"  (arglists task-name)))))
+      (let [args (arglists task-name)]
+        (if (and (not project) (project-needed? args))
+          (abort "Couldn't find project.clj, which is needed for" task-name)
+          (abort "Wrong number of arguments to" task-name "task."
+                 "\nExpected" args))))))

 (def arg-separator ",")


build-deps recurses using itself instead of just install

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -242,7 +242,8 @@

 (defn install-versioned-artifact
   [proot]
-  ;; TODO: voom build-deps first, then wrap install:
+  (println "Calling recursive build-deps on:" proot)
+  (print (:out (sh "lein" "voom" "build-deps" :dir proot)))
   (let [install-cmd ["lein" "voom" "wrap" "install" :dir proot]
         _ (apply println "install-versioned-artifact:" install-cmd)
         rtn (apply sh install-cmd)]


Got in and out reversed

Got in and out reversed

--- src/lazubot/worker.clj
+++ src/lazubot/worker.clj
@@ -11,7 +11,7 @@
     (register-socket! {:in reply-in :out reply-out :socket-type :rep
                        :configurator (fn [socket] (.connect socket addr))})
     (go-loop []
-             (when-let [message (<! reply-in)]
-               (>! reply-out message)
+             (when-let [message (<! reply-out)]
+               (>! reply-in message)
                (recur)))
     (println "Worker initialized")))


fix closure issue in tag-pill-view

fix closure issue in tag-pill-view

--- src/braid/ui/views/pills.cljs
+++ src/braid/ui/views/pills.cljs
@@ -22,20 +22,27 @@

 (defn tag-pill-view
   [tag-id]
-  (let [tag (subscribe [:tag tag-id])
+  (let [tag-id-atom (r/atom tag-id)
+        tag (subscribe [:tag] [tag-id-atom])
         open-group-id (subscribe [:open-group-id])
-        user-subscribed-to-tag? (subscribe [:user-subscribed-to-tag tag-id])]
-    (fn []
-      (let [path (routes/tag-page-path {:group-id @open-group-id
-                                        :tag-id (@tag :id)})
-            color (id->color (@tag :id))]
-        [:a.tag.pill {:class (if @user-subscribed-to-tag? "on" "off")
-                      :tabIndex -1
-                      :style {:background-color color
-                              :color color
-                              :border-color color}
-                      :href path}
-          [:div.name "#" (@tag :name)]]))))
+        user-subscribed-to-tag? (subscribe [:user-subscribed-to-tag] [tag-id-atom])]
+    (r/create-class
+      {:display-name "tag-pill-view"
+       :component-will-receive-props
+       (fn [_ [_ new-tag-id]]
+         (reset! tag-id-atom new-tag-id))
+       :reagent-render
+       (fn [tag-id]
+         (let [path (routes/tag-page-path {:group-id @open-group-id
+                                           :tag-id (@tag :id)})
+               color (id->color (@tag :id))]
+           [:a.tag.pill {:class (if @user-subscribed-to-tag? "on" "off")
+                         :tabIndex -1
+                         :style {:background-color color
+                                 :color color
+                                 :border-color color}
+                         :href path}
+            [:div.name "#" (@tag :name)]]))})))

 (defn user-pill-view


small fix

small fix

--- src/cljs/salava/core/ui/badge_grid.cljs
+++ src/cljs/salava/core/ui/badge_grid.cljs
@@ -77,9 +77,9 @@
                                  ]]
                                 [:div {:class (str "media-content " (if expired? "media-expired") (if revoked " media-revoked"))}
                                  [:a {:href "#" :on-click #(do
-                                                             (.replaceState js/history "" "Badge modal" (str "/badge/" id))
+                                                             (.replaceState js/history "" "Badge modal" (path-for (str "/badge/" id)))
                                                              (mo/open-modal [:badge :info] {:badge-id id} {:hide (fn []
-                                                                                (.replaceState js/history "" "Badge modal" "/badge")
+                                                                                (.replaceState js/history "" "Badge modal" (path-for "/badge"))
                                                                                (init-data state))}))}
                                   [:div.icons
                                      [:div.visibility-icon.inline


renamed some variables for sanity's sake

--- src/clojure/staircase/views/history.clj
+++ src/clojure/staircase/views/history.clj
@@ -55,7 +55,7 @@
    current-history
    (staircase.views.facets/snippet)])

-(defn centre-column [config]
+(defn right-column [config]
   [:div.sidebar.slide-right.col-xs-12.col-md-2.col-md-offset-10
    {:ng-class "{onscreen: !state.expanded, offscreen: state.expanded}"}
    [:div.panel.panel-default.next-steps
@@ -76,7 +76,7 @@
     [:div.panel-body {:ng-hide "nextSteps.length"}
      [:em "No steps available"]]]])

-(defn right-column [config]
+(defn centre-column [config]
   [:div.col-xs-12.slide-left.central-panel.flex-column
    {:ng-class "{'col-md-8': !state.expanded,
               'col-md-offset-2': !state.expanded}"}
@@ -96,4 +96,5 @@
 (defn snippet [config]
   (html [:div.container-fluid.history-view
          (apply vector :div.row.flex-row
-          ((juxt left-column centre-column right-column) config))]))
+          ;; L R C because of column re-ordering.
+          ((juxt left-column right-column centre-column) config))]))


moving display-features to ml/model

moving display-features to ml/model

--- src/clojure/zensols/nlparse/feature.clj
+++ src/clojure/zensols/nlparse/feature.clj
@@ -6,7 +6,6 @@
   (:require [clojure.tools.logging :as log]
             [clojure.pprint :refer (pprint)])
   (:require [clojure.string :as str])
-  (:require [zensols.tabres.display-results :as dr])
   (:require [zensols.nlparse.wordnet :as wn]
             [zensols.nlparse.parse :as pt]))

@@ -292,18 +291,3 @@
        (filter #(> (second %) 0))
        (take num-counts)
        (map first)))
-
-
--
-;; visualization
-(defn display-features [classifier-attributes class-attribute feature-sets]
-  (let [keys (map first (concat (list class-attribute) classifier-attributes))]
-   (->> feature-sets
-        (map (fn [tok]
-               (map (fn [tkey]
-                      (get tok tkey))
-                    keys)))
-        ((fn [data]
-           (dr/display-results data
-                               :column-names (map name keys)))))))


'git splits its own lines

'git splits its own lines

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -24,7 +24,8 @@
         rtn (apply sh "git" all-args)]
     (when-not (zero? (:exit rtn))
       (throw (ex-info "git error" (assoc rtn :git all-args))))
-    rtn))
+    (assoc rtn :lines (when (not= "\n" (:out rtn))
+                        (re-seq #"(?m)^.*$" (:out rtn))))))

 ;; === git sha-based versions ===

@@ -98,10 +99,8 @@

 (defn find-project-files
   [^File d]
-  (let [{:keys [out err exit]} (git {:gitdir d} "ls-files" "project.clj" "**/project.clj")
-        projects (when-not (empty? out)
-                   (s/split-lines out))]
-    (map #(str (.getParent d) "/" %) projects)))
+  (let [{:keys [lines]} (git {:gitdir d} "ls-files" "project.clj" "**/project.clj")]
+    (map #(str (.getParent d) "/" %) lines)))

 (defn contains-sha? [d sha]
   (prn "contains-sha?" d sha)
@@ -287,9 +286,8 @@
                   qprj)
         git-ptn (str #"\(defproject\s+" prj-ptn #"\s+\"" ver-ptn \")
         _ (prn :git-ptn git-ptn)
-        r (git {:gitdir gitdir} "log" "--name-only" "--all" "--pretty=format:%H"
-                 "-G" git-ptn "--" "project.clj" "**/project.clj")
-        lines (s/split-lines (:out r))]
+        {:keys [lines]} (git {:gitdir gitdir} "log" "--name-only" "--all" "--pretty=format:%H"
+                             "-G" git-ptn "--" "project.clj" "**/project.clj")]
     (->> lines
          (reductions (fn [[sha v] line]
                        (cond
@@ -315,7 +313,7 @@
   [gitdir]
   (let [r (git {:gitdir gitdir} "log" "--name-only" "--all"
                "--pretty=format:%H" "--" "project.clj" "**/project.clj")]
-    (->> (s/split-lines (:out r))
+    (->> (:lines r)
          (reductions (fn [[sha v] line]
                        (cond
                         (empty? line) [nil nil]
@@ -427,8 +425,7 @@
   [gitdir]
   (->
    (git {:gitdir gitdir} "ls-files" "project.clj" "**/project.clj")
-   :out
-   s/split-lines))
+   :lines))

 (defn box-add
   [proj & args]


'freshen supports pinning by version spec

Updated API for format-voom-ver to support -SNAPSHOT trimming

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -49,16 +49,15 @@
     {:ctime ctime :sha sha}))

 (defn format-voom-ver
-  [gver fmt]
-  (let [{:keys [ctime sha]} gver]
-    (str "-" (formatted-timestamp fmt ctime) "-g" sha)))
-
+  [gver]
+  (let [{:keys [ver ctime sha]} gver]
+    (str (s/replace ver #"-SNAPSHOT" "")
+         "-" (formatted-timestamp timestamp-fmt ctime) "-g" sha)))

 (defn update-proj-version
   [project long-sha?]
   (let [gver (-> project :root (get-voom-version :long-sha? long-sha?))
-        qual (format-voom-ver gver timestamp-fmt)
-        upfn #(str (s/replace % #"-SNAPSHOT" "") qual)
+        upfn #(format-voom-ver (assoc gver :ver %))
         nproj (update-in project [:version] upfn)
         nmeta (update-in (meta project) [:without-profiles :version] upfn)
         nnproj (with-meta nproj nmeta)]
@@ -139,6 +138,8 @@
   "[project {groupId name ctime sha}] [project coordinate-string]"
   [repos-dir pspec]
   (prn "find-matching-projects" repos-dir pspec)
+  ;; TODO: find correct sha and project.clj more efficiently and with
+  ;; less ambiguity. (only consider projects changed at the given sha)
   (let [{:keys [sha artifactId groupId]} pspec
         dirs (all-repos-dirs)
         sha-candidates (locate-sha dirs sha)
@@ -446,27 +447,23 @@
                  :branch branch}))
             (partition 2 1 (concat commits [:end]))))))

-;; Add metadata pinning (how big to bump? all? minor? sha?) -- warn about not updating
-;; Opt-in autobump  -- default to no major auto
-(defn get-fresh-versions []
-  (let [dirs (all-repos-dirs)
-        _ (fetch-checkout-all dirs)]
-    (into {}
-          (for [dir dirs
-                prj-file (find-project-files dir)]
-            (let [{:keys [group name version] :as prj} (project/read prj-file)
-                  gver (get-voom-version (:root prj) :gitdir dir)
-                  qual (format-voom-ver gver timestamp-fmt)
-                  new-ver (str (s/replace version #"-SNAPSHOT" "") qual)]
-              [(symbol group name) new-ver])))))
-
-(defn fresh-version [fresh-versions-map [prj ver :as dep]]
-  (if-let [new-ver (get fresh-versions-map prj)]
-    (assoc dep 1 new-ver)
-    (do
-      (when (ver-parse ver)
-        (println "Warning: didn't find or freshen voom-version dep" dep))
-      dep)))
+(defn fresh-version [[prj ver :as dep]]
+  (let [voom-meta (:voom-bump (meta dep))
+        ver-spec (or (:version voom-meta)
+                     (re-find #"^[^.]+." ver))
+        groups (->> (newest-voom-ver-by-spec prj ver-spec voom-meta)
+                    (map #(assoc % :voom-ver (format-voom-ver
+                                              (update-in % [:sha] subs 0 7))))
+                    (group-by :voom-ver))]
+    (case (count groups)
+     0 (do (println "No matching version found for" prj (pr-str ver-spec))
+           dep)
+     1 (assoc dep 1 (key (first groups)))
+     (do (println "\nMultiple bump resolutions for:"
+                  prj (pr-str ver-spec) (pr-str voom-meta))
+         (doseq [[voom-ver group] groups]
+           (prn voom-ver (map #(select-keys % [:gitdir :branch :path :ctime]) group)))
+         dep))))

 (defn rewrite-project-file [input-str replacement-map]
   (reduce (fn [^String text [[prj old-ver :as old-dep] [_ new-ver]]]
@@ -488,8 +485,7 @@
 (defn freshen [project & args]
   (let [prj-file-name (str (:root project) "/project.clj")
         old-deps (:dependencies project)
-        fresh-versions-map (get-fresh-versions)
-        desired-new-deps (map #(fresh-version fresh-versions-map %) old-deps)]
+        desired-new-deps (doall (map #(fresh-version %) old-deps))]
     (doseq [[[prj old-ver] [_ new-ver]] (map list old-deps desired-new-deps)]
       (println (format "%-40s" prj)
                (str old-ver


Fix #1

Fix #1

--- src/tailrecursion/boot/task/ring.clj
+++ src/tailrecursion/boot/task/ring.clj
@@ -1,5 +1,6 @@
 (ns tailrecursion.boot.task.ring
   (:require
+   [clojure.java.io                :as io]
    [tailrecursion.boot.core        :as core]
    [ring.adapter.jetty             :as jetty]
    [ring.middleware.session        :as session]
@@ -21,10 +22,9 @@

 (core/deftask files
   [& [docroot]]
-  (let [out (core/get-env :out-path)]
-    (ring-task #(-> %
-                  (file/wrap-file (or docroot out))
-                  (file-info/wrap-file-info)))))
+  (let [root (or docroot (core/get-env :out-path))]
+    (.mkdirs (io/file root))
+    (ring-task #(-> (file/wrap-file % root) (file-info/wrap-file-info)))))

 (core/deftask head
   []


Code that has been tested and 100% works.

--- src/divergence/system.cljs
+++ src/divergence/system.cljs
@@ -9,23 +9,7 @@
     {:id id :timepoints time-point}
     )
   (defn time-stream [time-line id]
-    {:id id :timelines time-line})
-)
-
-(def serial-data (atom ""))
-
-(defn save-to-local-db [data]
-  (.setItem js/localStorage "dm" data))
-
-(defn serialize [entities]
-  (doseq [e entities]
-    (if (= ":bunny" (pr-str (@e :name)))
-      (save-to-local-db (dissoc @e :ref :sprite :stage)))))
-
-(defn deserialize [entities]
-   (doseq [e entities
-           :when (= :bunny (@e :name))]
-     (reset! e (read-string (.getItem js/localStorage "dm")))))
+    {:id id :timelines time-line}))

 (defn as [entity k]
   (@entity k))
@@ -48,19 +32,10 @@
             y-future (move-entity @e [0 y-v 0])]
         (when (< 1 (count (filter (partial phys/colliding? x-future) es)))
           (swap! e assoc-in [:velocity 0] 0)
-          (swap! e assoc-in [:can-climb] 1) ;when character hits wall, can climb
-          ;(js/alert (count (filter (partial phys/colliding? x-future) es)))
-          )
+          (swap! e assoc-in [:can-climb] 1)) ;when character hits wall, can climb
         (when (< 1 (count (filter (partial phys/colliding? y-future) es)))
           (swap! e assoc-in [:velocity 1] 0)
-          (swap! e assoc-in [:can-jump] 1))
-        (if (and (= (@e :can-climb 1)) (< 2 (count (filter (partial phys/colliding? x-future) es))))
-          (
-        ;(when (= 2 (count (filter (partial phys/colliding? x-future) es)))
-          ;(js/alert (count (filter (partial phys/colliding? x-future) es)))
-          ;(swap! e assoc-in [:gravity] [0 0.2 0])
-          (swap! e assoc-in [:can-climb] 0)
-        ))))))
+          (swap! e assoc-in [:can-jump] 1))))))

 (defn push [entities player]


Make sure year also works with java.util.Date

which is provided by edn when reading an #inst

--- src/catalog/layout/common.clj
+++ src/catalog/layout/common.clj
@@ -146,9 +146,12 @@
                       (.withLocale Locale/GERMAN))]
     (time/format formatter (time/local-date year (* issue 2)))))

-(defn year [date]
+(defn year
+  "Grab the year out of `date` which can be a `time/local-date` or for
+  legacy reasons also a `java.util.Date`"
+  [date]
   (when date
-    (time/as date :year)))
+    (time/as (time/local-date date (time/zone-id "UTC")) :year)))

 (defn periodify
   "Add a period to the end of `s` if it is not nil and doesn't end in


Move the books under a new heading for Braille

The top level heading are now "Editorial", "Buchtipps" and "Neue
Braillebücher".

--- src/catalog/layout/dtbook.clj
+++ src/catalog/layout/dtbook.clj
@@ -49,8 +49,8 @@

 (defn subgenre-entry [subgenre items]
   (when-let [items (subgenre items)]
-    [:level2
-     [:h2 (layout/translations subgenre "FIXME")]
+    [:level3
+     [:h3 (layout/translations subgenre "FIXME")]
      (catalog-entries items)]))

 (defn subgenre-entries [items]
@@ -58,8 +58,8 @@

 (defn genre-entries [genre items]
   (when-let [items (genre items)]
-    [:level1
-     [:h1 (layout/translations genre "FIXME")]
+    [:level2
+     [:h2 (layout/translations genre "FIXME")]
      (cond
        (#{:kinder-und-jugendbücher} genre) (subgenre-entries items)
        :else (catalog-entries items))]))
@@ -94,7 +94,9 @@
       [:p {:brl:class (format "jr_%s" (layout/year date))}]]]
     [:bodymatter
      [:level1 [:h1 "Editorial"] [:p "..."]]
-     (for [genre layout/braille-genres] (genre-entries genre items))]]])
+     [:level1 [:h1 "Buchtipps"] [:p "..."]]
+     [:level1 [:h1 "Neue Braillebücher"]
+      (for [genre layout/braille-genres] (genre-entries genre items))]]]])

 (defn dtbook
   [items]


add a new site admin setting allowing the user to specify their smtp should connect securely using tls or ssl, and wire that setting into our mail sending approach.

--- src/metabase/email.clj
+++ src/metabase/email.clj
@@ -11,6 +11,7 @@
 (defsetting email-smtp-username "SMTP username.")
 (defsetting email-smtp-password "SMTP password.")
 (defsetting email-smtp-port "SMTP port." "587")
+(defsetting email-smtp-security "SMTP secure connection protocol. (tls, ssl, or none)" "none")

 ;; ## PUBLIC INTERFACE

@@ -43,10 +44,14 @@
     (when-not (email-smtp-password)
       (throw (Exception. "SMTP password is not set.")))
     ;; Now send the email
-    (let [{error :error error-message :message} (*send-email-fn* {:host (email-smtp-host)
-                                                                  :user (email-smtp-username)
-                                                                  :pass (email-smtp-password)
-                                                                  :port (Integer/parseInt (email-smtp-port))}
+    (let [{error :error error-message :message} (*send-email-fn* (-> {:host (email-smtp-host)
+                                                                      :user (email-smtp-username)
+                                                                      :pass (email-smtp-password)
+                                                                      :port (Integer/parseInt (email-smtp-port))}
+                                                                     (merge (case (keyword (email-smtp-security))
+                                                                              :tls {:tls true}
+                                                                              :ssl {:ssl true}
+                                                                              {})))
                                                                  {:from    (email-from-address)
                                                                   :to      recipients
                                                                   :subject subject


added ability to close open/focused thread with escape key

--- src/chat/client/views/threads.cljs
+++ src/chat/client/views/threads.cljs
@@ -85,6 +85,8 @@
                         :onKeyUp (fn [e]
                                    (when (and (= KeyCodes.X (.-keyCode e))
                                            (.-ctrlKey e))
+                                   (when (or (and (= KeyCodes.X (.-keyCode e))
+                                           (.-ctrlKey e)) (= KeyCodes.ESC (.-keyCode e)))
                                      (.preventDefault e)
                                      (.stopPropagation e)
                                      (dispatch! :hide-thread {:thread-id (thread :id)})))


removed whitespace.

removed whitespace.

--- src/clj/forma/hadoop/predicate.clj
+++ src/clj/forma/hadoop/predicate.clj
@@ -6,7 +6,6 @@
         [forma.matrix.utils :only (sparse-vector matrix-of)])
   (:require [cascalog.ops :as c]
             [cascalog.vars :as v]))
-

 ;; ### Cascalog Helpers

@@ -90,3 +89,4 @@
                 (construct (swap [nextpos outpos outval])
                            [[src :>> (swap [inpos nextpos inval])]
                             [aggr inpos inval :> outpos outval]]))))))
+


remove debug prn

remove debug prn

--- src/clj/shadow/devtools/server.clj
+++ src/clj/shadow/devtools/server.clj
@@ -194,7 +194,6 @@

 (defn shutdown-css [{:keys [css-packages] :as state}]
   (doseq [{:keys [dirty-check] :as pkg}  css-packages]
-    (prn [:shutdown-pkg pkg])
     (.close dirty-check)))

 (defn- send-to-clients-of-type [state client-type msg]


fix for the method and cred type defs

fix for the method and cred type defs

--- cloudstack/config/src/com/sixsq/slipstream/ssclj/resources/credential_template_cloud_cloudstack.clj
+++ cloudstack/config/src/com/sixsq/slipstream/ssclj/resources/credential_template_cloud_cloudstack.clj
@@ -8,8 +8,8 @@
     [com.sixsq.slipstream.ssclj.resources.credential-template :as p]
     [com.sixsq.slipstream.ssclj.resources.spec.credential-template-cloud-cloudstack]))

-(def ^:const credential-type "cloud-cred-" ct/cloud-service-type)
-(def ^:const method "store-cloud-cred-" ct/cloud-service-type)
+(def ^:const credential-type (str "cloud-cred-" ct/cloud-service-type))
+(def ^:const method (str "store-cloud-cred-" ct/cloud-service-type))

 (def resource-acl {:owner {:principal "ADMIN"
                            :type      "ROLE"}


Make type hint more generic as it causes drafter to fail

--- src/grafter/rdf/sesame.clj
+++ src/grafter/rdf/sesame.clj
@@ -18,7 +18,7 @@
                                    NumericLiteralImpl StatementImpl
                                    URIImpl)
            (org.openrdf.query BooleanQuery GraphQuery QueryLanguage
-                              TupleQuery Update BindingSet)
+                              Query TupleQuery Update BindingSet)
            (org.openrdf.query.impl DatasetImpl)
            (org.openrdf.repository Repository RepositoryConnection)
            (org.openrdf.repository.http HTTPRepository)
@@ -536,7 +536,7 @@

 (defn- sesame-results->seq
   ([prepared-query] (sesame-results->seq prepared-query identity))
-  ([^TupleQuery prepared-query converter-f]
+  ([^Query prepared-query converter-f]
      (let [^CloseableIteration results (.evaluate prepared-query)
            run-query (fn pull-query []
                        (if (.hasNext results)


implement 4 Business First assets

implement 4 Business First assets

Lakshmi Smartfabrics, Mumbad Construction Co., Palana Agroplex, PAD Factory

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -378,6 +378,30 @@
                  :effect (effect (mill :runner)
                                  (trash card {:cause :ability-cost}))}]}

+   "Lakshmi Smartfabrics"
+   {:events {:rez {:req (req (not= (:cid card) (:cid target)))
+                   :effect (effect (add-prop card :counter 1))}}
+    :abilities [{:req (req (seq (filter #(and (is-type? % "Agenda")
+                                              (= (get card :counter 0) (:agendapoints %))) (:hand corp))))
+                 :label "X power counters: Reveal an agenda worth X points from HQ"
+                 :effect (req (let [c (:counter card)]
+                                (resolve-ability
+                                  state side
+                                  {:prompt "Choose an agenda in HQ"
+                                   :choices {:req #(and (is-type? % "Agenda")
+                                                        (= c (:agendapoints %)))}
+                                   :msg (msg "reveal " (:title target) " from HQ")
+                                   :effect (req (let [title (:title target)
+                                                      pts (:agendapoints target)]
+                                                  (register-turn-flag! state side
+                                                    card :can-steal
+                                                    (fn [state side card]
+                                                      (if (= (:title card) title)
+                                                        ((constantly false)
+                                                         (toast state :runner "Cannot steal due to Lakshmi Smartfabrics." "warning"))
+                                                        true)))
+                                                  (add-prop state side card :counter (- pts))))} card nil)))}]}
+
    "Launch Campaign"
    (campaign 6 2)

@@ -453,6 +477,19 @@

    "Mumba Temple"
    {:recurring 2}
+
+   "Mumbad Construction Co."
+   {:derezzed-events {:runner-turn-ends corp-rez-toast}
+    :events {:corp-turn-begins {:effect (effect (add-prop card :advance-counter 1 {:placed true}))}}
+    :abilities [{:cost [:credit 2]
+                 :req (req (and (> (get card :advance-counter 0) 0)
+                                (some #(rezzed? %) (all-installed state :corp))))
+                 :label "Move an advancement token to a faceup card"
+                 :prompt "Choose a faceup card"
+                 :choices {:req #(rezzed? %)}
+                 :msg (msg "move an advancement token to " (card-str state target))
+                 :effect (effect (add-prop card :advance-counter -1 {:placed true})
+                                 (add-prop target :advance-counter 1 {:placed true}))}]}

    "Museum of History"
    {:flags {:corp-phase-12 (req (pos? (count (get-in @state [:corp :discard]))))}
@@ -505,6 +542,29 @@
    {:derezzed-events {:runner-turn-ends corp-rez-toast}
     :events {:corp-turn-begins ability}
     :abilities [ability]})
+
+   "PAD Factory"
+   {:abilities [{:cost [:click 1]
+                 :label "Place 1 advancement token on a card"
+                 :choices {:req #(and (:side % "Corp") (installed? %))}
+                 :msg (msg "place 1 advancement token on " (card-str state target))
+                 :effect (effect (add-prop target :advance-counter 1 {:placed true})
+                                 (register-turn-flag!
+                                   target :can-score
+                                   (fn [state side card]
+                                     (if (>= (:advance-counter card) (or (:current-cost card) (:advancementcost card)))
+                                       ((constantly false) (toast state :corp "Cannot score due to PAD Factory." "warning"))
+                                       true))))}]}
+
+   "Pālanā Agroplex"
+   (let [ability {:msg "make each player draw 1 card"
+                  :label "Make each player draw 1 card (start of turn)"
+                  :once :per-turn
+                  :effect (effect (draw 1) (draw :runner))}]
+     {:derezzed-events {:runner-turn-ends corp-rez-toast}
+      :flags {:corp-phase-12 (req true)}
+      :events {:corp-turn-begins ability}
+      :abilities [ability]})

    "Plan B"
    (advance-ambush


Fix non-potable water health drain

Fix non-potable water health drain

--- src/cljc/robinson/update.cljc
+++ src/cljc/robinson/update.cljc
@@ -1463,7 +1463,7 @@
   ([state]
   (-> state
     (update-in [:world :player :thirst] (fn [thirst] (min 0 (- thirst 10))))
-    (rp/player-update-hp (fn [hp] (max (- hp 10) 0)))
+    (rp/player-update-hp (fn [hp] (max (- hp 1) 0)))
     (rw/assoc-current-state :normal)))
   ([state {x :x y :y}]
   (if-let [water (get (rw/get-cell state x y) :water)]


separate header from tabs

separate header from tabs

--- src/cljs/go_client/views.cljs
+++ src/cljs/go_client/views.cljs
@@ -106,6 +106,10 @@
    {:id :game-list :label "Game List"}
    {:id :game-panel :label "Game"}])

+(defn header []
+  (let [server-state (re-frame/subscribe [:server-state])]
+    (fn [] [state-panel @server-state])))
+
 (defn tabs []
   (let [selected-panel (re-frame/subscribe [:active-panel])]
     [re-com/horizontal-tabs


Works directly calling JS

Works directly calling JS

+ uses native js api
+ no error handling
+ works with a channel

Can probably get goog xhr working now (maybe) rather than write all my
own error handling nonsense

* add this as an image into the dom

--- src/cljs/my_project/core.cljs
+++ src/cljs/my_project/core.cljs
@@ -42,7 +42,7 @@

     [goog.crypt             :as crypt]
     [goog.crypt.base64      :as b64]
-    [goog.labs.net.xhr      :as xhr2]
+    ; [goog.labs.net.xhr      :as xhr2]

     [om.core                :as om :include-macros true]
     [om.dom                 :as dom :include-macros true]))
@@ -57,104 +57,37 @@

 (def file-name "/data/tiles.png")

-
-
-(defprotocol IBytesPlz
-  (get-str [_])
-  (get-b64 [_])
-  (get-bytes [_ ]))
-; var utf8 = unescape(encodeURIComponent(str));
-
-; var arr = [];
-; for  var i = 0; i < utf8.length; i++) {
-;     arr.push(utf8.charCodeAt(i));
-
-(defn get-bytes-str [this]
-  (let [ret (js/Uint8ClampedArray. (count this))]
-    (doseq [i (range (count this))]
-      (let [c (.charCodeAt this i)]
-
-        (aset ret i (bit-and 0xff(if (< c 0)
-                      (- 65536 c)
-                      c)) )))
-    ret
-    ))
+(defprotocol IABitNicer
+  (get-status [_])
+  (okay? [_])
+  (get-blob! [_ uri cb]))

 (extend-type js/XMLHttpRequest
-  IBytesPlz
-
-  (get-str [this]
-    (.-responseText this))
-
-  (get-b64 [this]
-    (->
-      this
-      (get-bytes)
-      (b64/encodeByteArray)))
-
-  (get-bytes [this]
-    (->
-      this
-
-      ; (get-str)
-      ; (get-bytes-str)
-      (get-str)
-      (crypt/stringToUtf8ByteArray)
-      )))
-
-
-
-(def opts #js {"Content-type" "text/plain;charset=x-user-defined"
-               "responseType" "blob"})
-
-; (def ret (xhr2/send "GET" file-name nil opts))
-
-
-; (.then ret (fn [r]
-;              (let [arr (get-bytes r)
-;                    enc (get-b64 r)
-;                    ostr (get-str r) ]
-
-;                (println (.charCodeAt ostr 0))
-;                (println (.charCodeAt ostr 1))
-;                (log-js (get-bytes-str ostr))
-
-;                )
-
-;              ))
-
-
-(defn rep-array [arr]
-  (str "size: " (.-length arr) "\n"
-       "type: " (type arr) "\n"))
-
-(defn gaz-send [uri cb]
-  (let [xhr (js/XMLHttpRequest.) ]
+  IABitNicer
+  (get-status [this] (.-status this))
+  (okay? [this] (== 200 (get-status this)))
+
+  (get-blob! [xhr uri cb]
     (do
       (.open xhr "GET" uri true)
-      (.overrideMimeType xhr "text/plain; charset=x-user-defined")
-      (aset xhr "onreadystatechange"
-            (fn [e]
-              (let [ready-state (.-readyState xhr)
-                    status (.-status xhr)
-                    arr (get-bytes-str (.-responseText xhr)) ]
-                (when (and (== ready-state 4) (== status 200))
-                  (cb arr)
-                  )
-                )))
+      (aset xhr "responseType" "blob")
+      (aset xhr "onload" (fn [r]
+                           (when (okay? xhr)
+                             (cb (.-response xhr)))))
       (.send xhr))))

-
-(gaz-send file-name (fn [i]
-                      (log-js i)
-                      ))
-
-
-
-
-
-
-
+(defn load! [uri]
+  (let [ret-chan (chan)]
+    (-> (js/XMLHttpRequest.)
+        (get-blob! uri #(put! ret-chan %)))
+    ret-chan))
+
+(do
+  (go
+    (let [load-chan (load! file-name)
+          blob (<! load-chan)]
+      (log-js "Got blob!")
+      (log-js blob))))

 ;; }}}


fix balance

fix balance

--- src/cljs/takarabako/core.cljs
+++ src/cljs/takarabako/core.cljs
@@ -106,7 +106,7 @@
            (if (= type :expense)
              (* -1 value)
              (* 1 value))))
-        (map #(/ % 10))))
+        (map #(/ % 100))))

 (defn mean-reducer [memo x]
   (-> memo


Added initial code for novelty

Added initial code for novelty

--- src/clojush/pushgp/pushgp.clj
+++ src/clojush/pushgp/pushgp.clj
@@ -186,6 +186,10 @@
           ;; calculate epsilons for epsilon lexicase selection
           (when (= (:parent-selection @push-argmap) :epsilon-lexicase)
             (calculate-epsilons-for-epsilon-lexicase pop-agents @push-argmap))
+          ;; calculate novelty when necessary
+          (when (or (= (:parent-selection @push-argmap))
+                    (some #{:novelty} (:meta-error-categories @push-argmap)))
+            (calculate-novelty pop-agents @push-argmap)) ;REF haven't defined yet
           (timer @push-argmap :other)
           ;; report and check for success
           (let [[outcome best] (report-and-check-for-success (vec (doall (map deref pop-agents)))


CMR-677: Return errors in the xml format for requests with accept headers indicating xml; otherwise use JSON format.

--- src/cmr/common/api/errors.clj
+++ src/cmr/common/api/errors.clj
@@ -1,5 +1,6 @@
 (ns cmr.common.api.errors
-  (:require [cmr.common.log :refer [error]]))
+  (:require [cmr.common.log :refer [error]]
+            [clojure.data.xml :as x]))

 (def type->http-status-code
   {:not-found 404
@@ -11,6 +12,18 @@
 (def internal-error-ring-response
   {:status 500 :body {:errors ["An Internal Error has occurred."]} :content-type :json})

+(defn- response-type-body
+  "Returns the response content-type and body for the given errors and format"
+  [errors xml-format?]
+  (let [content-type (if xml-format? "application/xml" "application/json")
+        body (if xml-format?
+               (x/indent-str
+                 (x/element :errors {}
+                            (for [err errors]
+                              (x/element :error {} err))))
+               {:errors errors})]
+    [content-type body]))
+
 (defn exception-handler
   "A ring exception handler that will handle errors thrown by the cmr.common.services.errors
   functions."
@@ -20,11 +33,14 @@
       (catch clojure.lang.ExceptionInfo e
         (let [data (ex-data e)]
           (if (:type data)
-            (let [{:keys [type errors]} data
-                  status-code (type->http-status-code type)]
+            (let [accept-format (get-in request [:headers "accept"])
+                  xml-format? (when accept-format (re-find #"xml" accept-format))
+                  {:keys [type errors]} data
+                  status-code (type->http-status-code type)
+                  [content-type response-body] (response-type-body errors xml-format?)]
               {:status status-code
-               :headers {"Content-Type" "application/json"}
-               :body {:errors errors}})
+               :headers {"Content-Type" content-type}
+               :body response-body})
             (do
               (error e)
               internal-error-ring-response))))


Basic Fetch

Basic Fetch

--- src/hackernews/events.cljs
+++ src/hackernews/events.cljs
@@ -1,6 +1,6 @@
 (ns hackernews.events
   (:require
-   [re-frame.core :refer [reg-event-db after reg-event-fx reg-cofx reg-fx]]
+   [re-frame.core :refer [reg-event-db after reg-event-fx reg-cofx reg-fx dispatch]]
    [ajax.core :as ajax]
    [clojure.spec :as s]
    [hackernews.navigation :as ios-nav]
@@ -54,16 +54,14 @@
  validate-spec
  (fn [cofx [_ stories]]
    {:db (-> (update (:db cofx) :stories #(concat % stories))
-            (update-in [:front-page :current-page-num] inc))
-    }))
+            (update-in [:front-page :current-page-num] inc))}))

 (reg-event-fx
  :failed-loading-front-page-stories
  validate-spec
  (fn [cofx [_ error-response]]
    (throw (ex-info (str error-response "Failed loading stories") {:response error-response}))
-   {:db (:db cofx)}
-   ))
+   {:db (:db cofx)}))

 (reg-event-fx
  :loaded-story-comments
@@ -77,19 +75,47 @@

 (def hn-api "https://node-hnapi.herokuapp.com")

+(defn- url-encode
+  [string]
+  (some-> string str (js/encodeURIComponent) (.replace "+" "%20")))
+
+(defn- map->query
+  [m]
+  (some->> (seq m)
+           sort
+           (map (fn [[k v]]
+                  [(url-encode (name k))
+                   "="
+                   (url-encode (str v))]))
+           (interpose "&")
+           flatten
+           (apply str)))
+
 (defn fetch
-  [url params on-success]
-  (-> (js/fetch (str hn-api "/news" "?page=1") (clj->js params))
-      (.then js->clj)
-      (.then #(js/console.log %))
-      (.catch #(js/console.error %))))
+  [{:keys [url params method body on-success on-failure] :as request}]
+  (-> (str url "?" (map->query params))
+      (js/fetch (clj->js (select-keys request [:method :body])))
+      (.then #(.json %))
+      (.then #(js->clj % :keywordize-keys true))
+      (.then #(on-success %))
+      (.catch #(on-failure %))))
+
+(reg-fx
+ :fetch-http
+ (fn [{:as   request
+       :keys [url params method on-success on-failure]
+       :or   {on-success      [:http-no-on-success]
+              on-failure      [:http-no-on-failure]}}]
+   (fetch (assoc request
+                 :on-success #(dispatch (conj on-success %))
+                 :on-failure #(dispatch (conj on-failure %))))))

 (reg-event-fx
  :load-front-page-stories
  (fn [{:keys [db]} [_]]
-   {:http-xhrio {:method          :get
-                 :uri             (str hn-api "/news")
-                 :params {:page  (get-in db [:front-page :current-page-num])}
+   {:fetch-http {:method          :get
+                 :url             (str hn-api "/news")
+                 :params  {:page  (get-in db [:front-page :current-page-num])}
                  :timeout         8000
                  :response-format (ajax/json-response-format {:keywords? true})
                  :on-success      [:loaded-front-page-stories]
@@ -98,12 +124,12 @@
 (reg-event-fx
  :load-story-comments
  (fn [{:keys [db]} [_ story-id]]
-   {:http-xhrio {:method          :get
-                 :uri             (str hn-api "/item/" story-id)
-                 :timeout         8000
-                 :response-format (ajax/json-response-format {:keywords? true})
-                 :on-success      [:loaded-story-comments]
-                 :on-failure      [:failed-loading-story-comments]}}))
+   {:fetch-http{:method          :get
+                :url             (str hn-api "/item/" story-id)
+                :timeout         8000
+                :response-format (ajax/json-response-format {:keywords? true})
+                :on-success      [:loaded-story-comments]
+                :on-failure      [:failed-loading-story-comments]}}))

 (reg-event-fx
  :open-story-external


removed old repl namespace

removed old repl namespace

--- src/collabsubtitles/repl.cljs
+++ src/collabsubtitles/repl.cljs
@@ -1,2 +0,0 @@
-(ns collabsubtitles.repl
-  (:require [weasel.repl :as ws-repl]))


Split monolithic users tests in two separated tests.

--- test/uxbox/tests/test_users.clj
+++ test/uxbox/tests/test_users.clj
@@ -12,22 +12,25 @@

 (t/use-fixtures :each th/database-reset)

-(t/deftest test-http-update-and-retrieve-profile
+(t/deftest test-http-retrieve-profile
   (with-open [conn (up/get-conn)]
     (let [user (th/create-user conn 1)]
       ;; Retrieve
       (with-server {:handler (urt/app)}
         (let [uri (str th/+base-url+ "/api/profile/me")
               [status data] (th/http-get user uri)]
-          ;; (println "RESPONSE:" status data)
+          (println "RESPONSE:" status data)
           (t/is (= 200 status))
           (t/is (= (:fullname data) "User 1"))
           (t/is (= (:username data) "user1"))
           (t/is (= (:metadata data) "1"))
           (t/is (= (:email data) "user1@uxbox.io"))
-          (t/is (not (contains? data :password)))))
+          (t/is (not (contains? data :password))))))))

-      ;; Update
+;; Update
+(t/deftest test-http-update-profile
+  (with-open [conn (up/get-conn)]
+    (let [user (th/create-user conn 1)]
       (with-server {:handler (urt/app)}
         (let [uri (str th/+base-url+ "/api/profile/me")
               data (assoc user
@@ -43,5 +46,3 @@
           (t/is (= (:metadata data) "222"))
           (t/is (= (:email data) "user222@uxbox.io"))
           (t/is (not (contains? data :password))))))))
-
-


Add ex-component? and ex-without-components helpers

--- src/com/stuartsierra/component.clj
+++ src/com/stuartsierra/component.clj
@@ -187,6 +187,36 @@
             "system-map requires an even number of arguments")))
   (map->SystemMap (apply array-map keyvals)))

+(defn ex-component?
+  "True if the java.lang.Throwable has ex-data indicating it was
+  thrown by something in the com.stuartsierra.component namespace."
+  [throwable]
+  (let [{:keys [reason]} (ex-data throwable)]
+    (and (keyword? reason)
+         (= "com.stuartsierra.component"
+            (namespace reason)))))
+
+(defn ex-without-components
+  "If the java.lang.Throwable has ex-data provided by the
+  com.stuartsierra.component namespace, returns a new exception
+  instance with the :component and :system removed from its ex-data.
+  Preserves the message, cause, and stacktrace of the original
+  throwable. If the throwable was not created by this namespace,
+  returns it unchanged. Use this when you want to catch and rethrow
+  exceptions without including the full component or system."
+  [^Throwable throwable]
+  (if (ex-component? throwable)
+    (let [^Throwable ex
+          (ex-info (.getMessage throwable)
+                   (dissoc (ex-data throwable) :component :system)
+                   (.getCause throwable))]
+      ;; .getStackTrace should never be null, but .setStackTrace
+      ;; doesn't allow null, so we'll be careful
+      (when-let [stacktrace (.getStackTrace throwable)]
+        (.setStackTrace ex stacktrace))
+      ex)
+    throwable))
+
 ;; Copyright © 2013 Stuart Sierra

 ;; Permission is hereby granted, free of charge, to any person obtaining a copy of


fix tagging

fix tagging

--- src/neuseg/prepare.clj
+++ src/neuseg/prepare.clj
@@ -18,14 +18,22 @@
 (defn- format-case [input output]
   (clojure.string/join "\n" (map (partial clojure.string/join " ") [input output])))

+(defn- clean [text]
+  (clojure.string/replace text #"(\s|\u00a0)+" " "))
+
+(defn- trim [text]
+   (clojure.string/replace text #"(\s|\u00a0)+" ""))
+
 (defn tagging [text]
   (let [seged (seg text)]
-		(loop [raw text
+    (loop [raw text
            sgd seged
            ret [1]]
       (if (nil? (second raw)) (conj ret 1)
         (if (= (second raw) (second sgd))
-          (recur (rest raw) (rest sgd) (conj ret -1 -1))
+          (if (= (second raw) " ")
+            (recur (nthrest raw 2) (nthrest sgd 2) (conj ret 1 1))
+            (recur (rest raw) (rest sgd) (conj ret -1 -1)))
           (recur (rest raw) (nthrest sgd 2) (conj ret 1 1)))))))

 (defn gen-cases [text]
@@ -43,8 +51,8 @@
     (with-open [wrtr (writer baos :encoding "utf-8")]
       (with-open [rdr (reader file-corpus :encoding "utf-8")]
         (doseq [line (line-seq rdr)]
-          (swap! counter + (count line))
-          (.write wrtr (gen-cases line)))))
+          (swap! counter + (count (trim line)))
+          (.write wrtr (gen-cases (clean line))))))
     (with-open [wrtr (writer file-output  :encoding "utf-8")]
         (.write wrtr (str @counter " 32 2\n"))
           (.write wrtr (.toString baos "utf-8")))))


Fix typo in following function

Fix typo in following function

--- tutorial.vent/src/tutorial/vent/lib.clj
+++ tutorial.vent/src/tutorial/vent/lib.clj
@@ -36,7 +36,7 @@
     :following? true}})

 (defn following
-  [{:keys [user]}]
+  [{:keys [username]}]
   {"jane_smith"
    {:name "Jane Smith"
     :following? true}})