Switch to character tracking for primary values.

--- src/vault/data.clj
+++ src/vault/data.clj
@@ -6,10 +6,11 @@
     [fipp.printer :refer [pprint-document]]
     [puget.printer :as puget])
   (:import
-    clojure.lang.LineNumberingPushbackReader
     java.io.ByteArrayOutputStream
-    java.io.FilterInputStream
+    java.io.FilterReader
     java.io.InputStreamReader
+    java.io.OutputStreamWriter
+    java.io.PushbackReader
     java.nio.charset.Charset))

@@ -75,27 +76,40 @@
         false))))

-(defn- capturing-input-stream
-  "Wraps the given input stream with a proxy which will record the bytes read
-  to the given output stream."
-  [input output]
-  (proxy [FilterInputStream] [input]
-    (read
-      ([]
-       (let [b (.read input)]
-         (.write output b)
-         b))
-      ([buf off len]
-       (let [n (.read input buf off len)]
-         (.write output buf off n)
-         n)))))
-
-
 (def ^:dynamic *primary-bytes*
   "If bound when `read-data` is called, this var is set to an array containing
   the bytes which comprise the 'primary' EDN value in a data blob. These bytes
   are the target for inline signatures."
   nil)
+
+
+(defn- capturing-reader
+  "Wraps the given reader with a proxy which records the characters read to the
+  given output stream."
+  [input output]
+  (proxy [FilterReader] [input]
+    (read
+      ([]
+       (let [c (.read input)]
+         (.write output c)
+         c)))))
+
+
+(defn- read-primary-value!
+  "Reads the primary EDN value from a data blob. If *primary-bytes* is
+  thread-bound, it will be set to an array of bytes which form the value. This
+  is accomplished by copying the read characters into a byte array as they are
+  consumed by the EDN parser. Returns the parsed value."
+  [reader]
+  (let [copy-bytes (ByteArrayOutputStream.)
+        copy-writer (OutputStreamWriter. copy-bytes blob-charset)
+        reader (PushbackReader. (capturing-reader reader copy-writer))
+        ; TODO: specify readers? {:readers puget.data/data-readers}
+        value (edn/read reader)]
+    (when (thread-bound? #'*primary-bytes*)
+      (.flush copy-writer)
+      (set! *primary-bytes* (.toByteArray copy-bytes)))
+    value))

 (defn read-data
@@ -105,15 +119,8 @@
   [input]
   ; TODO: ensure `mark` is supported
   (if (read-header! input)
-    (let [primary-bytes (ByteArrayOutputStream.)
-          reader (-> input
-                     (capturing-input-stream primary-bytes)
-                     (InputStreamReader. blob-charset)
-                     LineNumberingPushbackReader.)
-          primary-value (edn/read reader)]
-      ; TODO: specify readers? {:readers puget.data/data-readers}
-      (when (thread-bound? #'*primary-bytes*)
-        (set! *primary-bytes* (.toByteArray primary-bytes)))
+    (let [reader (InputStreamReader. input blob-charset)
+          primary-value (read-primary-value! reader)]
       ; TODO: read remaining values from the stream
       primary-value)
     input))


is-text-content-type and no-content-type-header

Sometimes, for example, time.com and fortune.com will return their ads.txt page without a content-type header setting

In this case we need to:

a) call fixup-stream to slurp the stream to a string
b) assume we have text and read the data

--- src/ads_txt_crawler/crawl.clj
+++ src/ads_txt_crawler/crawl.clj
@@ -33,16 +33,19 @@
   (if (not (comment-line line))
     (parse-line line)))

-(defn is-text
-  "Do we have a text document.
+(defn is-text-content-type
+  "Do we have a content-type == text/plain

 Note: It was observed that some companies are returning text but not including a Content-Type value.
 So, we assume if there is no content-type header that we have text
 If there is a content-type header we'll check as before to ensure that it is set to text/plain/."
-  [url headers]
-  (if (contains? headers :content-type)
-    (clojure.string/starts-with? (:content-type headers) "text/plain")
-    true))
+  [headers]
+  (and (contains? headers :content-type)
+       (clojure.string/starts-with? (:content-type headers) "text/plain")))
+
+
+(defn no-content-type-header [headers]
+  (not (contains? headers :content-type)))

 (defn is-error [status]
   (>= status 400))
@@ -55,12 +58,12 @@
   [domain]
   (let [url (build-url domain)]
     ;; read the contents of url
-    ;; - ignore non-text returns
+    ;; - ignore non-text returns1
     ;; - ignore commented lines
     ;; - parse lines into map of values
     ;; - ignore
     (let [rtn {:domain domain}
-          {:keys [status headers body error] :as resp} (h/get-url url)]
+          {:keys [status headers body error] :as resp} (h/fixup-stream (h/get-url url))]
       (if error
         (assoc rtn :error true :message (format "Error: %s for %s" (.toString error) url))
         (if status
@@ -70,13 +73,16 @@
             ;; Issue without having headers
             (if (not headers)
               (assoc rtn :error true :status status (format "Error: headers are blank for %s" url))
-              ;; Non-text returned
-              (if (not (is-text url headers))
-                (assoc rtn :error true :status status :message (format "Error: non-text result for %s" url))
+              ;; If we have a content-type it needs to be text-plain
+              ;; Else if we are missing a content-type let's assume/hope that we have a text
+              ;; Note: without a content-type httpkit returns a stream so we need to call fixup-stream after get-url
+              (if (or (is-text-content-type headers) (no-content-type-header headers))
                 ;; Valid data. Process and return as data
                 (assoc rtn :error false :status status :records (remove nil? (map process-line (clojure.string/split-lines body))))
+                ;; Non-text returned
+                (assoc rtn :error true :status status :message (format "Error: non-text result for %s" url))
                 )))
-          ;; No status, No error
+          ;; No status, No errorbhtt
           (assoc rtn :error true :message (format "Error: Unknown issue calling %s" url)))))))

 (defn print-results


Add println debug

Add println debug

--- src/antlion_clojure/redis.clj
+++ src/antlion_clojure/redis.clj
@@ -2,6 +2,8 @@
   (:require [environ.core :refer [env]]
             [carmine-sentinel.core :as cs :refer [set-sentinel-groups!]]
             [taoensso.carmine :as car :refer [wcar]]))
+
+(println {:host (env :redis-sentinel-service-host) :port (env :redis-sentinel-service-port)})

 (set-sentinel-groups!
   {:redis-sentinel-service


Not finding poms, etc. in a repo isn't an error

When an artifact is in one of the Maven repositories configured in boot
but not in all of them you would see error messages about not being able
to find the artifact in those repositories. This isn't really an error
because if it's found in another repo it's fine.

--- boot/aether/src/boot/aether.clj
+++ boot/aether/src/boot/aether.clj
@@ -1,20 +1,21 @@
 (ns boot.aether
   (:require
-   [clojure.java.io             :as io]
-   [clojure.string              :as string]
-   [clojure.pprint              :as pprint]
-   [cemerick.pomegranate.aether :as aether]
-   [boot.util                   :as util]
-   [boot.pod                    :as pod]
-   [boot.gpg                    :as gpg]
-   [boot.from.io.aviso.ansi     :as ansi]
-   [boot.kahnsort               :as ksort])
+    [clojure.java.io             :as io]
+    [clojure.string              :as string]
+    [clojure.pprint              :as pprint]
+    [cemerick.pomegranate.aether :as aether]
+    [boot.util                   :as util]
+    [boot.pod                    :as pod]
+    [boot.gpg                    :as gpg]
+    [boot.from.io.aviso.ansi     :as ansi]
+    [boot.kahnsort               :as ksort])
   (:import
-   [boot App]
-   [java.io File]
-   [java.util.jar JarFile]
-   [java.util.regex Pattern]
-   [org.sonatype.aether.resolution DependencyResolutionException]))
+    [boot App]
+    [java.io File]
+    [java.util.jar JarFile]
+    [java.util.regex Pattern]
+    [org.sonatype.aether.resolution DependencyResolutionException]
+    [org.sonatype.aether.transfer MetadataNotFoundException ArtifactNotFoundException]))

 (def offline?             (atom false))
 (def update?              (atom :daily))
@@ -33,22 +34,42 @@
 (defn update-always!  []  (set-update! :always))
 (defn set-local-repo! [x] (reset! local-repo x))

+(defmulti on-transfer (fn [info] (:type info)))
+
+(defmethod on-transfer :started
+  [{:keys [method] {:keys [name repository size]} :resource}]
+  (letfn [(->k [size]
+            (when-not (neg? size)
+              (format " (%sk)" (Math/round (double (max 1 (/ size 1024)))))))]
+    (util/info "%s %s %s %s%s\n"
+      (case method :get "Retrieving" :put "Sending")
+      (.getName (io/file name))
+      (case method :get "from" :put "to")
+      repository
+      (str (->k size)))))
+
+(defmethod on-transfer :succeeded
+  [_])
+
+(defmethod on-transfer :corrupted
+  [{:keys [error]}]
+  (when error
+    (util/fail "%s\n" (.getMessage error))))
+
+(defmethod on-transfer :failed
+  [{:keys [error]}]
+  (when (and error
+             (not (instance? MetadataNotFoundException error))
+             (not (instance? ArtifactNotFoundException error)))
+    (util/fail "%s\n" (.getMessage error))))
+
+(defmethod on-transfer :default
+  [_])
+
 (defn transfer-listener
-  [{type :type meth :method {name :name repo :repository size :size} :resource err :error :as info}]
+  [info]
   (util/dbug "Aether: %s\n" (with-out-str (pprint/pprint info)))
-  (letfn [(->k [size] (if (neg? size) "" (str (Math/round (double (max 1 (/ size 1024)))))))]
-    (case type
-      :started
-      (util/info "%s %s from %s (%sk)\n"
-        (case meth :get "Retrieving" :put "Sending")
-        (.getName (io/file name))
-        repo
-        (->k size))
-
-      (:corrupted :failed)
-      (when err (util/fail "%s\n" (.getMessage err)))
-
-      nil)))
+  (on-transfer info))

 (defn ^{:boot/from :technomancy/leiningen} build-url
   "Creates java.net.URL from string"


fixed tab + whitespaces at end of lines

fixed tab + whitespaces at end of lines

--- instapapure.clj
+++ instapapure.clj
@@ -5,7 +5,7 @@
 ;; Database Layer ;;
 ;; ************** ;;

-(def db
+(def db
   {:classname "org.hsqldb.jdbcDriver"
    :subprotocol "hsqldb"
    :subname "file:db/instapapure"})
@@ -13,25 +13,25 @@
 (defn now [] (java.sql.Timestamp. (.getTime (java.util.Date.))))

 (defn create-instapapure-tables []
-  (create-table :posts
+  (create-table :posts
     [:id :int "IDENTITY" "PRIMARY KEY"]
     [:location :varchar "NOT NULL"]
     [:title :varchar "NOT NULL"]
     [:created_at :datetime]))

-;; we put the table creation in a try.
+;; we put the table creation in a try.
 ;; All calls after the 1st one will fail because the table is already there
 (try
   (with-connection db (create-instapapure-tables))
   (catch Exception _))

-(defn insert-post [location title]
+(defn insert-post [location title]
   (with-connection db
     (transaction
       (insert-values :posts
         [:location :title :created_at]
         [ location   title  (now)]))))
-
+
 (defn select-posts []
   (with-connection db
     (with-query-results res ["select * from posts"] (doall res))))
@@ -53,12 +53,12 @@
       [:h1 title]
       body]))

-(defn display-post [post]
-  [:li
+(defn display-post [post]
+  [:li
     [:span "(" (:id post) ") "]
     [:a {:href (:location post)} (:title post)]
     [:div " created at " (:created_at post)]])
-
+
 (defn show-posts []
   (layout "All Posts"
     (html
@@ -66,7 +66,7 @@
         (map display-post (select-posts))]
       [:a {:href "/post"} "New Post"]
       [:p "Drag the bookmarklet: "
-        [:a {:href bookmarklet} "Read later"]])))
+        [:a {:href bookmarklet} "Read later"]])))

 (defn new-post [location title]
   (insert-post location title)
@@ -83,20 +83,20 @@
       [:input {:type "text" :name "t"}]
       [:br]
       (submit-button "save"))))
-
+
 (defroutes instapapure-app
-   (GET "/public/*"
-     (or (serve-file (params :*)) :next))
-   (GET "/"
-       (show-posts))
-   (GET "/posts"
-     (show-posts))
-   (GET "/post"
-      (create-post))
-   (POST "/post"
-      (new-post (:l params) (:t params)))
-   (ANY "*"
-     (page-not-found)))
+  (GET "/public/*"
+    (or (serve-file (params :*)) :next))
+  (GET "/"
+    (show-posts))
+  (GET "/posts"
+    (show-posts))
+  (GET "/post"
+    (create-post))
+  (POST "/post"
+    (new-post (:l params) (:t params)))
+  (ANY "*"
+    (page-not-found)))

 (run-server {:port 8080}
-  "/*" (servlet instapapure-app))
+  "/*" (servlet instapapure-app))


Use defrender name as IDisplayName

Use defrender name as IDisplayName

--- frontend/utils.clj
+++ frontend/utils.clj
@@ -41,6 +41,8 @@
   [name args & body]
   `(defn ~name ~args
      (reify
+       om.core/IDisplayName
+       (~'display-name [~'_] ~(str name))
        om.core/IRender
        (~'render [~'_] ~@body))))


Fixed broken post structure

Fixed broken post structure

--- resources/fragments/onvim.clj
+++ resources/fragments/onvim.clj
@@ -3,17 +3,17 @@
  [:h2 "~ or ~"]
  [:h1 "Straw Horses & VIM: How They Tell You Editing Sucks, VS How It Actually Sucks"]
  [:h2 "Oliver Mooney"]
- [:section
-  [:p [:span.newthought "I am typing this in "
-       [:a {:href "http://spacemacs.org"} "Spacemacs"]
-       ]
-   ", a version of Emacs that's been overhauled to operate like Vim."]
-  [:p "I've watched "[:a {:href "https://vimeo.com/53144573"} "Drew Neil's talk on Vim"] " and bought his book, which I'm still working throuh. I've run through the VimTutor more than once, in Vim and in Spacemacs, and I've used Spacemacs for real work (both client work and to build the static site generator that creates these pages)."]
-  [:ul
-   [:li "The mouse is BAD (not if you've played video games all your life, it's not; first-person shooters are ALL ABOUT hitting arbitrary tiny targets fast, and I've been doing that for a decade or more for fun; and these days the touchpad on laptops is always in the same place, vastly reducing time needed to find & use it). For example, Neil (around 33 minutes into his talk) talks about a notional touch interaction where you've to pick out the opening and closing brackets/tags/quotes of a section of text to highlight them. But who would suggest that?! There's already a great way of selecting the matching closing tag in a text using a mouse: double-click the opening (or closing) tag. IntelliJ does this, and I'm sure others do too. It works " [:emphasis "without"] " you having to even consider the type of tag and finding it's matching symbol on the keyboard. The v-a-t workflow Neil describes is " [:strong "great"] ", but made-up examples of poor alternatives don't sell it."]
-   [:li "The cursor keys are BAD because... reasons?"]
-   [:li "Macros! Macros are the best. (Story about editing 23MB file here, long line lengths, v-a-t, automating in a macro)"]
-   [:li "Going backwards through text or shrinking text selections seems arbitrarily hard"]
-   [:li "The God-damned pound symbol (aka why I gave up on Emacs more than once)"]
-   [:li "You can't contract selections, only expand them (cf. Drew Neil again, c. 47:30). BOOOOO."]]]
+ [:section   [:p [:span.newthought "I am typing this in "
+                  [:a {:href "http://spacemacs.org"} "Spacemacs"]
+                  ]
+              ", a version of Emacs that's been overhauled to operate like Vim."]

+  [:p "I've watched "[:a {:href "https://vimeo.com/53144573"} "Drew Neil's talk on Vim"] " and bought his book, which I'm still working throuh. I've run through the VimTutor more than once, in Vim and in Spacemacs, and I've used Spacemacs for real work (both client work and to build the static site generator that creates these pages)."
+   [:ul
+    [:li "The mouse is BAD (not if you've played video games all your life, it's not; first-person shooters are ALL ABOUT hitting arbitrary tiny targets fast, and I've been doing that for a decade or more for fun; and these days the touchpad on laptops is always in the same place, vastly reducing time needed to find & use it). For example, Neil (around 33 minutes into his talk) talks about a notional touch interaction where you've to pick out the opening and closing brackets/tags/quotes of a section of text to highlight them. But who would suggest that?! There's already a great way of selecting the matching closing tag in a text using a mouse: double-click the opening (or closing) tag. IntelliJ does this, and I'm sure others do too. It works " [:emphasis "without"] " you having to even consider the type of tag and finding it's matching symbol on the keyboard. The v-a-t workflow Neil describes is " [:strong "great"] ", but made-up examples of poor alternatives don't sell it."]
+    [:li "The cursor keys are BAD because... reasons?"]
+    [:li "Macros! Macros are the best. (Story about editing 23MB file here, long line lengths, v-a-t, automating in a macro)"]
+    [:li "Going backwards through text or shrinking text selections seems arbitrarily hard"]
+    [:li "The God-damned pound symbol (aka why I gave up on Emacs more than once)"]
+    [:li "You can't contract selections, only expand them (cf. Drew Neil again, c. 47:30). BOOOOO."]]]]]
+


parse arglists from attribute map to get proper usage of defmacro

--- src/main/cljs_api_gen/parse.clj
+++ src/main/cljs_api_gen/parse.clj
@@ -139,6 +139,9 @@
         doc-forms (cond-> []
                     docstring (conj docstring)
                     attr-map (conj attr-map))
+        arglists (when-let [arglists (:arglists attr-map)]
+                   (when (= 'quote (first arglists))
+                     (second arglists)))
         signatures (if (vector? (first args))
                      (take 1 args)
                      (map first args))
@@ -152,7 +155,7 @@
               (not private?))
       {:expected-docs expected-docs
        :docstring (fix-docstring docstring)
-       :signature signatures
+       :signature (or arglists signatures)
        :type (cond
                constructor? "type"
                macro? "macro"


Only note that the stream exists if the stream exists.

--- twitter-producer/src/twitter_producer/core.clj
+++ twitter-producer/src/twitter_producer/core.clj
@@ -84,8 +84,10 @@
 (defn cleanup []
   (info "Cancelling the Twitter stream")
   (client/cancel-twitter-stream twitter-stream)
-  (info "Note that Kinesis stream" (-> kinesis-stream :stream-description :stream-arn)
-        "still exists"))
+  (when kinesis-stream
+    (info "Note that Kinesis stream"
+          (-> kinesis-stream :stream-description :stream-arn)
+          "still exists")))

 (defn -main
   "I don't do a whole lot ... yet."


Fix config handling in weasel component

Fix config handling in weasel component

--- weasel/src/clj/com/palletops/bakery/weasel.clj
+++ weasel/src/clj/com/palletops/bakery/weasel.clj
@@ -20,6 +20,8 @@
   has a function to start the weasel repl on the server side."
   {:sig [[WeaselOptions :- Weasel]]}
   [{:keys [host port] :as config}]
-  {:config (merge {:host "localhost" :port 9001} config)
-   :start-repl! #(piggieback/cljs-repl
-                  :repl-env (weasel/repl-env :ip host :port port))})
+  (let [config (merge {:host "localhost" :port 9001} config)]
+    {:config config
+     :start-repl! #(piggieback/cljs-repl
+                    :repl-env (weasel/repl-env
+                               :ip (:host config) :port (:port config)))}))


Factor out mount-webdav for #42

Factor out mount-webdav for #42

--- Clojure/src/ambly/repl/jsc.clj
+++ Clojure/src/ambly/repl/jsc.clj
@@ -217,6 +217,17 @@
   (when (:shutdown-agents-on-quit (:options repl-env))
     (shutdown-agents)))

+(defn- mount-webdav!
+  [repl-env endpoint-address endpoint-port]
+  (let [webdav-mount-point (str "/Volumes/Ambly-" endpoint-address ":" endpoint-port)
+        output-dir (io/file webdav-mount-point)]
+    (when (.exists output-dir)
+      (shell/sh "umount" webdav-mount-point))
+    (.mkdirs output-dir)
+    (shell/sh "mount_webdav" (str "http://" endpoint-address ":" endpoint-port) webdav-mount-point)
+    (reset! (:webdav-mount-point repl-env) webdav-mount-point)
+    webdav-mount-point))
+
 (defn setup
   [repl-env opts]
   (try
@@ -224,16 +235,11 @@
           [bonjour-name endpoint] (discover-and-choose-device (:choose-first-discovered (:options repl-env)) opts)
           endpoint-address (.getHostAddress (:address endpoint))
           endpoint-port (:port endpoint)
-          webdav-mount-point (str "/Volumes/Ambly-" endpoint-address ":" endpoint-port)
+          webdav-mount-point (mount-webdav! repl-env endpoint-address endpoint-port)
           output-dir (io/file webdav-mount-point)
           env (ana/empty-env)
           core (io/resource "cljs/core.cljs")]
       ((println-fn opts) "\nConnecting to" (bonjour-name->display-name bonjour-name) "...\n")
-      (reset! (:webdav-mount-point repl-env) webdav-mount-point)
-      (when (.exists output-dir)
-        (shell/sh "umount" webdav-mount-point))
-      (.mkdirs output-dir)
-      (shell/sh "mount_webdav" (str "http://" endpoint-address ":" endpoint-port) webdav-mount-point)
       (reset! (:socket repl-env)
         (socket endpoint-address (dec endpoint-port)))
       ;; Start dedicated thread to read messages from socket


Disabled an integration test that won't work because we don't have integration between our local jenkins and DynamoDB in AWS.

--- test/onix/integration.clj
+++ test/onix/integration.clj
@@ -42,10 +42,16 @@
                body (read-body response)]
            response => (contains {:status 200})))

-   (fact "Getting list of applications works"
-         (let [response (client/get (url+ "/applications") {:throw-exceptions false})
-               body (read-body response)
-               applications (:applications body)
-               count (count applications)]
-           response => (contains {:status 200})
-           (> count 0) => true)))
+   ;; This doesn't work because our local jenkins doesn't have credentials for
+   ;; access DynamoDB in AWS. We could set up the credentials but they'll keep
+   ;; having to be renewed. Or we could set up a jenkins *in* AWS? Or just not
+   ;; bother?
+
+   ;; (fact "Getting list of applications works"
+   ;;       (let [response (client/get (url+ "/applications") {:throw-exceptions false})
+   ;;             body (read-body response)
+   ;;             applications (:applications body)
+   ;;             count (count applications)]
+   ;;         response => (contains {:status 200})
+   ;;         (> count 0) => true))
+   )


configure project

configure project

--- datomic-dsl/project.clj
+++ datomic-dsl/project.clj
@@ -1,9 +1,6 @@
 (defproject datomic-dsl "0.1.0-SNAPSHOT"
-  :description "FIXME: write description"
-  :url "http://example.com/FIXME"
-  :license {:name "Eclipse Public License"
-            :url "http://www.eclipse.org/legal/epl-v10.html"}
-  :dependencies [[org.clojure/clojure "1.8.0"]]
+  :dependencies [[org.clojure/clojure "1.8.0"]
+                 [com.datomic/datomic-free "0.9.5350" :exclusions [joda-time]]]
   :main ^:skip-aot datomic-dsl.core
   :target-path "target/%s"
   :profiles {:uberjar {:aot :all}})


added test for join

added test for join

--- test/selmer/core_test.clj
+++ test/selmer/core_test.clj
@@ -467,6 +467,12 @@
   (is (thrown? Exception (render "{{f|hash:\"foo\"}}" {:f "foo"}))))

+(deftest filter-join
+  (is (= "1, 2, 3, 4"
+         (render "{{sequence|join:\", \"}}" {:sequence [1 2 3 4]})))
+  (is (= "1234"
+         (render "{{sequence|join}}" {:sequence [1 2 3 4]}))))
+
 (deftest filter-count
   (is (= "3" (render "{{f|count}}" {:f "foo"})))
   (is (= "4" (render "{{f|count}}" {:f [1 2 3 4]})))


Two tests pass!

Two tests pass!

--- test/test/datascript.cljs
+++ test/test/datascript.cljs
@@ -11,18 +11,21 @@

 (deftest test-joins
   (let [db (-> (dc/init-db)
-               (dc/add-record 1 :name "Ivan")
-               (dc/add-record 2 :name "Petr")
-               (dc/add-record 3 :name "Ivan")
-               (dc/add-record 1 :age 15)
-               (dc/add-record 2 :age 37)
-               (dc/add-record 3 :age 37)
-               (dc/add-record 4 :age 15))]
+               (dc/add-record 1 "name" "Ivan")
+               (dc/add-record 2 "name" "Petr")
+               (dc/add-record 3 "name" "Ivan")
+               (dc/add-record 1 "age" 15)
+               (dc/add-record 2 "age" 37)
+               (dc/add-record 3 "age" 37)
+               (dc/add-record 4 "age" 15))]
     (d/q '[:find ?w
-          :where [?w :name]] (fn [result]
-                                (println "result" result)
-                                (is (= result #{[1] [2] [3]}))) db)))
-
+          :where [?w "name"]] (fn [result]
+                                (is (= result #{[1] [2] [3]}))) db)
+   (d/q '[:find  ?e ?v
+           :where [?e "name" "Ivan"]
+                  [?e "age" ?v]] (fn [result]
+                         (is (= result #{[1 15] [3 37]}))) db)
+    ))

 ;(deftest test-joins
 ;  (let [db (-> (d/empty-db)


adding type validations

adding type validations

--- src/celestial/persistency.clj
+++ src/celestial/persistency.clj
@@ -17,7 +17,7 @@
     [celestial.roles :only (roles admin)]
     [cemerick.friend.credentials :as creds]
     [bouncer [core :as b] [validators :as v]]
-    [celestial.validations :only (str-v set-v validate! validate-nest)]
+    [celestial.validations :only (str-v set-v hash-v validate! validate-nest)]
     [clojure.string :only (split join)]
     [celestial.redis :only (wcar hsetall*)]
     [slingshot.slingshot :only  [throw+ try+]]
@@ -55,16 +55,31 @@

 (entity type :id type)

-(defn validate-type [t])
+(defn type-base-v [v]
+  (b/validate v [:type] [v/required]))
+
+(defn puppet-std-v [t]
+  (validate-nest t [:puppet-std]
+    [:module :name] [v/required str-v]
+    [:module :src] [v/required str-v]))
+
+(defn classes-v [t]
+   (validate t [:classes] [hash-v]))
+
+(defn validate-type [t]
+  (validate!
+    (cond-> (-> t type-base-v second)
+     (t :classes) (-> classes-v second)
+     (t :puppet-std) (-> puppet-std-v second)) ::non-valid-type))

 (entity system :indices [type])

 (defn validate-system
   [system]
- (validate!
+  (validate!
     (b/validate system
-      ;; [:type] [v/custom type-exists? :message "missing system type"]
-      [:machine :hostname]  [v/required str-v])
+       ;; [:type] [v/custom type-exists? :message "missing system type"]
+       [:machine :hostname]  [v/required str-v])
     ::non-valid-machine))

 (defn clone-system


Changed source to src in fire.

Changed source to src in fire.

--- src/clj/forma/source/fire.clj
+++ src/clj/forma/source/fire.clj
@@ -107,9 +107,9 @@
   position and value all defined. In this case, the value `?tuple` is
   a `FireTuple` thrift object containing all relevant characteristics
   of fires for that particular day."
-  [source]
+  [src]
   (<- [?dataset ?date ?t-res ?lat ?lon ?tuple]
-      (source ?line)
+      (src ?line)
       (p/mangle ?line :> ?lat ?lon ?kelvin _ _ ?datestring _ _ ?conf _ _ _)
       (p/add-fields "fire" "01" :> ?dataset ?t-res)
       (format-datestring ?datestring :> ?date)
@@ -118,8 +118,8 @@
 (defn reproject-fires
   "Aggregates fire data at the supplied path by modis pixel at the
   supplied resolution."
-  [m-res source]
-  (let [fires (fire-source source)]
+  [m-res src]
+  (let [fires (fire-source src)]
     (<- [?dataset ?m-res ?t-res ?tilestring ?date ?sample ?line ?tuple]
         (p/add-fields m-res :> ?m-res)
         (fires ?dataset ?date ?t-res ?lat ?lon ?tuple)


remove white space

remove white space

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -34,7 +34,7 @@
    "Blacklist"
    {:effect (effect (lock-zone (:cid card) :runner :discard))
     :leave-play (effect (release-zone (:cid card) :runner :discard))}
-
+
    "Brain-Taping Warehouse"
    {:events {:pre-rez
              {:req (req (and (= (:type target) "ICE") (has? target :subtype "Bioroid")))
@@ -291,8 +291,8 @@
                  :req (req (> (get-in @state [:runner :tag]) 0))
                  :effect (req (if (not= target "No Operation found")
                                 (let [c (move state :corp target :play-area)]
-                                  (shuffle! state :corp :deck)
-                                  (move state :corp c :deck {:front true})
+                                  (shuffle! state :corp :deck)
+                                  (move state :corp c :deck {:front true})
                                   (system-msg state side (str "uses Lily Lockwell to put " (:title c) " on top of R&D")))
                                 (do (shuffle! state :corp :deck)
                                     (system-msg state side (str "uses Lily Lockwell, but did not find an Operation in R&D"))))
@@ -353,7 +353,7 @@
    "Plan B"
    {:advanceable :always
     :access {:optional
-             {:prompt "Score an Agenda from HQ?"
+             {:prompt "Score an Agenda from HQ?"
               :req (req installed)
               :yes-ability {:prompt "Choose an Agenda to score"
                            :choices (req (filter #(and (has? % :type "Agenda")


use defcreate with lots

use defcreate with lots

--- src/clj_money/models/lots.clj
+++ src/clj_money/models/lots.clj
@@ -6,7 +6,9 @@
             [clj-money.util :refer [pprint-and-return]]
             [clj-money.validation :as validation]
             [clj-money.coercion :as coercion]
-            [clj-money.models.helpers :refer [with-storage]]
+            [clj-money.models.helpers :refer [with-storage
+                                              defcreate
+                                              defupdate]]
             [clj-money.models.storage :refer [create-lot
                                               select-lots-by-commodity-id]]))

@@ -20,37 +22,28 @@
                                   ::shares-purchased]))

 (defn- before-save
-  [lot]
+  [_ lot]
   (-> lot
       (update-in [:purchase-date] tc/to-long)
       (update-in [:shares-owned] (fnil identity (:shares-purchased lot)))))

 (defn- after-read
-  [lot]
-  (update-in lot [:purchase-date] tc/to-local-date))
+  ([lot] (after-read nil lot))
+  ([_ lot]
+   (update-in lot [:purchase-date] tc/to-local-date)))

-(defn- before-validation
-  [lot]
-  (coercion/coerce [(coercion/rule :local-date [:purchase-date])
-                    (coercion/rule :decimal [:shares-purchased])
-                    (coercion/rule :integer [:account-id])
-                    (coercion/rule :integer [:commodity-id])]
-                   lot ))
+(def ^:private coercion-rules
+  [(coercion/rule :local-date [:purchase-date])
+   (coercion/rule :decimal [:shares-purchased])
+   (coercion/rule :integer [:account-id])
+   (coercion/rule :integer [:commodity-id])])

-(defn- validate
-  [storage spec lot]
-  (validation/validate spec (before-validation lot)))
-
-(defn create
-  [storage-spec lot]
-  (with-storage [s storage-spec]
-    (let [validated (validate s ::new-lot lot)]
-      (if (validation/valid? validated)
-        (->> validated
-             before-save
-             (create-lot s)
-             after-read)
-        validated))))
+(def create
+  (defcreate {:before-save before-save
+              :create create-lot
+              :after-read after-read
+              :spec ::new-lot
+              :coercion-rules coercion-rules}))

 (defn select-by-commodity-id
   [storage-spec commodity-id]


working on init. list selection for edit

--- src/cljs/clj_money/forms.cljs
+++ src/cljs/clj_money/forms.cljs
@@ -1,7 +1,8 @@
 (ns clj-money.forms
   (:require-macros [reagent-forms.macros :refer [render-element]])
   (:require [reagent.core :as r]
-            [reagent-forms.core :refer [value-of]]
+            [reagent-forms.core :refer [value-of
+                                        default-selection]]
             [clj-money.inflection :as infl]))

 (defn- label
@@ -66,16 +67,19 @@
    (str (-> field name infl/last-segment infl/title-case) " is required.")])

 (defmethod reagent-forms.core/init-field :list-fn
-  [[tag {:keys [list-fn] :as attr}] {:keys [doc save!] :as context}]
+  [[tag {:keys [list-fn id] :as attr}] {:keys [doc save! get] :as context}]
   (let [options (r/atom [])
+        selection (r/atom (or (get id)
+                              (get-in (first @options)  [1 :key])))
         elem-attr {:on-focus (fn [_]
                                (reset! options (list-fn doc)))
-                   :on-change #(save! (:id attr) (value-of %))
-                   :name (:id attr)}]
+                   :on-change #(save! id (value-of %))
+                   :name id
+                   :default-value (default-selection @options @selection)}]
     (render-element attr
                     doc
                     [tag
                      elem-attr
                      (for [[display id] @options]
                        (with-meta [:option {:value id} display]
-                                  {:key (str "list-option-" (:id attr) "-" id)}))])))
+                                  {:key (str "list-option-" id "-" id)}))])))


remove second chart

remove second chart

--- src/cljs/takarabako/core.cljs
+++ src/cljs/takarabako/core.cljs
@@ -267,14 +267,10 @@
             [:tbody
              [:tr [:td.balance-key "Balance"] [:td.value (.toFixed (:sum balance) 2)]]
              [:tr [:td.balance-key "Transactions"] [:td.value (:count balance)]]
-             [:tr [:td.balance-key "Mean"] [:td.value (.toFixed (:mean balance) 2)]]]]]]
-         [:div.base-widget
-          [:div.widget.chart-widget
-           [:h3 "Daily"]
-           [:div.ct-line]]
-          [:div.widget.chart-widget
-           [:h3 "Total"]
-           [:div.ct-bar]]]]
+             [:tr [:td.balance-key "Mean"] [:td.value (.toFixed (:mean balance) 2)]]]]]]]
+        [:div.widget.chart-widget
+         [:h3 "Total"]
+         [:div.ct-bar]]
         [:div.widget.tx-widget
          [:div
           [:h3 "Transactions"]


Don't show add diffs for uncommitted changes, and improve html escaping

--- src/clojure/nightcode/git.clj
+++ src/clojure/nightcode/git.clj
@@ -2,7 +2,6 @@
   (:require [clojure.java.io :as io]
             [clojure.string :as string]
             [hiccup.core :as h]
-            [hiccup.util :as hu]
             [nightcode.dialogs :as dialogs]
             [nightcode.editors :as editors]
             [nightcode.shortcuts :as shortcuts]
@@ -16,7 +15,7 @@
            [javax.swing.tree DefaultMutableTreeNode DefaultTreeModel
             TreeSelectionModel]
            [org.eclipse.jgit.api Git]
-           [org.eclipse.jgit.diff DiffEntry DiffFormatter]
+           [org.eclipse.jgit.diff DiffEntry DiffEntry$ChangeType DiffFormatter]
            [org.eclipse.jgit.dircache DirCacheIterator]
            [org.eclipse.jgit.internal.storage.file FileRepository]
            [org.eclipse.jgit.lib PersonIdent ProgressMonitor Repository]
@@ -35,6 +34,13 @@
 (defn git-project?
   [path]
   (.exists (git-file path)))
+
+(defn escape-html
+  [text]
+  (-> text
+      (string/replace "&" "&")
+      (string/replace "<" "<")
+      (string/replace ">" ">")))

 (defn format-diff!
   [^ByteArrayOutputStream out ^DiffFormatter df ^DiffEntry diff]
@@ -80,7 +86,7 @@

 (defn ident->str
   [^PersonIdent ident]
-  (hu/escape-html (str (.getName ident) " <" (.getEmailAddress ident) ">")))
+  (escape-html (str (.getName ident) " <" (.getEmailAddress ident) ">")))

 (defn clj->html
   [& forms]
@@ -91,7 +97,7 @@
 (defn create-html
   [^Git git ^RevCommit commit]
   (clj->html
-    [:div {:class "head"} (or (some-> commit .getFullMessage)
+    [:div {:class "head"} (or (some-> commit .getFullMessage escape-html)
                               (utils/get-string :uncommitted-changes))]
     (when commit
       (list [:div (format (utils/get-string :author)
@@ -105,10 +111,12 @@
           df (doto (DiffFormatter. out)
                (.setRepository repo))
           [old-tree new-tree] (diff-trees repo commit)]
-      (for [diff (.scan df old-tree new-tree)]
+      (for [^DiffEntry diff (.scan df old-tree new-tree)
+            :when (or (some? commit)
+                      (not= DiffEntry$ChangeType/ADD (.getChangeType diff)))]
         (->> (format-diff! out df diff)
              string/split-lines
-             (map hu/escape-html)
+             (map escape-html)
              (map add-formatting)
              (#(conj % [:br] [:br])))))))


Added background color to 'show-vector-field' function

--- src/clojure2d/extra/utils.clj
+++ src/clojure2d/extra/utils.clj
@@ -74,9 +74,8 @@
       (dotimes [_ 2500000]
         (let [x (r/drand (- m/PI) m/PI)
               y (r/drand (- m/PI) m/PI)
-              v1 (v/vec2 x y)
-              v2 (v/add v1 (f v1))]
-          (line c  (norm-out x) (norm-out y) (norm-out (v2 0)) (norm-out (v2 1))))))
+              v (f (v/vec2 x y))]
+          (point c (norm-out (v 0)) (norm-out (v 1))))))
     (show-window {:canvas c})))

 (defn show-image


Ensure no nil routes are passed along.

Ensure no nil routes are passed along.

--- src/cmr/http/kit/app/core.clj
+++ src/cmr/http/kit/app/core.clj
@@ -5,6 +5,13 @@
    [cmr.plugin.jar.components.registry :as registry]
    [cmr.plugin.jar.types.web.routes :as jar-routes]
    [taoensso.timbre :as log]))
+
+(defn site-routes
+  [httpd-component routes-fns]
+  (->> routes-fns
+       (map #(% httpd-component))
+       (remove nil?)
+       vec))

 (defn collected-routes
   "This function checks to see if there are any plugins with the configured
@@ -28,7 +35,7 @@
     ;; the configuration function which extract the routes from the config
     ;; data. The route functions provided in the configuration data will be
     ;; called by a middleware wrapper.
-    {:site-routes (concat (map #(% httpd-component) plugins-site-routes-fns)
+    {:site-routes (concat (site-routes httpd-component plugins-site-routes-fns)
                           (main-site-routes-fn httpd-component))
      :plugins-api-routes-fns plugins-api-routes-fns
      :main-api-routes-fn main-api-routes-fn}))


add ugen docs for play-buf

add ugen docs for play-buf

--- src/overtone/sc/ugen/buf_io.clj
+++ src/overtone/sc/ugen/buf_io.clj
@@ -4,14 +4,14 @@
 (def specs
      [
       {:name "PlayBuf",
-       :args [{:name "numChannels" :mode :num-outs}
-              {:name "bufnum", :default 0}
-              {:name "rate", :default 1.0}
-              {:name "trigger", :default 1.0}
-              {:name "startPos", :default 0.0}
-              {:name "loop", :default 0.0}
+       :args [{:name "numChannels" :mode :num-outs :doc "The number of channels that the buffer will be. This must be a fixed integer. The architechture of the SynthDef cannot change after it is compiled. Warning: if you supply a bufnum of a buffer that has a different numChannels then you have specified to the play-buf, it will fail silently."}
+              {:name "bufnum", :default 0 :doc "The index of the buffer to use."}
+              {:name "rate", :default 1.0 :doc "1.0 is the server's sample rate, 2.0 is one octave up, 0.5 is one octave down -1.0 is backwards normal rate ... etc. Interpolation is cubic. Note:  if the buffer's sample rate is different from the server's, you will need to multiply the desired playback rate by (file's rate / server's rate). The UGen (buf-rate-scale bufnum) returns this factor."}
+              {:name "trigger", :default 1.0 :doc "A trigger causes a jump to the startPos. A trigger occurs when a signal changes from <= 0 to > 0."}
+              {:name "startPos", :default 0.0 :doc "Sample frame to start playback."}
+              {:name "loop", :default 0.0 :doc "1 means true, 0 means false. This is modulateable."}
               {:name "action", :default :none :map DONE-ACTIONS}]
-       :doc "play samples from a buffer"}
+       :doc "Plays back a sample resident in a buffer"}

       ;; TGrains : MultiOutUGen {
       ;; 	*ar { arg numChannels, trigger=0, bufnum=0, rate=1, centerPos=0,


Add function for string conversion

Add function for string conversion

--- src/discuss/utils/common.cljs
+++ src/discuss/utils/common.cljs
@@ -195,6 +195,11 @@
   [sub st]
   (not= (.indexOf st sub) -1))

+(defn str->int
+  "Convert String to Integer."
+  [s]
+  (js/parseInt s))
+

 ;;;; CSS modifications
 (defn toggle-class


SQUASHME Rework to use qualified imports

--- src/grimoire/api/fs/write.clj
+++ src/grimoire/api/fs/write.clj
@@ -1,17 +1,17 @@
 (ns grimoire.api.fs.write
   "Filesystem datastore implementation of the Grimoire API."
   (:refer-clojure :exclude [isa?])
-  (:require [grimoire.things :refer :all]
+  (:require [grimoire.things :as t]
             [grimoire.api :as api]
-            [grimoire.api.fs.impl :refer :all]))
+            [grimoire.api.fs.impl :as impl]))

 ;; Interacting with the datastore - writing
 ;;--------------------------------------------------------------------

 (defmethod api/write-meta :filesystem [config thing data]
-  (let [thing  (ensure-thing thing)
+  (let [thing  (t/ensure-thing thing)
         _      (assert thing)
-        handle (thing->meta-handle config thing)
+        handle (impl/thing->meta-handle config thing)
         _      (assert handle)]
     (.mkdirs (.getParentFile handle))
     (spit handle (pr-str data))
@@ -22,9 +22,9 @@
          thing
          config
          (-> config :datastore :notes)]}
-  (let [thing  (ensure-thing thing)
+  (let [thing  (t/ensure-thing thing)
         _      (assert thing)
-        handle (thing->notes-handle config thing)
+        handle (impl/thing->notes-handle config thing)
         _      (assert thing)]
     (.mkdirs (.getParentFile handle))
     (spit handle data)))
@@ -32,12 +32,12 @@
 ;; FIXME: add write-example

 (defmethod api/write-related :filesystem [config thing related-things]
-  (let [thing  (ensure-thing thing)
+  (let [thing  (t/ensure-thing thing)
         _      (assert thing)
-        _      (assert (isa? :def thing))
-        handle (thing->related-handle config thing)
+        _      (assert (t/def? thing))
+        handle (impl/thing->related-handle config thing)
         _      (assert thing)]
     (.mkdirs (.getParentFile handle))
     (doseq [thing related-things]
-      (spit handle (str (thing->path thing) \newline)
+      (spit handle (str (t/thing->path thing) \newline)
             :append true))))


mobile: Make cards with background

mobile: Make cards with background

--- apps/mobile/src/souptitle_mobile/ios/core.cljs
+++ apps/mobile/src/souptitle_mobile/ios/core.cljs
@@ -28,10 +28,8 @@
     :chapter {:screen chapter-screen}}
    {:card-style {:position "absolute"
                  :top 0
-                 :bottom 0}
-    :navigation-options {:gestures-enabled false ;; TODO: looks like it is old version of config
-                         }
-    }))
+                 :bottom 0
+                 :background-color "black"}}))

 (def main-tabs
   (nav/create-tab-navigator


riemann.time.controlled: Use of with-redefs to be slightly more forgiving.

--- src/riemann/time/controlled.clj
+++ src/riemann/time/controlled.clj
@@ -57,11 +57,7 @@
   then restores them. Definitely not threadsafe. Not safe by any standard,
   come to think of it. Only for testing purposes."
   [f]
-  (let [unix-time   riemann.time/unix-time
-        linear-time riemann.time/linear-time]
-    ; Please forgive me.
-    (intern 'riemann.time 'unix-time unix-time-controlled)
-    (intern 'riemann.time 'linear-time linear-time-controlled)
-    (f)
-    (intern 'riemann.time 'unix-time unix-time)
-    (intern 'riemann.time 'linear-time linear-time)))
+  ; Please forgive me.
+  (with-redefs [riemann.time/unix-time unix-time-controlled
+                riemann.time/linear-time linear-time-controlled]
+    (f)))


Formatting

Formatting


CMR-4473: As a metadata-db user, I want to delete a service association concept from metadata-db.

--- metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/delete_test.clj
+++ metadata-db-app/int_test/cmr/metadata_db/int_test/concepts/delete_test.clj
@@ -20,7 +20,8 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (deftest delete-concepts-test
-  (doseq [concept-type [:collection :granule :variable :variable-association :service]]
+  (doseq [concept-type [:collection :granule :variable :variable-association :service
+                        :service-association]]
     (cd-spec/general-delete-test concept-type ["REG_PROV" "SMAL_PROV"])))

 (deftest delete-tag-general


Fix various bugs on executors module.

Fix various bugs on executors module.

--- vendor/executors/core.clj
+++ vendor/executors/core.clj
@@ -6,12 +6,14 @@

 (ns executors.core
   "A executos service abstraction layer."
-  (:import java.util.concurrent.ForkJoinPool
+  (:import java.util.function.Supplier
+           java.util.concurrent.ForkJoinPool
+           java.util.concurrent.Future
            java.util.concurrent.CompletableFuture
            java.util.concurrent.ExecutorService
+           java.util.concurrent.TimeoutException
            java.util.concurrent.ThreadFactory
            java.util.concurrent.TimeUnit
-           java.util.concurrent.Supplier
            java.util.concurrent.ScheduledExecutorService
            java.util.concurrent.Executors))

@@ -91,14 +93,13 @@
   (-execute [this task]
     (CompletableFuture/runAsync ^Runnable task this))

-  IExecutorService
   (-submit [this task]
     (let [supplier (reify Supplier (get [_] (task)))]
       (CompletableFuture/supplyAsync supplier this))))

 (extend-type ScheduledExecutorService
   IScheduledExecutor
-  (-schedule [_ ms func]
+  (-schedule [this ms func]
     (let [fut (.schedule this func ms TimeUnit/MILLISECONDS)]
       (ScheduledTask. fut))))


about page

about page

--- frontend/components/about.cljs
+++ frontend/components/about.cljs
@@ -3,20 +3,221 @@
             [clojure.string :as str]
             [frontend.async :refer [put!]]
             [frontend.components.common :as common]
-            [frontend.components.crumbs :as crumbs]
-            [frontend.env :as env]
+            [frontend.components.shared :as shared]
             [frontend.state :as state]
-            [frontend.stefon :refer [data-uri]]
+            [frontend.stefon :as stefon]
             [frontend.utils :as utils :include-macros true]
-            [frontend.utils.github :refer [auth-url]]
-            [om.core :as om :include-macros true]
-            [om.dom :as dom :include-macros true]
-            [sablono.core :as html :refer-macros [html]])
-  (:require-macros [frontend.utils :refer [defrender]]))
+            [om.core :as om :include-macros true])
+  (:require-macros [frontend.utils :refer [defrender html]]))
+
+(defn team []
+  [{:name "Paul Biggar"
+    :role "Founder"
+    :github "pbiggar"
+    :twitter "paulbiggar"
+    :email "paul@circleci.com"
+    :img-path (stefon/asset-path "/img/outer/about/paul.png")
+    :visible true
+    :bio ["You might not know it by looking at him, but Paul is a wicked card shark. When he's not making his poker buddies cry, he seeks out mogul-laced ski trails to hurl himself down, and within the first five minutes of meeting him he'll probably tell you the story about how he mostly landed a backflip on his skis. Lest his ego get too big, though, we can always remind him of the time he failed at a YCombinator startup, and he'll go bury his emotions in the sweet sweet taste of artisan chocolate--or any chocolate, really.",
+          "Paul's been interviewed by the Wall Street Journal, and one of his proudest achievements was giving a Google Tech Talk on compilers and programming languages. He wrote phc, an open source PHP compiler, while doing his PhD on compilers and static analysis in Dublin. After moving to the Bay Area, Paul worked on the Firefox Javascript engine, started Circle, and then wrote stefon, an asset pipeline for Clojure. Because it pains Paul to see so much time wasted due to inadequate developer tools, he approaches continuous integration from the perspective of developer productivity. He loves to focus on building the Circle product, but, as he'll tell you while he's walloping you at table tennis, he also has to take care of the business side of things, too."]}
+   {:name "Allen Rohner"
+    :img-path (stefon/asset-path "/img/outer/about/allen.png")
+    :visible true
+    :role "Founder"
+    :github "arohner"
+    :twitter "arohner"
+    :email "allen@circleci.com"
+    :bio ["Allen loves Ultimate Frisbee: he's played in the snow, on the beach, on Thanksgiving Day, New Year's Eve, and New Year's Day, and he regularly plays in 110 degree August heat. His future plans include the tacocopter, the burrito bomber, and the mosquito laser. When Allen's not coding, he spends his time making his own pizza dough and brewing his own beer. He'd make his own whiskey, too, if he wanted to wait 10 years for a drink.",
+          "Back in the day, Allen started work on his own self-hosting, native code lisp, and then the clouds parted and he discovered Clojure. Since then, he's become a Clojure contributor, and has commits in clojure.core, contrib, lein, ring, compojure, noir, and about a dozen more libraries. He finished SICP, and wrote Scriptjure, a Clojure to Javascript compiler, 2 years before ClojureScript. Other devs used his work as a basis for Stevedore, which he's happy to say is used in production every day at Circle. In addition to co-founding Circle as a means to bring Continuous Deployment to the masses, he looks forward to building tools that help debug test failures by anticipating common problems. He currently deploys six times a day, and more on weekends."]}
+   {:name "David Lowe"
+    :visible true
+    :role "Backend Developer"
+    :github "dlowe"
+    :twitter "j_david_lowe"
+    :email "dlowe@circleci.com"
+    :img-path (stefon/asset-path "/img/outer/about/david.png")
+    :bio ["David is responsible for all of the bugs. He wrote his first buggy code in BASIC with a pencil and paper, and he's been getting better at it ever since. He keeps a 1/4 acre garden and eats almost entirely home-grown veggies during the growing season. Helping to balance out the numerous times that he's lost at chess, David has won the IOCCC on 6 separate occasions. In a past life, he wrote MTA software which at one time was sending about 1% of the internet's email.",
+          "Besides being invited to speak at the Frozen Perl Conference, OIT's CSET Department, and SOU's CS Department, David co-founded the SF perl user group, the southern Oregon geek group, and the Rogue hack lab hackerspace. He drank the automated testing kool-aid years ago, and after introducing and championing (and constantly fiddling with) continuous integration tools at his last N jobs, he came to Circle, and is particularly keen on building and scaling things which would be impossible to justify for any single small company where CI isn't what they do. He splits his time between introducing new bugs, telling kids to get off his lawn, and baking pies. His current running total is roughly 1500 delicious pastry concoctions."]}
+   {:name "Jenneviere Villegas"
+    :img-path (stefon/asset-path "/img/outer/about/jenneviere.png")
+    :visible true
+    :role "Operations"
+    :github "jenneviere"
+    :twitter "jenneviere"
+    :email "jenneviere@circleci.com"
+    :bio ["Jenneviere moved to the Bay Area in 2010 after spending a few months there, singing and dancing, as the lead in a rock opera. She then worked as an extra on the movie Twixt, and when she realized that Mr. Coppola wasn't going to cast her as the lead in his next film, she began drowning her sorrows in hoppy IPAs and the soothing click of knitting needles. She took the black and works the Gate at That Thing In The Desert, and has only written a single line of code, ever.",
+          "Drawing from her many years' experience in her previous position as the Customer Amazement Specialist, Operations Manager, Returns Siren, and Retail Store Maven for a certain large utility kilt manufacturer, Jenneviere brings her skills as a professional pottymouth, dabbler in inappropriate and snarky humor, and cat wrangling to the team at Circle, and spends most of her time trying to keep everyone well-groomed and hairball free."]}
+   {:name "Daniel Woelfel"
+    :img-path (stefon/asset-path "/img/outer/about/daniel.png")
+    :visible true
+    :role "Backend Developer"
+    :github "dwwoelfel"
+    :twitter "DanielWoelfel"
+    :email "daniel@circleci.com"
+    :bio ["Despite all our coercions, promises, bribes, and outright threats for nearly a year, it took us putting Daniel in a time-out and forcing him to type things about himself to get a bio out of him. He doesn't really have any hobbies: if he's doing something, it's usually either reading romantic fiction (not to be confused with romance novels!), coding, or binge-watching episodes of tv-show-he-just-discovered-that-is-so-awesome-he-can't-put-it-down. One of his first programming projects was an app written in Python that creates an exact replica of an image using only html tables. It's been almost 2 years since he last touched the thing, and it's still cranking out tables.",
+          "Daniel has a bachelors degree in Math from Texas A&M. He has written an app to graph Kickstarter projects, and was a customer (the 155th!) before he joined the Circle team. He looks forward to helping increase the 'wow, I can do something cool with this!' feeling that users get when they use Circle, and has been tinkering with a few things recently to make that possible. He currently helps feed his movie habit by helping organize weekly movie nights at the office. Next up: Cyrano de Bergerac."]}
+   {:name "Mahmood Ali"
+    :img-path (stefon/asset-path "/img/outer/about/mahmood.png")
+    :visible true
+    :role "Backend Developer"
+    :github "notnoopci"
+    :twitter "notnoop"
+    :email "mahmood@circleci.com"
+    :bio ["Mahmood loves car camping, which might explain why he also likes moving as much as he does. He and his family have moved 6 times in the last 6 years, though his baby boy has been completely lazy and hasn't offered to carry a single box yet. In between relocation to new abodes, Mahmood spends the nicer Boston weather exploring bike trails and learning computer languages. He's determined that his son will know Java before he can talk.",
+          "During his time at MIT, Mahmood spoke at a few Java research conferences including Devoxx, and has pushed code to Java 8--and Java 7--compilers. He's been a speaker at OOPSLA/Splash, and is active in the open-source community. He enjoys being reminded of his in-production projects, like java-apns, every time he gets support tickets. He acknowledges his own fallibility, and aims to help the Circle team continue to bring reliable test automation to all developers. His Achilles Heel is his pair of permanently underachieving glasses."]}
+   {:name "Gordon Syme"
+    :img-path (stefon/asset-path "/img/outer/about/gordon.png")
+    :visible true
+    :role "Backend Developer"
+    :github "gordonsyme"
+    :twitter "gordon_syme"
+    :email "gordon@circleci.com"
+    :bio ["Gordon has been racing dinghies right through the winter off the coast of Ireland for the past 16-odd years, and as his oft-showcased cabinet of prize coffee mugs will tell you, he's damn good at it. When he's not busy bludgeoning a piano with his ham-fisted fingers, he spends his free time rolling down mountains on a bicycle… sometimes even the right way up. In his down time, he's a board game shark, though you won't catch him trying to buy Boardwalk or get out of jail free.",
+          "Gordon joins the team after spending significant time at Amazon building tools to monitor the entire network (he built their DWDM monitoring from the ground up). He also built a JVM bytecode recompiler to enable running applications on a clustered VM without needing re-programming effort, and has grand plans for how he's going to make waves at Circle. We're pretty sure they include company Power Grid tournaments."]}
+   {:name "Danny King"
+    :img-path (stefon/asset-path "/img/outer/about/danny.png")
+    :visible true
+    :role "Designer"
+    :github "dannykingme"
+    :twitter "dannykingme"
+    :email "danny@circleci.com"
+    :bio ["Danny (not to be confused with Daniel) has batted a .500 baseball season with zero strikeouts and once took 2nd place at a poker tournament at the Mirage in Vegas. When he was 15 he, along with two of his paintball teammates, won a pickup paintball game against the three top-rated players from the number one team in the world, though he reckons this is only arguably impressive. In the world of virtual sports, Danny has scored over a million points in Tony Hawk's Pro Skater, and has racked up massive karma points by designing a website--pro bono--for a non-profit organization that helps provide activity bags to hospitalized children. He was selected for a reality TV show on Fox but he turned it down (they're evil).",
+          "Danny finished high school at the young age of 16. Two years after that, he cashed his first design freelance check. His past clients include Verizon, Lego, The Tribune, and Tyson Foods, and he has four individual 5-star rated projects in the Age of Empires design community. Not only does he design, but he's learned a bit of code, too, so he can build the things he designs, and his past projects include writing a tool that auto-hides Google Map's UI with simple CSS. He comes to Circle bursting with fresh ideas (like the new logo!) and can be found manipulating pixels with his hood securely in the Up position."]}
+   {:name "Nick Gottlieb"
+    :img-path (stefon/asset-path "/img/outer/about/nick.png")
+    :visible true
+    :role "Marketing Engineer"
+    :github "worldsoup"
+    :twitter "worldsoup"
+    :email "nick@circleci.com"
+    :bio ["Nick is an aspiring merman who spends most of his time outside of the Circle office in the ocean; surfing, diving, sailing, and swimming. He lived in Japan for 3 years as a student, consultant, actor, and vagabond and wrote his senior thesis on the cultural importance of baseball in the country. He won a hackathon by building a social haiku app for iPhone (which is still in the App Store). Eventually he came back to the US and got his first ‘real job’ at a digital consultancy where he optimized conversion rates for websites that comprise hundreds of thousands of visitors and generate millions in revenue every month.",
+          "In 2012 Nick was lured to San Francisco by the prospect of hitting it big with his own startup, which crashed and burned, but he liked the place so decided to stick around. He loves the open work culture at Circle which allows him to fulfill his constant need to get-shit-done while helping developers do the same. One day he will unplug his computer and sail around the world."]}
+   {:name "Emile Snyder"
+    :visible true
+    :role "Backend Developer"
+    :github "esnyder"
+    :twitter "emilesnyder"
+    :email "emile@circleci.com"}
+   {:name "Dave Jarvis"
+    :img-path (stefon/asset-path "/img/outer/about/dave.png")
+    :visible true
+    :role "Developer"
+    :github "venantius"
+    :twitter "venantius"
+    :email "dave@circleci.com"
+    :bio ["Dave's worst nightmare is to be boring. His childhood was split between New York City, Tokyo, and Bristol (U.K.), and he's never really felt at home anywhere since. In his spare time he plays an unreasonable amount of pool at the diviest bars he can find, and gardens aggressively in the hours before they open. One of the lucky few to live somewhere in San Francisco with a decent back yard, he's also a (discreet) amateur archer. In his prior life as a theater nerd, he designed theater sets (a production of Richard III being his favorite) and acted in independent theater productions in Chicago. Along with a few friends, he founded, edited and wrote a blog consisting of critical essays on video games, right up until the day he forgot to renew the domain name. Womp-womp.",
+          "CircleCI is his first job as a software developer, though his prior job involved hacking together the tools and libraries needed to help analyze petabyte-scale datasets as a data scientist. Before that, he worked as an honest-to-god economist for a small consulting outfit in Chicago, where he conducted economic impact analysis work for such clients as Argonne National Laboratory and the U.S. Department of Energy. He's now in the midst of launching a small hedge fund...because there actually *are* enough hours in the day. He joins Circle with the daydream of getting the time between each push and the next commit just that tiny bit shorter."]}
+   {:name "Tim Dixon"
+    :img-path (stefon/asset-path "/img/outer/about/tim.png")
+    :visible true
+    :role "Developer"
+    :github "startling"
+    :email "tim@circleci.com"}
+   {:name "Ian Duncan"
+    :visible true
+    :role "Developer"
+    :github "iand675"
+    :twitter "iand675"
+    :email "ian@circleci.com"}
+   {:name "Joshua Ballanco"
+    :img-path (stefon/asset-path "/img/outer/about/josh.png")
+    :visible true
+    :role "Developer"
+    :github "jballanc"
+    :twitter "manhattanmetric"
+    :email "jballanc@circleci.com"}])
+
+(def placeholder-image [:svg.about-placeholder {:height "150px" :width "150px" :viewBox "0 0 150 150"}
+                        [:path.bust {:d "M-1.673,151.75v-13.856c0,0,0.901-8.505,11.143-11.142c0,0,16.495-6.022,29.415-11.646 c6.681-2.907,8.119-4.652,14.859-7.631c0,0,0.703-3.461,0.45-5.521h5.271c0,0,1.204,0.702,0-7.43c0,0-6.425-1.705-6.725-14.655 c0,0-4.825,1.625-5.121-6.224c-0.202-5.321-4.318-9.939,1.607-13.753l-3.012-8.131c0,0-6.023-32.826,11.294-28.008 c-7.305-8.734,41.409-17.465,44.574,10.24c0,0,2.256,14.958,0,25.197c0,0,7.113-0.824,2.357,12.852c0,0-2.609,9.836-6.627,7.628 c0,0,0.656,12.447-5.668,14.559c0,0,0.449,6.625,0.449,7.075l6.025,0.903c0,0-0.906,5.424,0.152,6.022c0,0,7.142,4.894,15.657,7.081 c16.414,4.212,35.837,11.44,35.837,17.766c0,0,1.659,8.435,1.659,18.673H-1.673z",
+                                     :fill "#ccc"}]])
+
+(defn placeholder-bio [name]
+  [:div.bio-coming-soon
+   [:p
+    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi iaculis mi ante, at mattis purus varius sed. Maecenas sollicitudin volutpat nunc eget volutpat. Fusce sollicitudin adipiscing tincidunt. Duis tincidunt quis eros id egestas. Nunc ac nisi mollis, egestas enim quis, bibendum odio. Vestibulum facilisis lorem ante, ut placerat elit pellentesque non. Maecenas blandit urna non pharetra venenatis. Quisque malesuada, tellus nec porta luctus, mi lorem mattis elit, sit amet semper neque ligula sed orci. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse eu lectus lobortis, condimentum orci faucibus, porta leo. Donec pretium sapien sit amet orci rhoncus, in suscipit erat fringilla. Donec viverra nulla dolor. Nam id libero ultricies, viverra nisi et, commodo lorem. Maecenas ac risus lobortis, pellentesque ante in, consectetur nulla."]
+   [:div.coming-soon
+    {:placeholder (str "Sorry, we're still working on " (first (str/split name #" ")) "'s bio.")}]])
+
+(defn contact [app owner]
+  (reify
+    om/IRender
+    (render [_]
+      (html
+       [:div#contact.contact.page
+        [:div.banner
+         [:div.container
+          [:h1 "Contact us"]
+          [:h3 "We'd love to hear from you."]]]
+        [:div.container.content
+         [:div.row
+          [:div.span6 [:h3 "Fill the form"]
+           (om/build shared/contact-form app)]
+          [:div.span6.vcard
+           [:h3 "Don't like forms? Contact us anyway!"]
+           [:ul
+            [:li [:a.email {:href "mailto:sayhi@circleci.com"}
+                  [:i.fa.fa-envelope]
+                  "sayhi@circleci.com"]]
+            [:li [:a {:href "https://www.hipchat.com/gjwkHcrD5"}
+                  [:i.fa.fa-comments]
+                  "Live Support"]]
+            [:li [:a {:href "https://twitter.com/circleci"}
+                  [:i.fa.fa-twitter]
+                  "@circleci"]]
+            [:li.tel [:i.fa.fa-phone " 800 585-7075 / +1 415 944-3995"]]
+            [:li.adr [:i.fa.fa-globe]
+             [:a {:target "_blank", :href "https://goo.gl/maps/uhkLn"}
+              [:span.postal-code "94105"]]]]
+           [:h3 "Press Inquiries"]
+           [:p
+            "Drop a line to "
+            [:a {:href "mailto:press@circleci.com"} "press@circleci.com"]
+            " or call Paul at +1 415 341 2432."]]]]]))))

 (defn about [app owner]
   (reify
     om/IRender
     (render [_]
       (html
-       [:div "about"]))))
+       [:div
+        [:div.about.page
+         [:div.banner
+          [:div.container
+           [:h1 "About us"]
+           [:h3
+            "CircleCI was founded in 2011 with the mission of giving every developer state of the art automated testing and continuous integration tools."]]]
+         [:div.container.content
+          [:h2 "Meet the CircleCI Team"]
+          (map-indexed
+           (fn [i member]
+             [:div.member.row {:class (if (odd? i) "right" "left")}
+              (if (:img-path member)
+                [:img {:alt (:name member)
+                       :height 150
+                       :src (:img-path member)
+                       :width 150
+                       :class (if (odd? i) "pull-right" "pull-left")}]
+
+                placeholder-image)
+              [:div.span9
+               [:h3 (:name member)]
+               [:h4 (:role member)]
+               [:ul.clearfix
+                [:li
+                 [:a.fa.fa-envelope {:href (str "mailto:" (:email member))}]
+                 " "
+                 [:a.fa.fa-github {:href (str "https://github.com/" (:github member))}]
+                 " "
+                 [:a.fa.fa-twitter {:href (str "https://twitter.com/" (:twitter member))}]]]
+               (if (:bio member)
+                 (for [p (:bio member)]
+                   [:p p])
+                 (placeholder-bio (:name member)))]])
+           (team))
+          [:div#jobs-cta
+           [:p
+            "We're looking for amazing people to join us on this journey. Want to join the team? "]
+           [:a.btn.btn-large.btn-primary
+            {:href "/jobs"}
+            "CircleCI is hiring!"]]]]
+        (om/build contact app)]))))


remove awful bootstrap component

remove awful bootstrap component

--- frontend/components/build.cljs
+++ frontend/components/build.cljs
@@ -79,7 +79,7 @@
             hide-pills? (or (>= 1 (count containers))
                             (empty? (remove :filler-action (mapcat :actions containers))))]
         (html
-         [:div.containers.pagination.pagination-centered (when hide-pills? {:style {:display "none"}})
+         [:div.containers (when hide-pills? {:style {:display "none"}})
           [:ul.container-list
            (for [container containers]
              (om/build container-pill


use new pseudo pm-osc ugen in sc book examples alongside a couple of minor tweaks here and there

--- docs/sc-book/sc-one.clj
+++ docs/sc-book/sc-one.clj
@@ -94,11 +94,7 @@

 (demo (* 0.5 (sin-osc 100 (* 10 (sin-osc 500 0)))))

-;;we could also define our own pseudo ugen fn:
-
-(defn pm-osc [car-freq mod-freq pm-index mod-phase]
-  (with-ugens
-    (sin-osc car-freq (* pm-index (sin-osc mod-freq mod-phase)))))
+;;we can use the pm-osc pseudo ugen provided by overtone:

 (demo (* 0.5 (pm-osc 100 500 10 0)))

@@ -127,7 +123,7 @@
 ;;
 ;;/////////////

-(demo 30
+(demo 10
       (let [trigger       (line:kr :start 1, :end 20, :dur 60)
             freq          (t-rand:kr :lo 100, :hi 1000, :trig (impulse:kr trigger))
             num-harmonics (t-rand:kr :lo 1,   :hi 10,   :trig (impulse:kr trigger))
@@ -208,14 +204,12 @@
 ;;
 ;;/////////////

-(defn pm-osc [car-freq mod-freq pm-index mod-phase]
-  (with-ugens
-    (sin-osc car-freq (* pm-index (sin-osc mod-freq mod-phase)))))
+

 (demo 10 (let [r (impulse:kr 10)
                c (t-rand:kr :lo 100, :hi 5000, :trig r)
                m (t-rand:kr :lo 100, :hi 5000, :trig r)]
-           (* 0.3 (pm-osc c m 12 0))))
+           (* [0.3 0.3] (pm-osc c m 12 0))))

 (demo 10 (let [rate 4
                carrier (+ 700 (* 500 (lf-noise0:kr rate)))
@@ -291,9 +285,10 @@
 (do
   (ctl a :freq (midi->hz 64))
   (ctl c :freq (midi->hz 72)))
-(kill a)
-(kill b)
-(kill c)
+(do
+  (kill a)
+  (kill b)
+  (kill c))

@@ -325,9 +320,7 @@
 ;;}).add;
 ;;)

-(defn pm-osc [car-freq mod-freq pm-index mod-phase]
-  (with-ugens
-    (sin-osc car-freq (* pm-index (sin-osc mod-freq mod-phase)))))
+

 (defsynth pmc-rotale [midi 60 tone 3 art 1 amp 0.8 pan 0]
   (let [freq (midicps midi)


fix problem (#1125)

fix problem (#1125)

--- src/cljs/main/broadfcui/page/workspace/details.cljs
+++ src/cljs/main/broadfcui/page/workspace/details.cljs
@@ -160,7 +160,7 @@
      (this :-refresh-workspace))
    :component-will-receive-props
    (fn [{:keys [props next-props this after-update]}]
-     (when (not= (:tab-name props) (:tab-name next-props))
+     (when (some identity (utils/changes [:tab-name :workspace-id] props next-props))
        (after-update this :-refresh-workspace)))
    :-refresh-workspace
    (fn [{:keys [props state]}]


matcher-combinators: Improve `sequences-test`

--- test/com/nomistech/clojure_the_language/c_800_libraries/s_106_matcher_combinators/matcher_generators_test.clj
+++ test/com/nomistech/clojure_the_language/c_800_libraries/s_106_matcher_combinators/matcher_generators_test.clj
@@ -98,25 +98,30 @@

 ;;;; From docs

-(deftest test-matching-sequences
-  ;; A sequence is interpreted as an `equals` matcher, which specifies
-  ;; count and order of matching elements. The elements, themselves,
-  ;; are matched based on their types.
-  (is (match? [1 3] [1 3]))
-  (is (match? [1 odd?] [1 3]))
-  (is (match? [#"red" #"violet"] ["Roses are red" "Violets are ... violet"]))
+(deftest sequences-test
+  ;; A sequence is interpreted as an `equals` matcher, which specifies count and
+  ;; order of matching elements. The elements are matched based on their types.

-  ;; use m/prefix when you only care about the first n items
-  (is (match? (m/prefix [odd? 3]) [1 3 5]))
+  (is (match? [1 2 3]
+              [1 2 3]))
+  (is (match? [1 even? 3]
+              [1 2 3]))
+  (is (match? [#"red"
+               #"violet"]
+              ["Roses are red"
+               "Violets are ... violet"]))

-  ;; use m/in-any-order when order doesn't matter
-  (is (match? (m/in-any-order [odd? odd? even?]) [1 2 3]))
+  ;; Use `m/prefix` when you only care about the first n items.
+  (is (match? (m/prefix [1 even?])
+              [1 2 3]))

-  ;; NOTE: in-any-order is O(n!) because it compares every expected element
+  ;; Use `m/in-any-order` when order doesn't matter.
+  ;; NOTE: `m/in-any-order` is O(n!) because it compares every expected element
   ;; with every actual element in order to find a best-match for each one,
   ;; removing matched elements from both sequences as it goes.
   ;; Avoid applying this to long sequences.
-  )
+  (is (match? (m/in-any-order [odd? odd? even?])
+              [1 2 3])))

 (deftest test-matching-sets
   ;; A set is also interpreted as an `equals` matcher.


remove the default test coming with `lein new`

--- test/bitfondue/handler_test.clj
+++ test/bitfondue/handler_test.clj
@@ -3,6 +3,3 @@
             [ring.mock.request :as mock])
   (:use midje.sweet))

-(deftest a-test
-  (testing "FIXME, I fail."
-    (is (= 0 1))))


Yikes, typo

Yikes, typo

--- test/desdemona/metrics_test.clj
+++ test/desdemona/metrics_test.clj
@@ -7,7 +7,7 @@
   (let [job {:lifecycles []}
         task {}
         lifecycle {:lifecycle/task task
-                   :lifecycle/calls :onyx-lifecycle.metrics.metrics/calls}
+                   :lifecycle/calls :onyx.lifecycle.metrics.metrics/calls}
         opts {:pedantic true}
         lifecycle-with-opts (merge lifecycle opts)]
     (is (= {:lifecycles [lifecycle]}


+lose

+lose

--- src/babel/english/lexicon.clj
+++ src/babel/english/lexicon.clj
@@ -788,13 +788,17 @@
                         :past "looked up"
                         :present {:3sing "looks up"}}}

+   "lose" {:english {:participle "losing"
+                     :past "lost"}
+           :synsem {:cat :verb
+                    :sem {:pred :lose}}}
+
    "love" {:synsem {:cat :verb
                     :sem {:pred :amare
                           :subj {:human true}}}}

    "lower" {:synsem {:cat :verb
                      :sem {:pred :lower}}}
-
    "Luisa and I"
    [{:english {:note "♂"}
      :synsem {:cat :noun


markdown ignores ws after list/header

markdown ignores ws after list/header

--- src/braid/server/markdown.clj
+++ src/braid/server/markdown.clj
@@ -7,11 +7,12 @@
   (insta/parser
     "S ::= ( <#'^'> LINE <#'\\n|$'> )*
     <LINE> ::= ( ( HEADER | LIST ) / PLAIN_LINE )
+    ws ::= #'\\s*'
     DOT ::= #'.'
     TEXT ::= #'.*'
-    HEADER ::= #'\\#+' TEXT
+    HEADER ::= #'\\#+' <ws> TEXT
     LIST ::= ( LIST_LINE <'\\n'> ) +
-    LIST_LINE ::= <#'\\s*(-|\\*)'> TEXT
+    LIST_LINE ::= <#'\\s+(-|\\*)'> <ws> TEXT
     PLAIN_LINE ::= TEXT (* TODO: add inline things *)
     "))


fix Commercial Bankers Group

fix Commercial Bankers Group

fixes #1409

--- src/clj/game/cards-assets.clj
+++ src/clj/game/cards-assets.clj
@@ -150,7 +150,7 @@
                   :label "Gain 3 [Credits] (start of turn)"
                   :once :per-turn
                   :msg "gain 3 [Credits]"
-                  :effect (effect (damage :net 1 {:card card}))}]
+                  :effect (effect (gain :credit 3))}]
      {:derezzed-events {:runner-turn-ends corp-rez-toast}
       :events {:corp-turn-begins ability}
       :abilities [ability]})


Make read-string-safe nil-safe, fix npe.

--- src/clj/konserve/platform.clj
+++ src/clj/konserve/platform.clj
@@ -10,7 +10,7 @@

 (defn read-string-safe [s]
   (binding [*read-eval* false]
-    (read-string s)))
+    (when s (read-string s))))

 (defrecord CouchKeyValueStore [db]
   IAsyncKeyValueStore


minor

minor

--- src/clj_beautify/beautify.clj
+++ src/clj_beautify/beautify.clj
@@ -30,9 +30,11 @@
     (println test)
     test))

+;; TODO: not sure of the performance reprocussions of regex string replacement
 (defn- unwrap-comments
   [s]
-  (let [f (clojure.string/replace s (re-pattern "\"\\(comment ") ";")] ;; TODO: could also be ! token
+  ;; TODO: could also be ! token
+  (let [f (clojure.string/replace s (re-pattern "\"\\(comment ") ";")]
     (if (not= s f)
       ;; then
       (clojure.string/replace f (re-pattern "\\)\"(\n)?") "\n")


New functions get-month and get-day

New functions get-month and get-day

--- src/clj_calendar/calendar.clj
+++ src/clj_calendar/calendar.clj
@@ -31,6 +31,16 @@
     "Returns the year for the current date."
     [calendar]
     (.get calendar java.util.Calendar/YEAR))
+
+(defn get-month
+    "Returns the month of the current year."
+    [calendar]
+    (inc (.get calendar java.util.Calendar/MONTH)))
+
+(defn get-day
+    "Returns the day of the current month"
+    [calendar]
+    (.get calendar java.util.Calendar/DAY_OF_MONTH))

 (defn get-week
     "Returns week number within the current year."


Fix player screen centering bug

Fix player screen centering bug

--- src/cljc/robinson/update.cljc
+++ src/cljc/robinson/update.cljc
@@ -302,38 +302,22 @@
   {:pre  [(not (nil? state))]
    :post [(not (nil? %))]}
   (log/info "move-outside-safe-zone")
-  (let [[player-cell x y] (rw/player-cellxy state)
+  (let [[player-cell x y]    (rw/player-cellxy state)
         [target-x
-         target-y] (rw/player-adjacent-xy state direction)
-        target-place      (rv/xy->place-id state target-x target-y)
+         target-y]           (rw/player-adjacent-xy state direction)
+        target-place         (rv/xy->place-id state target-x target-y)
         rv/visible-place-ids (rv/visible-place-ids state target-x target-y)
         _ (log/info "target-x" target-x "target-y" target-y)
         _ (log/info "target-place" target-place)
-       vp-pos             (apply rc/xy->pos
-                            (rv/+xy (rc/pos->xy (get-in state [:world :viewport :pos]))
-                                 (rv/-xy [target-x target-y] [x y])))
-       ;;dest-place        (-> state :world :places dest-place-id)
+       vp-pos                (apply rc/xy->pos
+                               (rv/+xy (rc/pos->xy (get-in state [:world :viewport :pos]))
+                                    (rv/-xy [target-x target-y] [x y])))
        {width :width
         height :height}  (get-in state [:world :viewport])]
       (log/debug "viewport-pos" vp-pos)
-      ;#+clj
-      #_(log/debug "npcs" (with-out-str (clojure.pprint/pprint (-> state :world :npcs))))
       (-> state
         (assoc-in [:world :viewport :pos] vp-pos)
         (rworldgen/load-unload-places))))
-      ;(-> state
-      ;  (tx/when-> on-raft
-      ;    (dec-cell-item-count :raft))
-      ;  (assoc-in [:world :viewport :pos] vp-pos)
-        ;; unload the current place
-        ;;(dissoc-in [:world :places orig-place-id])
-        ;; change the place
-        ;;(assoc-in [:world :current-place] dest-place-id)
-        ;;(assoc-in [:world :places dest-place-id] dest-place)
-        ;; move player
-      ;  (assoc-in [:world :player :pos] {:x target-x :y target-y})
-      ;  (tx/when-> on-raft
-      ;    (conj-in-cell-items (ig/id->item :raft) target-x target-y)))))

 (defn move
   "Move the player one space provided her/she is able. Else do combat. Else swap positions
@@ -353,23 +337,25 @@
     (log/info "not collide?" (not (rw/collide? state target-x target-y {:include-npcs? false})))
     (log/info "not mounted-on-raft?" (not (rw/player-mounted-on-raft? state)))
     (cond
+      ;; Don't move paralyzed player
       (rp/player-paralyzed? state)
         (-> state
           (rc/append-log "You can not move (paralyzed).")
           inc-time)
+      ;; Open space (may include npc) and not on raft?
       (and (not (rw/collide? state target-x target-y {:include-npcs? false}))
            (not (rw/player-mounted-on-raft? state)))
         (as-> state state
-          (if (and (not (rv/xy-in-safe-zone? state target-x target-y))
-                   (not= :fixed (get-in state [:world :places (rw/current-place-id state) :movement])))
-            (move-outside-safe-zone state direction)
-            state)
           (if (rw/npc-at-xy state target-x target-y)
             ;; collided with npc. Engage in combat.
             (let [npc (rw/npc-at-xy state target-x target-y)]
               (log/info "npc" npc)
               (rcombat/attack state [:world :player] (rnpc/npc->keys state npc)))
             (as-> state state
+              (if (and (not (rv/xy-in-safe-zone? state target-x target-y))
+                       (not= :fixed (get-in state [:world :places (rw/current-place-id state) :movement])))
+                (move-outside-safe-zone state direction)
+                state)
               (assoc-in state [:world :player :pos :x] target-x)
               (assoc-in state [:world :player :pos :y] target-y)
               (let [cell  (rw/get-cell state target-x target-y)
@@ -378,6 +364,7 @@
                   (rdesc/search state)
                   state))))
           (inc-time state))
+      ;; Swap places with party members
       (= (get (rw/npc-at-xy state target-x target-y) :in-party?) true)
         (-> state
           (assoc-in [:world :player :pos :x] target-x)
@@ -391,6 +378,7 @@
                                      (assoc-in [:pos :x] player-x)
                                      (assoc-in [:pos :y] player-y))
                                  npc))))
+      ;; Passable water terrain and on raft?
       (and (not (rw/collide-in-water? state target-x target-y))
            (rw/player-mounted-on-raft? state))
         (as-> state state


better layout on mobile

better layout on mobile

--- src/cljs/moon/components.cljs
+++ src/cljs/moon/components.cljs
@@ -95,8 +95,8 @@
                    (when (seq current)
                      (->current-exercise current))
                    (d/div {:class "row heading"}
-                          (d/h1 {:class "col-xs-8"} "Total")
-                          (d/h1 {:class "col-xs-4"} (->hours (:total-duration data))))
+                          (d/h1 {:class "col-xs-6"} "Total")
+                          (d/h1 {:class "col-xs-6"} (->hours (:total-duration data))))

                    (->go-button (:running-workout data))
                    (->total-workout (:workout data))))))


Open login when route requires authentication and there is no session

--- src/cljs/my_money/routes.cljs
+++ src/cljs/my_money/routes.cljs
@@ -1,6 +1,7 @@
 (ns my-money.routes
   (:require [bide.core :as r]
-            [my-money.app.controller.navigation :as nc]))
+            [my-money.app.controller.navigation :as nc]
+            [reagent.session :as session]))

 (def router
   (r/router [["/" :home]
@@ -12,9 +13,12 @@
 (defn on-navigate
   "A function which will be called on each route change."
   [e! name params query]
-  (if (= name :home)
-    (e! (nc/->CloseModal))
-    (e! (nc/->OpenModal name))))
+  (if (and (not (session/get :identity))
+           (#{:config :upload} name))
+    (e! (nc/->OpenModal :login))
+    (if (= name :home)
+      (e! (nc/->CloseModal))
+      (e! (nc/->OpenModal name)))))

 (defn start! [e!]
   (r/start! router {:default     :home


Also coerce sink node sinks to dsinks.

Also coerce sink node sinks to dsinks.

--- src/clojure/parkour/graph.clj
+++ src/clojure/parkour/graph.clj
@@ -189,8 +189,9 @@

 (defmethod sink :reduce
   [node dsink]
-  (let [node (assoc node :stage :sink, :sink dsink, :sink-id (gen-id))]
-    (assoc (source (dseq/dseq dsink)) :requires [node])))
+  (let [dsink (dsink/dsink dsink), dseq (dseq/dseq dsink),
+        node (assoc node :stage :sink, :sink dsink, :sink-id (gen-id))]
+    (assoc (source dseq) :requires [node])))

 (defn ^:private map-only
   "Configuration step for map-only jobs."


Print number of incompetents only when autoconstructive.

--- src/clojush/pushgp/report.clj
+++ src/clojush/pushgp/report.clj
@@ -358,8 +358,9 @@
       (println "Max copy number of one program:" (apply max (vals frequency-map)))
       (println "Min copy number of one program:" (apply min (vals frequency-map)))
       (println "Median copy number:" (nth (sort (vals frequency-map)) (Math/floor (/ (count frequency-map) 2)))))
-    (println "Number of random replacements for reproductively incompetent individuals:"
-             (count (filter :random-replacement-for-reproductively-incompetent-genome population)))
+    (when (:autoconstructive argmap)
+      (println "Number of random replacements for reproductively incompetent individuals:"
+               (count (filter :random-replacement-for-reproductively-incompetent-genome population))))
     (when @global-print-behavioral-diversity
       (swap! population-behaviors #(take-last population-size %)) ; Only use behaviors during evaluation, not those during simplification
       (println "Behavioral diversity:" (behavioral-diversity))


Cleaned up :iso-mends related mime-type.

--- src/cmr/common/mime_types.clj
+++ src/cmr/common/mime_types.clj
@@ -21,7 +21,6 @@
    :echo10 "application/echo10+xml"
    :iso "application/iso19115+xml"
    :iso-smap "application/iso-smap+xml"
-   :iso-mends "application/iso19115+xml"
    :iso19115 "application/iso19115+xml"
    :dif "application/dif+xml"
    :csv "text/csv"
@@ -66,8 +65,3 @@
   (let [mime-type (mime-type-from-headers headers supported-types)]
     (validate-request-mime-type mime-type supported-types)
     (mime-type->format mime-type)))
-
-(defn alias-of-iso-mends?
-  "Returns true if the given result format is an alias of :iso-mends"
-  [result-format]
-  (some #{result-format} [:iso :iso19115]))


Whitespace

Whitespace

--- src/dependable/core_types.clj
+++ src/dependable/core_types.clj
@@ -1,10 +1,10 @@
 (defrecord requirement [status id spec])

-(defn present
+(defn present
   ([id] (present id nil))
   ([id spec] (->requirement :present id spec)))

-(defn absent
+(defn absent
   ([id] (absent id nil))
   ([id spec] (->requirement :absent id spec)))


Updated body conversion utility functions to handle data arg.

--- src/dragon/blog/post/util.clj
+++ src/dragon/blog/post/util.clj
@@ -15,19 +15,19 @@
    :inhibit-separator (config/template-skip-marker system)))

 (defn selmer->html
-  [system content]
-  (selmer/render content {}))
+  [system data content]
+  (selmer/render content (assoc data :system system)))

 (defn md+selmer->html
-  [system content]
+  [system data content]
   (->> content
        (md->html system)
-       (selmer->html system)))
+       (selmer->html system data)))

 (defn selmer+md->html
-  [system content]
+  [system data content]
   (->> content
-       (selmer->html system)
+       (selmer->html system data)
        (md->html system)))

 (defn convert-body!
@@ -36,11 +36,11 @@
     :md
       (update-in data [:body] (partial md->html system))
     :selmer
-      (update-in data [:body] (partial selmer->html system))
+      (update-in data [:body] (partial selmer->html system data))
     [:md :selmer]
-      (update-in data [:body] (partial md+selmer->html system))
+      (update-in data [:body] (partial md+selmer->html system data))
     [:selmer :md]
-      (update-in data [:body] (partial selmer+md->html system))))
+      (update-in data [:body] (partial selmer+md->html system data))))

 (defn join-excerpt
   [system words number]


Add workaround for juxt/bidi#196

Add workaround for juxt/bidi#196

--- lib/edge.ig.bidi/src/edge/bidi/ig.clj
+++ lib/edge.ig.bidi/src/edge/bidi/ig.clj
@@ -3,6 +3,17 @@
     bidi.vhosts
     [integrant.core :as ig]))

+;; Workaround for https://github.com/juxt/bidi/issues/187 pending a merge of https://github.com/juxt/bidi/pull/196
+(defn- fix-vhost
+  "Remove coercions to the route structures"
+  [vhost input]
+  (update vhost :vhosts
+          (fn [vhosts]
+            (mapv
+              vector
+              (map first vhosts)
+              (map second input)))))
+
 (defmethod ig/init-key ::vhost
   [_ args]
-  (apply bidi.vhosts/vhosts-model args))
+  (fix-vhost (apply bidi.vhosts/vhosts-model args) args))


chopping to minimal 1.7-alpha5 issue

chopping to minimal 1.7-alpha5 issue

--- test/midje/util/t_one_seven.clj
+++ test/midje/util/t_one_seven.clj
@@ -3,23 +3,6 @@
         [midje.util laziness thread-safe-var-nesting]
         [midje.test-util]))

-;; Justification for use of eagerly
-(def counter (atom :needs-to-be-initialized))
-(def #^:dynamic *mocked-function-produces-next-element* inc)
-
-(defn function-under-test-produces-a-lazy-list []
-  (iterate *mocked-function-produces-next-element* 1))
-
-(defn mock-use []
-  (binding [*mocked-function-produces-next-element* (fn [n] (swap! counter inc) (inc n))]
-    (eagerly (take 5 (function-under-test-produces-a-lazy-list)))))
-
-(fact "eagerly forces evaluation"
-  (reset! counter 1)
-  (mock-use)
-  @counter => 5)
-
-;; After justification, more facts.

 (unfinished exploder)


Passes test-liveness

Passes test-liveness

--- test/minijava/test_liveness.clj
+++ test/minijava/test_liveness.clj
@@ -71,7 +71,6 @@
                (addl b c)
                (movl c a)
                (jmp l1))]
-    (= (live-ranges (live prog))
-       [{:id c, :start 1, :end 5}
-        {:id b, :start 2, :end 5}
-        {:id a, :start 4, :end 5}])))
+   (is (= (live-ranges (live prog))
+       (hash-map  b [(live-range b 0 5)]
+ 									c [(live-range c 0 5)])))))


:sparkles: Improve a bit more dnd sortable trees:

--- frontend/src/uxbox/main/ui/hooks.cljs
+++ frontend/src/uxbox/main/ui/hooks.cljs
@@ -102,7 +102,11 @@
 ;; - Ignore events originated in non-draggable children.
 ;; - At drag operation end, all elements that have received some enter/over
 ;;   event and have not received the corresponding leave event, are notified
-;;   so they can clean up.
+;;   so they can clean up. This can be occur, for example, if
+;;    * some leave events are throttled out because of a slow computer
+;;    * some corner cases of mouse entering a container element, and then
+;;      moving into a contained element. This is anyway mitigated by not
+;;      stopping propagation of leave event.
 ;;
 ;; Do not remove commented out lines, they are useful to debug events when
 ;; things go weird.
@@ -171,7 +175,6 @@
         on-drag-leave
         (fn [event]
           (when-not (dnd/from-child? event)
-            (dom/stop-propagation event)
             ;; (dnd/trace event data "drag-leave")
             (cleanup)))


add missing in leiningen/new/templates.clj binary-renderer

--- src/leiningen/new/cryogen.clj
+++ src/leiningen/new/cryogen.clj
@@ -2,7 +2,18 @@
   (:require [leiningen.new.templates :refer [renderer sanitize year ->files]]
             [leinjacker.utils :refer [lein-generation]]
             [leiningen.core.main :as main]
-            [clojure.java.io :refer [file]]))
+            [clojure.string :as string]
+            [clojure.java.io :refer [file] :as io]))
+
+(defn binary-renderer
+  "Create a binary renderer function that looks for mustache templates in the
+  right place given the name of your template."
+  [name]
+  (fn [file]
+    (let [path (string/join "/" ["leiningen" "new" (sanitize name) file])]
+      (if-let [resource (io/resource path)]
+        (io/input-stream resource)
+        (main/abort (format "Template resource '%s' not found." path))))))

 (defn check-lein-version []
   (if (< (lein-generation) 2)
@@ -15,14 +26,15 @@
   (let [options {:name name
                  :sanitized (sanitize name)
                  :year (year)}
-        render (renderer "cryogen")]
+        render (renderer "cryogen")
+        binary (binary-renderer "cryogen")]
     (main/info "Generating fresh 'lein new' Cryogen project.")
     (with-redefs [leiningen.new.templates/render-text (fn [text _] text)]
       (->files options
                [".gitignore"  (render "gitignore")]
                ["project.clj" (render "project.clj")]
                ;;static resources
-               ["resources/templates/img/cryogen.png" (render "img/cryogen.png")]
+               ["resources/templates/img/cryogen.png" (binary "img/cryogen.png")]
                ;;themes
                ["resources/templates/themes/blue/html/archives.html" (render "themes/blue/html/archives.html")]
                ["resources/templates/themes/blue/html/base.html" (render "themes/blue/html/base.html")]