dfs builder now runs dfs, limited to 1 element

Builder now has the functionality to run the dfs, but it won't work on
maps whose states are larger than one element. I plan to address, this, of
course, after I wrap it into a two-argument function.

Also, I need to handle the path if there is no sentence ending with a
terminal (in which case it should generate any sentence).

--- wysitutwyg/src-clj/wysitutwyg/markov/builder.clj
+++ wysitutwyg/src-clj/wysitutwyg/markov/builder.clj
@@ -1,2 +1,130 @@
 (ns wysitutwyg.markov.builder
-  (:require [clojure.data.json :as json]))+  (:require [clojure.data.json :as json]))
+
+;; Fixes seed for reproducability
+(def ^:dynamic ^java.util.Random *rnd* (java.util.Random. 1))
+(defn get-rand [x]
+  (.nextInt *rnd* x))
+
+(def map-loc "resources/public/corpora/loremipsum/1.json")
+
+(def datamap
+  (let [initial (into {}
+                   (for [[k v] (json/read-str (slurp map-loc))]
+                     [(keyword k) v]))]
+    (-> initial
+        (update-in [:end] #(into #{} %))
+        (update-in [:start] #(apply hash-map (apply concat %)))
+        (update-in [:counts] #(apply hash-map (apply concat %))))))
+
+(defn pick-word
+  "Takes a map of counts in the form of {'sad' 2, 'mad' 3} (values from the
+  n-gram map) and picks a word, by the ratio of the counts."
+  [words]
+  (if-let [word-seq (seq words)]
+    (let [keys (vec (map first word-seq))
+          counts (vec (map second word-seq))
+          r (get-rand (reduce + counts))]
+      (loop [i 0 sum 0]
+        (if (< r (+ (counts i) sum))
+            (nth keys i)
+            (recur (inc i) (+ (counts i) sum)))))))
+
+; ((:counts datamap) ["a"])
+; (pick-word (:start datamap))
+; (pick-word ((datamap :counts) ["a"]))
+
+;;;   Our aim is: "Pick the first generated sentence of size n which has as
+;;; its last member an end node. If there is no possible sentence of length n
+;;; ending in an end node, pick the last selected."
+;;;   The current implementation uses a straight BFS.
+
+;; Base case: (depth=n) OR (no children return !nil)
+
+(defn pick-words
+  "Returns a lazy sequence of the next states from the start state, generated
+  by repeatedly picking words."
+  [counts]
+  (letfn [(step [candidates]
+            (if-let [w (pick-word candidates)]
+              (cons w (step (dissoc candidates w)))
+              nil))]
+    (lazy-seq (step counts))))
+
+(prn (pick-words ((datamap :counts) ["a"])))
+(prn (pick-words ((datamap :counts) ["a"])))
+(prn (pick-words ((datamap :counts) ["a"])))
+(prn (pick-words (datamap :start)))
+
+(defn find-first-end
+  "Returns the first end node following the specified state, nil if none."
+  [state {:keys [counts end] :as datamap}]
+  (first (filter end (pick-words (counts state)))))
+
+(assert (find-first-end ["accepted"] datamap))
+(assert (not (find-first-end ["as"] datamap)))
+
+(defn words-to-states
+  "Takes a state and a collection of words, and maps it to the next set of
+  states."
+  [state words]
+  (map #(conj (vec (rest state)) %) words))
+
+;; TODO: Is this dfs code needlessly complex/confusing? Probably. Refactor?
+(declare dfs)
+
+(defn dfs-step
+  "Maps dfs to the words (sideways expansion), mutually recursive with dfs.
+  Returns lazy sequence of state/nil values."
+  [state datamap n depth words]
+  (->> (words-to-states state words)
+       (map #(dfs % datamap n (inc depth)))
+       (filter #(not= nil %))
+       (first)))
+
+;; TODO: It won't work on 2-grams, 3-grams, etc. Only singles.
+(defn dfs
+  "Runs the dfs (downwards expansion), call this to start."
+  [state {:keys [counts] :as datamap} n depth]
+  (if (= depth n)
+      (if-let [end-state (find-first-end state datamap)]
+        (cons state (vector (vector end-state)))) ; hahaha that's silly
+      (let [words (pick-words (counts state))]
+        (if-let [result (dfs-step state datamap n depth words)]
+          (cons state result)))))
+
+;(defn dfs-begin
+;  [{:keys [start counts] :as datamap} n depth]
+
+
+(prn "With No:" (dfs ["No"] datamap 5 0))
+; "No one who chooses to distinguish." - how to get it to return this?
+(prn "With No:" (dfs ["No"] datamap 2 0))
+;;; What do we do if it's nil (cannot find any sentences of that length)?
+;;; We could do:
+;;;   * Run it with a different start node, but that may just delay it. So,
+;;;     that doesn't actually solve our problem!
+;;;   * Do a single-path dfs to the targeted depth.
+
+#_(defn lazy-chain
+  "Given a starting state, returns a lazy sequence of generated words until it
+  reaches an end state."
+  [start-state counts]
+  (if-let [next-word (pick-word (counts (map #(apply str %) start-state)))]
+    (cons (apply str next-word)
+          (lazy-seq (lazy-chain (conj (vec (rest start-state))
+                                      next-word)
+                                counts)))))
+
+#_(defn generate-text
+  "Given a starting state as a string, generates n further words from the given
+  count graph. Ends once n words have been generated, or when a terminal node
+  has been reached."
+  [state n counts]
+  (->> (reverse state)
+       (map #(apply str %))
+       (apply conj (->> counts
+                        (lazy-chain (map seq state))
+                        (take (dec n))))
+       (interpose \space)
+       (apply str)))


use re-seq

use re-seq

--- word-count/example.clj
+++ word-count/example.clj
@@ -12,12 +12,10 @@

 ;; Another approach
 (ns phrase
- (:require [clojure.string :refer [split lower-case]]))
+ (:require [clojure.string :refer [lower-case]]))

-(defn- sanitize-and-split [phrase]
-  (-> (lower-case phrase)
-      (split #"\W+")))
+(defn words [s]
+  (re-seq #"\w+" s))

-(defn word-count [phrase]
-  (-> (sanitize-and-split phrase)
-      (frequencies)))
+(defn word-count [s]
+  (-> s lower-case words frequencies))


Problem added - Find Distinct Items

Problem added - Find Distinct Items


Make a few functions more idiomatic

Make a few functions more idiomatic

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -7,10 +7,10 @@
   (:require [sandbar.stateful-session :as session]))

 (defn get-solved [user]
-  (into #{}
-        (:solved (fetch-one :users
-                            :where {:user user}
-                            :only [:solved]))))
+  (set
+   (:solved (fetch-one :users
+                       :where {:user user}
+                       :only [:solved]))))

 (defn get-problem [x]
   (fetch-one :problems :where {:_id x}))
@@ -23,15 +23,14 @@
 (defn mark-completed [id]
   (if-let [user (session/session-get :user)]
     (do
-      (when (not-any? #(= % id) (get-solved user))
-
+      (when (not-any? #{id} (get-solved user))
         (update! :users {:user user} {:$push {:solved id}})
         (update! :problems {:_id id} {:$inc {:times-solved 1}}))
       (flash-msg "Congratulations, you've solved the problem!" "/problems"))
     (flash-msg "You've solved the problem! If you log in we can track your progress." "/problems")))

 (defn get-tester [restricted]
-  (reduce #(conj %1 (symbol %2)) secure-tester restricted))
+  (into secure-tester (map symbol restricted)))

 (def sb (sandbox*))

@@ -41,16 +40,16 @@
         func-name (:function-name p)
         sb-tester (get-tester (:restricted p))]
     (try
-      (loop [t tests]
-        (if (empty? t)
+      (loop [[test & more] tests]
+        (if-not test
           (mark-completed id)
-          (let [testcase (replace-str "__" code (first t))]
+          (let [testcase (replace-str "__" code test)]
             (if (sb sb-tester (read-string testcase))
-              (recur (rest t))
+              (recur more)
               (do
                 (session/flash-put! :code code)
                 (flash-error "You failed the unit tests."
-                           (str "/problem/" id)))))))
+                             (str "/problem/" id)))))))
       (catch Exception e
         (do
           (session/flash-put! :code code)


Optimized ning client

Optimized ning client

--- src/engulf/ning_client.clj
+++ src/engulf/ning_client.clj
@@ -3,18 +3,30 @@
    (:use lamina.core)
    (:require [clojure.tools.logging :as log])
    (:import com.ning.http.client.AsyncHttpClient
+            com.ning.http.client.AsyncHandler
+            com.ning.http.client.AsyncHandler$STATE
             com.ning.http.client.PerRequestConfig
             com.ning.http.client.AsyncCompletionHandler))

+(defrecord Response [status])
+
+(deftype StatusHandler [status res-ch]
+  com.ning.http.client.AsyncHandler
+  (onStatusReceived [this status-resp]
+                    (compare-and-set! status nil (.getStatusCode status-resp))
+                    AsyncHandler$STATE/CONTINUE)
+  (onHeadersReceived [this headers]
+                     AsyncHandler$STATE/CONTINUE)
+  (onBodyPartReceived [this body-part]
+                      AsyncHandler$STATE/CONTINUE)
+  (onCompleted [this]
+               (enqueue (.success res-ch)
+                        (Response. @status))
+               AsyncHandler$STATE/CONTINUE)
+  (onThrowable [this e] (enqueue (.error res-ch) e)))
+
 (defn client-handler [res-ch]
-  (proxy [com.ning.http.client.AsyncCompletionHandler] []
-          (onCompleted [response]
-            (let [content-type   (.getContentType response)
-                  status         (.getStatusCode  response)]
-              (enqueue (.success res-ch)
-                       {:status status :content-type content-type})))
-          (onThrowable [e]
-            (enqueue (.error res-ch) e))))
+  (StatusHandler. (atom nil) res-ch))

 (def method-prep-map
      {:get (memfn prepareGet url)


Use with-open on some more DB connections

--- src/env_logger/handler.clj
+++ src/env_logger/handler.clj
@@ -58,29 +58,31 @@
   redirect to the value of (:query-params (:next request)).
   On failed authentication, renders the login page."
   [request]
-  (let [username (get-in request [:form-params "username"])
-        password (get-in request [:form-params "password"])
-        otp (get-in request [:form-params "otp"])
-        session (:session request)
-        use-ldap? (get-conf-value :use-ldap)
-        user-data (if use-ldap?
-                    (when-let [password (u/get-password-from-ldap username)]
-                      {:pw-hash password})
-                    (u/get-user-data db/postgres username))]
-    (if (:error user-data)
-      (render-file "templates/error.html"
-                   {})
-      (if (or (and user-data (h/check password (:pw-hash user-data)))
-              (and (seq otp)
-                   (otp-value-valid? otp)
-                   (contains? (u/get-yubikey-id db/postgres-ds username)
-                              (YubicoClient/getPublicId otp))))
-        (let [next-url (get-in request [:query-params :next]
-                               (str (get-conf-value :url-path) "/"))
-              updated-session (assoc session :identity (keyword username))]
-          (assoc (resp/redirect next-url) :session updated-session))
-        (render-file "templates/login.html"
-                     {:error "Error: an invalid credential was provided"})))))
+  (with-open [con (jdbc/get-connection db/postgres-ds)]
+    (let [username (get-in request [:form-params "username"])
+          password (get-in request [:form-params "password"])
+          otp (get-in request [:form-params "otp"])
+          session (:session request)
+          use-ldap? (get-conf-value :use-ldap)
+          user-data (if use-ldap?
+                      (when-let [password (u/get-password-from-ldap username)]
+                        {:pw-hash password})
+                      (u/get-user-data con username))]
+      (if (:error user-data)
+        (render-file "templates/error.html"
+                     {})
+        (if (or (and user-data (h/check password (:pw-hash user-data)))
+                (and (seq otp)
+                     (otp-value-valid? otp)
+                     (contains? (u/get-yubikey-id con username)
+                                (YubicoClient/getPublicId otp))))
+          (let [next-url (get-in request [:query-params :next]
+                                 (str (get-conf-value :url-path) "/"))
+                updated-session (assoc session :identity (keyword username))]
+            (assoc (resp/redirect next-url) :session updated-session))
+          (render-file "templates/login.html"
+                       {:error (str "Error: an invalid credential "
+                                    "was provided")}))))))

 (defn unauthorized-handler
   "Handles unauthorized requests."
@@ -286,39 +288,40 @@
   (POST "/rt-observations" request
         (if-not (check-auth-code (:code (:params request)))
           response-unauthorized
-          (if-not (db/test-db-connection db/postgres-ds)
-            response-server-error
-            (if (pos? (db/insert-ruuvitag-observation
-                       db/postgres-ds
-                       (parse-string (:observation (:params request)) true)))
-              "OK" response-server-error))))
+          (with-open [con (jdbc/get-connection db/postgres-ds)]
+            (if-not (db/test-db-connection con)
+              response-server-error
+              (if (pos? (db/insert-ruuvitag-observation
+                         con
+                         (parse-string (:observation (:params request)) true)))
+                "OK" response-server-error)))))
   ;; Testbed image name storage
   (POST "/tb-image" request
         (if-not (check-auth-code (:code (:params request)))
           response-unauthorized
-          (if-not (db/test-db-connection db/postgres-ds)
-            response-server-error
-            (if (re-find #"testbed-\d{4}-\d{2}-\d{2}T\d{2}:\d{2}\+\d{4}\.png"
-                         (:name (:params request)))
-              (if (db/insert-tb-image-name db/postgres-ds
-                                           (db/get-last-obs-id
-                                            db/postgres-ds)
-                                           (:name (:params
-                                                   request)))
-                "OK" response-server-error)
-              response-invalid-request))))
+          (with-open [con (jdbc/get-connection db/postgres-ds)]
+            (if-not (db/test-db-connection con)
+              response-server-error
+              (if (re-find #"testbed-\d{4}-\d{2}-\d{2}T\d{2}:\d{2}\+\d{4}\.png"
+                           (:name (:params request)))
+                (if (db/insert-tb-image-name con
+                                             (db/get-last-obs-id con)
+                                             (:name (:params request)))
+                  "OK" response-server-error)
+                response-invalid-request)))))
   ;; Latest yardcam image name storage
   (POST "/yc-image" request
         (if-not (check-auth-code (:code (:params request)))
           response-unauthorized
-          (if-not (db/test-db-connection db/postgres-ds)
-            response-server-error
-            (let [image-name (:image-name (:params request))]
-              (if (yc-image-validity-check image-name)
-                (if (db/insert-yc-image-name db/postgres-ds
-                                             image-name)
-                  "OK" response-server-error)
-                response-invalid-request)))))
+          (with-open [con (jdbc/get-connection db/postgres-ds)]
+            (if-not (db/test-db-connection con)
+              response-server-error
+              (let [image-name (:image-name (:params request))]
+                (if (yc-image-validity-check image-name)
+                  (if (db/insert-yc-image-name con
+                                               image-name)
+                    "OK" response-server-error)
+                  response-invalid-request))))))
   ;; Serve static files
   (route/files "/")
   (route/not-found "404 Not Found"))


Fix bug where VALUES clause bindings couldn't be clojure sets

--- src/grafter/rdf4j/sparql.clj
+++ src/grafter/rdf4j/sparql.clj
@@ -63,9 +63,12 @@
         values-block (str/join " " (map (partial ->sparql-str k) vals))]
     (str/replace q regex (str "$1 " values-block  " $2"))))

+(defn- sequential-or-set? [c]
+  (or (sequential? c) (set? c)))
+
 (defn- rewrite-values-clauses [q bindings]
   (let [values-bindings (->> bindings
-                             (filter (comp sequential? second))
+                             (filter (comp sequential-or-set? second))
                              (into {}))]
     (reduce rewrite-values-clauses* q values-bindings)))


Implement -read-example for the fs backend

--- src/grimoire/api/fs/read.clj
+++ src/grimoire/api/fs/read.clj
@@ -140,7 +140,13 @@
       (fail (str "No note for object "
                  (t/thing->path (t/thing->parent thing)))))))

-;; FIXME: read-example
+(defmethod api/-read-example ::fs/Config [config thing]
+  {:pre [(t/example? thing)]}
+  (let [handle (io/file (:handle thing))]
+    (if (.exists handle) ;; guard against missing files
+      (-> handle slurp succeed)
+      (fail (str "No such example! "
+                 (:handle thing))))))

 (defmethod api/-read-meta ::fs/Config [config thing]
   (let [thing  (t/ensure-thing thing)


Fixing another error in algorithms.bitwise

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

--- src/conexp/contrib/algorithms/bitwise.clj
+++ src/conexp/contrib/algorithms/bitwise.clj
@@ -9,7 +9,7 @@
 (ns conexp.contrib.algorithms.bitwise
   (:import [java.util BitSet])
   (:import [java.util.concurrent SynchronousQueue])
-  (:use [conexp.fca.contexts :only (objects attributes incidence)]))
+  (:use [conexp.fca.contexts :only (objects attributes incidence-relation)]))

 ;;; Helpers to convert to and from BitSets
@@ -104,7 +104,7 @@
         attribute-vector (vec (attributes context)),
         object-count     (count object-vector),
         attribute-count  (count attribute-vector),
-        incidence-matrix (to-binary-matrix object-vector attribute-vector (incidence context))]
+        incidence-matrix (to-binary-matrix object-vector attribute-vector (incidence-relation context))]
     [object-vector attribute-vector object-count attribute-count incidence-matrix]))

 (defmacro with-binary-context


Add support for remote repositories via SPARQL & Sesame HTTP API.

--- src/grafter/rdf/sesame.clj
+++ src/grafter/rdf/sesame.clj
@@ -12,6 +12,8 @@
    [org.openrdf.repository Repository RepositoryConnection]
    [org.openrdf.query.resultio TupleQueryResultFormat]
    [org.openrdf.repository.sail SailRepository]
+   [org.openrdf.repository.http HTTPRepository]
+   [org.openrdf.repository.sparql SPARQLRepository]
    [org.openrdf.sail.memory MemoryStore]
    [org.openrdf.rio Rio RDFWriter RDFHandler]
    [org.openrdf.rio.binary BinaryRDFParserFactory]
@@ -353,6 +355,15 @@
      (native-store (io/file datadir) "spoc,posc,cosp"))
   ([datadir indexes]
      (NativeStore. datadir indexes)))
+
+(defn http-repo [repo-url]
+  (HTTPRepository. repo-url))
+
+(defn sparql-repo
+  ([query-url]
+     (SPARQLRepository. query-url))
+  ([query-url update-url]
+     (SPARQLRepository. query-url update-url)))

 (defn repo
   ([] (repo (MemoryStore.)))


code cleanup

code cleanup

--- code-breaker.clj
+++ code-breaker.clj
@@ -43,11 +43,11 @@
           matches))
       matches)))

-(defn find-inexact-matches [guess answer exact-matches]
+(defn count-inexact-matches [guess answer exact-matches]
   "Returns count of the inexact matches -- color and position -- between both sets"
-  (let [without-exact-matches (drop-elements-by-indexes guess exact-matches)]
+  (let [guess-without-exact-matches (drop-elements-by-indexes guess exact-matches)]
     (count (clojure.set/intersection
-      (set without-exact-matches)
+      (set guess-without-exact-matches)
       (set answer)))))

 (defn evaluate-guess [guess answer]
@@ -55,7 +55,6 @@
   (map validate-color-seq [guess answer])
   (let [exact-matches
         (find-exact-matches guess answer)]
-    (let [inexact-match-count
-        (find-inexact-matches guess answer exact-matches)]
-      [(count exact-matches) inexact-match-count])))
+    [ (count exact-matches)
+      (count-inexact-matches guess answer exact-matches) ]))


Whitespace fixes.

Whitespace fixes.

--- src/ipython_clojure/core.clj
+++ src/ipython_clojure/core.clj
@@ -104,7 +104,8 @@

 (defn read-until-delimiter [socket]
   (let [preamble (doall (drop-last
-                         (take-while (comp not #(= "<IDS|MSG>" (try-convert-to-string %)))
+                         (take-while (comp not #(= "<IDS|MSG>"
+                                                   (try-convert-to-string %)))
                                      (repeatedly #(zmq/receive socket)))))]
     preamble))

@@ -166,7 +167,6 @@
     (send-message-piece socket metadata)
     (finish-message socket content)))

-
 (defn read-raw-message [socket]
   {:idents (read-until-delimiter socket)
    :delimiter "<IDS|MSG>"
@@ -194,16 +194,13 @@
                       parent-header {} session-id signer)
         (send-message iopub-socket "pyin" (pyin-content @execution-count message)
                       parent-header {} session-id signer)
-
         (try
-          (let [s# (new java.io.StringWriter)
-              [output results]
+          (let [s# (new java.io.StringWriter) [output results]
               (binding [*out* s#]
-                (let [result (pr-str (eval (load-string (get-in message [:content :code]))))
+                (let [result (pr-str (eval (load-string
+                                            (get-in message [:content :code]))))
                       output (str s#)]
-                  [output, result]
-                  ))
-              ]
+                  [output, result]))]
             (send-router-message shell-socket "execute_reply"
                                  {:status "ok"
                                   :execution_count @execution-count
@@ -213,7 +210,6 @@
                                   :engine session-id
                                   :status "ok"
                                   :started (now)} session-id signer (:idents message))
-
             ;; Send stdout
             (send-message iopub-socket "pyout"
                           {:execution_count @execution-count
@@ -221,7 +217,6 @@
                            :metadata {}
                            }
                           parent-header {} session-id signer)
-
             ;; Send results
             (send-message iopub-socket "execute_result"
                           {:execution_count @execution-count
@@ -229,7 +224,6 @@
                            :metadata {}
                            }
                           parent-header {} session-id signer))
-
           (catch Exception e
             ;; Send error on iopub socket
             (send-message iopub-socket "error"
@@ -239,7 +233,6 @@
                            :traceback (map #(.toString %) (.getStackTrace e))
                            }
                           parent-header {} session-id signer)
-
             ;; Send an error execute_reply message
             (send-router-message shell-socket "execute_reply"
                                  {:status "error"
@@ -254,7 +247,6 @@
                                   :status "ok"
                                   :started (now)} session-id signer (:idents message)))
           )
-
         (send-message iopub-socket "status" (status-content "idle")
                       parent-header {} session-id signer)))))

@@ -302,7 +294,6 @@
             (println "Message dump:" message)
             (System/exit -1)))))))

-
 (defrecord Heartbeat [addr]
     Runnable
     (run [this]


Fix jupyter-console example

Fix jupyter-console example

--- src/ipython_clojure/core.clj
+++ src/ipython_clojure/core.clj
@@ -60,10 +60,12 @@
         content  (cheshire/generate-string kernel-info-content)]

     ;; First send the client identifiers for the router socket's benefit
-    (doseq [ident (:idents message)]
-      (zmq/send socket ident zmq/send-more))
-    (zmq/send socket (byte-array 0) zmq/send-more)
-
+    (when (not (empty? (:idents message)))
+      (doseq [ident (:idents message)]
+        (zmq/send socket ident zmq/send-more))
+      (zmq/send socket (byte-array 0) zmq/send-more))
+
+    (send-message-piece socket (get-in message [:header :session]))
     (send-message-piece socket "<IDS|MSG>")
     (send-message-piece socket (signer header parent_header metadata content))
     (send-message-piece socket header)
@@ -78,10 +80,12 @@
         content  (cheshire/generate-string kernel-info-content)]

     ;; First send the client identifiers for the router socket's benefit
-    (doseq [ident (:idents message)]
-      (zmq/send socket ident zmq/send-more))
-    (zmq/send socket (byte-array 0) zmq/send-more)
-
+    (when (not (empty? (:idents message)))
+      (doseq [ident (:idents message)]
+        (zmq/send socket ident zmq/send-more))
+      (zmq/send socket (byte-array 0) zmq/send-more))
+
+    (send-message-piece socket (get-in message [:header :session]))
     (send-message-piece socket "<IDS|MSG>")
     (send-message-piece socket (signer header parent_header metadata content))
     (send-message-piece socket header)
@@ -145,10 +149,12 @@
         metadata (cheshire/generate-string metadata)
         content (cheshire/generate-string content)]

-    (doseq [ident idents] ; First send the zmq identifiers for the router socket's benefit
-      (zmq/send socket ident zmq/send-more))
-    (zmq/send socket (byte-array 0) zmq/send-more)
-
+    (when (not (empty? idents))
+      (doseq [ident idents] ; First send the zmq identifiers for the router socket's benefit
+        (zmq/send socket ident zmq/send-more))
+      (zmq/send socket (byte-array 0) zmq/send-more))
+
+    (send-message-piece socket session-id)
     (send-message-piece socket "<IDS|MSG>")
     (send-message-piece socket (signer header parent_header metadata content))
     (send-message-piece socket header)


Add some examples

Add some examples

--- src/distributed_transducers_poc/trial.clj
+++ src/distributed_transducers_poc/trial.clj
@@ -15,22 +15,23 @@
 (defn word-frequency [text]
     (r/fold merge-counts count-words (clojure.string/split text #"\s+")))

-
-(time (take 10 (doall (pmap #(clj-fuzzy.levensthein/distance "book" %) (clojure.string/split (slurp "resources/lilja.txt") #"\s+")))))
+;(time (take 10 (doall (pmap #(clj-fuzzy.levensthein/distance "book" %) (clojure.string/split (slurp "resources/lilja.txt") #"\s+")))))
+; Big file local
 ;"Elapsed time: 452925.488452 msecs"

 ; (time (doall (take 10 (word-frequency (slurp "resources/big.txt")))))

 ;(r/fold concat #(conj %1 (clj-fuzzy.levensthein/distance "book" %2)) ["backi" "buck" "yyy"])

-;(comment
+(comment
 (time (doall (take 10 (super-fold concat
                                   #(conj %1 (clj-fuzzy.levensthein/distance "book" %2))
-                                  (clojure.string/split (slurp "resources/lilja.txt") #"\s+")
-                                  5))))
-;)
-;"Elapsed time: 219173.54034 msecs"
-;(4 4 3 8 5 4 3 2 4 4)
+                                  (clojure.string/split (slurp "resources/big.txt") #"\s+")
+                                  10))))
+)
+; Big file 10 Lambdas
+; "Elapsed time: 109665.06582 msecs"
+; (11 4 5 3 6 5 4 4 4 4)

 (comment


fix(goto def): goto def for special forms does not throw exc anymore. Fix #819

--- ccw.core/src/clj/ccw/editors/clojure/clojure_hyperlink_detector.clj
+++ ccw.core/src/clj/ccw/editors/clojure/clojure_hyperlink_detector.clj
@@ -1,5 +1,6 @@
 (ns ccw.editors.clojure.clojure-hyperlink-detector
   (:require [clojure.zip :as z]
+            [clojure.string :as str]
             [paredit.loc-utils :as lu]
             [clojure.tools.nrepl :as repl]
             [ccw.editors.clojure.editor-support :as ed]
@@ -43,13 +44,13 @@
                                                (let [client (.client connection)]
                                                  (repl/response-values (repl/message client {:op :eval :code command})))))
                                            1000)]
-        (if (and file line ns)
+        (if (every? str/blank? [file line ns])
+          (do
+            (.setStatusLineErrorMessage editor ClojureEditorMessages/Cannot_find_declaration)
+            nil)
           {"file" file
            "line" (Integer/valueOf line)
-           "ns" ns}
-          (do
-            (.setStatusLineErrorMessage editor ClojureEditorMessages/Cannot_find_declaration)
-            nil))))))
+           "ns" ns})))))

 (defn detect-hyperlinks
   [offset ^IClojureEditor editor]


Update sample-jobdef.clj to have the actual behavior of wait-on-step reflected in the comments.

Fixed comment on the behaviour of wait-on-step.  The comments on the function in src/main/clj/lemur/core.clj are correct, but the statement about throwing exceptions that was here was not correct.

--- examples/sample-jobdef.clj
+++ examples/sample-jobdef.clj
@@ -340,5 +340,11 @@
 ;  :ready
 ;(wait <stage>)

-; If you want to block on step completion; if timeout is reached, it will stop and throw an exception.
+; If you want to block on step completion use wait-on-step as below;
+; returns a map with information on how the job completed.  If the timeout expires it might look like
+;    {:timeout true, :success false}
+; if the job completes before the timeout expires it might look like
+;    {:success true}
+; Read the function documentation for more details.
+;
 ;(wait-on-step step timeout-seconds)


Exclude more ICE-specific namespaces in the root_property_identifier_gen rule

--- resources/rules/pre_identifier_merge/step_a_ontology_to_ice/step_a/root_property_identifier_gen.clj
+++ resources/rules/pre_identifier_merge/step_a_ontology_to_ice/step_a/root_property_identifier_gen.clj
@@ -15,6 +15,8 @@
   # exclude the oboInOwl:ObsoleteProperty property
   filter (?top_level_property != oboInOwl:ObsoleteProperty)
   # exclude ICE world properties (IAO, CCP extension ontology, OA ontology)
+  filter (!contains (str(?top_level_property), 'http://www.w3.org/2000/01/rdf-schema#member'))
+  filter (!contains (str(?top_level_property), ' http://www.w3.org/ns/prov'))
   filter (!contains (str(?top_level_property), 'ext/IAO_'))
   filter (!contains (str(?top_level_property), 'obo/IAO_'))
   filter (!contains (str(?top_level_property), 'http://www.w3.org/ns/oa#'))


eip functions dont require with-ctx

eip functions dont require with-ctx

--- src/aws/provider.clj
+++ src/aws/provider.clj
@@ -70,7 +70,7 @@
        (handle-volumes spec endpoint instance-id)
        (when-let [ip (get-in spec [:machine :ip])]
          (debug (<<  "Associating existing ip ~{ip} to instance-id"))
-         (with-ctx (assoc-pub-ip endpoint instance-id ip)))
+         (assoc-pub-ip endpoint instance-id ip))
        (update-ip spec endpoint instance-id)
        (wait-for-ssh (pub-dns endpoint instance-id) user [5 :minute])
        (set-hostname spec endpoint instance-id user)
@@ -83,7 +83,7 @@
       (wait-for-status this "running" [5 :minute])
       (when-let [ip (get-in spec [:machine :ip])]
         (debug (<<  "Associating existing ip ~{ip} to ~{instance-id}"))
-        (with-ctx (assoc-pub-ip endpoint instance-id ip)))
+        (assoc-pub-ip endpoint instance-id ip))
       (update-ip spec endpoint instance-id)
       (wait-for-ssh (pub-dns endpoint instance-id) user [5 :minute])
       ))
@@ -102,7 +102,7 @@
   (stop [this]
     (with-instance-id
        (debug "stopping" instance-id)
-       (when-not (first (:addresses (with-ctx (describe-eip endpoint instance-id))))
+       (when-not (first (:addresses (describe-eip endpoint instance-id)))
          (debug "clearing dynamic ip from system")
          (s/update-system (spec :system-id)
            (dissoc-in* (s/get-system (spec :system-id)) [:machine :ip])))


Fixes CLJS tests

Fixes CLJS tests

--- test/expound/alpha_test.cljc
+++ test/expound/alpha_test.cljc
@@ -1373,13 +1373,11 @@
       (mutate-coll form))))

 (deftest test-assert2
-  (try
-    (binding [s/*explain-out* expound/printer]
-      (s/assert (s/nilable #{"Insufficient input" "Extra input" "no method"}) "Key must be integer"))
-    (catch Exception e
-      (is (string/includes?
-           (:cause (Throwable->map e))
-           "\"Key must be integer\"\n\nshould be one of: `Extra input`,`Insufficient input`,`no method`")))))
+  (is (thrown-with-msg?
+       #?(:cljs :default :clj Exception)
+       #"\"Key must be integer\"\n\nshould be one of: `Extra input`,`Insufficient input`,`no method`"
+       (binding [s/*explain-out* expound/printer]
+         (s/assert (s/nilable #{"Insufficient input" "Extra input" "no method"}) "Key must be integer")))))

 (defn inline-specs [keyword]
   (walk/postwalk


Add type hints (just for documentation).

--- src/beicon/core.cljs
+++ src/beicon/core.cljs
@@ -96,9 +96,9 @@
 (defn publish
   "Create a connectable (hot) observable
   from other observable."
-  ([ob]
+  ([^observable ob]
    (publish ob true))
-  ([ob connect?]
+  ([^observable ob connect?]
    {:pre [(observable? ob)]}
    (let [ob' (.publish ob)]
      (when connect?
@@ -108,12 +108,12 @@
 (defn share
   "Returns an observable sequence that shares a single
   subscription to the underlying sequence."
-  [ob]
+  [^observable ob]
   (.share ob))

 (defn connect!
   "Connect the connectable observable."
-  [ob]
+  [^observable ob]
   {:pre [(connectable? ob)]}
   (.connect ob))

@@ -258,19 +258,19 @@

 (defn push!
   "Pushes the given value to the bus stream."
-  [b v]
+  [^subject b v]
   {:pre [(bus? b)]}
   (.onNext b v))

 (defn error!
   "Pushes the given error to the bus stream."
-  [b e]
+  [^subject b e]
   {:pre [(bus? b)]}
   (.onError b e))

 (defn end!
   "Ends the given bus stream."
-  [b]
+  [^subject b]
   {:pre [(bus? b)]}
   (.onCompleted b))

@@ -281,7 +281,7 @@
 (defn on-value
   "Subscribes a function to invoke for each element
   in the observable sequence."
-  [ob f]
+  [^observable ob f]
   {:pre [(observable? ob)]}
   (let [disposable (.subscribeOnNext ob #(f %))]
     #(.dispose disposable)))
@@ -289,7 +289,7 @@
 (defn on-error
   "Subscribes a function to invoke upon exceptional termination
   of the observable sequence."
-  [ob f]
+  [^observable ob f]
   {:pre [(observable? ob)]}
   (let [disposable (.subscribeOnError ob #(f %))]
     #(.dispose disposable)))
@@ -297,7 +297,7 @@
 (defn on-end
   "Subscribes a function to invoke upon graceful termination
   of the observable sequence."
-  [ob f]
+  [^observable ob f]
   {:pre [(observable? ob)]}
   (let [disposable (.subscribeOnCompleted ob #(f %))]
     #(.dispose disposable)))
@@ -308,7 +308,7 @@
    (subscribe ob nf nil nil))
   ([ob nf ef]
    (subscribe ob nf ef nil))
-  ([ob nf ef cf]
+  ([^observable ob nf ef cf]
    {:pre [(observable? ob)]}
    (let [disposable (.subscribe ob nf ef cf)]
      #(.dispose disposable))))
@@ -334,7 +334,7 @@
 (defn choice
   "Create an observable that surfaces any of the given
   sequences, whichever reacted first."
-  ([a b]
+  ([^observable a ^observable b]
    {:pre [(observable? a)
           (observable? b)]}
    (.amb a b))
@@ -346,7 +346,7 @@
   into one observable sequence."
   ([ob' ob]
    (zip vector ob' ob))
-  ([f ob' ob]
+  ([f ^observable ob' ^observable ob]
    {:pre [(observable? ob') (observable? ob)]}
    (.zip ob ob' f)))

@@ -354,40 +354,44 @@
   "Concatenates all of the specified observable
   sequences, as long as the previous observable
   sequence terminated successfully."
-  ([a b]
+  ([^observable a ^observable ob]
    {:pre [(observable? a)
-          (observable? b)]}
-   (.concat a b))
+          (observable? ob)]}
+   (.concat ob a))
   ([a b & more]
-   (cljs.core/reduce concat (concat a b) more)))
+   (let [ob (last more)
+         obs (into [b] (butlast more))]
+     (cljs.core/reduce concat (concat a ob) more))))

 (defn merge
   "Merges all the observable sequences and Promises
   into a single observable sequence."
-  ([a b]
+  ([^observable a ^observable b]
    {:pre [(observable? a)
           (observable? b)]}
-   (.merge a b))
+   (.merge b a))
   ([a b & more]
-   (cljs.core/reduce merge (merge a b) more)))
+   (let [ob (last more)
+         obs (into [b] (butlast more))]
+     (cljs.core/reduce concat (merge a ob) more))))

 (defn merge-all
   "Merges an observable sequence of observable
   sequences into an observable sequence."
-  [ob]
+  [^observable ob]
   (.mergeAll ob))

 (defn filter
   "Filters the elements of an observable sequence
   based on a predicate."
-  [f ob]
+  [f ^observable ob]
   {:pre [(observable? ob)]}
   (.filter ob #(boolean (f %))))

 (defn map
   "Apply a function to each element of an observable
   sequence."
-  [f ob]
+  [f ^observable ob]
   {:pre [(observable? ob)]}
   (.map ob #(f %)))

@@ -398,7 +402,7 @@
   into one observable sequence."
   ([ob]
    (flat-map identity ob))
-  ([f ob]
+  ([f ^observable ob]
    {:pre [(observable? ob)]}
    (.flatMap ob #(f %))))

@@ -406,7 +410,7 @@
   "Bypasses a specified number of elements in an
   observable sequence and then returns the remaining
   elements."
-  [n ob]
+  [^number n ^observable ob]
   {:pre [(observable? ob) (number? n)]}
   (.skip ob n))

@@ -414,14 +418,14 @@
   "Bypasses elements in an observable sequence as long
   as a specified condition is true and then returns the
   remaining elements."
-  [f ob]
+  [f ^observable ob]
   {:pre [(observable? ob) (fn? f)]}
   (.skipWhile ob #(boolean (f %))))

 (defn skip-until
   "Returns the values from the source observable sequence
   only after the other observable sequence produces a value."
-  [pob ob]
+  [pob ^observable ob]
   {:pre [(observable? ob) (observable? pob)]}
   (.skipUntil ob pob))

@@ -429,24 +433,24 @@
   "Bypasses a specified number of elements in an
   observable sequence and then returns the remaining
   elements."
-  [n ob]
+  [^number n ^observable ob]
   {:pre [(observable? ob) (number? n)]}
   (.take ob n))

 (defn slice
   "Returns a shallow copy of a portion of an Observable
   into a new Observable object."
-  ([begin ob]
+  ([begin ^observable ob]
    {:pre [(observable? ob) (number? begin)]}
    (.slice ob begin))
-  ([begin end ob]
+  ([begin end ^observable ob]
    {:pre [(observable? ob) (number? begin) (number? end)]}
    (.slice ob begin end)))

 (defn take-while
   "Returns elements from an observable sequence as long as a
   specified predicate returns true."
-  [f ob]
+  [f ^observable ob]
   {:pre [(observable? ob) (fn? f)]}
   (.takeWhile ob f))

@@ -454,10 +458,10 @@
   "Applies an accumulator function over an observable
   sequence, returning the result of the aggregation as a
   single element in the result sequence."
-  ([f ob]
+  ([f ^observable ob]
    {:pre [(observable? ob) (fn? f)]}
    (.reduce ob f))
-  ([f seed ob]
+  ([f seed ^observable ob]
    {:pre [(observable? ob) (fn? f)]}
    (.reduce ob f seed)))

@@ -465,10 +469,10 @@
   "Applies an accumulator function over an observable
   sequence and returns each intermediate result.
   Same as reduce but with intermediate results"
-  ([f ob]
+  ([f ^observable ob]
    {:pre [(observable? ob) (fn? f)]}
    (.scan ob f))
-  ([f seed ob]
+  ([f seed ^observable ob]
    {:pre [(observable? ob) (fn? f)]}
    (.scan ob f seed)))

@@ -479,13 +483,13 @@
   (the instance) produces an element."
   ([ob' ob]
    (with-latest-from vector ob' ob))
-  ([f ob' ob]
+  ([f ob' ^observable ob]
    (.withLatestFrom ob ob' f)))

 (defn catch
   "Continues an observable sequence that is terminated
   by an exception with the next observable sequence."
-  [handler ob]
+  [handler ^observable ob]
   {:pre [(or (observable? handler)
              (fn? handler))]}
   (.catch ob handler))
@@ -493,7 +497,7 @@
 (defn tap
   "Invokes an action for each element in the
   observable sequence."
-  [f ob]
+  [f ^observable ob]
   {:pre [(observable? ob) (fn? f)]}
   (.tap ob f))

@@ -517,7 +521,7 @@
   "Returns an observable sequence that emits only the
   first item emitted by the source Observable during
   sequential time windows of a specified duration."
-  [ms ob]
+  [ms ^observable ob]
   {:pre [(observable? ob) (number? ms)]}
   (.throttle ob ms))

@@ -525,20 +529,20 @@
   "Emits an item from the source Observable after a
   particular timespan has passed without the Observable
   omitting any other items."
-  [ms ob]
+  [ms ^observable ob]
   {:pre [(observable? ob) (number? ms)]}
   (.debounce ob ms))

 (defn sample
   "Samples the observable sequence at each interval."
-  [ms ob]
+  [ms ^observable ob]
   {:pre [(observable? ob) (number? ms)]}
   (.sample ob ms))

 (defn ignore
   "Ignores all elements in an observable sequence leaving
   only the termination messages."
-  [ob]
+  [^observable ob]
   {:pre [(observable? ob)]}
   (.ignoreElements ob))

@@ -550,8 +554,6 @@
   observables."
   ([pauser ob]
    (pausable pauser false ob))
-   ;; {:pre [(observable? ob) (observable? pauser)]}
-   ;; (.pausable ob pauser))
   ([pauser buffer? ob]
    {:pre [(observable? ob) (observable? pauser)]}
    (if buffer?
@@ -561,9 +563,11 @@
 (defn dedupe
   "Returns an observable sequence that contains only
   distinct contiguous elements."
-  ([ob]
+  ([^observable ob]
+   {:pre [(observable? ob)]}
    (.distinctUntilChanged ob))
-  ([f ob]
+  ([f ^observable ob]
+   {:pre [(observable? ob)]}
    (.distinctUntilChanged ob f)))

 (defn dedupe'
@@ -572,18 +576,22 @@
   Usage of this operator should be considered carefully
   due to the maintenance of an internal lookup structure
   which can grow large."
-  ([ob]
+  ([^observable ob]
+   {:pre [(observable? ob)]}
    (.distinct ob))
-  ([f ob]
+  ([f ^observable ob]
+   {:pre [(observable? ob)]}
    (.distinct ob f)))

 (defn buffer
   "Projects each element of an observable sequence into zero
   or more buffers which are produced based on element count
   information."
-  ([n ob]
+  ([n ^observable ob]
+   {:pre [(observable? ob)]}
    (.bufferWithCount ob n))
-  ([n skip ob]
+  ([n skip ^observable ob]
+   {:pre [(observable? ob)]}
    (.bufferWithCount ob n skip)))

 (defn retry
@@ -591,15 +599,16 @@
   repeats the source observable the specified number of
   times or until it terminates. If no number of retries
   is given, it will be retried indefinitely."
-  ([ob]
+  ([^observable ob]
+   {:pre [(observable? ob)]}
    (.retry ob))
-  ([n ob]
+  ([n ^observable ob]
+   {:pre [(observable? ob)]}
    (.retry ob n)))

 (defn to-observable
   "Hides the identity of an observable sequence."
   [b]
-  {:pre [(or (observable? b) (bus? b))]}
   (.asObservable b))

 (defn transform


Cosmetic change on lense declaration on colorpicker (workspace).

--- src/uxbox/main/ui/workspace/colorpicker.cljs
+++ src/uxbox/main/ui/workspace/colorpicker.cljs
@@ -28,8 +28,8 @@

 (defn- focus-shape
   [id]
-  (as-> (l/in [:shapes-by-id id]) $
-    (l/derive $ st/state)))
+  (-> (l/in [:shapes-by-id id])
+      (l/derive st/state)))

 (defn- colorpicker-render
   [own {:keys [x y shape attr] :as opts}]


updated tests to reflect new default namespace

--- test/matross/config_test.clj
+++ test/matross/config_test.clj
@@ -1,7 +1,6 @@
 (ns matross.config-test
   (:require [clojure.test :refer :all]
             [matross.config :refer :all]))
-

 (deftest config-resolver-behaves
   (testing "I can retrieve values"
@@ -11,13 +10,13 @@
       (is (not (= (kwd cr) (:kwd cr))))))

   (testing "Templating occurs properly"
-    (let [cr (config-resolver {:default {:foo "{{fact/bar}}" :baz "{{foo}}"}
+    (let [cr (config-resolver {:var {:foo "{{fact/bar}}" :baz "{{foo}}"}
                                :fact {:bar "herp"}})]
       (is (= (:foo cr) ((keyword "fact/bar") cr)))
       (is (= (:foo cr) (:baz cr)))))

   (testing "I can use select-keys"
-    (let [cr (config-resolver {:default {:a "{{b}}" :b "value"}})
+    (let [cr (config-resolver {:var {:a "{{b}}" :b "value"}})
           sub-set (select-keys cr [:a])]
       (println sub-set)
       (is (= (:a sub-set) "value")))))


Publish function can now handle Clojure datatypes

--- lib/compojure/cometd/cometd.clj
+++ lib/compojure/cometd/cometd.clj
@@ -1,7 +1,12 @@
+;; compojure.cometd
+;;
 ;; An interface to Jetty's cometd implementation
+
 (ns compojure.cometd
-  (:import (org.mortbay.cometd.continuation ContinuationCometdServlet)
-           (dojox.cometd MessageListener)))
+  (:use    (compojure json))
+  (:import (dojox.cometd MessageListener)
+           (org.mortbay.cometd.continuation ContinuationCometdServlet)
+           (org.mortbay.util.ajax JSON$Generator)))

 (def *cometd*
   (new ContinuationCometdServlet))
@@ -9,6 +14,7 @@
 ;;;; Sending and receiving

 (defn new-client
+  "Create a new cometd client object."
   ([]   (new-client "compojure"))
   ([id] (new-client *cometd* id))
   ([servlet id]
@@ -21,6 +27,13 @@
   (.. servlet (getBayeux)
               (getChannel channel true)))

+(defn- json-generator
+  "Creates a JSON.Generator object for outputting Clojure data structures."
+  [data]
+  (proxy [JSON$Generator] []
+    (addJSON [buffer]
+      (.append buffer (json data)))))
+
 (defn publish
   "Publish a message to a channel."
   ([channel message]
@@ -28,7 +41,10 @@
   ([client channel message]
     (publish *cometd* client channel message))
   ([servlet client channel message]
-    (.publish (get-channel servlet channel) client message nil)))
+    (.publish (get-channel servlet channel)
+              client
+              (json-generator message)
+              nil)))

 (defn subscribe
   "Subscribe to a channel."
@@ -42,3 +58,26 @@
             (func mesg))))
       (.subscribe (get-channel servlet channel) client))))

+;;;; Security ;;;;
+
+(comment
+(defn allowed-to?)
+
+(defn create-security-policy
+  "Create a extensible security policy for an existing cometd servlet."
+  [servlet]
+  (.. servlet
+      (getBayeux)
+      (setSecurityPolicy
+        (proxy SecurityPolicy
+          (canPublish [])))))
+
+(defn deny-subscribe
+  "Deny subscription requests matching a predicate."
+  [pred])
+
+
+(defn deny-publish
+  [pred])
+
+)


Simplify/improve array-eq impl

Simplify/improve array-eq impl

--- src/caesium/util.clj
+++ src/caesium/util.clj
@@ -3,17 +3,17 @@

   This ns is not considered public API, and may break without semver
   major version increments."
-  (:require [caesium.byte-bufs :as bb])
+  (:require [caesium.byte-bufs :as bb]
+            [byte-streams :as bs])
   (:import (java.util Arrays)
            (org.apache.commons.codec.binary Hex)))

-(defn array-eq
+(def array-eq
   "Compares two byte arrays for equality.

   Inputs will be converted to bytes as required. Please note that this
   is not constant time!"
-  [a b]
-  (Arrays/equals (bb/->bytes a) (bb/->bytes b)))
+  bs/bytes=)

 (defn unhexify
   [^String s]


Upgrade dependencies

Upgrade dependencies

--- ancient-clj/project.clj
+++ ancient-clj/project.clj
@@ -5,22 +5,22 @@
             :url "https://opensource.org/licenses/MIT"
             :year 2013
             :key "mit"}
-  :dependencies [[org.clojure/clojure "1.8.0" :scope "provided"]
+  :dependencies [[org.clojure/clojure "1.10.1" :scope "provided"]
                  [org.clojure/data.xml "0.2.0-alpha6"]
                  [version-clj "0.1.2"]
                  ;; Note that this is the samve version used by s3-wagon-private 1.3.0
                  [com.amazonaws/aws-java-sdk-s3 "1.11.28"]
-                 [clj-http "2.1.0"
+                 [clj-http "3.11.0"
                   :exclusions [com.cognitect/transit-clj
                                crouton
                                org.apache.httpcomponents/httpclient]]
                  [commons-logging "1.2"]
-                 [joda-time "2.9.2"]
-                 [potemkin "0.4.3"]]
+                 [joda-time "2.10.8"]
+                 [potemkin "0.4.5"]]
   :scm {:dir ".."}
-  :profiles {:dev {:dependencies [[midje "1.8.3"]
-                                  [clj-time "0.11.0"]
-                                  [http-kit "2.1.19"]]
-                   :plugins [[lein-midje "3.1.3"]]}}
+  :profiles {:dev {:dependencies [[midje "1.9.9"]
+                                  [clj-time "0.15.2"]
+                                  [http-kit "2.5.0"]]
+                   :plugins [[lein-midje "3.2.2"]]}}
   :aliases {"test" ["midje"]}
   :pedantic? :abort)


the hook fn passed to do-split must return the model it was passed - is this a good idea..

--- src/main/clojure/org/dada/demo/whales.clj
+++ src/main/clojure/org/dada/demo/whales.clj
@@ -173,19 +173,33 @@
 (insert *metamodel* narwhals-length)

 ;;----------------------------------------
-;; demonstrate splitting
+;; demonstrate reduction (sum)
+;;----------------------------------------
+
+(insert *metamodel* (do-reduce-sum whales :length))
+(insert *metamodel* (do-reduce-sum whales :weight))
+(insert *metamodel* (do-reduce-sum heavier-whales-length :length))
+(insert *metamodel* (do-reduce-sum longer-whales-weight :weight))
+
+;;----------------------------------------
+;; demonstrate splitting [and more reduction)
 ;;----------------------------------------

 (let [type-to-route (apply hash-map (interleave types (range (count types))))
       #^"[Ljava.lang.String;" route-to-type (into-array String types)]
-  (do-split whales :type false type-to-route #(aget route-to-type #^Integer %) #(insert *metamodel* %)))
-
-;;----------------------------------------
-;; demonstrate reduction (sum)
-;;----------------------------------------
-
-(def heavier-whales-length-sum (do-reduce-sum heavier-whales-length :length))
-(insert *metamodel* heavier-whales-length-sum)
+  (do-split
+   whales
+   :type
+   false
+   type-to-route
+   #(aget route-to-type #^Integer %)
+   (fn [#^Model model]
+       (insert *metamodel* model)
+       (insert *metamodel* (do-reduce-sum model :length))
+       (insert *metamodel* (do-reduce-sum model :weight))
+       model				; TODO: do we really need to be able to override the model ? should threading go here ?
+       )
+   ))

 ;;----------------------------------------
 ;; select - being refactored into filter, transform, aggregate, group, ...


Fix join test.

Fix join test.

--- test/onyx/peer/join_test.clj
+++ test/onyx/peer/join_test.clj
@@ -4,7 +4,8 @@
             [onyx.peer.task-lifecycle-extensions :as l-ext]
             [onyx.plugin.core-async :refer [take-segments!]]
             [onyx.test-helper :refer [load-config]]
-            [onyx.api]))
+            [onyx.api]
+            [taoensso.timbre :refer [info warn trace fatal] :as timbre]))

 (def id (java.util.UUID/randomUUID))

@@ -17,7 +18,6 @@
 (def env (onyx.api/start-env env-config))

 (def peer-group (onyx.api/start-peer-group peer-config))
-
 (def batch-size 2)

 (def people
@@ -32,11 +32,11 @@

 (def ages (map #(select-keys % [:id :age]) people))

-(def name-chan (chan (inc names)))
+(def name-chan (chan (inc (count names))))

-(def age-chan (chan (inc ages)))
+(def age-chan (chan (inc (count ages))))

-(def out-chan (chan (sliding-buffer (inc n-messages))))
+(def out-chan (chan 10000 #_(sliding-buffer (inc n-messages))))

 (doseq [name names]
   (>!! name-chan name))
@@ -96,6 +96,15 @@
   [_ event]
   {:onyx.core/params [(atom {})]})

+(defmethod l-ext/inject-lifecycle-resources :names
+  [_ _] {:core.async/chan name-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :ages
+  [_ _] {:core.async/chan age-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :out
+  [_ _] {:core.async/chan out-chan})
+
 (def v-peers (onyx.api/start-peers 4 peer-group))

 (onyx.api/submit-job
@@ -105,7 +114,7 @@

 (def results (take-segments! out-chan))

-(fact (into #{} (butlast results)) => (into #{} people))
+(fact (set (butlast results)) => (set people))

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


Use Clojure’s DynamicClassLoader to make keg/join test work

--- test/powderkeg/core_test.clj
+++ test/powderkeg/core_test.clj
@@ -1,13 +1,19 @@
 (ns powderkeg.core-test
   (:require [powderkeg.core :as keg]
             [clojure.test :refer :all]))
+
+(defn clojure-dynamic-classloader [f]
+  (let [cl (.getContextClassLoader (Thread/currentThread))]
+    (.setContextClassLoader (Thread/currentThread) (clojure.lang.DynamicClassLoader. cl))
+    (f)
+    (.setContextClassLoader (Thread/currentThread) cl)))

 (defn with-local [f]
   (keg/connect! "local[2]")
   (f)
   (keg/disconnect!))

-(use-fixtures :once with-local)
+(use-fixtures :once clojure-dynamic-classloader with-local)

 (deftest rdd
   (is (= (into [] (keg/rdd (range 10)))


Move future test function on the top of namespace file.

--- test/promesa/core_tests.cljs
+++ test/promesa/core_tests.cljs
@@ -4,6 +4,11 @@
             [promesa.core :as p]))

 (enable-console-print!)
+
+(defn future
+  [sleep value]
+  (p/promise (fn [resolve]
+               (js/setTimeout #(resolve value) sleep))))

 (t/deftest promise-from-value
   (let [p1 (p/promise 1)]
@@ -83,12 +88,6 @@
       (p/then p3 (fn [v]
                    (t/is (= v "foo"))
                    (done))))))
-
-
-(defn future
-  [sleep value]
-  (p/promise (fn [resolve]
-               (js/setTimeout #(resolve value) sleep))))

 (t/deftest chaining-using-then
   (t/async done


Fixed error on validation not being shown

--- src/ardoq/swagger/api.clj
+++ src/ardoq/swagger/api.clj
@@ -127,7 +127,7 @@
                (.printStackTrace e)
                (when notifier
                  (send-failure-email! session client (str "Failed reading request " (.getMessage e))))
-               {:status 422
+               {:status 500
                 :headers {"Content-Type" "application/json"}
                 :body (json/write-str {:error (.getMessage e)})})
              (catch clojure.lang.ExceptionInfo e
@@ -138,9 +138,9 @@
                  {:status 404
                   :headers {"Content-Type" "application/json"}
                   :body (json/write-str {:error (str (-> e ex-data :trace-redirects first) " returned 404")})}
-                 {:status 500
+                 {:status 422
                   :headers {"Content-Type" "application/json"}
-                  :body (json/write-str {:error (str "Internal error" (-> e ex-data :causes))})}))
+                  :body (json/write-str {:error (-> e ex-data :causes)})}))
              (catch Exception e
                (.printStackTrace e)
                (when notifier


Fix debug string in mail system

Fix debug string in mail system

--- systems/mail/src/containium/systems/mail.clj
+++ systems/mail/src/containium/systems/mail.clj
@@ -31,9 +31,9 @@
     (send-message this from to subject body nil))

   (send-message [this from to subject body opts]
-    (debug logger "Sending email from" from "to" to "with subject" subject "using options" opts)
     (let [from (str from)
           to (map str (flatten [to]))]
+      (debug logger "Sending email from" from "to" (apply str (interpose ", " to)) "with subject" subject "using options" opts)
       (postal/send-message smtp (merge {:from from, :to to, :subject subject, :body body} opts)))))


Compile/cast :host-regex String to regex.Pattern

--- systems/ring/src/containium/systems/ring.clj
+++ systems/ring/src/containium/systems/ring.clj
@@ -52,7 +52,7 @@
 (defmacro matcher
   "Evaluates to a match form, used by the make-app function."
   [{:keys [host-regex context-path]} uri-sym server-name-sym]
-  (let [host-test `(re-matches ~host-regex ~server-name-sym)
+  (let [host-test `(re-matches ~(if host-regex (re-pattern host-regex)) ~server-name-sym)
         context-test `(and (.startsWith ~uri-sym ~context-path)
                            (= (get ~uri-sym ~(count context-path)) \/))]
     `(and ~@(remove nil? (list (when host-regex host-test)


Print every HTTP request and App sorting result. Disable with :print-request false, in :ring-conf

--- systems/ring/src/containium/systems/ring.clj
+++ systems/ring/src/containium/systems/ring.clj
@@ -45,7 +45,9 @@
                     "having a context-path nor a host-regex ("
                     (apply str (interpose ", " (map :name non-deterministic)))
                     ")."))))
-  (->> apps (sort-by #(get % :sort-value)) reverse))
+  (let [sorted (->> apps (sort-by #(get % :sort-value)) reverse)]
+    (log-fn (apply str "Sorted apps: " (interpose ", " (map :name apps))))
+    sorted))

 (defmacro matcher
@@ -85,8 +87,11 @@
                                                 (let [~'app (~'sorted ~index)]
                                                   (boxure/call-in-box
                                                    (:box ~'app)
-                                                   ((:handler-fn ~'app)
-                                                   ~(if-let [cp (-> app :ring-conf :context-path)]
+                                                   (; Optionally print the request map before execution
+                                                    ~(if-not (= false (-> app :ring-conf :print-requests))
+                                                      `(do (println "[" ~(str (:name app)) "] " ~'request) (:handler-fn ~'app))
+                                                      `(:handler-fn ~'app))
+                                                    ~(if-let [cp (-> app :ring-conf :context-path)]
                                                       `(update-in ~'request [:uri]
                                                                   #(subs % ~(count cp)))
                                                       'request)))))))))


Move item-view into its own component.

Move item-view into its own component.

--- src/lab_notebook/core.cljs
+++ src/lab_notebook/core.cljs
@@ -3,6 +3,15 @@
             [om.dom :as dom]))

 (defonce appstate (atom {}))
+
+(defn item-view [cursor component]
+  (reify
+    om/IRender
+    (render [this]
+      (dom/div nil
+        (dom/div nil (:summary cursor))
+        (dom/div nil (:date-time cursor))
+        (dom/div nil (:notes cursor))))))

 (defn app-container [cursor component]
   (reify
@@ -12,10 +21,7 @@
         (dom/h1 nil "Lab notebook")
         nil
         (for [entry (:entries cursor)]
-          (dom/div nil
-            (dom/div nil (:summary entry))
-            (dom/div nil (:date-time entry))
-            (dom/div nil (:notes entry))))))))
+          (om/build item-view entry))))))

 (om/root app-container appstate
   {:target (. js/document (getElementById "app"))})


Add alias to remove ambiguity on reading

--- test/tick/interval_test.cljc
+++ test/tick/interval_test.cljc
@@ -1,7 +1,6 @@
 ;; Copyright © 2016-2017, JUXT LTD.

 (ns tick.interval-test
-  (:refer-clojure :exclude [contains? complement partition-by group-by conj extend group-by])
   (:require
     [clojure.spec.alpha :as s]
     [tick.core :as t]
@@ -11,27 +10,16 @@
        [cljs.test :refer-macros [deftest is testing run-tests]])
     #?(:cljs
        [tick.js-joda :refer [ChronoUnit]])
-    [tick.interval :refer [interval compose-r contains? divide-by-period relation concur
-                           union as-interval starts? basic-relations not-yet-implemented
-                           complement-r  disjoint? temporal?
-                           started-by? intersection concur? conj overlaps? equals? temporal-amount?
-                           meets? intersection-r met-by? extend finished-by? scale concurrencies
-                           make-relation preceded-by? precedes? during?
-                           ordered-disjoint-intervals? divide-by-duration overlapped-by? converse-r
-                            bounds am
-                            finishes? conv narrow
-                           difference pm divide-by-divisor
-                           complement group-by]])
+    [tick.interval :as ti])
   #?(:clj
      (:import
        [java.time.temporal ChronoUnit])))

-
 (s/check-asserts true)

 (deftest basic-relations-test
-  (is (= (count basic-relations) 13))
-  (is (distinct? basic-relations)))
+  (is (= (count ti/basic-relations) 13))
+  (is (distinct? ti/basic-relations)))

 ;; We can construct every possible combination of interval relation with just 4 instants.
 (def instants [(t/instant "2017-07-30T09:00:00Z")
@@ -43,531 +31,531 @@
 ;; From [ALSPAUGH-2009]
 (deftest distinct-test
   (is
-   (= [1]   ; Each interval should have just one relation that is true
-      (distinct
-       (let [f (apply juxt basic-relations)]
-         (for [x1 instants
-               x2 instants
-               y1 instants
-               y2 instants
-               :when (t/< x1 x2)
-               :when (t/< y1 y2)
-               :let [x (interval x1 x2)
-                     y (interval y1 y2)]]
-           ;; For each combination, count how many relations are true
-           ;; (should be just one each time)
-           (count (filter true? (f x y)))))))))
+    (= [1]   ; Each interval should have just one relation that is true
+       (distinct
+         (let [f (apply juxt ti/basic-relations)]
+           (for [x1 instants
+                 x2 instants
+                 y1 instants
+                 y2 instants
+                 :when (t/< x1 x2)
+                 :when (t/< y1 y2)
+                 :let [x (ti/interval x1 x2)
+                       y (ti/interval y1 y2)]]
+             ;; For each combination, count how many relations are true
+             ;; (should be just one each time)
+             (count (filter true? (f x y)))))))))

 ;; Exhaustive: because any pair of definite intervals are described by one of the relations.
 (deftest exhaustive-test []
   (is
-   (= 13 ; Thirteen basic relations
-      (count
-       (distinct
-        (for [x1 instants
-              x2 instants
-              y1 instants
-              y2 instants
-              :when (t/< x1 x2)
-              :when (t/< y1 y2)
-              :let [x (interval x1 x2)
-                    y (interval y1 y2)]]
-          ;; For each combination, count how many relations are true
-          ;; (should be just one each time)
-          (relation x y)))))))
+    (= 13 ; Thirteen basic relations
+       (count
+         (distinct
+           (for [x1 instants
+                 x2 instants
+                 y1 instants
+                 y2 instants
+                 :when (t/< x1 x2)
+                 :when (t/< y1 y2)
+                 :let [x (ti/interval x1 x2)
+                       y (ti/interval y1 y2)]]
+             ;; For each combination, count how many relations are true
+             ;; (should be just one each time)
+             (ti/relation x y)))))))

 (deftest disjoint-test []
-  (is (disjoint?
-        (interval (instants 0) (instants 1))
-        (interval (instants 2) (instants 3))))
-  (is (= (disjoint?
-           (interval (instants 0) (instants 1))
-           (interval (instants 2) (instants 3))) precedes?))
+  (is (ti/disjoint?
+        (ti/interval (instants 0) (instants 1))
+        (ti/interval (instants 2) (instants 3))))
+  (is (= (ti/disjoint?
+           (ti/interval (instants 0) (instants 1))
+           (ti/interval (instants 2) (instants 3))) ti/precedes?))
   (is (nil?
-       (disjoint?
-         (interval (instants 0) (instants 2))
-         (interval (instants 1) (instants 3)))))
+        (ti/disjoint?
+          (ti/interval (instants 0) (instants 2))
+          (ti/interval (instants 1) (instants 3)))))
   (is (nil?
-       (disjoint?
-         (interval (instants 0) (instants 3))
-         (interval (instants 1) (instants 2))))))
+        (ti/disjoint?
+          (ti/interval (instants 0) (instants 3))
+          (ti/interval (instants 1) (instants 2))))))

 ;; concur is really the complement to disjoint, but we'll test it
 ;; anywhere to ensure the complement function is working as expected.

 (deftest concur?-test []
   (is (nil?
-       (concur?
-         (interval (instants 0) (instants 1))
-         (interval (instants 2) (instants 3)))))
-  (is (= (concur?
-           (interval (instants 0) (instants 2))
-           (interval (instants 1) (instants 3)))
-         overlaps?))
-  (is (= (concur?
-           (interval (instants 0) (instants 3))
-           (interval (instants 1) (instants 2)))
-         contains?)))
+        (ti/concur?
+          (ti/interval (instants 0) (instants 1))
+          (ti/interval (instants 2) (instants 3)))))
+  (is (= (ti/concur?
+           (ti/interval (instants 0) (instants 2))
+           (ti/interval (instants 1) (instants 3)))
+         ti/overlaps?))
+  (is (= (ti/concur?
+           (ti/interval (instants 0) (instants 3))
+           (ti/interval (instants 1) (instants 2)))
+         ti/contains?)))

 (deftest concur-test []
   (is
-   (=
-    (interval (instants 1) (instants 2))
-    (concur
-     (interval (instants 0) (instants 2))
-     (interval (instants 1) (instants 3)))))
-
-  (is
-   (=
-    (interval (instants 1) (instants 2))
-    (concur
-     (interval (instants 1) (instants 3))
-     (interval (instants 0) (instants 2)))))
-
-  (is
-   (nil?
-    (concur
-     (interval (instants 0) (instants 1))
-     (interval (instants 2) (instants 3)))))
-
-  (is
-   (nil?
-    (concur
-     (interval (instants 0) (instants 1))
-     (interval (instants 1) (instants 2)))))
-
-  (is
-   (=
-    (interval (instants 0) (instants 2))
-    (concur
-     (interval (instants 0) (instants 2))
-     (interval (instants 0) (instants 3)))))
-
-  (is
-   (=
-    (interval (instants 0) (instants 2))
-    (concur
-     (interval (instants 0) (instants 3))
-     (interval (instants 0) (instants 2)))))
-
-  (is
-   (=
-    (interval (instants 1) (instants 3))
-    (concur
-     (interval (instants 1) (instants 3))
-     (interval (instants 0) (instants 3))))))
+    (=
+      (ti/interval (instants 1) (instants 2))
+      (ti/concur
+        (ti/interval (instants 0) (instants 2))
+        (ti/interval (instants 1) (instants 3)))))
+
+  (is
+    (=
+      (ti/interval (instants 1) (instants 2))
+      (ti/concur
+        (ti/interval (instants 1) (instants 3))
+        (ti/interval (instants 0) (instants 2)))))
+
+  (is
+    (nil?
+      (ti/concur
+        (ti/interval (instants 0) (instants 1))
+        (ti/interval (instants 2) (instants 3)))))
+
+  (is
+    (nil?
+      (ti/concur
+        (ti/interval (instants 0) (instants 1))
+        (ti/interval (instants 1) (instants 2)))))
+
+  (is
+    (=
+      (ti/interval (instants 0) (instants 2))
+      (ti/concur
+        (ti/interval (instants 0) (instants 2))
+        (ti/interval (instants 0) (instants 3)))))
+
+  (is
+    (=
+      (ti/interval (instants 0) (instants 2))
+      (ti/concur
+        (ti/interval (instants 0) (instants 3))
+        (ti/interval (instants 0) (instants 2)))))
+
+  (is
+    (=
+      (ti/interval (instants 1) (instants 3))
+      (ti/concur
+        (ti/interval (instants 1) (instants 3))
+        (ti/interval (instants 0) (instants 3))))))

 ;; Sequence tests

-;; TODO: Support this: (interval (t/now) (t/seconds 10))
-;; TODO: Don't allow this: (interval (t/now)) -- returns an illegal interval
+;; TODO: Support this: (ti/interval (t/now) (t/seconds 10))
+;; TODO: Don't allow this: (ti/interval (t/now)) -- returns an illegal ti/interval

 (deftest ordered-disjoint-intervals?-test
   (is
-   (ordered-disjoint-intervals? []))
-  (is
-   (ordered-disjoint-intervals?
-    [(interval (t/instant "2017-07-30T09:00:00Z")
-               (t/instant "2017-07-30T10:00:00Z"))]))
-  (is
-   (ordered-disjoint-intervals?
-    [(interval (t/instant "2017-07-30T09:00:00Z")
-               (t/instant "2017-07-30T10:00:00Z"))
-     (interval (t/instant "2017-07-30T11:00:00Z")
-               (t/instant "2017-07-30T13:00:00Z"))]))
-  (is
-   (ordered-disjoint-intervals?
-    [(interval (t/instant "2017-07-30T09:00:00Z")
-               (t/instant "2017-07-30T11:00:00Z"))
-     (interval (t/instant "2017-07-30T11:00:00Z")
-               (t/instant "2017-07-30T13:00:00Z"))]))
-  (is
-   (ordered-disjoint-intervals?
-    [(interval (t/instant "2017-07-30T09:00:00Z")
-               (t/instant "2017-07-30T11:00:00Z"))
-     (interval (t/instant "2017-07-30T11:00:00Z")
-               (t/instant "2017-07-30T13:00:00Z"))
-     (interval (t/instant "2017-07-30T16:00:00Z")
-               (t/instant "2017-07-30T18:00:00Z"))]))
-  (is
-   (false?
-    (ordered-disjoint-intervals?
-     [(interval (t/instant "2017-07-30T09:00:00Z")
-                (t/instant "2017-07-30T12:00:00Z"))
-      (interval (t/instant "2017-07-30T11:00:00Z")
-                (t/instant "2017-07-30T13:00:00Z"))])))
-
-  (is
-   (false?
-    (ordered-disjoint-intervals?
-     [(interval (t/instant "2017-07-30T11:00:00Z")
-                (t/instant "2017-07-30T13:00:00Z"))
-      (interval (t/instant "2017-07-30T09:00:00Z")
-                (t/instant "2017-07-30T10:00:00Z"))]))))
+    (ti/ordered-disjoint-intervals? []))
+  (is
+    (ti/ordered-disjoint-intervals?
+      [(ti/interval (t/instant "2017-07-30T09:00:00Z")
+                    (t/instant "2017-07-30T10:00:00Z"))]))
+  (is
+    (ti/ordered-disjoint-intervals?
+      [(ti/interval (t/instant "2017-07-30T09:00:00Z")
+                    (t/instant "2017-07-30T10:00:00Z"))
+       (ti/interval (t/instant "2017-07-30T11:00:00Z")
+                    (t/instant "2017-07-30T13:00:00Z"))]))
+  (is
+    (ti/ordered-disjoint-intervals?
+      [(ti/interval (t/instant "2017-07-30T09:00:00Z")
+                    (t/instant "2017-07-30T11:00:00Z"))
+       (ti/interval (t/instant "2017-07-30T11:00:00Z")
+                    (t/instant "2017-07-30T13:00:00Z"))]))
+  (is
+    (ti/ordered-disjoint-intervals?
+      [(ti/interval (t/instant "2017-07-30T09:00:00Z")
+                    (t/instant "2017-07-30T11:00:00Z"))
+       (ti/interval (t/instant "2017-07-30T11:00:00Z")
+                    (t/instant "2017-07-30T13:00:00Z"))
+       (ti/interval (t/instant "2017-07-30T16:00:00Z")
+                    (t/instant "2017-07-30T18:00:00Z"))]))
+  (is
+    (false?
+      (ti/ordered-disjoint-intervals?
+        [(ti/interval (t/instant "2017-07-30T09:00:00Z")
+                      (t/instant "2017-07-30T12:00:00Z"))
+         (ti/interval (t/instant "2017-07-30T11:00:00Z")
+                      (t/instant "2017-07-30T13:00:00Z"))])))
+
+  (is
+    (false?
+      (ti/ordered-disjoint-intervals?
+        [(ti/interval (t/instant "2017-07-30T11:00:00Z")
+                      (t/instant "2017-07-30T13:00:00Z"))
+         (ti/interval (t/instant "2017-07-30T09:00:00Z")
+                      (t/instant "2017-07-30T10:00:00Z"))]))))

 (deftest union-test
-  (let [coll1 [(interval (t/instant "2017-07-30T09:00:00Z")
-                         (t/instant "2017-07-30T12:00:00Z"))]
-        coll2 [(interval (t/instant "2017-07-30T11:00:00Z")
-                         (t/instant "2017-07-30T15:00:00Z"))]
-        coll3 [(interval (t/instant "2017-07-30T17:00:00Z")
-                         (t/instant "2017-07-30T19:00:00Z"))]]
-    (is (= 1 (count (union coll1 coll2))))
-    (is (ordered-disjoint-intervals? (union coll1 coll2)))
-    (is (= 2 (count (union coll1 coll2 coll3))))
-    (is (ordered-disjoint-intervals? (union coll1 coll2 coll3)))))
+  (let [coll1 [(ti/interval (t/instant "2017-07-30T09:00:00Z")
+                            (t/instant "2017-07-30T12:00:00Z"))]
+        coll2 [(ti/interval (t/instant "2017-07-30T11:00:00Z")
+                            (t/instant "2017-07-30T15:00:00Z"))]
+        coll3 [(ti/interval (t/instant "2017-07-30T17:00:00Z")
+                            (t/instant "2017-07-30T19:00:00Z"))]]
+    (is (= 1 (count (ti/union coll1 coll2))))
+    (is (ti/ordered-disjoint-intervals? (ti/union coll1 coll2)))
+    (is (= 2 (count (ti/union coll1 coll2 coll3))))
+    (is (ti/ordered-disjoint-intervals? (ti/union coll1 coll2 coll3)))))

 (deftest intersection-test
-  (let [coll1 [(interval (t/instant "2017-01-01T06:00:00Z")
-                         (t/instant "2017-01-01T07:00:00Z"))
-
-               (interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T09:00:00Z"))
-
-               (interval (t/instant "2017-01-01T09:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-
-               (interval (t/instant "2017-01-01T13:00:00Z")
-                         (t/instant "2017-01-01T15:00:00Z"))
-
-               (interval (t/instant "2017-01-01T17:00:00Z")
-                         (t/instant "2017-01-01T19:00:00Z"))]
-
-        coll2 [(interval (t/instant "2017-01-01T09:00:00Z")
-                         (t/instant "2017-01-01T10:00:00Z"))
-
-               (interval (t/instant "2017-01-01T11:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-
-               (interval (t/instant "2017-01-01T14:00:00Z")
-                         (t/instant "2017-01-01T18:00:00Z"))]]
-    (is
-      (= [(interval (t/instant "2017-01-01T09:00:00Z") (t/instant "2017-01-01T10:00:00Z"))
-          (interval (t/instant "2017-01-01T11:00:00Z") (t/instant "2017-01-01T12:00:00Z"))
-          (interval (t/instant "2017-01-01T14:00:00Z") (t/instant "2017-01-01T15:00:00Z"))
-          (interval (t/instant "2017-01-01T17:00:00Z") (t/instant "2017-01-01T18:00:00Z"))]
-        (intersection coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-               (interval (t/instant "2017-01-01T14:00:00Z")
-                         (t/instant "2017-01-01T16:00:00Z"))]
-
-        coll2 [(interval (t/instant "2017-01-01T09:00:00Z")
-                         (t/instant "2017-01-01T11:00:00Z"))
-               (interval (t/instant "2017-01-01T13:00:00Z")
-                         (t/instant "2017-01-01T17:00:00Z"))]]
-
-    (is
-      (= [(interval (t/instant "2017-01-01T09:00:00Z") (t/instant "2017-01-01T11:00:00Z"))
-          (interval (t/instant "2017-01-01T14:00:00Z") (t/instant "2017-01-01T16:00:00Z"))]
-        (intersection coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-               (interval (t/instant "2017-01-01T14:00:00Z")
-                         (t/instant "2017-01-01T16:00:00Z"))]
-        coll2 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))]]
-    (is
-     (=
-       [(interval (t/instant "2017-01-01T08:00:00Z")
-                  (t/instant "2017-01-01T12:00:00Z"))]
-      (intersection coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-               (interval (t/instant "2017-01-01T17:00:00Z")
-                         (t/instant "2017-01-01T19:00:00Z"))]
-
-
-        coll2 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T18:00:00Z"))]]
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T06:00:00Z")
+                            (t/instant "2017-01-01T07:00:00Z"))
+
+               (ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T09:00:00Z"))
+
+               (ti/interval (t/instant "2017-01-01T09:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+
+               (ti/interval (t/instant "2017-01-01T13:00:00Z")
+                            (t/instant "2017-01-01T15:00:00Z"))
+
+               (ti/interval (t/instant "2017-01-01T17:00:00Z")
+                            (t/instant "2017-01-01T19:00:00Z"))]
+
+        coll2 [(ti/interval (t/instant "2017-01-01T09:00:00Z")
+                            (t/instant "2017-01-01T10:00:00Z"))
+
+               (ti/interval (t/instant "2017-01-01T11:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+
+               (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                            (t/instant "2017-01-01T18:00:00Z"))]]
+    (is
+      (= [(ti/interval (t/instant "2017-01-01T09:00:00Z") (t/instant "2017-01-01T10:00:00Z"))
+          (ti/interval (t/instant "2017-01-01T11:00:00Z") (t/instant "2017-01-01T12:00:00Z"))
+          (ti/interval (t/instant "2017-01-01T14:00:00Z") (t/instant "2017-01-01T15:00:00Z"))
+          (ti/interval (t/instant "2017-01-01T17:00:00Z") (t/instant "2017-01-01T18:00:00Z"))]
+         (ti/intersection coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                            (t/instant "2017-01-01T16:00:00Z"))]
+
+        coll2 [(ti/interval (t/instant "2017-01-01T09:00:00Z")
+                            (t/instant "2017-01-01T11:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T13:00:00Z")
+                            (t/instant "2017-01-01T17:00:00Z"))]]
+
+    (is
+      (= [(ti/interval (t/instant "2017-01-01T09:00:00Z") (t/instant "2017-01-01T11:00:00Z"))
+          (ti/interval (t/instant "2017-01-01T14:00:00Z") (t/instant "2017-01-01T16:00:00Z"))]
+         (ti/intersection coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                            (t/instant "2017-01-01T16:00:00Z"))]
+        coll2 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))]]
+    (is
+      (=
+        [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                      (t/instant "2017-01-01T12:00:00Z"))]
+        (ti/intersection coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T17:00:00Z")
+                            (t/instant "2017-01-01T19:00:00Z"))]
+
+
+        coll2 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T18:00:00Z"))]]

     (is (=
-         [(interval (t/instant "2017-01-01T08:00:00Z")
-                    (t/instant "2017-01-01T12:00:00Z"))
-          (interval (t/instant "2017-01-01T17:00:00Z")
-                    (t/instant "2017-01-01T18:00:00Z"))]
-         (intersection coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T12:00:00Z")
+          [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                        (t/instant "2017-01-01T12:00:00Z"))
+           (ti/interval (t/instant "2017-01-01T17:00:00Z")
+                        (t/instant "2017-01-01T18:00:00Z"))]
+          (ti/intersection coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T12:00:00Z")
+                            (t/instant "2017-01-01T14:00:00Z"))]
+        coll2 [(ti/interval (t/instant "2017-01-01T11:00:00Z")
+                            (t/instant "2017-01-01T14:00:00Z"))]]
+    (is (= [(ti/interval (t/instant "2017-01-01T12:00:00Z")
                          (t/instant "2017-01-01T14:00:00Z"))]
-        coll2 [(interval (t/instant "2017-01-01T11:00:00Z")
-                         (t/instant "2017-01-01T14:00:00Z"))]]
-    (is (= [(interval (t/instant "2017-01-01T12:00:00Z")
-                      (t/instant "2017-01-01T14:00:00Z"))]
-           (intersection coll1 coll2))))
-
-  (let [coll1 [(interval (t/parse "2017-04-11T00:00")
+           (ti/intersection coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/parse "2017-04-11T00:00")
+                            (t/parse "2017-04-14T00:00"))
+               (ti/interval (t/parse "2017-04-18T00:00")
+                            (t/parse "2017-04-20T00:00"))
+               (ti/interval (t/parse "2017-12-20T00:00")
+                            (t/parse "2017-12-23T00:00"))
+               (ti/interval (t/parse "2017-12-27T00:00")
+                            (t/parse "2018-01-01T00:00"))
+               (ti/interval (t/parse "2018-01-02T00:00")
+                            (t/parse "2018-01-08T00:00"))]
+        coll2 [(ti/bounds "2017")]]
+    (is (= [(ti/interval (t/parse "2017-04-11T00:00")
                          (t/parse "2017-04-14T00:00"))
-               (interval (t/parse "2017-04-18T00:00")
+            (ti/interval (t/parse "2017-04-18T00:00")
                          (t/parse "2017-04-20T00:00"))
-               (interval (t/parse "2017-12-20T00:00")
+            (ti/interval (t/parse "2017-12-20T00:00")
                          (t/parse "2017-12-23T00:00"))
-               (interval (t/parse "2017-12-27T00:00")
-                         (t/parse "2018-01-01T00:00"))
-               (interval (t/parse "2018-01-02T00:00")
-                         (t/parse "2018-01-08T00:00"))]
-        coll2 [(bounds "2017")]]
-    (is (= [(interval (t/parse "2017-04-11T00:00")
-                      (t/parse "2017-04-14T00:00"))
-            (interval (t/parse "2017-04-18T00:00")
-                      (t/parse "2017-04-20T00:00"))
-            (interval (t/parse "2017-12-20T00:00")
-                      (t/parse "2017-12-23T00:00"))
-            (interval (t/parse "2017-12-27T00:00")
-                      (t/parse "2018-01-01T00:00"))]
-           (intersection coll1 coll2))))
-
-  (let [coll1 [(interval (t/parse "2017-04-11T00:00")
+            (ti/interval (t/parse "2017-12-27T00:00")
+                         (t/parse "2018-01-01T00:00"))]
+           (ti/intersection coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/parse "2017-04-11T00:00")
+                            (t/parse "2017-04-14T00:00"))
+               (ti/interval (t/parse "2017-04-18T00:00")
+                            (t/parse "2017-04-20T00:00"))
+               (ti/interval (t/parse "2017-12-20T00:00")
+                            (t/parse "2017-12-23T00:00"))
+               (ti/interval (t/parse "2017-12-27T00:00")
+                            (t/parse "2018-01-01T00:00"))
+               (ti/interval (t/parse "2018-01-02T00:00")
+                            (t/parse "2018-01-08T00:00"))]
+        coll2 [(ti/bounds "2017")]]
+    (is (= [(ti/interval (t/parse "2017-04-11T00:00")
                          (t/parse "2017-04-14T00:00"))
-               (interval (t/parse "2017-04-18T00:00")
+            (ti/interval (t/parse "2017-04-18T00:00")
                          (t/parse "2017-04-20T00:00"))
-               (interval (t/parse "2017-12-20T00:00")
+            (ti/interval (t/parse "2017-12-20T00:00")
                          (t/parse "2017-12-23T00:00"))
-               (interval (t/parse "2017-12-27T00:00")
-                         (t/parse "2018-01-01T00:00"))
-               (interval (t/parse "2018-01-02T00:00")
-                         (t/parse "2018-01-08T00:00"))]
-        coll2 [(bounds "2017")]]
-    (is (= [(interval (t/parse "2017-04-11T00:00")
-                      (t/parse "2017-04-14T00:00"))
-            (interval (t/parse "2017-04-18T00:00")
-                      (t/parse "2017-04-20T00:00"))
-            (interval (t/parse "2017-12-20T00:00")
-                      (t/parse "2017-12-23T00:00"))
-            (interval (t/parse "2017-12-27T00:00")
-                      (t/parse "2018-01-01T00:00"))]
-           (intersection coll1 coll2)))
+            (ti/interval (t/parse "2017-12-27T00:00")
+                         (t/parse "2018-01-01T00:00"))]
+           (ti/intersection coll1 coll2)))

     (testing "Empty sets"
       (let [coll1 []
-            coll2 [(interval (t/instant "2017-01-01T09:00:00Z")
-                             (t/instant "2017-01-01T10:00:00Z"))
-
-                   (interval (t/instant "2017-01-01T11:00:00Z")
-                             (t/instant "2017-01-01T12:00:00Z"))
-
-                   (interval (t/instant "2017-01-01T14:00:00Z")
-                             (t/instant "2017-01-01T18:00:00Z"))]]
+            coll2 [(ti/interval (t/instant "2017-01-01T09:00:00Z")
+                                (t/instant "2017-01-01T10:00:00Z"))
+
+                   (ti/interval (t/instant "2017-01-01T11:00:00Z")
+                                (t/instant "2017-01-01T12:00:00Z"))
+
+                   (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                                (t/instant "2017-01-01T18:00:00Z"))]]
         (is
-         (= []
-            (intersection coll1 coll2)))
+          (= []
+             (ti/intersection coll1 coll2)))
         (is
-         (= []
-            (intersection coll2 coll1)))
+          (= []
+             (ti/intersection coll2 coll1)))
         (is
-         (= []
-            (intersection [] [])))))))
+          (= []
+             (ti/intersection [] [])))))))

 (deftest difference-test
-  (let [coll1 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-               (interval (t/instant "2017-01-01T14:00:00Z")
-                         (t/instant "2017-01-01T16:00:00Z"))]
-
-        coll2 [(interval (t/instant "2017-01-01T09:00:00Z")
-                         (t/instant "2017-01-01T11:00:00Z"))
-               (interval (t/instant "2017-01-01T13:00:00Z")
-                         (t/instant "2017-01-01T17:00:00Z"))]]
-
-    (is
-      (= [(interval (t/instant "2017-01-01T08:00:00Z")
-                    (t/instant "2017-01-01T09:00:00Z"))
-          (interval (t/instant "2017-01-01T11:00:00Z")
-                    (t/instant "2017-01-01T12:00:00Z"))]
-         (difference coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-               (interval (t/instant "2017-01-01T14:00:00Z")
-                         (t/instant "2017-01-01T16:00:00Z"))]
-        coll2 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))]]
-    (is
-      (=
-        [(interval (t/instant "2017-01-01T14:00:00Z")
-                   (t/instant "2017-01-01T16:00:00Z"))]
-        (difference coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T12:00:00Z"))
-               (interval (t/instant "2017-01-01T17:00:00Z")
-                         (t/instant "2017-01-01T19:00:00Z"))]
-
-
-        coll2 [(interval (t/instant "2017-01-01T08:00:00Z")
-                         (t/instant "2017-01-01T18:00:00Z"))]]
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                            (t/instant "2017-01-01T16:00:00Z"))]
+
+        coll2 [(ti/interval (t/instant "2017-01-01T09:00:00Z")
+                            (t/instant "2017-01-01T11:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T13:00:00Z")
+                            (t/instant "2017-01-01T17:00:00Z"))]]
+
+    (is
+      (= [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                       (t/instant "2017-01-01T09:00:00Z"))
+          (ti/interval (t/instant "2017-01-01T11:00:00Z")
+                       (t/instant "2017-01-01T12:00:00Z"))]
+         (ti/difference coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                            (t/instant "2017-01-01T16:00:00Z"))]
+        coll2 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))]]
+    (is
+      (=
+        [(ti/interval (t/instant "2017-01-01T14:00:00Z")
+                      (t/instant "2017-01-01T16:00:00Z"))]
+        (ti/difference coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T12:00:00Z"))
+               (ti/interval (t/instant "2017-01-01T17:00:00Z")
+                            (t/instant "2017-01-01T19:00:00Z"))]
+
+
+        coll2 [(ti/interval (t/instant "2017-01-01T08:00:00Z")
+                            (t/instant "2017-01-01T18:00:00Z"))]]

     (is (=
-          [(interval (t/instant "2017-01-01T18:00:00Z")
-                     (t/instant "2017-01-01T19:00:00Z"))]
-          (difference coll1 coll2))))
-
-  (let [coll1 [(interval (t/instant "2017-01-01T12:00:00Z")
-                         (t/instant "2017-01-01T14:00:00Z"))]
-        coll2 [(interval (t/instant "2017-01-01T11:00:00Z")
-                         (t/instant "2017-01-01T14:00:00Z"))]]
-    (is (empty? (difference coll1 coll2))))
-
-  (is (= [(bounds "2017-07-31" "2017-08-13")]
-         (difference
-           [(bounds "2017-07-31" "2017-08-13")]
-           [(bounds "2017-01-01")])))
+          [(ti/interval (t/instant "2017-01-01T18:00:00Z")
+                        (t/instant "2017-01-01T19:00:00Z"))]
+          (ti/difference coll1 coll2))))
+
+  (let [coll1 [(ti/interval (t/instant "2017-01-01T12:00:00Z")
+                            (t/instant "2017-01-01T14:00:00Z"))]
+        coll2 [(ti/interval (t/instant "2017-01-01T11:00:00Z")
+                            (t/instant "2017-01-01T14:00:00Z"))]]
+    (is (empty? (ti/difference coll1 coll2))))
+
+  (is (= [(ti/bounds "2017-07-31" "2017-08-13")]
+         (ti/difference
+           [(ti/bounds "2017-07-31" "2017-08-13")]
+           [(ti/bounds "2017-01-01")])))

   (testing "Empty sets"
     (let [coll1 []
-          coll2 [(interval (t/instant "2017-01-01T09:00:00Z")
-                           (t/instant "2017-01-01T10:00:00Z"))
-
-                 (interval (t/instant "2017-01-01T11:00:00Z")
-                           (t/instant "2017-01-01T12:00:00Z"))
-
-                 (interval (t/instant "2017-01-01T14:00:00Z")
-                           (t/instant "2017-01-01T18:00:00Z"))]]
+          coll2 [(ti/interval (t/instant "2017-01-01T09:00:00Z")
+                              (t/instant "2017-01-01T10:00:00Z"))
+
+                 (ti/interval (t/instant "2017-01-01T11:00:00Z")
+                              (t/instant "2017-01-01T12:00:00Z"))
+
+                 (ti/interval (t/instant "2017-01-01T14:00:00Z")
+                              (t/instant "2017-01-01T18:00:00Z"))]]
       (is
         (= []
-           (difference coll1 coll2)))
+           (ti/difference coll1 coll2)))
       (is
         (= coll2
-           (difference coll2 coll1)))
+           (ti/difference coll2 coll1)))
       (is
         (= []
-           (difference [] []))))))
+           (ti/difference [] []))))))

 ;; We are reclaiming 'disjoin' to mean to 'end the joining of' or 'to become disjoint'.

 #_(deftest disj-test
-  (is (=
-        [(interval (t/local-date-time "2017-01-01T00:00")
-                   (t/local-date-time "2017-07-04T00:00"))
-         (interval (t/local-date-time "2017-07-05T00:00")
-                   (t/local-date-time "2018-01-01T00:00"))]
-       (disj [(bounds "2017")] (bounds (t/date "2017-07-04"))))))
+    (is (=
+          [(ti/interval (t/local-date-time "2017-01-01T00:00")
+                        (t/local-date-time "2017-07-04T00:00"))
+           (ti/interval (t/local-date-time "2017-07-05T00:00")
+                        (t/local-date-time "2018-01-01T00:00"))]
+          (disj [(bounds "2017")] (bounds (t/date "2017-07-04"))))))

 #_(deftest complement-test
-  ;; Not sure why this is failing on the equals check
-  #_(is (=
-       [[(tick.core/min-of-type (t/time "2017-01-01T00:00:00Z"))
-         (t/time "2017-01-01T00:00:00Z")]
-
-        [(t/time "2017-01-04T00:00:00Z")
-         (t/time "2017-01-05T00:00:00Z")]
-
-        [(t/time "2018-01-01T00:00:00Z")
-         (tick.core/max-of-type (t/time "2017-01-01T00:00:00Z"))
-         ]]
-
-       (complement [[(t/time "2017-01-01T00:00:00Z")
-                     (t/time "2017-07-04T00:00:00Z")]
-                    [(t/time "2017-07-05T00:00:00Z")
-                     (t/time "2018-01-01T00:00:00Z")]])))
-
-  (is (= [] (complement (complement [])))))
+    ;; Not sure why this is failing on the equals check
+    #_(is (=
+            [[(tick.core/min-of-type (t/time "2017-01-01T00:00:00Z"))
+              (t/time "2017-01-01T00:00:00Z")]
+
+             [(t/time "2017-01-04T00:00:00Z")
+              (t/time "2017-01-05T00:00:00Z")]
+
+             [(t/time "2018-01-01T00:00:00Z")
+              (tick.core/max-of-type (t/time "2017-01-01T00:00:00Z"))
+              ]]
+
+            (complement [[(t/time "2017-01-01T00:00:00Z")
+                          (t/time "2017-07-04T00:00:00Z")]
+                         [(t/time "2017-07-05T00:00:00Z")
+                          (t/time "2018-01-01T00:00:00Z")]])))
+
+    (is (= [] (complement (complement [])))))

 ;; Division test

 (deftest division-test
-  (is (= 7 (count (t/divide (bounds (t/year 2012) (t/year 2018)) t/year)))))
+  (is (= 7 (count (t/divide (ti/bounds (t/year 2012) (t/year 2018)) t/year)))))

 (deftest group-by-intervals-test
   (testing "p and s"
     (is
       (=
-        {(t/year 2017) [(interval
+        {(t/year 2017) [(ti/interval
                           (t/local-date-time "2017-12-20T00:00")
                           (t/local-date-time "2018-01-01T00:00"))]
-         (t/year 2018) [(interval
+         (t/year 2018) [(ti/interval
                           (t/local-date-time "2018-01-01T00:00")
                           (t/local-date-time "2018-01-10T00:00"))]}
-        (group-by
-          (t/divide (bounds (t/year 2016) (t/year 2019)) t/year)
-          [(interval (t/local-date-time #inst "2017-12-20")
-                     (t/local-date-time #inst "2018-01-10"))]))))
+        (ti/group-by
+          (t/divide (ti/bounds (t/year 2016) (t/year 2019)) t/year)
+          [(ti/interval (t/local-date-time #inst "2017-12-20")
+                        (t/local-date-time #inst "2018-01-10"))]))))

   (testing "O"
     (is
       (=
-        {(t/year 2015) [(bounds (t/year-month "2015-06") (t/year-month "2015-12"))]
-         (t/year 2016) [(bounds (t/year 2016))]
-         (t/year 2017) [(bounds (t/year-month "2017-01") (t/year-month "2017-06"))]}
-        (group-by
-          (t/divide (bounds (t/year 2014) (t/year 2018)) t/year)
-          [(bounds (t/year-month "2015-06") (t/year-month "2017-06"))]))))
+        {(t/year 2015) [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]
+         (t/year 2016) [(ti/bounds (t/year 2016))]
+         (t/year 2017) [(ti/bounds (t/year-month "2017-01") (t/year-month "2017-06"))]}
+        (ti/group-by
+          (t/divide (ti/bounds (t/year 2014) (t/year 2018)) t/year)
+          [(ti/bounds (t/year-month "2015-06") (t/year-month "2017-06"))]))))

   (testing "M and e"
     (is
       (=
         {(t/year 2015) [(t/year 2015)]
          (t/year 2016) [(t/year 2016)]}
-        (group-by
-          (t/divide (bounds (t/year 2014) (t/year 2017)) t/year)
-          (t/divide (bounds (t/year 2015) (t/year 2016)) t/year)))))
+        (ti/group-by
+          (t/divide (ti/bounds (t/year 2014) (t/year 2017)) t/year)
+          (t/divide (ti/bounds (t/year 2015) (t/year 2016)) t/year)))))

   (testing "s"
     (is (=
-          {(t/year 2015) [(bounds (t/year 2015))]
-           (t/year 2016) [(bounds (t/year 2016))]}
-          (group-by
-            (t/divide (bounds (t/year 2014) (t/year 2017)) t/year)
-            [(bounds (t/year 2015) (t/year 2016))]))))
+          {(t/year 2015) [(ti/bounds (t/year 2015))]
+           (t/year 2016) [(ti/bounds (t/year 2016))]}
+          (ti/group-by
+            (t/divide (ti/bounds (t/year 2014) (t/year 2017)) t/year)
+            [(ti/bounds (t/year 2015) (t/year 2016))]))))

   (testing "f"
     (is
       (=
-        {(t/year 2015) [(bounds (t/year-month "2015-06") (t/year-month "2015-12"))]}
-        (group-by
+        {(t/year 2015) [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]}
+        (ti/group-by
           [(t/year 2014) (t/year 2015) (t/year 2016)]
-          [(bounds (t/year-month "2015-06") (t/year-month "2015-12"))]))))
+          [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]))))

   (testing "F"
     (is
       (=
-        {(bounds (t/year-month "2015-06") (t/year-month "2015-12"))
-         [(bounds (t/year-month "2015-06") (t/year-month "2015-12"))]}
-        (group-by
-          [(bounds (t/year-month "2015-06") (t/year-month "2015-12"))]
+        {(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))
+         [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]}
+        (ti/group-by
+          [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))]
           [(t/year 2014) (t/year 2015) (t/year 2016)]))))

   (testing "d"
     (is
       (=
-        {(t/year 2015) [(bounds (t/year-month "2015-03") (t/year-month "2015-09"))]}
-        (group-by
+        {(t/year 2015) [(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]}
+        (ti/group-by
           [(t/year 2014) (t/year 2015) (t/year 2016)]
-          [(bounds (t/year-month "2015-03") (t/year-month "2015-09"))]))))
+          [(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]))))

   (testing "D"
     (is
       (=
-        {(bounds (t/year-month "2015-03") (t/year-month "2015-09"))
-         [(bounds (t/year-month "2015-03") (t/year-month "2015-09"))]}
-
-        (group-by
-          [(bounds (t/year-month "2015-03") (t/year-month "2015-09"))]
+        {(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))
+         [(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]}
+
+        (ti/group-by
+          [(ti/bounds (t/year-month "2015-03") (t/year-month "2015-09"))]
           [(t/year 2014) (t/year 2015) (t/year 2016)]))))

   (testing "o"
     (is
       (=
-        {(bounds (t/year-month "2015-06") (t/year-month "2017-06"))
-         [(bounds (t/year-month "2015-06") (t/year-month "2015-12"))
+        {(ti/bounds (t/year-month "2015-06") (t/year-month "2017-06"))
+         [(ti/bounds (t/year-month "2015-06") (t/year-month "2015-12"))
           (t/year "2016")
-          (bounds (t/year-month "2017-01") (t/year-month "2017-06"))]}
-        (group-by
-          [(bounds (t/year-month "2015-06") (t/year-month "2017-06"))]
-          (t/divide (bounds (t/year 2014) (t/year 2018)) t/year))))))
+          (ti/bounds (t/year-month "2017-01") (t/year-month "2017-06"))]}
+        (ti/group-by
+          [(ti/bounds (t/year-month "2015-06") (t/year-month "2017-06"))]
+          (t/divide (ti/bounds (t/year 2014) (t/year 2018)) t/year))))))

 (deftest group-by-test
   (is
     (= 31
        (count
-         (group-by
+         (ti/group-by
            t/date
            [(t/date "2015-05-20") (t/year-month "2015-06")])))))

 (deftest group-by-empty-test
-  (is (= {} (group-by t/date []))))
+  (is (= {} (ti/group-by t/date []))))


replace the match-everything clause with only matching certain routes

--- src/bitfondue/handler.clj
+++ src/bitfondue/handler.clj
@@ -72,7 +72,12 @@

 (defroutes app-routes
   (GET "/dashboard" [] home)
-  (GET "*" [] (slurp "resources/public/index.html"))
+  (GET "/" [] serve-html5-app)
+  (GET "/features" [] serve-html5-app)
+  (GET "/pricing" [] serve-html5-app)
+  (GET "/about" [] serve-html5-app)
+  (GET "/login" [] serve-html5-app)
+  (GET "/register" [] serve-html5-app)
   (GET "/chunks" [] chunks)
   (POST "/login" [] login)
   (POST "/upload" [] upload)