Fix error in previously un-run test

Fix error in previously un-run test

--- test/io/perun_test.clj
+++ test/io/perun_test.clj
@@ -399,7 +399,7 @@
         (p/inject-scripts :scripts #{"test.js"} :remove #{#"baz"} :extensions [".htm"])
         (testing "inject-scripts"
           (comp
-           (content-check :path "hammock/foo.htm"
+           (content-check :path "bar/hammock/foo.htm"
                           :content (str "<script>" js-content "</script>")
                           :msg "`inject-scripts` should alter the contents of a file")
            (content-check :path "baz.htm"


minor atom ref bug fixed hellhound socketserver

--- src/hellhound/connection/server.clj
+++ src/hellhound/connection/server.clj
@@ -29,8 +29,8 @@
   []
   (compojure/routes
    (compojure/context "/hellhound" []
-                      (compojure/GET  "/" req (ring-handshake req))
-                      (compojure/POST "/" req (ring-ajax-post req)))))
+                      (compojure/GET  "/" req (@ring-handshake req))
+                      (compojure/POST "/" req (@ring-ajax-post req)))))


Added a little error checking to "lein appengine-prepare", since putting the appengine-magic dependency into :dependencies instead of :dev-dependencies can cause confusing errors.

--- src/leiningen/appengine_prepare.clj
+++ src/leiningen/appengine_prepare.clj
@@ -1,6 +1,7 @@
 (ns leiningen.appengine-prepare
   "Prepares a the Google App Engine application for deployment."
-  (:use appengine-magic.utils)
+  (:use appengine-magic.utils
+        [leiningen.core :only [abort]])
   (:require leiningen.compile leiningen.jar leiningen.util.file
             [lancet.core :as lancet])
   (:import java.io.File))
@@ -19,6 +20,10 @@
         compile-path-exists? (.isDirectory compile-path)
         compile-path-empty? (= 0 (-> compile-path .list seq count))]
     (println "preparing App Engine application" prj-display-name "for deployment")
+    ;; check for basic correctness
+    (when (some (fn [x] (= 'appengine-magic (first x)))
+                (:dependencies project))
+      (abort "project.clj error: put appengine-magic in :dev-dependencies, not :dependencies"))
     ;; compile all; when successful (status is 0), continue to prepare
     (when (= 0 (leiningen.compile/compile (if (contains? project :aot)
                                               project


optimize js*

optimize js*

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -2033,64 +2033,101 @@
   [_ env [_ target & [field & member+] :as form] _ _]
   (disallowing-recur (analyze-dot env target field member+ form)))

+(defn get-js-tag [form]
+  (let [form-meta (meta form)
+        tag       (:tag form-meta)]
+    (if-not (nil? tag)
+      tag
+      (when (true? (:numeric form-meta))
+        'number))))
+
+(defn js-star-interp
+  [env ^String s]
+  (let [idx (.indexOf s "~{")]
+    (if (== -1 idx)
+      (list s)
+      (let [end (.indexOf s "}" idx)
+            inner (:name (resolve-existing-var env (symbol (subs s (+ 2 idx) end))))]
+        (lazy-seq
+          (cons (subs s 0 idx)
+            (cons inner
+              (js-star-interp env (subs s (inc end))))))))))
+
+(defn js-star-seg
+  [^String s]
+  (let [idx (.indexOf s "~{")]
+    (if (== -1 idx)
+      (list s)
+      (let [end (.indexOf s "}" idx)]
+        (lazy-seq
+          (cons (subs s 0 idx)
+            (js-star-seg (subs s (inc end)))))))))
+
+(def NUMERIC_SET '#{any number long double})
+
+(defn numeric-type?
+  #?(:cljs {:tag boolean})
+  [t]
+  ;; TODO: type inference is not strong enough to detect that
+  ;; when functions like first won't return nil, so variadic
+  ;; numeric functions like cljs.core/< would produce a spurious
+  ;; warning without this - David
+  (if (nil? t)
+    true
+    (if (and (symbol? t) (not (nil? (get NUMERIC_SET t))))
+      true
+      (when #?(:clj  (set? t)
+               :cljs (cljs-set? t))
+        (or (contains? t 'number)
+            (contains? t 'long)
+            (contains? t 'double)
+            (contains? t 'any))))))
+
+(defn analyze-js-star* [env jsform args form]
+  (let [enve      (assoc env :context :expr)
+        argexprs  (vec (map #(analyze enve %) args))
+        form-meta (meta form)
+        segs      (js-star-seg jsform)
+        tag       (get-js-tag form)
+        js-op     (:js-op form-meta)
+        numeric   (:numeric form-meta)]
+    (when (true? numeric)
+      (let [types (map #(infer-tag env %) argexprs)]
+        (when-not (every? numeric-type? types)
+          (warning :invalid-arithmetic env
+            {:js-op js-op
+             :types (into [] types)}))))
+    {:op :js
+     :env env
+     :segs segs
+     :args argexprs
+     :tag tag
+     :form form
+     :children argexprs
+     :js-op js-op
+     :numeric numeric}))
+
+(defn analyze-js-star [env jsform args form]
+  (disallowing-recur (analyze-js-star* env jsform args form)))
+
 (defmethod parse 'js*
   [op env [_ jsform & args :as form] _ _]
   (when-not (string? jsform)
     (throw (error env "Invalid js* form")))
-  (if args
-    (disallowing-recur
-     (let [seg (fn seg [^String s]
-                 (let [idx (.indexOf s "~{")]
-                   (if (= -1 idx)
-                     (list s)
-                     (let [end (.indexOf s "}" idx)]
-                       (lazy-seq
-                         (cons (subs s 0 idx)
-                           (seg (subs s (inc end)))))))))
-           enve (assoc env :context :expr)
-           argexprs (vec (map #(analyze enve %) args))]
-       (when (-> form meta :numeric)
-         (let [types (map #(infer-tag env %) argexprs)]
-           (when-not (every?
-                       (fn [t]
-                         (or (nil? t)
-                             (and (symbol? t) ('#{any number long double} t))
-                             ;; TODO: type inference is not strong enough to detect that
-                             ;; when functions like first won't return nil, so variadic
-                             ;; numeric functions like cljs.core/< would produce a spurious
-                             ;; warning without this - David
-                             (and (set? t)
-                                  (or (contains? t 'number)
-                                      (contains? t 'long)
-                                      (contains? t 'double)
-                                      (contains? t 'any)))))
-                       types)
-             (warning :invalid-arithmetic env
-               {:js-op (-> form meta :js-op)
-                :types (into [] types)}))))
-       {:env env :op :js :segs (seg jsform) :args argexprs
-        :tag (or (-> form meta :tag)
-                 (and (-> form meta :numeric) 'number)
-                 nil)
-        :form form :children argexprs
-        :js-op (-> form meta :js-op)
-        :numeric (-> form meta :numeric)}))
-    (let [interp (fn interp [^String s]
-                   (let [idx (.indexOf s "~{")]
-                     (if (= -1 idx)
-                       (list s)
-                       (let [end (.indexOf s "}" idx)
-                             inner (:name (resolve-existing-var env (symbol (subs s (+ 2 idx) end))))]
-                         (lazy-seq
-                           (cons (subs s 0 idx)
-                             (cons inner
-                               (interp (subs s (inc end))))))))))]
-      {:env env :op :js :form form :code (apply str (interp jsform))
-       :tag (or (-> form meta :tag)
-                (and (-> form meta :numeric) 'number)
-                nil)
-       :js-op (-> form meta :js-op)
-       :numeric (-> form meta :numeric)})))
+  (if-not (nil? args)
+    (analyze-js-star env jsform args form)
+    (let [code      (apply str (js-star-interp env jsform))
+          tag       (get-js-tag form)
+          form-meta (meta form)
+          js-op     (:js-op form-meta)
+          numeric   (:numeric form-meta)]
+      {:op :js
+       :env env
+       :form form
+       :code code
+       :tag tag
+       :js-op js-op
+       :numeric numeric})))

 (defn- analyzed?
   #?(:cljs {:tag boolean})


cleanup; Refactored card to cond in all classes consistently

--- src/main/untangled/ui/elements.cljc
+++ src/main/untangled/ui/elements.cljc
@@ -10,8 +10,8 @@
 (defn ui-avatar
   "Render an icon or a short string within an avatar. Normal HTML/React attributes can be included, and should be a cljs map (not a js object).

-  color (optional): :primary, :accent
-  size (optional): huge"
+  `:color` - :none (default), :primary, :accent
+  `:size` - :regular (default), huge"
   [{:keys [className color size style] :as props :or {className ""}} child]
   (let [legal-colors #{:primary :accent}
         legal-sizes  #{:medium :large :xlarge :huge}
@@ -98,18 +98,6 @@
   [{:keys [className size color disabled active] :or {className ""} :as props} & children]
   (apply ui-flat-button (update props :className str " c-button--circular") children))

-(def color-types
-  {:primary "c-card--primary"
-   :accent  "c-card--accent"})
-
-(def card-types
-  {:bordered    "c-card--bordered"
-   :transparent "c-card--transparent"
-   :square      "c-card--square"})
-
-(def size-types
-  {:expand "c-card--expand"
-   :wide   "c-card--wide"})

 (defn ui-card
   "Card component
@@ -131,7 +119,7 @@
     ...)
     all paramters optional
     "
-  [{:keys [type
+  [{:keys [style
            title
            color
            size
@@ -143,18 +131,20 @@
            ;; menu-icon
            ;; menu-items
            className] :as attrs} & children]
-  {:pre [(or (nil? type) (keyword? type))
+  {:pre [(or (nil? style) (keyword? style))
          (or (nil? title) (string? title))]}
-  (let [className  (or className "")
-        classes    (cond->
-                     (str "c-card " className)
-                     type (str " " (card-types type))
-                     size (str " " (size-types size))
-                     color (str " " (color-types color)))
-        attributes (-> attrs
-                     (merge {:className classes})
-                     (dissoc :title :type :color :size :actions :image :image-position :media-type :media)
-                     clj->js)]
+  (let [legal-styles #{:bordered :transparent :square}
+        legal-colors #{:primary :accent}
+        legal-sizes  #{:expand :wide}
+        className    (or className "")
+        classes      (cond-> (str "c-card " className)
+                       (contains? legal-styles style) (str " c-card--" (name style))
+                       (contains? legal-colors color) (str " c-card--" (name color))
+                       (contains? legal-sizes size) (str " c-card--" (name size)))
+        attributes   (-> attrs
+                       (merge {:className classes})
+                       (dissoc :title :style :color :size :actions :image :image-position :media-type :media)
+                       clj->js)]
     (dom/div attributes
       (when media
         (dom/div #js {:className (str "c-card__media")}
@@ -465,7 +455,6 @@
             (when content content)
             (when actions actions)))
         (dom/div #js {:className (str "c-backdrop" state)})))))
-;TODO: Change the position to fixed and wrap the example in ui-iframe.  My testing with this did not work as expected.

 (def ui-modal
   "Render a modal. Normal HTML/React attributes can be included, and should be a cljs map (not a js object).


add property for agent log purge timing

add property for agent log purge timing

--- config/jsk-conf.clj
+++ config/jsk-conf.clj
@@ -29,4 +29,8 @@
  ; agents are considered dead after not receiving heartbeats after :dead-after-milliseconds
  :heartbeats {:interval-milliseconds 1000
               :dead-after-milliseconds 30000}
+
+ ; how often agents check their log file and purge data for which acks
+ ; have already been received
+ :agents {:msg-log-purge-milliseconds 60000}
  }


update the connection-spec acquisition code for our generic SQL driver to unify it based on acquiring a connection for a given DATABASE and to replace the memoize/ttl with our own atom for caching db connection pools to each database.  This avoids the unnecessary recreation of connection pools every so many hours.

--- src/metabase/driver/generic_sql.clj
+++ src/metabase/driver/generic_sql.clj
@@ -65,9 +65,6 @@

      Return `nil` to prevent FIELD from being aliased.")

-  (get-connection-for-sync ^java.sql.Connection [this details]
-    "*OPTIONAL*. Get a connection used for a Sync step. By default, this returns a pooled connection.")
-
   (prepare-value [this, ^Value value]
     "*OPTIONAL*. Prepare a value (e.g. a `String` or `Integer`) that will be used in a korma form. By default, this returns VALUE's `:value` as-is, which
      is eventually passed as a parameter in a prepared statement. Drivers such as BigQuery that don't support prepared statements can skip this
@@ -89,38 +86,49 @@
      SECONDS-OR-MILLISECONDS refers to the resolution of the int in question and with be either `:seconds` or `:milliseconds`."))

-(def ^{:arglists '([connection-spec])}
-  connection-spec->pooled-connection-spec
+;; use an atom with {:db <conn-pool>}
+;; when something changes about the database we shutdown the pool and let it be replaced
+
+(def ^:dynamic ^:private connection-pools
+  "A map of our currently open connection pools, keyed by DATABASE `:id`."
+  (atom {}))
+
+(defn- create-connection-pool
+  "Create a new C3P0 `ComboPooledDataSource` for connecting to the given DATABASE."
+  [{:keys [id engine details]}]
+  (log/debug (u/format-color 'magenta "Creating new connection pool for database %d ..." id))
+  (let [spec (connection-details->spec (driver/engine->driver engine) details)]
+    (kdb/connection-pool (assoc spec :minimum-pool-size           1
+                                     ;; prevent broken connections closed by dbs by testing them every 3 mins
+                                     :idle-connection-test-period (* 3 60)
+                                     ;; prevent overly large pools by condensing them when connections are idle for 15m+
+                                     :excess-timeout              (* 15 60)))))
+
+(defn db->pooled-connection-spec
   "Return a JDBC connection spec that includes a cp30 `ComboPooledDataSource`.
-   Theses connection pools are cached so we don't create multiple ones to the same DB.
-   Pools are destroyed after they aren't used for more than 3 hours."
-  (memoize/ttl
-   (fn [spec]
-     (log/debug (u/format-color 'magenta "Creating new connection pool..."))
-     (kdb/connection-pool (assoc spec :minimum-pool-size           1
-                                      ;; prevent broken connections closed by dbs by testing them every 3 mins
-                                      :idle-connection-test-period (* 3 60)
-                                      ;; prevent overly large pools by condensing them when connections are idle for 15m+
-                                      :excess-timeout              (* 15 60))))
-   :ttl/threshold (* 6 60 60 1000)))
+   Theses connection pools are cached so we don't create multiple ones to the same DB."
+  [{:keys [id], :as database}]
+  (if (contains? @connection-pools id)
+    ;; we have an existing pool for this database, so use it
+    (get @connection-pools id)
+    ;; need to create a new pool
+    (let [new-pool (create-connection-pool database)]
+      ;; add the newly created pool to the cache so we maintain a reference to it
+      (reset! connection-pools (assoc @connection-pools id new-pool))
+      ;; just return the newly created pool
+      new-pool)))

 (defn db->jdbc-connection-spec
   "Return a JDBC connection spec for DATABASE. Normally this will have a C3P0 pool as its datasource, unless the database is `short-lived`."
-  {:arglists '([database] [driver details])}
   ;; TODO - I don't think short-lived? key is really needed anymore. It's only used by unit tests, and its original purpose was for creating temporary DBs;
   ;; since we don't destroy databases at the end of each test anymore, it's probably time to remove this
-  ([{:keys [engine details]}]
-   (db->jdbc-connection-spec (driver/engine->driver engine) details))
-  ([driver {:keys [short-lived?], :as details}]
-   (let [connection-spec (connection-details->spec driver details)]
-     (if short-lived?
-       connection-spec
-       (connection-spec->pooled-connection-spec connection-spec)))))
-
-(def ^{:arglists '([database] [driver details])}
-  db->connection
-  "Return a [possibly pooled] connection to DATABASE. Make sure to close this when you're done! (e.g. by using `with-open`)"
-  (comp jdbc/get-connection db->jdbc-connection-spec))
+  [{:keys [engine details], :as database}]
+  (let [driver (driver/engine->driver engine)]
+    (if (:short-lived? details)
+      ;; short-lived connections are not pooled, so just return an ephemeral connection
+      (connection-details->spec driver details)
+      ;; default behavior is to use a pooled connection
+      (db->pooled-connection-spec database))))

 (defn escape-field-name
@@ -210,8 +218,8 @@

 (defmacro with-metadata
   "Execute BODY with `java.sql.DatabaseMetaData` for DATABASE."
-  [[binding driver database] & body]
-  `(with-open [^java.sql.Connection conn# (get-connection-for-sync ~driver (:details ~database))]
+  [[binding _ database] & body]
+  `(with-open [^java.sql.Connection conn# (jdbc/get-connection (db->jdbc-connection-spec ~database))]
      (let [~binding (.getMetaData conn#)]
        ~@body)))

@@ -309,7 +317,6 @@
    :current-datetime-fn     (constantly (k/sqlfn* :NOW))
    :excluded-schemas        (constantly nil)
    :field->alias            (u/drop-first-arg name)
-   :get-connection-for-sync db->connection
    :prepare-value           (u/drop-first-arg :value)
    :set-timezone-sql        (constantly nil)
    :stddev-fn               (constantly :STDDEV)})
@@ -338,14 +345,11 @@

 (defn- db->korma-db
   "Return a Korma DB spec for Metabase DATABASE."
-  ([database]
-   (db->korma-db (driver/engine->driver (:engine database)) (:details database)))
-  ([driver details]
-   (assoc (kx/create-db (connection-details->spec driver details))
-          :pool (db->jdbc-connection-spec driver details))))
-
-(defn- table+db->entity [{schema :schema, table-name :name} db]
-  (k/database (kx/create-entity [schema table-name]) db))
+  [database]
+  (let [driver  (driver/engine->driver (:engine database))
+        details (:details database)]
+    (assoc (kx/create-db (connection-details->spec driver details))
+      :pool (db->jdbc-connection-spec database))))

 (defn korma-entity
   "Return a Korma entity for [DB and] TABLE.
@@ -353,8 +357,8 @@
     (-> (sel :one Table :id 100)
         korma-entity
         (select (aggregate (count :*) :count)))"
-  ([table]
-   (korma-entity (table/database table) table))
-
-  ([db table]             (table+db->entity table (db->korma-db db)))
-  ([driver details table] (table+db->entity table (db->korma-db driver details))))
+  ([table]    (korma-entity (table/database table) table))
+  ([db table] (let [{schema :schema, table-name :name} table]
+                (k/database
+                  (kx/create-entity [schema table-name])
+                  (db->korma-db db)))))


Update comments.

Update comments.

--- src/oc/storage/resources/common.clj
+++ src/oc/storage/resources/common.clj
@@ -98,7 +98,7 @@
 (def Status (schema/pred #(#{:draft :published} (keyword %))))

 (def PollReply
-  "A poll reply."
+  "An option you can vote on in a poll."
   {:body schema/Str
    :author lib-schema/Author
    :reply-id lib-schema/UniqueID
@@ -106,7 +106,7 @@
    :votes [lib-schema/UniqueID]})

 (def Poll
-  "A poll item."
+  "A user poll for voting."
   {:poll-uuid lib-schema/UniqueID
    :question schema/Str
    :can-add-reply schema/Bool


Avoid logging non-important pull failures.

--- src/replikativ/crdt/cdvcs/impl.cljc
+++ src/replikativ/crdt/cdvcs/impl.cljc
@@ -77,7 +77,7 @@
                                       (= type :not-superset)
                                       (= type :conflicting-meta)
                                       (= type :pull-unnecessary))
-                                (do (debug e) :rejected)
+                                :rejected
                                 (do (debug e) (throw e))))))
                  new-commits (set/difference (-> pulled :state :commit-graph keys set)
                                              (-> b-cdvcs :commit-graph keys set))]


tweak docs

tweak docs

--- src/voke/system/collision/util.cljs
+++ src/voke/system/collision/util.cljs
@@ -29,8 +29,8 @@
   [entity :- Entity
    new-center :- Vector2
    new-velocity :- Vector2]
-  ; Queue an update to this entity's center; these updates get run in a single batch at the
-  ; end of this tick, so that all entities in cljs-land have their centers updated at once.
+  ; Queue an update to this entity's center and velocity; these updates get run in a single batch at the
+  ; end of this tick, so that all entities in cljs-land have their centers+velocities updated at once.
   (update-entity! (entity :id)
                   :collision-system
                   (fn [entity]
@@ -45,7 +45,7 @@
   ; In order to be correct, the voke collision system needs to maintain this invariant:
   ; at all times, no two entities are occuping the same space.
   ; By updating the JS-land collision system multiple times per tick, we maintain this invariant.
-  ; if we did not do this, two entities moving toward each other could both end up occuping
+  ; If we did not do this, two entities moving toward each other could both end up occuping
   ; the same space.
   (-update-entity-center (entity :id) new-center)

@@ -66,7 +66,7 @@

 (sm/defn get-updated-entity-center :- Entity
   "Returns the given entity, with its most up-to-date center value spliced in.
-  See `apply-movement`."
+  See `apply-movement` for an explanation of why the js-land collision system has more up-to-date center values."
   [entity :- Entity]
   (assoc-in entity
             [:shape :center]


Stupid uid fn added to websocket component

--- src/clj/hellhound/components/websocket.clj
+++ src/clj/hellhound/components/websocket.clj
@@ -48,7 +48,8 @@
   ([event-msg-handler web-server-adapter]
    (new-channel-socket-server event-msg-handler web-server-adapter {}))
   ([event-msg-handler web-server-adapter options]
-   (let [opts (merge {:packer  (packer/->TransitPacker :json {} {})}
+   (let [opts (merge {:packer  (packer/->TransitPacker :json {} {})
+                      :user-id-fn  (fn [_] (str (quot (System/currentTimeMillis) 1000)))}
                      options)]
      (map->WebSocketServer {:web-server-adapter web-server-adapter
                             :handler event-msg-handler


Skynet - Virus, further simplification

Skynet - Virus, further simplification

--- src/clojureplayground/codingame_helper.clj
+++ src/clojureplayground/codingame_helper.clj
@@ -55,14 +55,12 @@
 (defn skynet-virus [& args]
   (let [[_ L E] (map s->i (spws (read-line)))
         [links egws] (split-at (* 2 L) (mapcat #(map s->i (spws %)) (repeatedly (+ E L) read-line)))
-        lks (vec
-              (map-indexed
-                #(let [[from to] %2]
-                  {:i % :f from :t to})
-                (partition 2 links)))
+        lks (mapv (fn [[from to]]
+                    {:f from :t to})
+                  (partition 2 links))
         egs (set egws)]
     (reduce (fn [ls si]
-              (let [{:keys [i f t]} (node-to-cut si ls egs)]
+              (let [{:keys [f t]} (node-to-cut si ls egs)]
                 (println f t)ls))
             lks
             (repeatedly read))))


added --verbose flag and dynamic var

added --verbose flag and dynamic var

--- src/me/panzoo/story.clj
+++ src/me/panzoo/story.clj
@@ -24,6 +24,10 @@

   (:gen-class))

+(def ^:dynamic *verbose?*
+  "Whether to log messages to std-err or not."
+  false)
+
 ; ## Utilities
 ;
 ; A few utility functions to make it easier to print messages to the console,
@@ -32,8 +36,9 @@
 ; over a lexical scope.

 (defn message [& s]
-  (binding [*out* (io/writer System/err)]
-    (println (apply str s))))
+  (when *verbose?*
+    (binding [*out* (io/writer System/err)]
+      (println (apply str s)))))

 (defn each
   "Apply f to each item of coll in order for side effects only.
@@ -489,6 +494,8 @@
                  ["-t" "--theme" "SyntaxHighlighter theme file"]
                  ["-l" "--language" "SyntaxHighlighter language"]
                  ["-s" "--stylesheet" "A stylesheet file to include"]
+                 ["-v" "--verbose" "Turn on verbose output"
+                  :default false :flag true]
                  ["-h" "--help" "Show this help" :default false :flag true])]

 ; For the brush, theme, and stylesheet options the program first tries to read
@@ -509,7 +516,8 @@
                 *theme* (or (:theme amap) *theme*)
                 *language* (or (:language amap) *language*)
                 *stylesheet* (:stylesheet amap)
-                *static-brushes* (:brush amap)]
+                *static-brushes* (:brush amap)
+                *verbose?* (:verbose amap)]

 ; When no output file is given, the program renders to standard-out.


Parse control characters

Parse control characters

--- src/multi_repl/core.clj
+++ src/multi_repl/core.clj
@@ -12,7 +12,7 @@

 (defn print-err [& args]
   (binding [*out* *err*]
-    (apply prn args)))
+    (apply println args)))

 (defrecord Repl [command proc sink source]
   component/Lifecycle
@@ -52,38 +52,50 @@
   (-> (new-repl ["python" "-u" "python-repl.py"])
       (component/start)))

-(defn run-input [repl input]
-  (if (= input "exit")
-    (do (component/stop repl)
-        (System/exit 0))
-    (let [{:keys [error result]} (eval-in-repl repl input)]
-      (if error
-        (println "\nERROR:" error)
-        (println "\n" result)))))
-
-(defn valid-input? [input]
+(defn parse-input [input]
   (print-err "valid-input?" input)
-  (boolean (re-matches #".*\r" input)))
-
-(defn read-char [reader]
-  (-> (.readCharacter reader)
-      char))
+  (cond
+    (= input [27 91 65])           :up
+    (= input [27 91 66])           :down
+    (= input [27 91 67])           :right
+    (= input [27 91 68])           :left
+    (= input [127])                :backspace
+    (= input [101 120 105 116 13]) :exit
+    (= (last input) 13)            (->> input
+                                        (map char)
+                                        (apply str)
+                                        clojure.string/trim)
+    :else                          false))

 (defn read-input [reader]
-  (loop [c (read-char reader)
-         buffer ""]
-    (let [buffer (str buffer c)]
-      (if (valid-input? buffer)
-        (clojure.string/trim buffer)
-        (do (print-flush c)
-            (recur (read-char reader)
-                   buffer))))))
+  (loop [buffer [(.readCharacter reader)]]
+    (if-let [parsed (parse-input buffer)]
+      parsed
+      (do (print-flush (char (last buffer)))
+          (recur (conj buffer (.readCharacter reader)))))))
+
+(defmulti run-input (fn [repl input]
+                      (if (keyword? input) input :string)))
+
+(defmethod run-input :default [repl input]
+  (println "\nUNKNOWN INPUT:" input))
+
+(defmethod run-input :exit [repl _]
+  (component/stop repl)
+  (System/exit 0))
+
+(defmethod run-input :string [repl input]
+  (let [{:keys [error result]} (eval-in-repl repl input)]
+    (if error
+      (println "\nERROR:" error)
+      (println "\n" result))))

 (defn -main [& args]
   (let [repl (start-python-repl)
         reader (ConsoleReader.)]
     (print-flush "> ")
     (loop [input (read-input reader)]
+      (print-err "input" input)
       (run-input repl input)
       (print-flush "> ")
       (recur (read-input reader)))))


[CIRCLE-1640] Convert project settings overview to card (#1503)

* [CIRCLE-1640] Convert project settings overview to card

* refactor overview and follow-sidebar + cr

--- src-cljs/frontend/components/project_settings.cljs
+++ src-cljs/frontend/components/project_settings.cljs
@@ -106,93 +106,90 @@
              :data-success-text "Started..."
              :type "submit"}])])))))

-(defn follow-sidebar [{:keys [username reponame] :as project} owner]
+(defn overview [project-data owner]
   (reify
     om/IInitState
     (init-state [_]
       {:show-modal? false})
+
     om/IRenderState
     (render-state [_ {:keys [show-modal?]}]
-      (let [project-id (project-model/id project)
+      (let [project (:project project-data)
+            username (:username project)
+            reponame (:reponame project)
             vcs-url (:vcs_url project)
-            controls-ch (om/get-shared owner [:comms :controls])]
-        (html
-         [:article
-          [:div
-           (if (:followed project)
-             (list
-              [:h2 "You're following " (vcs-url/project-name vcs-url)]
-              [:p
-               "We'll keep an eye on this and update you with personalized build emails and notifications."
-               [:br]
-               "You can update your notifications from your "
-               [:a {:href "/account"} "account settings"]
-               "."]
-              (when show-modal?
-                (let [close-fn #(om/set-state! owner :show-modal? false)]
-                  (modal/modal-dialog
-                   {:title (gstring/format "Stop building %s/%s on CircleCI?" username reponame)
-                    :body (html
-                           [:div
-                            [:p
-                             (gstring/format
-                              "When you stop building %s on CircleCI, we will stop all builds and unfollow all teammates who are currently following the project."
-                              reponame)]])
-                    :actions [(button/button {:on-click close-fn} "Cancel")
-                              (button/managed-button
-                               {:on-click #(raise! owner [:stopped-building-project {:vcs-url vcs-url
-                                                                                :project-id project-id
-                                                                                :on-success close-fn}])
-                                :kind :danger
-                                :loading-text "Stopping Builds..."
-                                :success-text "Builds Stopped"}
-                               "Stop Building")]
-                    :close-fn close-fn})))
-
-              (button/managed-button
-               {:on-click #(raise! owner [:unfollowed-project {:vcs-url vcs-url :project-id project-id}])
-                :loading-text "Unfollowing..."
-                :kind :primary}
-               "Unfollow Project")
-
-              [:div
-               [:h2 "You're building " (vcs-url/project-name vcs-url)]
-
-               (button/button {:on-click #(om/set-state! owner :show-modal? true)
-                               :kind :danger}
-                              "Stop Building")])
-             (list
-              [:h2 "You're not following this repo"]
-              [:p
-               "We can't update you with personalized build emails and notifications unless you follow this project. "
-               "Projects are only tested if they have a follower."]
-              (button/managed-button
-               {:on-click #(raise! owner [:followed-project {:vcs-url vcs-url
-                                                             :project-id project-id}])
-                :loading-text "Following..."}
-               "Follow")))]])))))
-
-(defn overview [project-data owner]
-  (reify
-    om/IRender
-    (render [_]
-      (html
-       [:section.overview
-        [:article
-         [:h2 "How to configure " (vcs-url/project-name (get-in project-data [:project :vcs_url]))]
-         [:h4 "Option 1"]
-         [:p "Do nothing! CircleCI infers many settings automatically. Works great for Ruby, Python, NodeJS, Java and Clojure. However, if it needs tweaks or doesn't work, see below."]
-         [:h4 "Option 2"]
-         [:p
-          "Override inferred settings and add new test commands "
-          [:a {:href "#setup"} "through the web UI"]
-          ". This works great for prototyping changes."]
-         [:h4 "Option 3"]
-         [:p
-          "Override all settings via a "
-          [:a (open-ext {:href "https://circleci.com/docs/configuration/"}) "circle.yml file"]
-          " in your repo. Very powerful."]]
-        (om/build follow-sidebar (:project project-data))]))))
+            project-id (project-model/id project)]
+        (html
+          (card/collection
+            (concat
+              [(card/titled
+                 {:title (str "How to configure " (vcs-url/project-name (get-in project-data [:project :vcs_url])))}
+                 (html
+                   [:div
+                    [:b "Option 1"]
+                    [:p "Do nothing! CircleCI infers many settings automatically. Works great for Ruby, Python, NodeJS, Java and Clojure. However, if it needs tweaks or doesn't work, see below."]
+                    [:b "Option 2"]
+                    [:p
+                     "Override inferred settings and add new test commands "
+                     [:a {:href "#setup"} "through the web UI"]
+                     ". This works great for prototyping changes."]
+                    [:b "Option 3"]
+                    [:p
+                     "Override all settings via a "
+                     [:a (open-ext {:href "https://circleci.com/docs/configuration/"}) "circle.yml file"]
+                     " in your repo. Very powerful."]]))]
+              (if (:followed project)
+                [(card/titled
+                   {:title (str "You're following " (vcs-url/project-name vcs-url))}
+                   (html
+                     [:div
+                      [:p
+                       "We'll keep an eye on this and update you with personalized build emails and notifications."
+                       [:br]
+                       "You can update your notifications from your "
+                       [:a {:href "/account"} "account settings"]
+                       "."]
+                      (when show-modal?
+                        (let [close-fn #(om/set-state! owner :show-modal? false)]
+                          (modal/modal-dialog
+                            {:title (gstring/format "Stop building %s/%s on CircleCI?" username reponame)
+                             :body (html
+                                     [:div
+                                      [:p
+                                       (gstring/format
+                                         "When you stop building %s on CircleCI, we will stop all builds and unfollow all teammates who are currently following the project."
+                                         reponame)]])
+                             :actions [(button/button {:on-click close-fn} "Cancel")
+                                       (button/managed-button
+                                         {:on-click #(raise! owner [:stopped-building-project {:vcs-url vcs-url
+                                                                                :project-id project-id
+                                                                                :on-success close-fn}])
+                                          :kind :danger
+                                          :loading-text "Stopping Builds..."
+                                          :success-text "Builds Stopped"}
+                                         "Stop Building")]
+                             :close-fn close-fn})))
+
+                      (button/managed-button
+                        {:on-click #(raise! owner [:unfollowed-project {:vcs-url vcs-url :project-id project-id}])
+                         :loading-text "Unfollowing..."
+                         :kind :primary}
+                        "Unfollow Project")]))
+
+                 (card/titled {:title (str "You're building " (vcs-url/project-name vcs-url))}
+                              (button/button {:on-click #(om/set-state! owner :show-modal? true)
+                                              :kind :danger}
+                                             "Stop Building"))]
+                [(card/titled
+                   {:title "You're not following this repo"}
+                   (html
+                     [:div
+                      [:p "We can't update you with personalized build emails and notifications unless you follow this project. "
+                       "Projects are only tested if they have a follower."]
+                      (button/managed-button
+                        {:on-click #(raise! owner [:followed-project {:vcs-url vcs-url :project-id project-id}])
+                         :loading-text "Following..."}
+                        "Follow")]))]))))))))

 (defn build-environment [project-data owner]
   (reify


Updates for November

Updates for November

--- scrape-n-mail/src/scrape_n_mail/core.cljs
+++ scrape-n-mail/src/scrape_n_mail/core.cljs
@@ -191,7 +191,7 @@
       [:br]
       [:p "Dear " (::submitter-name (first name-records)) ","]

-      [:p "Our general call for names for Wellbeing for October 2019 has gone out to the newDharma mailing list."]
+      [:p "Our general call for names for Wellbeing for November 2019 has gone out to the newDharma mailing list."]

       [:p "Currently, the community is holding the following names on the altar "
           "in support of their wellbeing at your request. Click "


elevation shows reps

elevation shows reps

--- src/ontrail/summary.clj
+++ src/ontrail/summary.clj
@@ -28,7 +28,7 @@
      :tdistance true-distance
      :avghr (avghr db-retmap)
      :repeats (if-let [reps (:repeats db-retmap)] (when (> reps 0) reps))
-     :elevation (if-let [elevation (:repeats db-retmap)] (when (> elevation 0)
+     :elevation (if-let [elevation (:elevation db-retmap)] (when (> elevation 0)
      elevation))
      :count count
      key sport}))


Use re-named ack-message / retry-message

--- src/onyx/plugin/sql.clj
+++ src/onyx/plugin/sql.clj
@@ -109,26 +109,26 @@

   p-ext/PipelineInput

-  (ack-message [_ _ message-id]
-    (let [part (get @pending-messages message-id)
+  (ack-segment [_ _ segment-id]
+    (let [part (get @pending-messages segment-id)
           content {:status :acked :partition (:message part)}
           read-content (extensions/read-chunk log :chunk task-id)
           updated-content (update-partition read-content content (:message part))]
       (extensions/force-write-chunk log :chunk updated-content task-id)
-      (swap! pending-messages dissoc message-id)))
-
-  (retry-message
-    [_ _ message-id]
+      (swap! pending-messages dissoc segment-id)))
+
+  (retry-segment
+    [_ _ segment-id]
     (let [snapshot @pending-messages
-          message (get snapshot message-id)]
-      (swap! pending-messages dissoc message-id)
+          message (get snapshot segment-id)]
+      (swap! pending-messages dissoc segment-id)
       (if (:partition message)
         (>!! read-ch {:partition (:partition message)})
         (>!! read-ch :done))))

   (pending?
-    [_ _ message-id]
-    (get @pending-messages message-id))
+    [_ _ segment-id]
+    (get @pending-messages segment-id))

   (drained?
     [_ _]
@@ -182,7 +182,7 @@
     (function/read-batch event))

   (write-batch
-    [_ {:keys [onyx.core/results ]}]
+    [_ {:keys [onyx.core/results]}]
     (doseq [msg (mapcat :leaves (:tree results))]
       (jdbc/with-db-transaction
         [conn pool]


refactor random-int

refactor random-int

--- src/tic_tac_toe/tic_tac_toe.clj
+++ src/tic_tac_toe/tic_tac_toe.clj
@@ -141,7 +141,7 @@
   (<= start value end))

 (defn random-int [from to]
-  (let [random (Random.)]
-    (+ (.nextInt random (inc to)) from)))
-
-;; (random-int 0 2)
+  (let [random (Random.)
+        inc-to (inc to)
+        next-int (.nextInt random inc-to)]
+    (+ next-int from)))


write atom names as strings

write atom names as strings

--- src/atom_finder/questions/comment_counts.clj
+++ src/atom_finder/questions/comment_counts.clj
@@ -123,6 +123,6 @@
       read-lines
       (map (fn [[[proj in-function comment atom] count]]
              {:proj proj :in-function (boolean in-function)
-              :comment (boolean comment) :atom atom :count count}))
+              :comment (boolean comment) :atom (some-> atom name) :count count}))
       (maps-to-csv "comment-counts_2018-01-08_01_in-function.csv")
  ))


Fix missing rename from last commit

Fix missing rename from last commit

--- src/braid/core/client/ui/styles/message.cljs
+++ src/braid/core/client/ui/styles/message.cljs
@@ -29,7 +29,7 @@
      ; causing hover-cards to display under subsequent messages
      ["> .info"
       "> .avatar img"
-      "> .post-message"
+      "> .footer"
       "> .content > img"
       "> .content > .dummy > .user > .pill"
       "> .content > .dummy > .tag > .pill"


Add more test cases to squirrel-play

Add more test cases to squirrel-play

The previous set of test cases was arguably thin on the high temperature cases, which encouraged programs to pass everything except the cases over 100 degrees.

--- src/clojush/problems/ec_ai_demos/squirrel_play.clj
+++ src/clojush/problems/ec_ai_demos/squirrel_play.clj
@@ -31,11 +31,21 @@
    [59, false]
    [59, true]
    [60, false]
-   [59, true]
+   [60, true]
+   [61, true]
+   [61, false]
+   [89, false]
+   [89, true]
    [91, false]
    [91, true]
+   [99, false]
+   [99, true]
    [101, true]
-   [101, false]])
+   [101, false]
+   [105, true]
+   [105, false]
+   [200, true]
+   [200, false]])

 (defn expected-output
   [inputs]


Reverted the subvector change.

Reverted the subvector change.

--- src/clojure/uncomplicate/neanderthal/core.clj
+++ src/clojure/uncomplicate/neanderthal/core.clj
@@ -660,12 +660,10 @@

   If the requested region is not within the dimensions of `x`, throws ExceptionInfo.
   "
-  ([^Vector x ^long k ^long l]
-   (if (<= (+ k l) (.dim x))
-     (.subvector x k l)
-     (throw (ex-info "Requested subvector is out of bounds." {:k k :l l :k+l (+ k l) :dim (.dim x)}))))
-  ([^Vector x ^long k]
-   (subvector x k (- (.dim x) k))))
+  [^Vector x ^long k ^long l]
+  (if (<= (+ k l) (.dim x))
+    (.subvector x k l)
+    (throw (ex-info "Requested subvector is out of bounds." {:k k :l l :k+l (+ k l) :dim (.dim x)}))))

 ;; ================= Matrix =======================


hidden null network

hidden null network

--- src/clj/swarmpit/docker/engine/mapper/inbound.clj
+++ src/clj/swarmpit/docker/engine/mapper/inbound.clj
@@ -61,6 +61,7 @@
   [networks]
   (->> networks
        (map ->network)
+       (filter #(not (contains? #{"null"} (:driver %))))
        (into [])))

 (defn ->plugins


Working on resize canvas bug.

Working on resize canvas bug.

--- src/cljs/wombats_web_client/panels/game_play.cljs
+++ src/cljs/wombats_web_client/panels/game_play.cljs
@@ -17,15 +17,24 @@
 ;; Helper Methods
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defn- resize-canvas []
+(defn- resize-canvas [arena-atom]
   (let [root-element (first (array-seq (.getElementsByClassName js/document root-class)))
         canvas-element (.getElementById js/document canvas-id)
         half-width (/ (.-offsetWidth root-element) 2)
         height (.-offsetHeight root-element)
         dimension (min height half-width)]

+    (arena/arena @arena-atom canvas-id)
     (set! (.-width canvas-element) dimension)
     (set! (.-height canvas-element) dimension)))
+
+(defn- on-resize [arena-atom cmpnt-state]
+  (let [resize-id (:timeout-fn @cmpnt-state)]
+    (js/clearTimeout resize-id)
+    (let [new-resize-id (js/setTimeout
+                                   #(resize-canvas arena-atom)
+                                   500)]
+      (swap! cmpnt-state assoc :timeout-fn new-resize-id))))

 (defn- show-winner-modal
   [winner]
@@ -36,12 +45,13 @@
 ;; Lifecycle Methods
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

-(defn- component-did-mount [cmpnt-state]
+(defn- component-did-mount [arena cmpnt-state]
   ;; Add resize listener
-  (.addEventListener js/window
-                     "resize"
-                     (:resize-fn @cmpnt-state))
-  (resize-canvas))
+  (let [resize-fn #(on-resize arena cmpnt-state)]
+    (.addEventListener js/window
+                       "resize"
+                       resize-fn))
+  (resize-canvas arena))

 (defn- component-will-mount [game-id]
   (ws/send-message :join-game {:game-id game-id}))
@@ -134,18 +144,19 @@

 (defn game-play [{:keys [game-id]}]
   (let [arena (re-frame/subscribe [:game/arena])
-        cmpnt-state (reagent/atom {:resize-fn #(resize-canvas)})
+        cmpnt-state (reagent/atom {:resize-fn nil
+                                   :timeout-fn nil})
         messages (re-frame/subscribe [:game/messages])
         user (re-frame/subscribe [:current-user])
         games (re-frame/subscribe [:games])]

     (reagent/create-class
-     {:component-did-mount #(component-did-mount cmpnt-state)
+     {:component-did-mount #(component-did-mount arena cmpnt-state)
       :component-will-mount #(component-will-mount game-id)
       :component-will-unmount #(component-will-unmount game-id cmpnt-state)
       :display-name "game-play-panel"
       :reagent-render
-      (fn []
+      (fn [{:keys [game-id]}]
         (let [game (get @games game-id)
               winner (:game/winner game)]
           (arena/arena @arena canvas-id)


refactor simulator render method

refactor simulator render method

--- src/cljs/wombats_web_client/panels/simulator.cljs
+++ src/cljs/wombats_web_client/panels/simulator.cljs
@@ -57,20 +57,20 @@
        (render-tabs active-pane stack-trace)]]]))

 (defn- render
-  [sim-pane
-   templates
-   wombats
-   active-frame
-   stack-trace
-   simulator-display-mini-map
-   simulator-mini-map
-   simulator-state]
+  [{:keys [simulator-pane
+           templates
+           wombats
+           active-frame
+           stack-trace
+           simulator-display-mini-map
+           simulator-mini-map
+           simulator-state]}]
   [:div {:class-name "simulator-panel"}
    [simulator-arena/render (if (and simulator-display-mini-map
                                     simulator-mini-map)
                              simulator-mini-map
                              active-frame)]
-   [render-right-pane @sim-pane stack-trace]
+   [render-right-pane @simulator-pane stack-trace]
    [simulator-controls/render simulator-state simulator-display-mini-map]])

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -78,22 +78,14 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn simulator []
-  (let [simulator-pane (re-frame/subscribe [:simulator/active-pane])
-        templates (re-frame/subscribe [:simulator/templates])
-        wombats (re-frame/subscribe [:my-wombats])
-        active-frame (re-frame/subscribe [:simulator/active-frame])
-        stack-trace (re-frame/subscribe [:simulator/player-stack-trace])
-        simulator-display-mini-map (re-frame/subscribe [:simulator/display-mini-map])
-        simulator-mini-map (re-frame/subscribe [:simulator/mini-map])
-        simulator-state (re-frame/subscribe [:simulator/state])]
-    (reagent/create-class
-     {:component-will-mount #(component-will-mount!)
-      :props-name "simulator-panel"
-      :reagent-render #(render simulator-pane
-                               @templates
-                               @wombats
-                               @active-frame
-                               @stack-trace
-                               @simulator-display-mini-map
-                               @simulator-mini-map
-                               simulator-state)})))
+  (reagent/create-class
+   {:component-will-mount #(component-will-mount!)
+    :props-name "simulator-panel"
+    :reagent-render #(render {:simulator-pane (re-frame/subscribe [:simulator/active-pane])
+                              :templates @(re-frame/subscribe [:simulator/templates])
+                              :wombats @(re-frame/subscribe [:my-wombats])
+                              :active-frame @(re-frame/subscribe [:simulator/active-frame])
+                              :stack-trace @(re-frame/subscribe [:simulator/player-stack-trace])
+                              :simulator-display-mini-map @(re-frame/subscribe [:simulator/display-mini-map])
+                              :simulator-mini-map @(re-frame/subscribe [:simulator/mini-map])
+                              :simulator-state (re-frame/subscribe [:simulator/state])})}))


Address PR comments.

Address PR comments.

--- src/com/farmlogs/conduit/reliable_channel.clj
+++ src/com/farmlogs/conduit/reliable_channel.clj
@@ -137,9 +137,9 @@
   "Listen for Confirm messages.

    A message is Ack'd once the broker routes the message or determines
-  the message is unraoutable.
-
-   A message is Nack'd when the borker encounters an
+  the message is unroutable.
+
+   A message is Nack'd when the broker encounters an
   exception (eg. out of memory or a disk failure) while trying to
   route the message."
   [confirmation-chan]
@@ -160,7 +160,7 @@
   [confirmation-chan]
   (reify ReturnListener
     (handleReturn [_ reply-code reply-text exchange routing-key properties body]
-      (let [headers (-> properties (.getHeaders))]
+      (let [headers (.getHeaders properties)]
         (a/>!! confirmation-chan (->Confirm (get headers (str ::delivery-tag))
                                             false
                                             :failure))
@@ -170,7 +170,7 @@
                      :reply-text reply-text
                      :exchange exchange
                      :routing-key routing-key
-                     :body (-> (Base64/getEncoder) (.encodeToString body))}))))))
+                     :body  (.encodeToString (Base64/getEncoder) body)}))))))

 (defn ->reliable-chan
   "Return an implementation of the the ReliablePublish protocol."


Create sample-params for sample tracks.

Create sample-params for sample tracks.

--- sonic-jam/src/sonic_jam/core.cljs
+++ sonic-jam/src/sonic_jam/core.cljs
@@ -348,6 +348,11 @@
                                (om/transact! (om/observe owner (grids))
                                              (fn [c] (assoc c (get grid "id") grid)))
                                (go (>! set-state-ch grid-id)))
+                             "sample"
+                             (om/transact! cursor (fn [c] (assoc c
+                                                                 "type" value
+                                                                 "sample-params" {})))
+                             "synth"
                              (om/transact! cursor (fn [c] (assoc c
                                                                  "type" value
                                                                  "synth-params" {}))))


Structural validation errors are now strings

--- src/kixi/datastore/structural_validation.clj
+++ src/kixi/datastore/structural_validation.clj
@@ -48,7 +48,7 @@
                                     (take max-errors)) lines)]
         (if (first invalids)
           {::ms/valid false
-           ::ms/explain (map #(s/explain-data schema %) invalids)}
+           ::ms/explain (map #(s/explain-str schema %) invalids)}
           {::ms/valid true})))
     (catch Exception e
       {::ms/valid false


added charity link under Alderhey

added charity link under Alderhey

--- src/prais2/content.cljc
+++ src/prais2/content.cljc
@@ -300,7 +300,8 @@
          [:a (core/href "http://www.thebromptonfountain.org.uk/" :target "_blank") "The Brompton Fountain"]]

    :ACH [[:a (core/href "http://www.alderhey.nhs.uk/departments/cardiac/" :target "_blank") "Liverpool, Alder Hey Hospital"]
-         [:a (core/href "http://www.alderheycharity.org/" :target "_blank") "Alder Hey Charity"]]
+         [:a (core/href "http://www.alderheycharity.org/" :target "_blank") "Alder Hey Charity"]
+         [:a (core/href "https://heartchild.info/web/" :target "_blank") "Children’s Heart Association"]]

    :GUY [[:a (core/href "http://www.evelinalondon.nhs.uk/our-services/hospital/heart-services/overview.aspx" :target "_blank")
           "London, Evelina London Children's Hospital"]


I guess the code is supposed to work in CLJS too

--- src/main/clojure/clojure/test/check/rose_tree.cljc
+++ src/main/clojure/clojure/test/check/rose_tree.cljc
@@ -123,7 +123,9 @@
 (defn ^:private unchunk
   "Returns an equivalent lazy seq that is not chunked."
   [a-lazy-seq]
-  (take Double/POSITIVE_INFINITY a-lazy-seq))
+  (take
+   #?(:clj Double/POSITIVE_INFINITY :cljs js/Infinity)
+   a-lazy-seq))

 (defn shrink
   {:no-doc true}


Fix comment typos

Fix comment typos

--- src/reagent/interop.clj
+++ src/reagent/interop.clj
@@ -57,7 +57,7 @@
     `(aset ~object ~@names ~value)))

 (defmacro .' [& args]
-  ;; Deprecated since names starting with . cause problems with bootstraped cljs.
+  ;; Deprecated since names starting with . cause problems with bootstrapped cljs.
   (let [ns (str cljs.analyzer/*cljs-ns*)
         line (:line (meta &form))]
     (binding [*out* *err*]
@@ -66,7 +66,7 @@
   `($ ~@args))

 (defmacro .! [& args]
-  ;; Deprecated since names starting with . cause problems with bootstraped cljs.
+  ;; Deprecated since names starting with . cause problems with bootstrapped cljs.
   (let [ns (str cljs.analyzer/*cljs-ns*)
         line (:line (meta &form))]
     (binding [*out* *err*]


ccw.util.edn: Wrap tests in deftest

ccw.util.edn: Wrap tests in deftest

--- ccw.core/src/clj/ccw/util/edn.clj
+++ ccw.core/src/clj/ccw/util/edn.clj
@@ -1,6 +1,6 @@
 (ns ccw.util.edn
   (:require [clojure.edn :as edn]
-            [clojure.test :refer [testing is]]))
+            [clojure.test :refer [deftest testing is]]))

 (defn read-vector
   "Reads a vector from the EDN string s. Returns an empty vector if s does not
@@ -14,10 +14,11 @@
       x
       [])))

-(testing "read-vector"
-  (testing "returns the vector in the input string"
-    (is (= [123 456] (read-vector "[123 456]"))))
-  (testing "returns an empty vector if input is invalid EDN"
-    (is (= [] (read-vector "[123"))))
-  (testing "returns an empty vector if input is not a vector"
-    (is (= [] (read-vector "123")))))
+(deftest test-read-vector
+  (testing "read-vector"
+    (testing "returns the vector in the input string"
+      (is (= [123 456] (read-vector "[123 456]"))))
+    (testing "returns an empty vector if the input is invalid EDN"
+      (is (= [] (read-vector "[123"))))
+    (testing "returns an empty vector if the input is not a vector"
+      (is (= [] (read-vector "123"))))))


Rename the xml file from post process street segs

Forgot that doing the post process street segments
writes out a whole new file too, so we need to
rename it in this scenario as well.

--- src/vip/data_processor/output/street_segments.clj
+++ src/vip/data_processor/output/street_segments.clj
@@ -11,7 +11,8 @@
    [vip.data-processor.errors :as errors]
    [vip.data-processor.util :as util])
   (:import
-   [javax.xml.stream XMLInputFactory XMLOutputFactory XMLEventFactory]))
+   [javax.xml.stream XMLInputFactory XMLOutputFactory XMLEventFactory]
+   [java.nio.file Files StandardCopyOption]))

 (defn add-element
   [event-factory writer el-name el-content]
@@ -135,9 +136,9 @@
           (.add writer event)))
       (.close reader)
       (.close writer)
-      (-> (assoc ctx :xml-output-file (.toPath tmpfile))
-          ;; Not sure if we care about this, we may want to just throw it away
-          (assoc :xml-output-file-old xml-output-file)))
+      (assoc ctx :xml-output-file
+             (Files/move (.toPath tmpfile) xml-output-file
+                         (into-array [StandardCopyOption/REPLACE_EXISTING]))))
     ctx))

 (defn insert-street-segment-nodes


fix typo

fix typo

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10504 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/mm.clj
+++ acqEngine/src/org/micromanager/mm.clj
@@ -113,7 +113,7 @@
          (let [result# ~expr]
            (send-to-log
              (str "--> "
-                  (forms-to-log-string
+                  (form-to-log-string
                     result#)))
            result#))))
    ([expr] `(log-cmd 1 ~expr)))


supersets work great

supersets work great

--- test/bluebell/utils/symset_test.clj
+++ test/bluebell/utils/symset_test.clj
@@ -62,5 +62,13 @@
         _ (is (= (supersets-of s #{[:num :num :num]})
                  #{[:num :num :num]
                    {:vec 3}
-                   :map}))]
+                   :map}))
+        s (add-set s {:kattskit 119})
+        _ (is (= (supersets-of s #{{:kattskit 119}})
+                 #{:map {:kattskit 119}}))
+        _ (is (= (supersets-of s #{[:num :num :num]})
+                 #{[:num :num :num]
+                   {:vec 3}
+                   :map}))
+        ]
     ))


Add more tests around Go job aggregation

--- test/buildviz/go/aggregate_test.clj
+++ test/buildviz/go/aggregate_test.clj
@@ -11,6 +11,13 @@
                                            :start start-time
                                            :end end-time
                                            :actual-stage-run actual-stage-run}))
+
+(defn- a-job-instance-with-xml [xml actual-stage-run]
+  {:outcome "pass"
+   :start 100
+   :end 200
+   :actual-stage-run actual-stage-run
+   :junit-xml xml})

 (defn- a-stage-instance [job-instances stage-run]
   {:pipeline-name "my pipeline"
@@ -26,6 +33,11 @@

 (deftest test-aggregate-jobs-for-stage
   (testing "outcome"
+    (testing "should reduce multiple jobs to only one"
+      (is (= 1
+             (count (:job-instances (aggregate/aggregate-jobs-for-stage (a-stage-instance [(a-job-instance "pass" "1")
+                                                                                (a-job-instance "fail" "1")
+                                                                                (a-job-instance "pass" "1")] "1")))))))
     (testing "should set outcome to pass for all jobs passing"
       (is (= "pass"
              (:outcome (aggregated-job-instance (aggregate/aggregate-jobs-for-stage (a-stage-instance [(a-job-instance "pass" "1")
@@ -63,4 +75,10 @@
         (is (= 200
                (:start aggregated-job)))
         (is (= 300
-               (:end aggregated-job)))))))
+               (:end aggregated-job))))))
+
+  (testing "xml"
+    (testing "should merge XML"
+      (is (= "<?xml version=\"1.0\" encoding=\"UTF-8\"?><testsuites><testsuite name=\"some test\"></testsuite><testsuite name=\"another test\"></testsuite></testsuites>"
+             (:junit-xml (aggregated-job-instance (aggregate/aggregate-jobs-for-stage (a-stage-instance [(a-job-instance-with-xml "<testsuites><testsuite name=\"some test\"/></testsuites>" "1")
+                                                                                (a-job-instance-with-xml "<testsuite name=\"another test\"></testsuite>" "1")] "1")))))))))


Updated test-get-calendar

Updated test-get-calendar

--- test/clj_calendar/calendar_test.clj
+++ test/clj_calendar/calendar_test.clj
@@ -114,11 +114,14 @@
         (is (or
             (=  (type  (get-calendar)) java.util.Calendar)
             (=  (type  (get-calendar)) java.util.GregorianCalendar)))
-        (is (>  (.get (get-calendar) (java.util.Calendar/YEAR)) 2000))
-        (is (>= (.get (get-calendar) (java.util.Calendar/MONTH)) 0))
-        (is (<  (.get (get-calendar) (java.util.Calendar/MONTH)) 12))
+        (is (== (.get (get-calendar) (java.util.Calendar/ERA)) java.util.GregorianCalendar/AD))
+        (is (>  (.get (get-calendar) (java.util.Calendar/YEAR)) 2000))       ; must be valid in all cases
+        (is (>= (.get (get-calendar) (java.util.Calendar/MONTH)) 0))         ; must be valid in all cases
+        (is (<  (.get (get-calendar) (java.util.Calendar/MONTH)) 12))        ; must be valid in all cases
         (is (>= (.get (get-calendar) (java.util.Calendar/DAY_OF_MONTH)) 0))
         (is (<= (.get (get-calendar) (java.util.Calendar/DAY_OF_MONTH)) 31)) ; let's be on the safe side
+        (is (>= (.get (get-calendar) (java.util.Calendar/DAY_OF_WEEK_IN_MONTH)) 0))
+        (is (<= (.get (get-calendar) (java.util.Calendar/DAY_OF_WEEK_IN_MONTH)) 4))
         (is (>= (.get (get-calendar) (java.util.Calendar/DAY_OF_YEAR)) 0))
         (is (<= (.get (get-calendar) (java.util.Calendar/DAY_OF_YEAR)) 366)) ; let's be on the safe side
         (is (>= (.get (get-calendar) (java.util.Calendar/WEEK_OF_YEAR)) 0))


test st/explain

test st/explain

--- test/cljc/spec_tools/core_test.cljc
+++ test/cljc/spec_tools/core_test.cljc
@@ -192,11 +192,14 @@
   (testing "without conforming"
     (is (= st/+invalid+ (st/conform spec/int? "12")))
     (is (= {::s/problems [{:path [], :pred 'int?, :val "12", :via [], :in []}]}
-           (st/explain-data spec/int? "12"))))
+           (st/explain-data spec/int? "12")))
+    (is (= "val: \"12\" fails predicate: int?\n"
+           (with-out-str (st/explain spec/int? "12")))))
   (testing "with conforming"
     (is (= 12 (st/conform spec/int? "12" conform/string-conforming)))
-    (is (= nil
-           (st/explain-data spec/int? "12" conform/string-conforming)))))
+    (is (= nil (st/explain-data spec/int? "12" conform/string-conforming)))
+    (is (= "Success!\n"
+           (with-out-str (st/explain spec/int? "12" conform/string-conforming))))))

 (s/def ::height integer?)
 (s/def ::weight integer?)


more motor option adjustments

more motor option adjustments

--- src/stash_bot/core.cljs
+++ src/stash_bot/core.cljs
@@ -134,8 +134,7 @@
         (set! led (js/five.Led. "GPIO16"))
         (set! servo
           (js/five.Servo (clj->js {:pin "GPIO18"
-                                   :type "continuous"
-                                   :deadband [90,92]})))
+                                   :type "continuous"})))
         (next-fn)))))

 (defn- init-web-server []


Formatting.

Formatting.

--- test/clj_ravendb/client_putting_indexes_test.clj
+++ test/clj_ravendb/client_putting_indexes_test.clj
@@ -7,7 +7,10 @@
             [clojure.pprint :as pprint]))

 (let [client (client ravendb-url ravendb-database)
-      idx {:name "DocumentsByName" :alias "doc" :where "doc.name ==\"Test\"" :select "new { doc.name }"}]
+      idx {:name "DocumentsByName"
+           :alias "doc"
+           :where "doc.name ==\"Test\""
+           :select "new { doc.name }"}]
   (deftest test-put-index-with-invalid-index-throws
     (testing "Putting an index with an invalid form."
       (is (thrown? AssertionError


rewrite (defn exception-generator) without recursion: use mapcat instead

--- src/babel/english/morphology.cljc
+++ src/babel/english/morphology.cljc
@@ -894,191 +894,189 @@
                                      :subcat {:1 {:agr {:number :plur
                                                         :person :3rd}}}}}]))))))))

-;; TODO: rewrite with recur or map or similar, rather than recursively.
 (defn exception-generator [lexicon]
-  (if (not (empty? lexicon))
-    (let [lexeme-kv (first lexicon)
-          lexemes (second lexeme-kv)]
-      (let [result (mapcat (fn [path-and-merge-fn]
-                             (let [path (:path path-and-merge-fn)
-                                   merge-fn (:merge-fn path-and-merge-fn)]
-                               ;; a lexeme-kv is a pair of a key and value. The key is a string (the word's surface form)
-                               ;; and the value is a list of lexemes for that string.
-                               (log/trace (str "'" (first lexeme-kv) "' looking at path: " path))
-                               (mapcat (fn [lexeme]
-                                         ;; this is where a unify/dissoc that supported
-                                         ;; non-maps like :top and :fail, would be useful:
-                                         ;; would not need the (if (not (fail? lexeme)..)) check
-                                         ;; to avoid a difficult-to-understand error:
-                                         ;; "java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap"
-                                         (let [lexeme (cond (= lexeme :fail)
-                                                            :fail
-                                                            (= lexeme :top)
-                                                            :top
-                                                            true
-                                                            (copy lexeme))
-                                               debug (if (string? (get-in lexeme path :none))
-                                                       (do (log/trace (str "lexeme:" (strip-refs lexeme)))
-                                                           (log/trace (str "merge-fn: " (strip-refs (merge-fn lexeme))))))
-                                               synsem-check
-                                               (if (string? (get-in lexeme path :none))
-                                                 (unify (get-in lexeme [:synsem])
-                                                         (get-in (merge-fn lexeme) [:synsem] :top)))]
-                                           (if (and (string? (get-in lexeme path :none))
-                                                    (not (fail? synsem-check)))
-                                             (list {(get-in lexeme path)
-                                                    (unify
-                                                     (dissoc-paths lexeme [path
-                                                                           [:english :english]])
-                                                     (merge-fn lexeme)
-                                                     {:synsem synsem-check}
-                                                     {:english {:exception true}})}))))
-                                       lexemes)))
-                           [
-                            ;; 1. plural exceptions: e.g. "men","women":
-                            {:path [:english :plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :noun}
-                                :english {:agr {:number :plur}
-                                          :english (get-in val [:english :plur])}})}
-
-                            ;; <2. past exceptions: e.g. "sleep" -> "slept">
-                            {:path [:english :past :1sing]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :sing
-                                                            :person :1st}}}}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past :1sing])}})}
-
-                            {:path [:english :past :2sing]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :sing
-                                                            :person :2nd}}}}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past :2sing])}})}
-
-                            {:path [:english :past :3sing]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :sing
-                                                            :person :3rd}}}}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past :3sing])}})}
-
-                            {:path [:english :past :1plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :1st}}}}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past :1plur])}})}
-
-                            {:path [:english :past :2plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :2nd}}}}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past :2plur])}})}
-
-                            {:path [:english :past :3plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :3rd}}}}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past :3plur])}})}
-
-                            {:path [:english :past]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb}
-                                :english {:infl :past
-                                          :english (get-in val [:english :past])}})}
-                            ;; </2. past exceptions: e.g. "sleep" -> "slept">
-
-                            ;; <3. present exceptions: e.g. "be" -> "am">
-                            {:path [:english :present :1sing]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :sing
-                                                            :person :1st}}}}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present :1sing])}})}
-
-                            {:path [:english :present :2sing]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :sing
-                                                            :person :2nd}}}}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present :2sing])}})}
-
-                            {:path [:english :present :3sing]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :sing
-                                                            :person :3rd}}}}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present :3sing])}})}
-
-                            {:path [:english :present :1plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :1st}}}}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present :1plur])}})}
-
-                            {:path [:english :present :2plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :2nd}}}}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present :2plur])}})}
-
-                            {:path [:english :present :3plur]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb
-                                         :subcat {:1 {:agr {:number :plur
-                                                            :person :3rd}}}}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present :3plur])}})}
-
-                            {:path [:english :present]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb}
-                                :english {:infl :present
-                                          :english (get-in val [:english :present])}})}
-                            ;; </3. present exceptions: e.g. "be" -> "am"
-
-                            {:path [:english :participle]
-                             :merge-fn
-                             (fn [val]
-                               {:synsem {:cat :verb}
-                                :english {:infl :participle
-                                          :english (get-in val [:english :participle])}})}
-
-
-                            ])]
-        (concat result (exception-generator (rest lexicon)))))))
+  (->>
+   lexicon
+   (mapcat
+    (fn [lexeme-kv]
+      (let [lexemes (second lexeme-kv)]
+        (mapcat (fn [path-and-merge-fn]
+                  (let [path (:path path-and-merge-fn)
+                        merge-fn (:merge-fn path-and-merge-fn)]
+                    ;; a lexeme-kv is a pair of a key and value. The key is a string (the word's surface form)
+                    ;; and the value is a list of lexemes for that string.
+                    (log/trace (str "'" (first lexeme-kv) "' looking at path: " path))
+                    (->> lexemes
+                         (mapcat (fn [lexeme]
+                                   ;; this is where a unify/dissoc that supported
+                                   ;; non-maps like :top and :fail, would be useful:
+                                   ;; would not need the (if (not (fail? lexeme)..)) check
+                                   ;; to avoid a difficult-to-understand error:
+                                   ;; "java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap"
+                                   (let [lexeme (cond (= lexeme :fail)
+                                                      :fail
+                                                      (= lexeme :top)
+                                                      :top
+                                                      true
+                                                      (copy lexeme)) ;; TODO: don't need to (copy)
+                                         debug (if (string? (get-in lexeme path :none))
+                                                 (do (log/trace (str "lexeme:" (strip-refs lexeme)))
+                                                     (log/trace (str "merge-fn: " (strip-refs (merge-fn lexeme))))))
+                                         synsem-check
+                                         (if (string? (get-in lexeme path :none))
+                                           (unify (get-in lexeme [:synsem])
+                                                  (get-in (merge-fn lexeme) [:synsem] :top)))]
+                                     (if (and (string? (get-in lexeme path :none))
+                                              (not (fail? synsem-check))) ;; TODO: (not (= :fail))
+                                       (list {(get-in lexeme path)
+                                              (unify
+                                               (dissoc-paths lexeme [path
+                                                                     [:english :english]])
+                                               (merge-fn lexeme)
+                                               {:synsem synsem-check}
+                                               {:english {:exception true}})}))))))))
+                [
+                 ;; 1. plural exceptions: e.g. "men","women":
+                 {:path [:english :plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :noun}
+                     :english {:agr {:number :plur}
+                               :english (get-in val [:english :plur])}})}
+
+                 ;; <2. past exceptions: e.g. "sleep" -> "slept">
+                 {:path [:english :past :1sing]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :sing
+                                                 :person :1st}}}}
+                     :english {:infl :past
+                               :english (get-in val [:english :past :1sing])}})}
+
+                 {:path [:english :past :2sing]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :sing
+                                                 :person :2nd}}}}
+                     :english {:infl :past
+                               :english (get-in val [:english :past :2sing])}})}
+
+                 {:path [:english :past :3sing]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :sing
+                                                 :person :3rd}}}}
+                     :english {:infl :past
+                               :english (get-in val [:english :past :3sing])}})}
+
+                 {:path [:english :past :1plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :plur
+                                                 :person :1st}}}}
+                     :english {:infl :past
+                               :english (get-in val [:english :past :1plur])}})}
+
+                 {:path [:english :past :2plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :plur
+                                                 :person :2nd}}}}
+                     :english {:infl :past
+                               :english (get-in val [:english :past :2plur])}})}
+
+                 {:path [:english :past :3plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :plur
+                                                 :person :3rd}}}}
+                     :english {:infl :past
+                               :english (get-in val [:english :past :3plur])}})}
+
+                 {:path [:english :past]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb}
+                     :english {:infl :past
+                               :english (get-in val [:english :past])}})}
+                 ;; </2. past exceptions: e.g. "sleep" -> "slept">
+
+                 ;; <3. present exceptions: e.g. "be" -> "am">
+                 {:path [:english :present :1sing]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :sing
+                                                 :person :1st}}}}
+                     :english {:infl :present
+                               :english (get-in val [:english :present :1sing])}})}
+
+                 {:path [:english :present :2sing]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :sing
+                                                 :person :2nd}}}}
+                     :english {:infl :present
+                               :english (get-in val [:english :present :2sing])}})}
+
+                 {:path [:english :present :3sing]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :sing
+                                                 :person :3rd}}}}
+                     :english {:infl :present
+                               :english (get-in val [:english :present :3sing])}})}
+
+                 {:path [:english :present :1plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :plur
+                                                 :person :1st}}}}
+                     :english {:infl :present
+                               :english (get-in val [:english :present :1plur])}})}
+
+                 {:path [:english :present :2plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :plur
+                                                 :person :2nd}}}}
+                     :english {:infl :present
+                               :english (get-in val [:english :present :2plur])}})}
+
+                 {:path [:english :present :3plur]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb
+                              :subcat {:1 {:agr {:number :plur
+                                                 :person :3rd}}}}
+                     :english {:infl :present
+                               :english (get-in val [:english :present :3plur])}})}
+
+                 {:path [:english :present]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb}
+                     :english {:infl :present
+                               :english (get-in val [:english :present])}})}
+                 ;; </3. present exceptions: e.g. "be" -> "am"
+
+                 {:path [:english :participle]
+                  :merge-fn
+                  (fn [val]
+                    {:synsem {:cat :verb}
+                     :english {:infl :participle
+                               :english (get-in val [:english :participle])}})}]))))))
+

 (defn phonize [a-map a-string]
   (let [common {:phrasal false}]


Load main ui using url

Load main ui using url

--- src/atom/core.cljs
+++ src/atom/core.cljs
@@ -11,7 +11,7 @@
                         (clj->js {:width 800
                                   :height 600})))
   ; Path is relative to the compiled js file (main.js in our case)
-  (.loadUrl @main-window (str "file://" js/__dirname "/public/index.html"))
+  (.loadUrl @main-window "http://localhost:3449/index.html")
   (.on @main-window "closed" #(reset! main-window nil)))

 (.start crash-reporter)


Use adjacent-to for adjacent-coords

Use adjacent-to for adjacent-coords

--- src/tile_game/board.clj
+++ src/tile_game/board.clj
@@ -1,5 +1,5 @@
 (ns tile-game.board
-  (:require [tile-game.coordinates :refer [distance]]
+  (:require [tile-game.coordinates :refer [distance adjacent-to]]
             [clojure.math.numeric-tower :as math]
             [clojure.set :as set]
             [clojure.string :as s]))
@@ -46,9 +46,7 @@
   (index->coords board (tile->index board tile)))

 (defn adjacent-coords [board [x y]]
-  (let [adj-loc (map (fn [[dx dy]] [(+ x dx) (+ y dy)])
-                     (vals dir-delta))]
-    (filter (partial bounded-coords? board) adj-loc)))
+  (filter (partial bounded-coords? board) (adjacent-to [x y])))

 (defn- adjacent-tiles [board tile]
   (map (partial coords->tile board)


Fixes copy-paste bug.

Fixes copy-paste bug.

--- src/active/clojure/match.clj
+++ src/active/clojure/match.clj
@@ -354,7 +354,7 @@
   (s/or :required (s/cat :path ::path :binding-key ::binding-key :binding ::binding)))

 (s/def ::optional-path-exists-with-binding
-  (s/or :optional (s/cat :qmark ::qmark :path ::path :binding-key ::binding-key :binding ::binding)))
+  (s/or :required (s/cat :qmark ::qmark :path ::path :binding-key ::binding-key :binding ::binding)))

 (s/def ::key-matches-without-binding
   (s/or :required (s/cat :key ::key :match-value ::match-value)))


fix riffle invocation in benchmark

fix riffle invocation in benchmark

--- src/riffle/cli.clj
+++ src/riffle/cli.clj
@@ -139,7 +139,7 @@

         encoder (if base64? #(bt/decode % :base64) bs/to-byte-array)
         decoder (if base64? #(bt/encode % :base64) identity)
-        riffle (if mmap? r/mapped-riffle r/riffle)]
+        riffle (if mmap? r/mapped-riffle #(r/riffle % (int (/ 1024 (count files)))))]

     (when errors
       (println "Expected arguments:\n" summary "\n")
@@ -160,8 +160,7 @@
           (assert files "must define files to benchmark")
           (flush)
           (let [{:keys [num-reads]} options
-                descriptors (int (/ 1024 (count files)))
-                rs (->> files (map io/file) (map #(riffle descriptors)) vec)]
+                rs (->> files (map io/file) (map riffle) vec)]
             (dotimes [log2-readers 8]
               (let [readers (long (Math/pow 2 log2-readers))]
                 (println)


force import-id to string

force import-id to string

--- src/vip/data_processor/output/xml_helpers.clj
+++ src/vip/data_processor/output/xml_helpers.clj
@@ -6,7 +6,7 @@
 (defn create-xml-file
   [{:keys [import-id] :as ctx}]
   (let [xml-file (Files/createTempFile
-                  import-id ".xml" (into-array FileAttribute []))]
+                  (str import-id) ".xml" (into-array FileAttribute []))]
     (-> ctx
         (assoc :xml-output-file xml-file)
         (update :to-be-cleaned conj xml-file))))


formatting

formatting

--- src/ads_txt_crawler/core.clj
+++ src/ads_txt_crawler/core.clj
@@ -15,7 +15,11 @@
   (let [opts (parse-opts args cli-options)]
     (let [targets-file (or (:targets (:options opts)))
           database-file (:database (:options opts))
-          domains (if targets-file (domains/read-file targets-file) (domains/clean-list args))
-          output-fnc (if database-file (c/save-results database-file) c/print-results)]
+          domains (if targets-file
+                    (domains/read-file targets-file)
+                    (domains/clean-list args))
+          output-fnc (if database-file
+                       (c/save-results database-file)
+                       c/print-results)]
       (c/crawl domains output-fnc))))


Use Nokia instrumented Jetty

Use Nokia instrumented Jetty

--- src/tyranitar/setup.clj
+++ src/tyranitar/setup.clj
@@ -4,7 +4,7 @@
               [clojure.string :as cs :only (split)]
               [clojure.tools.logging :refer (info warn error)]
               [clojure.java.io :as io]
-              [ring.adapter.jetty :refer [run-jetty]])
+              [nokia.adapter.instrumented-jetty :refer [run-jetty]])
     (:import (java.lang Integer Throwable)
              (java.util.logging LogManager)
              (com.yammer.metrics Metrics)


Polished docstrings for lucene.clj

Polished docstrings for lucene.clj

--- src/vix/lucene.clj
+++ src/vix/lucene.clj
@@ -39,9 +39,11 @@
 (def index-path "/var/lucene/vix")

 (defn #^StandardAnalyzer create-analyzer []
+  "Creates a StandardAnalyzer that tokenizes fulltext fields."
   (StandardAnalyzer. (. Version LUCENE_35)))

 (defn create-directory [path]
+  "Create a directory with either :RAM or a directory as the path argument."
   (if (= path :RAM)
     (RAMDirectory.)
     (NIOFSDirectory. (File. path))))
@@ -50,6 +52,7 @@
 (def analyzer (create-analyzer))

 (defn #^IndexReader create-index-reader [#^Directory directory]
+  "Create IndexReader for the specified directory."
   (. IndexReader open directory))

 (defn #^Field create-field
@@ -91,7 +94,7 @@
      (= (class value) java.lang.Long) (.setLongValue field value)
      :default (.setIntValue field -1))))

-(defn distill-plaintext
+(defn #^String distill-plaintext
   "Distills the text values from an HTML string.
    The value of each node is returned on a new line, followed by the
    values of the title attributes of all img nodes"
@@ -109,8 +112,9 @@
                (map #(:title (:attrs %)) (html/select resource [:img]))))))
     html))

-(defn #^Document create-document
-  [vix-doc]
+(defn #^Document create-document [vix-doc]
+  "Creates a Lucene Document object representing the Vix document that
+   is passed as a map (e.g. directly from the database).."
   (let [{:keys [feed
                 slug
                 title
@@ -157,6 +161,8 @@
                                       :indexed)))))

 (defn #^IndexWriter create-index-writer [analyzer directory mode]
+  "Creates an IndexWriter with the provided analyzer and directory.
+   The mode has three options: :create, :append or :create-or-append."
   (let [config (IndexWriterConfig. (Version/LUCENE_35) analyzer)]

     (doto config
@@ -172,13 +178,17 @@
     (IndexWriter. directory config)))

 (defn #^IndexWriter close-index-writer [writer]
+  "Closes the provided IndexWriter and writes the changes to disk (or RAM)."
   (doto writer
     (.close)))

 (defmulti add-documents-to-index!
+  "Supports adding documents to either a provided IndexWriter or
+   through an IndexWriter created for the provided documents specifically."
   (fn [x documents] [(class x) (class documents)]))

 (defmethod add-documents-to-index! [Directory Object] [directory documents]
+  "Adds the documents to the index for the provided directory."
   (let [writer (create-index-writer (create-analyzer)
                                     directory
                                     :create-or-append)]
@@ -186,15 +196,23 @@
     (close-index-writer writer)))

 (defmethod add-documents-to-index! [IndexWriter Object] [writer documents]
+  "Adds the documents to the provided IndexWriter, but doesn't close it
+   (i.e. the IndexWriter needs to be closed externally to write the
+   changes to disk or memory)."
   (doseq [document documents]
     (.addDocument writer (create-document document))))

 (defn delete-document-from-index! [directory slug]
+  "Deletes the document with the provided slug from the provided Lucene
+   Directory object."
   (doto (create-index-writer (create-analyzer) directory :append)
     (.deleteDocuments (Term. "slug" slug))
     (.close)))

 (defn update-document-in-index! [directory slug document]
+  "Deletes the existing document with the provided slug from the
+   provided Lucene Directory object and creates a new document using
+   the provided document map."
   (let [analyzer (create-analyzer)]
     (doto (create-index-writer analyzer directory :append)
       (.updateDocument (Term. "slug" slug)
@@ -214,7 +232,18 @@
       (NumericRangeQuery/newLongRange field-name min max true true))))

 (defn #^QueryWrapperFilter create-filter [filters]
-  "Creates a filter for the category, which is wrapped in double quotes."
+  "Creates a Lucene BooleanQuery wrapped in a QueryWrapperFilter with one
+   or more filter queries (if zero this function returns nil).
+
+   The following filters are possible:
+   :published-between {:min rfc3339-date-string :max rfc-3339-date-string}
+   :updated-between {:min rfc3339-date-string :max rfc-3339-date-string}
+   :language String (literal)
+   :feed String (literal)
+   :slug String (literal)
+   :draft Boolean
+
+   See the unit tests for examples."
   (let [{:keys [published-between
                 updated-between
                 language
@@ -263,6 +292,10 @@
       (QueryWrapperFilter. bq))))

 (defn search
+  "Runs a query (with or without a filter) and returns the result.
+   Also able to paginate when after-doc-id and after-score are provided.
+   See the unit tests for examples. The return value is a map with
+   :total-hits and :docs."
   ([query filter limit reader analyzer]
      (search query filter limit nil nil reader analyzer))
   ([query filter limit after-doc-id after-score reader analyzer]
@@ -318,12 +351,16 @@
           (drop (* per-page (- target-page 1)) (:docs result)))))))

 (defn #^Document get-doc [reader doc-id]
+  "Reads the document with the provided doc-id from the index."
   (.document reader doc-id))

-(defn get-docs [reader docs]
-  (map #(get-doc reader (.doc %)) docs))
+(defn get-docs [reader score-docs]
+  "Returns a sequence of the individual documents for a Lucene ScoreDoc[]
+   array."
+  (map #(get-doc reader (.doc %)) score-docs))

 (defn document-to-map [document]
+  "Converts a Lucene document to a Vix document map."
   {:slug (.get document "slug")
    :title (.get document "title")
    :feed (.get document "feed")


Update docs.

Update docs.

--- src/clj/forma/hadoop/jobs/cdm.clj
+++ src/clj/forma/hadoop/jobs/cdm.clj
@@ -1,4 +1,7 @@
 (ns forma.hadoop.jobs.cdm
+  "This namespace defines a Cascalog query to convert FORMA data in MODIS
+  coordinates into map tile coordinates for use in Global Forest Watch
+  visualizations."
   (:use [cascalog.api]
         [forma.gfw.cdm :only (latlon->google-tile)]
         [forma.utils :only (positions)])
@@ -8,15 +11,36 @@
             [cascalog.ops :as c]))

 (defn first-hit
+  "Returns the first value in a vector of numbers that is greater than or equal
+   to a threshold.
+
+  Arguments:
+    thresh - The threshold value.
+    series - A vector of numbers.
+
+  Example usage:
+    > (first-hit 5 [1 2 3 4 5 6 7 8 9 10])
+    > 5
+  "
   [thresh series]
   (first (positions (partial <= thresh) series)))

 (defn convert-for-vizz
-  "Output x,y,z and period of first detection greater than threshold, per specification of common data model with Vizzuality.
+  "Output x,y,z and period of first detection greater than threshold, per
+   specification of common data model with Vizzuality.

-  Usage:
-   (?- (hfs-seqfile \"s3n://formaresults/analysis/xyzperiod\")
-     (get-first-hit (hfs-seqfile \"s3n://formaresults/finaloutput\") 50 \"16\"))"
+  Arguments:
+    est-map - A mapping that contains :est-start key with a datestring value
+    forma-src - The FORMA source data tap
+    thresh - The threshold number
+    t-res - The temporal resolution as a string
+    out-t-res - The output temporal resolution as a string
+
+  Example usage:
+   > (let [source-tap (hfs-seqfile \"s3n://formaresults/finaloutput\")
+           sink-tap (hfs-seqfile \"s3n://formaresults/analysis/xyzperiod\")]
+   >   (?- sink-tap
+   >     (convert-for-vizz source-tap 50 \"16\" \"32\"))"
   [est-map forma-src thresh t-res out-t-res]
   (let [epoch-period (date/datetime->period out-t-res "2000-01-01")
         ts-start-period (date/datetime->period t-res (:est-start est-map))
@@ -30,4 +54,4 @@
         (- ?period-new-res epoch-period :> ?relative-period)
         (r/modis->latlon ?s-res ?mod-h ?mod-v ?s ?l :> ?lat ?lon)
         (latlon->google-tile ?lat ?lon z :> ?tx ?ty)
-        (identity z :> ?z))))+        (identity z :> ?z))))