(ns str.core
  (:require clojure.string)
  (:refer-clojure :exclude [reverse replace contains?]))

(declare slice)

;; Taken from [jackknife "0.1.6"]
(defmacro defalias
  "Defines an alias for a var: a new var with the same root binding (if
  any) and similar metadata. The metadata of the alias is its initial
  metadata (as provided by def) merged into the metadata of the original."
  ([name orig]
   `(do
      (alter-meta!
       (if (.hasRoot (var ~orig))
         (def ~name (.getRawRoot (var ~orig)))
         (def ~name))
       ;; When copying metadata, disregard {:macro false}.
       ;; Workaround for http://www.assembla.com/spaces/clojure/tickets/273
       #(conj (dissoc % :macro)
              (apply dissoc (meta (var ~orig)) (remove #{:macro} (keys %)))))
      (var ~name)))
  ([name orig doc]
   (list `defalias (with-meta name (assoc (meta name) :doc doc)) orig)))

(defmacro alias-ns
  "Create an alias for all public vars in ns in this ns."
  [namespace]
  `(do ~@(map
          (fn [n] `(defalias ~(.sym n) ~(symbol (str (.ns n)) (str (.sym n)))))
          (vals (ns-publics namespace)))))

(alias-ns clojure.string)

(defn- ^String slice-relative-to-end
  [^String s ^long index ^long length]
  (if (neg? (+ (.length s) index)) ; slice outside beg of s
    nil
    (slice s (+ (.length s) index) length)))

(defn ^String slice
  "Return a slice of s beginning at index and of the given length.

  If index is negative the starting index is relative to the end of the string.

  The default length of the slice is 1.

  If the requested slice ends outside the string boundaries, we return
  the substring of s starting at index.

  Returns nil if index falls outside the string boundaries or if
  length is negative."
  ([^String s ^long index]
   (slice s index 1))
  ([^String s ^long index ^long length]
   (cond
     (neg? length) nil
     (neg? (+ (.length s) index)) nil ; slice relative to end falls outside s
     (neg? index) (slice-relative-to-end s index length)
     (>= index (.length s)) nil
     (> (- length index) (.length (.substring s index))) (.substring s index)
     :else (let [end (+ index length)]
             (.substring s index end)))))

(defn ^String ends-with?
  "Return s if s ends with suffix."
  ([^String s ^String suffix]
   (when (.endsWith s suffix)
     s))
  ([^String s ^String suffix ignore-case]
   (let [end (.substring s (max 0 (- (.length s) (.length suffix))))]
     (when (.equalsIgnoreCase end suffix)
       s))))

(defn ^String starts-with?
  "Return s if s starts with with prefix.

  If a third argument is provided the string comparison is insensitive to case."
  ([^String s ^String prefix]
   (when (.startsWith s prefix)
     s))
  ([^String s ^String prefix ignore-case]
   (let [beg (.substring s 0 (.length prefix))]
     (when (.equalsIgnoreCase beg prefix)
       s))))

(defn ^String chop
  "Return a new string with the last character removed.

  If the string ends with \\r\\n, both characters are removed.

  Applying chop to an empty string is a no-op."
  [^String s]
  (if (.endsWith s "\r\n")
    (.substring s 0 (- (.length s) 2))
    (.substring s 0 (max 0 (dec (.length s))))))

(defn ^String chomp
  "Return a new string with the given record separator removed from
  the end (if present).

  If seperator is not provided chomp will remove \\n, \\r or \\r\\n from
  the end of s."
  ([^String s]
   (cond
     (.endsWith s "\r\n") (.substring s 0 (- (.length s) 2))
     (.endsWith s "\r") (.substring s 0 (dec (.length s)))
     (.endsWith s "\n") (.substring s 0 (dec (.length s)))
     :else s))
  ([^String s ^String separator]
   (if (.endsWith s separator)
     (.substring s 0 (- (.length s) (.length separator)))
     s)))

(defn ^String capitalize
  "Return a new string where the first character is in upper case and
  all others in lower case."
  [^String s]
  (case (.length s)
    0 ""
    1 (upper-case s)
    (str (upper-case (.substring s 0 1)) (lower-case (.substring s 1)))) )

(defn ^String swap-case
  "Change lower case characters to upper case and vice versa."
  [^String s]
  (let [invert-case (fn [c]
                      (cond
                        (Character/isLowerCase c) (Character/toUpperCase c)
                        (Character/isUpperCase c) (Character/toLowerCase c)
                        :else c))]
    (->> s (map invert-case) (apply str))))

(defn- gen-padding
  "Generate the necessary padding to fill s upto width."
  [^String s ^String padding ^long width]
  (let [missing (- width (.length s))
        full-lengths (Math/floor (/ missing (.length padding)))
        remaining (if (zero? full-lengths) (- width (.length s))
                      (rem missing (* full-lengths (.length padding))))]
    (.concat (apply str (repeat full-lengths padding))
             (.substring padding 0 remaining))))

(defn ^String pad-right
  "Pad the end of s with padding, or spaces, until the length of s matches
  width."
  ([^String s ^long width]
   (pad-right s width " "))
  ([^String s ^long width ^String padding]
   {:pre [(not-empty padding)
          (not (nil? s))]
    :post [(= (.length %) width)]}
   (if (<= width (.length s))
     s
     (.concat s (gen-padding s padding width)))))

(defn ^String pad-left
  "Pad the beginning of s with padding, or spaces, until the length of
  s matches width."
  ([^String s ^long width]
   (pad-left s width " "))
  ([^String s ^long width ^String padding]
   {:pre [(not-empty padding)
          (not (nil? s))]
    :post [(= (.length %) width)]}
   (if (<= width (.length s))
     s
     (.concat (gen-padding s padding width) s))))

(defn ^String center
  "Pad both ends of s with padding, or spaces, until the length of s
  matches width."
  ([^String s ^long width]
   (center s width " "))
  ([^String s ^long width ^String padding]
   {:pre [(not-empty padding)
          (not (nil? s))]
    :post [(= (.length %) width)]}
   (if (<= width (.length s))
     s
     (let [missing (- width (.length s))
           full-lengths (Math/ceil (/ missing (.length padding)))
           p (gen-padding s padding width)
           lengths-before (Math/floor (/ full-lengths 2))]
       (str (.substring p 0 (* (.length padding) lengths-before))
            s
            (.substring p (* (.length padding) lengths-before)))))))

(ns str.core
  (:require clojure.string)
  (:refer-clojure :exclude [reverse replace contains?]))

(declare slice)

;; Taken from [jackknife "0.1.6"]
(defmacro defalias
  "Defines an alias for a var: a new var with the same root binding (if
  any) and similar metadata. The metadata of the alias is its initial
  metadata (as provided by def) merged into the metadata of the original."
  ([name orig]
   `(do
      (alter-meta!
       (if (.hasRoot (var ~orig))
         (def ~name (.getRawRoot (var ~orig)))
         (def ~name))
       ;; When copying metadata, disregard {:macro false}.
       ;; Workaround for http://www.assembla.com/spaces/clojure/tickets/273
       #(conj (dissoc % :macro)
              (apply dissoc (meta (var ~orig)) (remove #{:macro} (keys %)))))
      (var ~name)))
  ([name orig doc]
   (list `defalias (with-meta name (assoc (meta name) :doc doc)) orig)))

(defmacro alias-ns
  "Create an alias for all public vars in ns in this ns."
  [namespace]
  `(do ~@(map
          (fn [n] `(defalias ~(.sym n) ~(symbol (str (.ns n)) (str (.sym n)))))
          (vals (ns-publics namespace)))))

(alias-ns clojure.string)

(defn- ^String slice-relative-to-end
  [^String s ^long index ^long length]
  (if (neg? (+ (.length s) index)) ; slice outside beg of s
    nil
    (slice s (+ (.length s) index) length)))

(defn ^String slice
  "Return a slice of s beginning at index and of the given length.

  If index is negative the starting index is relative to the end of the string.

  The default length of the slice is 1.

  If the requested slice ends outside the string boundaries, we return
  the substring of s starting at index.

  Returns nil if index falls outside the string boundaries or if
  length is negative."
  ([^String s ^long index]
   (slice s index 1))
  ([^String s ^long index ^long length]
   (cond
     (neg? length) nil
     (neg? (+ (.length s) index)) nil ; slice relative to end falls outside s
     (neg? index) (slice-relative-to-end s index length)
     (>= index (.length s)) nil
     (> (- length index) (.length (.substring s index))) (.substring s index)
     :else (let [end (+ index length)]
             (.substring s index end)))))

(defn ^String ends-with?
  "Return s if s ends with suffix."
  ([^String s ^String suffix]
   (when (.endsWith s suffix)
     s))
  ([^String s ^String suffix ignore-case]
   (if-not ignore-case
     (ends-with? s suffix)
     (let [end (.substring s (max 0 (- (.length s) (.length suffix))))]
       (when (.equalsIgnoreCase end suffix)
         s)))))

(defn ^String starts-with?
  "Return s if s starts with with prefix.

  If a third argument is provided the string comparison is insensitive to case."
  ([^String s ^String prefix]
   (when (.startsWith s prefix)
     s))
  ([^String s ^String prefix ignore-case]
   (if-not ignore-case
     (starts-with? s prefix)
     (let [beg (.substring s 0 (.length prefix))]
       (when (.equalsIgnoreCase beg prefix)
         s)))))

(defn ^String chop
  "Return a new string with the last character removed.

  If the string ends with \\r\\n, both characters are removed.

  Applying chop to an empty string is a no-op."
  [^String s]
  (if (.endsWith s "\r\n")
    (.substring s 0 (- (.length s) 2))
    (.substring s 0 (max 0 (dec (.length s))))))

(defn ^String chomp
  "Return a new string with the given record separator removed from
  the end (if present).

  If seperator is not provided chomp will remove \\n, \\r or \\r\\n from
  the end of s."
  ([^String s]
   (cond
     (.endsWith s "\r\n") (.substring s 0 (- (.length s) 2))
     (.endsWith s "\r") (.substring s 0 (dec (.length s)))
     (.endsWith s "\n") (.substring s 0 (dec (.length s)))
     :else s))
  ([^String s ^String separator]
   (if (.endsWith s separator)
     (.substring s 0 (- (.length s) (.length separator)))
     s)))

(defn ^String capitalize
  "Return a new string where the first character is in upper case and
  all others in lower case."
  [^String s]
  (case (.length s)
    0 ""
    1 (upper-case s)
    (str (upper-case (.substring s 0 1)) (lower-case (.substring s 1)))) )

(defn ^String swap-case
  "Change lower case characters to upper case and vice versa."
  [^String s]
  (let [invert-case (fn [c]
                      (cond
                        (Character/isLowerCase c) (Character/toUpperCase c)
                        (Character/isUpperCase c) (Character/toLowerCase c)
                        :else c))]
    (->> s (map invert-case) (apply str))))

(defn- gen-padding
  "Generate the necessary padding to fill s upto width."
  [^String s ^String padding ^long width]
  (let [missing (- width (.length s))
        full-lengths (Math/floor (/ missing (.length padding)))
        remaining (if (zero? full-lengths) (- width (.length s))
                      (rem missing (* full-lengths (.length padding))))]
    (.concat (apply str (repeat full-lengths padding))
             (.substring padding 0 remaining))))

(defn ^String pad-right
  "Pad the end of s with padding, or spaces, until the length of s matches
  width."
  ([^String s ^long width]
   (pad-right s width " "))
  ([^String s ^long width ^String padding]
   {:pre [(not-empty padding)
          (not (nil? s))]
    :post [(= (.length %) width)]}
   (if (<= width (.length s))
     s
     (.concat s (gen-padding s padding width)))))

(defn ^String pad-left
  "Pad the beginning of s with padding, or spaces, until the length of
  s matches width."
  ([^String s ^long width]
   (pad-left s width " "))
  ([^String s ^long width ^String padding]
   {:pre [(not-empty padding)
          (not (nil? s))]
    :post [(= (.length %) width)]}
   (if (<= width (.length s))
     s
     (.concat (gen-padding s padding width) s))))

(defn ^String center
  "Pad both ends of s with padding, or spaces, until the length of s
  matches width."
  ([^String s ^long width]
   (center s width " "))
  ([^String s ^long width ^String padding]
   {:pre [(not-empty padding)
          (not (nil? s))]
    :post [(= (.length %) width)]}
   (if (<= width (.length s))
     s
     (let [missing (- width (.length s))
           full-lengths (Math/ceil (/ missing (.length padding)))
           p (gen-padding s padding width)
           lengths-before (Math/floor (/ full-lengths 2))]
       (str (.substring p 0 (* (.length padding) lengths-before))
            s
            (.substring p (* (.length padding) lengths-before)))))))

Test for ignore-case in starts- and ends-with

I just passed `false` as ignore-case and it did the wrong thing.  This
wasn't how I intended these to be used but I figure others might make
the same mistake


(ns beicon.core
  (:require [beicon.extern.rxjs]
            [cats.protocols :as p]
            [cats.context :as ctx])
  (:refer-clojure :exclude [true? map filter reduce merge repeat repeatedly zip
                            dedupe drop take take-while concat partition]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Observables Constructors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprotocol IObservableValue
  (-end? [_] "Returns true if is end value.")
  (-error? [_] "Returns true if is end value.")
  (-next? [_] "Returns true if is end value."))

(extend-type default
  IObservableValue
  (-next? [_] true)
  (-error? [_] false)
  (-end? [_] false))

(extend-type nil
  IObservableValue
  (-next? [_] false)
  (-error? [_] false)
  (-end? [_] true))

(extend-type js/Error
  IObservableValue
  (-next? [_] false)
  (-error? [_] true)
  (-end? [_] false))

(extend-type cljs.core.ExceptionInfo
  IObservableValue
  (-next? [_] false)
  (-error? [_] true)
  (-end? [_] false))

(defn create
  "Creates an observable sequence from a specified
  subscribe method implementation."
  [sf]
  {:pre [(fn? sf)]}
  (js/Rx.Observable.create
   (fn [ob]
     (letfn [(callback [v]
               (cond
                 (-next? v)
                 (.onNext ob v)

                 (-end? v)
                 (.onCompleted ob)

                 (-error? v)
                 (.onError ob v)))]
       (try
         (sf callback)
         (catch js/Error e
           (.onError ob e)))))))

(defn repeat
  "Generates an observable sequence that repeats the
  given element."
  ([v]
   (repeat v -1))
  ([v n]
   {:pre [(number? v)]}
   (js/Rx.Observable.repeat v n)))

(defn publish
  [ob]
  (let [ob' (.publish ob)]
    (.connect ob')
    ob'))

(defn from-coll
  "Generates an observable sequence from collection."
  [coll]
  (let [array (into-array coll)]
    (js/Rx.Observable.fromArray array)))

(defn from-callback
  [f & args]
  {:pre [(fn? f)]}
  (create (fn [sink]
            (apply f sink args)
            (sink nil))))

(defn from-poll
  "Creates an observable sequence polling given
  function with given interval."
  [ms f]
  (create (fn [sick]
            (let [semholder (volatile! nil)
                  sem (js/setInterval
                       (fn []
                         (let [v (f)]
                           (when (or (-end? v) (-error? v))
                             (js/clearInterval @semholder))
                           (sick v)))
                       ms)]
              (vreset! semholder sem)))))

(defn once
  "Returns an observable sequence that contains
  a single element."
  [v]
  (js/Rx.Observable.just v))

(defn never
  "Returns an observable sequence that is already
  in end state."
  []
  (create (fn [sink]
            (sink nil))))

(defn observable?
  "Return true if `ob` is a instance
  of Rx.Observable."
  [ob]
  (instance? js/Rx.Observable ob))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Bus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn bus
  "Bus is an observable sequence that allows you to push
  values into the stream."
  []
  (js/Rx.Subject.))

(defn bus?
  "Return true if `b` is a Subject instance."
  [b]
  (instance? js/Rx.Subject b))

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

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

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Observable Subscription
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn on-value
  "Subscribes a function to invoke for each element
  in the observable sequence."
  [ob f]
  {:pre [(observable? ob) (fn? f)]}
  (.subscribeOnNext ob f))

(defn on-error
  "Subscribes a function to invoke upon exceptional termination
  of the observable sequence."
  [ob f]
  {:pre [(observable? ob) (fn? f)]}
  (.subscribeOnError ob f))

(defn on-end
  "Subscribes a function to invoke upon graceful termination
  of the observable sequence."
  [ob f]
  {:pre [(observable? ob) (fn? f)]}
  (.subscribeOnCompleted ob f))

(defn subscribe
  "Subscribes an observer to the observable sequence."
  [ob nf ef cf]
  {:pre [(observable? ob)]}
  (.subscribe ob nf ef cf))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Observable Transformations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn choice
  "Create an observable that surfaces any of the given
  sequences, whichever reacted first."
  ([a b]
   {:pre [(observable? a)
          (observable? b)]}
   (.amb a b))
  ([a b & more]
   (cljs.core/reduce choice (choice a b) more)))

(defn zip
  "Merges the specified observable sequences or Promises
  into one observable sequence."
  [a b]
  {:pre [(observable? a)
         (observable? b)]}
  (.zip a b vector))

(defn concat
  "Concatenates all of the specified observable
  sequences, as long as the previous observable
  sequence terminated successfully."
  ([a b]
   {:pre [(observable? a)
          (observable? b)]}
   (.concat a b))
  ([a b & more]
   (cljs.core/reduce concat (concat a b) more)))

(defn merge
  "Merges all the observable sequences and Promises
  into a single observable sequence."
  ([a b]
   {:pre [(observable? a)
          (observable? b)]}
   (.merge a b))
  ([a b & more]
   (cljs.core/reduce merge (merge a b) more)))

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

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

(defn flat-map
  "Projects each element of an observable sequence to
  an observable sequence and merges the resulting
  observable sequences or Promises or array/iterable
  into one observable sequence."
  [f ob]
  {:pre [(observable? ob)]}
  (.flatMap ob #(f %)))

(defn skip
  "Bypasses a specified number of elements in an
  observable sequence and then returns the remaining
  elements."
  [n ob]
  {:pre [(observable? ob) (number? n)]}
  (.skip ob n))

(defn skip-while
  "Bypasses elements in an observable sequence as long
  as a specified condition is true and then returns the
  remaining elements."
  [f ob]
  {:pre [(observable? ob) (fn? f)]}
  (.skipWhile ob f))

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

(defn take
  "Bypasses a specified number of elements in an
  observable sequence and then returns the remaining
  elements."
  [n ob]
  {:pre [(observable? ob) (number? n)]}
  (.take ob n))

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

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

(defn tap
  "Invokes an action for each element in the
  observable sequence."
  [f ob]
  {:pre [(observable? ob) (fn? f)]}
  (.tap ob f))

(defn throttle
  "Returns an Observable that emits only the first item
  emitted by the source Observable during sequential
  time windows of a specified duration."
  [ms ob]
  {:pre [(observable? ob) (number? ms)]}
  (.throttle ob ms))

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

(defn pausable
  [pauser ob]
  {:pre [(observable? ob) (observable? pauser)]}
  (.pausable ob pauser))

(defn dedupe
  "Returns an observable sequence that contains only
  distinct contiguous elements."
  ([ob]
   (.distinctUntilChanged ob))
  ([f ob]
   (.distinctUntilChanged ob f)))

(defn dedupe'
  "Returns an observable sequence that contains only d
  istinct elements.
  Usage of this operator should be considered carefully
  due to the maintenance of an internal lookup structure
  which can grow large."
  ([ob]
   (.distinct ob))
  ([f 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]
   (.bufferWithCount ob n))
  ([n skip ob]
   (.bufferWithCount ob n skip)))

(defn pipe-to-atom
  ([ob]
   (let [a (atom nil)]
     (pipe-to-atom a ob)))
  ([a ob]
   (on-value ob #(reset! a %))
   a)
  ([a ob f]
   (on-value ob #(swap! a f %))
   a))

(defn- sink-step
  [sink]
  (fn
    ([r]
     (sink nil)
     r)
    ([_ input]
     (sink input)
     input)))

(defn transform
  [xform stream]
  (let [ns (create (fn [sink]
                     (let [xsink (xform (sink-step sink))
                           step (fn [input]
                                  (let [v (xsink nil input)]
                                    (when (reduced? v)
                                      (xsink @v))))
                           unsub (on-value stream step)]
                       (on-end stream #(do (xsink nil)
                                           (sink nil)))
                       (fn []
                         (.dispose unsub)))))]
    ns))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cats Integration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def observable-context
  (reify
    p/Context
    (-get-level [_] ctx/+level-default+)

    p/Functor
    (-fmap [_ f obs]
      (map f obs))

    p/Applicative
    (-pure [_ v]
      (once v))

    (-fapply [_ pf pv]
      (.zip pf pv #(%1 %2)))

    p/Monad
    (-mreturn [_ v]
      (once v))

    (-mbind [_ mv f]
      (flat-map f mv))))

(extend-protocol p/Contextual
  js/Rx.Observable
  (-get-context [_] observable-context)

  js/Rx.Subject
  (-get-context [_] observable-context))

(ns beicon.core
  (:require [beicon.extern.rxjs]
            [cats.protocols :as p]
            [cats.context :as ctx])
  (:refer-clojure :exclude [true? map filter reduce merge repeat repeatedly zip
                            dedupe drop take take-while concat partition]))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Observables Constructors
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defprotocol IObservableValue
  (-end? [_] "Returns true if is end value.")
  (-error? [_] "Returns true if is end value.")
  (-next? [_] "Returns true if is end value."))

(extend-type default
  IObservableValue
  (-next? [_] true)
  (-error? [_] false)
  (-end? [_] false))

(extend-type nil
  IObservableValue
  (-next? [_] false)
  (-error? [_] false)
  (-end? [_] true))

(extend-type js/Error
  IObservableValue
  (-next? [_] false)
  (-error? [_] true)
  (-end? [_] false))

(extend-type cljs.core.ExceptionInfo
  IObservableValue
  (-next? [_] false)
  (-error? [_] true)
  (-end? [_] false))

(defn create
  "Creates an observable sequence from a specified
  subscribe method implementation."
  [sf]
  {:pre [(fn? sf)]}
  (js/Rx.Observable.create
   (fn [ob]
     (letfn [(callback [v]
               (cond
                 (-next? v)
                 (.onNext ob v)

                 (-end? v)
                 (.onCompleted ob)

                 (-error? v)
                 (.onError ob v)))]
       (try
         (sf callback)
         (catch js/Error e
           (.onError ob e)))))))

(defn repeat
  "Generates an observable sequence that repeats the
  given element."
  ([v]
   (repeat v -1))
  ([v n]
   {:pre [(number? v)]}
   (js/Rx.Observable.repeat v n)))

(defn publish
  [ob]
  (let [ob' (.publish ob)]
    (.connect ob')
    ob'))

(defn from-coll
  "Generates an observable sequence from collection."
  [coll]
  (let [array (into-array coll)]
    (js/Rx.Observable.fromArray array)))

(defn from-callback
  [f & args]
  {:pre [(fn? f)]}
  (create (fn [sink]
            (apply f sink args)
            (sink nil))))

(defn from-poll
  "Creates an observable sequence polling given
  function with given interval."
  [ms f]
  (create (fn [sick]
            (let [semholder (volatile! nil)
                  sem (js/setInterval
                       (fn []
                         (let [v (f)]
                           (when (or (-end? v) (-error? v))
                             (js/clearInterval @semholder))
                           (sick v)))
                       ms)]
              (vreset! semholder sem)))))

(defn from-atom
  [atm]
  (create (fn [sink]
            (let [key (keyword (gensym "beicon"))]
              (add-watch atm key (fn [_ _ _ val]
                                   (sink val)))
              (fn []
                (remove-watch atm key))))))

(defn once
  "Returns an observable sequence that contains
  a single element."
  [v]
  (js/Rx.Observable.just v))

(defn never
  "Returns an observable sequence that is already
  in end state."
  []
  (create (fn [sink]
            (sink nil))))

(defn observable?
  "Return true if `ob` is a instance
  of Rx.Observable."
  [ob]
  (instance? js/Rx.Observable ob))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Bus
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn bus
  "Bus is an observable sequence that allows you to push
  values into the stream."
  []
  (js/Rx.Subject.))

(defn bus?
  "Return true if `b` is a Subject instance."
  [b]
  (instance? js/Rx.Subject b))

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

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

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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Observable Subscription
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn on-value
  "Subscribes a function to invoke for each element
  in the observable sequence."
  [ob f]
  {:pre [(observable? ob) (fn? f)]}
  (.subscribeOnNext ob f))

(defn on-error
  "Subscribes a function to invoke upon exceptional termination
  of the observable sequence."
  [ob f]
  {:pre [(observable? ob) (fn? f)]}
  (.subscribeOnError ob f))

(defn on-end
  "Subscribes a function to invoke upon graceful termination
  of the observable sequence."
  [ob f]
  {:pre [(observable? ob) (fn? f)]}
  (.subscribeOnCompleted ob f))

(defn subscribe
  "Subscribes an observer to the observable sequence."
  [ob nf ef cf]
  {:pre [(observable? ob)]}
  (.subscribe ob nf ef cf))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Observable Transformations
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defn choice
  "Create an observable that surfaces any of the given
  sequences, whichever reacted first."
  ([a b]
   {:pre [(observable? a)
          (observable? b)]}
   (.amb a b))
  ([a b & more]
   (cljs.core/reduce choice (choice a b) more)))

(defn zip
  "Merges the specified observable sequences or Promises
  into one observable sequence."
  [a b]
  {:pre [(observable? a)
         (observable? b)]}
  (.zip a b vector))

(defn concat
  "Concatenates all of the specified observable
  sequences, as long as the previous observable
  sequence terminated successfully."
  ([a b]
   {:pre [(observable? a)
          (observable? b)]}
   (.concat a b))
  ([a b & more]
   (cljs.core/reduce concat (concat a b) more)))

(defn merge
  "Merges all the observable sequences and Promises
  into a single observable sequence."
  ([a b]
   {:pre [(observable? a)
          (observable? b)]}
   (.merge a b))
  ([a b & more]
   (cljs.core/reduce merge (merge a b) more)))

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

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

(defn flat-map
  "Projects each element of an observable sequence to
  an observable sequence and merges the resulting
  observable sequences or Promises or array/iterable
  into one observable sequence."
  [f ob]
  {:pre [(observable? ob)]}
  (.flatMap ob #(f %)))

(defn skip
  "Bypasses a specified number of elements in an
  observable sequence and then returns the remaining
  elements."
  [n ob]
  {:pre [(observable? ob) (number? n)]}
  (.skip ob n))

(defn skip-while
  "Bypasses elements in an observable sequence as long
  as a specified condition is true and then returns the
  remaining elements."
  [f ob]
  {:pre [(observable? ob) (fn? f)]}
  (.skipWhile ob f))

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

(defn take
  "Bypasses a specified number of elements in an
  observable sequence and then returns the remaining
  elements."
  [n ob]
  {:pre [(observable? ob) (number? n)]}
  (.take ob n))

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

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

(defn tap
  "Invokes an action for each element in the
  observable sequence."
  [f ob]
  {:pre [(observable? ob) (fn? f)]}
  (.tap ob f))

(defn throttle
  "Returns an Observable that emits only the first item
  emitted by the source Observable during sequential
  time windows of a specified duration."
  [ms ob]
  {:pre [(observable? ob) (number? ms)]}
  (.throttle ob ms))

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

(defn pausable
  [pauser ob]
  {:pre [(observable? ob) (observable? pauser)]}
  (.pausable ob pauser))

(defn dedupe
  "Returns an observable sequence that contains only
  distinct contiguous elements."
  ([ob]
   (.distinctUntilChanged ob))
  ([f ob]
   (.distinctUntilChanged ob f)))

(defn dedupe'
  "Returns an observable sequence that contains only d
  istinct elements.
  Usage of this operator should be considered carefully
  due to the maintenance of an internal lookup structure
  which can grow large."
  ([ob]
   (.distinct ob))
  ([f 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]
   (.bufferWithCount ob n))
  ([n skip ob]
   (.bufferWithCount ob n skip)))

(defn pipe-to-atom
  ([ob]
   (let [a (atom nil)]
     (pipe-to-atom a ob)))
  ([a ob]
   (on-value ob #(reset! a %))
   a)
  ([a ob f]
   (on-value ob #(swap! a f %))
   a))

(defn- sink-step
  [sink]
  (fn
    ([r]
     (sink nil)
     r)
    ([_ input]
     (sink input)
     input)))

(defn transform
  [xform stream]
  (let [ns (create (fn [sink]
                     (let [xsink (xform (sink-step sink))
                           step (fn [input]
                                  (let [v (xsink nil input)]
                                    (when (reduced? v)
                                      (xsink @v))))
                           unsub (on-value stream step)]
                       (on-end stream #(do (xsink nil)
                                           (sink nil)))
                       (fn []
                         (.dispose unsub)))))]
    ns))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Cats Integration
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(def observable-context
  (reify
    p/Context
    (-get-level [_] ctx/+level-default+)

    p/Functor
    (-fmap [_ f obs]
      (map f obs))

    p/Applicative
    (-pure [_ v]
      (once v))

    (-fapply [_ pf pv]
      (.zip pf pv #(%1 %2)))

    p/Monad
    (-mreturn [_ v]
      (once v))

    (-mbind [_ mv f]
      (flat-map f mv))))

(extend-protocol p/Contextual
  js/Rx.Observable
  (-get-context [_] observable-context)

  js/Rx.Subject
  (-get-context [_] observable-context))

Add the ability to derive stream from atom.


(ns braid.lib.s3
  (:require
   [clojure.data.json :as json]
   [clojure.string :as string]
   [org.httpkit.client :as http]
   [braid.base.conf :refer [config]]
   [braid.lib.aws :as aws])
  (:import
   (java.time.temporal ChronoUnit)
   (org.apache.commons.codec.binary Base64 Hex)))

(defn s3-host
  [{bucket :aws-bucket region :aws-region}]
  (str bucket ".s3." region ".amazonaws.com"))

(defn generate-s3-upload-policy
  [{:aws/keys [credentials-provider] region :aws-region bucket :aws-bucket :as config} {:keys [starts-with]}]
  (when credentials-provider
    (let [[api-key api-secret] (credentials-provider)
          utc-now (aws/utc-now)
          day (.format utc-now aws/basic-date-format)
          date (.format utc-now aws/basic-date-time-format)
          credential (->> [api-key day region "s3" "aws4_request"]
                          (string/join "/"))
          policy (-> {:expiration (-> (.plus utc-now 5 ChronoUnit/MINUTES)
                                      (.format aws/date-time-format))
                      :conditions
                      [{:bucket bucket}
                       ["starts-with" "$key" starts-with]
                       {:acl "private"}
                       ["starts-with" "$Content-Type" ""]
                       ["content-length-range" 0 (* 500 1024 1024)]

                       {"x-amz-algorithm" "AWS4-HMAC-SHA256"}
                       {"x-amz-credential" credential}
                       {"x-amz-date" date}]}
                     json/write-str
                     aws/str->bytes
                     Base64/encodeBase64String)]
      {:bucket bucket
       :region region
       :auth {:policy policy
              :key api-key
              :signature (->>
                          (aws/str->bytes policy)
                          (aws/hmac-sha256
                           (aws/signing-key
                            {:aws-api-secret api-secret
                             :aws-region region
                             :day day
                             :service "s3"}))
                          Hex/encodeHexString)
              :credential credential
              :date date}})))

(defn- get-signature
  [{:aws/keys [credentials-provider] region :aws-region bucket :aws-bucket :as config} utc-now path query-str]
  (let [[_ api-secret] (credentials-provider)]
    (->> ["AWS4-HMAC-SHA256"
          (.format utc-now aws/basic-date-time-format)
          (string/join "/" [(.format utc-now aws/basic-date-format) region "s3"
                            "aws4_request"])
          (aws/canonical-request
           {:method "GET"
            :path (str "/" path)
            :query-string query-str
            :headers {"host" (str bucket ".s3." region ".amazonaws.com")}
            :body nil})]
         (string/join "\n")
         aws/str->bytes
         (aws/hmac-sha256
          (aws/signing-key {:aws-api-secret api-secret
                            :aws-region region
                            :day (.format utc-now aws/basic-date-format)
                            :service "s3"}))
         aws/bytes->hex)))

(defn readable-s3-url
  [{:aws/keys [credentials-provider] region :aws-region :as config} expires-seconds path]
  (let [[api-key _] (credentials-provider)
        utc-now (aws/utc-now)
        query-str (str "X-Amz-Algorithm=AWS4-HMAC-SHA256"
                       "&X-Amz-Credential=" api-key "/" (.format utc-now aws/basic-date-format) "/" region "/s3/aws4_request"
                       "&X-Amz-Date=" (.format utc-now aws/basic-date-time-format)
                       (str "&X-Amz-Expires=" expires-seconds)
                       "&X-Amz-SignedHeaders=host")]
    (str "https://" (s3-host config)
         "/" path
         "?" query-str
         "&X-Amz-Signature=" (get-signature config utc-now path query-str))))

(defn- make-request
  [{:aws/keys [credentials-provider] region :aws-region bucket :aws-bucket :as config} {:keys [body method path] :as request}]
  (let [[api-key api-secret] (credentials-provider)
        utc-now (aws/utc-now)
        req (update request :headers
                    assoc
                    "x-amz-date" (.format utc-now aws/basic-date-time-format)
                    "x-amz-content-sha256" (aws/hex-hash body)
                    "Host" (str (s3-host config) ":443"))]
    (-> req
        (dissoc :method :path :query-string)
        (assoc-in [:headers "Authorization"]
                  (aws/auth-header {:now utc-now
                                    :service "s3"
                                    :request req
                                    :aws-api-secret api-secret
                                    :aws-api-key api-key
                                    :aws-region region})))))

(defn delete-file!
  [config path]
  ;; always returns 204, even if file does not exist
  @(http/delete (str "https://" (s3-host config) path)
                (make-request config {:method "DELETE"
                                      :path path
                                      :body ""})))

(defn upload-url-path
  [url]
  (when url
    (or ;; old style, with bucket after domain
     (second (re-matches #"^https://s3\.amazonaws\.com/[^/]+(/.*)$" url))
     ;; new style, with bucket in domain
     (second (re-matches #"^https://.+\.amazonaws\.com(/.*)$" url)))))

(ns braid.lib.s3
  (:require
   [clojure.data.json :as json]
   [clojure.string :as string]
   [org.httpkit.client :as http]
   [braid.base.conf :refer [config]]
   [braid.lib.aws :as aws])
  (:import
   (java.time.temporal ChronoUnit)
   (org.apache.commons.codec.binary Base64 Hex)))

(defn s3-host
  [{bucket :aws-bucket region :aws-region}]
  (str bucket ".s3." region ".amazonaws.com"))

(defn generate-s3-upload-policy
  [{:aws/keys [credentials-provider] region :aws-region bucket :aws-bucket :as config} {:keys [starts-with]}]
  (when credentials-provider
    (let [[api-key api-secret ?security-token] (credentials-provider)
          utc-now (aws/utc-now)
          day (.format utc-now aws/basic-date-format)
          date (.format utc-now aws/basic-date-time-format)
          credential (->> [api-key day region "s3" "aws4_request"]
                          (string/join "/"))
          policy (-> {:expiration (-> (.plus utc-now 5 ChronoUnit/MINUTES)
                                      (.format aws/date-time-format))
                      :conditions
                      [{:bucket bucket}
                       ["starts-with" "$key" starts-with]
                       {:acl "private"}
                       ["starts-with" "$Content-Type" ""]
                       ["content-length-range" 0 (* 500 1024 1024)]

                       {"x-amz-algorithm" "AWS4-HMAC-SHA256"}
                       {"x-amz-credential" credential}
                       {"x-amz-date" date}]}
                     (cond-> ?security-token
                       (update :conditions conj
                               {"x-amz-security-token" ?security-token}))
                     json/write-str
                     aws/str->bytes
                     Base64/encodeBase64String)]
      {:bucket bucket
       :region region
       :auth {:policy policy
              :key api-key
              :signature (->>
                          (aws/str->bytes policy)
                          (aws/hmac-sha256
                           (aws/signing-key
                            {:aws-api-secret api-secret
                             :aws-region region
                             :day day
                             :service "s3"}))
                          Hex/encodeHexString)
              :credential credential
              :date date}})))

(defn- get-signature
  [{:aws/keys [credentials-provider] region :aws-region bucket :aws-bucket :as config} utc-now path query-str]
  (let [[_ api-secret] (credentials-provider)]
    (->> ["AWS4-HMAC-SHA256"
          (.format utc-now aws/basic-date-time-format)
          (string/join "/" [(.format utc-now aws/basic-date-format) region "s3"
                            "aws4_request"])
          (aws/canonical-request
           {:method "GET"
            :path (str "/" path)
            :query-string query-str
            :headers {"host" (str bucket ".s3." region ".amazonaws.com")}
            :body nil})]
         (string/join "\n")
         aws/str->bytes
         (aws/hmac-sha256
          (aws/signing-key {:aws-api-secret api-secret
                            :aws-region region
                            :day (.format utc-now aws/basic-date-format)
                            :service "s3"}))
         aws/bytes->hex)))

(defn readable-s3-url
  [{:aws/keys [credentials-provider] region :aws-region :as config} expires-seconds path]
  (let [[api-key _ ?security-token] (credentials-provider)
        utc-now (aws/utc-now)
        query-str (str "X-Amz-Algorithm=AWS4-HMAC-SHA256"
                       "&X-Amz-Credential=" api-key "/" (.format utc-now aws/basic-date-format) "/" region "/s3/aws4_request"
                       "&X-Amz-Date=" (.format utc-now aws/basic-date-time-format)
                       (str "&X-Amz-Expires=" expires-seconds)
                       "&X-Amz-SignedHeaders=host")]
    (str "https://" (s3-host config)
         "/" path
         "?" query-str
         "&X-Amz-Signature=" (get-signature config utc-now path query-str)
         (when ?security-token
           (str "&X-Amz-Security-Token=" ?security-token)))))

(defn- make-request
  [{:aws/keys [credentials-provider] region :aws-region bucket :aws-bucket :as config} {:keys [body method path] :as request}]
  (let [[api-key api-secret ?session-token] (credentials-provider)
        utc-now (aws/utc-now)
        req (update request :headers
                    assoc
                    "x-amz-date" (.format utc-now aws/basic-date-time-format)
                    "x-amz-content-sha256" (aws/hex-hash body)
                    "Host" (str (s3-host config) ":443"))]
    (-> req
        (dissoc :method :path :query-string)
        (assoc-in [:headers "Authorization"]
                  (aws/auth-header {:now utc-now
                                    :service "s3"
                                    :request req
                                    :aws-api-secret api-secret
                                    :aws-api-key api-key
                                    :aws-region region}))
        (cond->
            ?session-token
          (assoc-in [:headers "X-Amz-Security-Token"] ?session-token)))))

(defn delete-file!
  [config path]
  ;; always returns 204, even if file does not exist
  @(http/delete (str "https://" (s3-host config) path)
                (make-request config {:method "DELETE"
                                      :path path
                                      :body ""})))

(defn upload-url-path
  [url]
  (when url
    (or ;; old style, with bucket after domain
     (second (re-matches #"^https://s3\.amazonaws\.com/[^/]+(/.*)$" url))
     ;; new style, with bucket in domain
     (second (re-matches #"^https://.+\.amazonaws\.com(/.*)$" url)))))

Allow aws credentials provider to optionally yield security token


(defproject cljam "0.2.1-SNAPSHOT"
  :description "A DNA Sequence Alignment/Map (SAM) library for Clojure"
  :url "https://github.com/chrovis/cljam"
  :license {:name "Apache License, Version 2.0"
            :url "http://www.apache.org/licenses/LICENSE-2.0.html"}
  :dependencies [[org.clojure/tools.logging "0.3.1"]
                 [org.clojure/tools.cli "0.3.5"]
                 [org.apache.commons/commons-compress "1.13"]
                 [me.raynes/fs "1.4.6"]
                 [clj-sub-command "0.3.0"]
                 [digest "1.4.5"]
                 [bgzf4j "0.1.0"]
                 [com.climate/claypoole "1.1.4"]
                 [camel-snake-kebab "0.4.0"]]
  :plugins [[lein-midje "3.2.1"]]
  :profiles {:dev {:dependencies [[org.clojure/clojure "1.8.0"]
                                  [midje "1.8.3" :exclusions [slingshot]]
                                  [cavia "0.3.1"]]
                   :plugins [[lein-bin "0.3.5"]
                             [lein-codox "0.10.3"]
                             [lein-marginalia "0.9.0"]]
                   :main ^:skip-aot cljam.main
                   :global-vars {*warn-on-reflection* true}}
             :1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]}
             :1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]}
             :1.9 {:dependencies [[org.clojure/clojure "1.9.0-alpha14"]
                                  [midje "1.9.0-alpha6"]]}
             :uberjar {:main cljam.main
                       :aot :all}}
  :aliases {"docs" ["do" "codox" ["marg" "-d" "target/literate" "-m"]]}
  :bin {:name "cljam"}
  :codox {:namespaces [#"^cljam\.(?!cli)(?!lsb)(?!main)(?!util)[^\.]+$"]
          :output-path "target/docs"
          :source-uri "https://github.com/chrovis/cljam/blob/{version}/{filepath}#L{line}"}
  :repl-options {:init-ns user}
  :signing {:gpg-key "developer@xcoo.jp"})

(defproject cljam "0.2.1-SNAPSHOT"
  :description "A DNA Sequence Alignment/Map (SAM) library for Clojure"
  :url "https://github.com/chrovis/cljam"
  :license {:name "Apache License, Version 2.0"
            :url "http://www.apache.org/licenses/LICENSE-2.0.html"}
  :dependencies [[org.clojure/tools.logging "0.3.1"]
                 [org.clojure/tools.cli "0.3.5"]
                 [org.apache.commons/commons-compress "1.13"]
                 [me.raynes/fs "1.4.6"]
                 [clj-sub-command "0.3.0"]
                 [digest "1.4.5"]
                 [bgzf4j "0.1.0"]
                 [com.climate/claypoole "1.1.4"]
                 [camel-snake-kebab "0.4.0"]]
  :plugins [[lein-midje "3.2.1"]]
  :profiles {:dev {:dependencies [[org.clojure/clojure "1.8.0"]
                                  [midje "1.8.3" :exclusions [slingshot]]
                                  [cavia "0.4.0"]]
                   :plugins [[lein-bin "0.3.5"]
                             [lein-codox "0.10.3"]
                             [lein-marginalia "0.9.0"]]
                   :main ^:skip-aot cljam.main
                   :global-vars {*warn-on-reflection* true}}
             :1.7 {:dependencies [[org.clojure/clojure "1.7.0"]]}
             :1.8 {:dependencies [[org.clojure/clojure "1.8.0"]]}
             :1.9 {:dependencies [[org.clojure/clojure "1.9.0-alpha14"]
                                  [midje "1.9.0-alpha6"]]}
             :uberjar {:main cljam.main
                       :aot :all}}
  :aliases {"docs" ["do" "codox" ["marg" "-d" "target/literate" "-m"]]}
  :bin {:name "cljam"}
  :codox {:namespaces [#"^cljam\.(?!cli)(?!lsb)(?!main)(?!util)[^\.]+$"]
          :output-path "target/docs"
          :source-uri "https://github.com/chrovis/cljam/blob/{version}/{filepath}#L{line}"}
  :repl-options {:init-ns user}
  :signing {:gpg-key "developer@xcoo.jp"})

Bump cavia version up to 0.4.0

Bump cavia version up to 0.4.0


(defproject posthere.io "1.0.3-SNAPSHOT"
  :description "Debug all the POST Requests."
  :url "http://posthere.io/"
  :license {
    :name "Mozilla Public License v2.0"
    :url "http://www.mozilla.org/MPL/2.0/"
  }
  :support {
    :name "Sean Johnson"
    :email "sean@snootymonkey.com"
  }

  :min-lein-version "2.5.1" ; highest version supported by Travis-CI as of 2/17/2015

  :dependencies [
    ;; Server-side
    [org.clojure/clojure "1.9.0-alpha7"] ; Lisp on the JVM http://clojure.org/documentation
    [org.clojure/core.match "0.3.0-alpha4"] ; Erlang-esque pattern matching https://github.com/clojure/core.match
    [defun "0.3.0-alapha"] ; Erlang-esque pattern matching for Clojure functions https://github.com/killme2008/defun
    [ring/ring-devel "1.6.0-beta1"] ; Web application library https://github.com/ring-clojure/ring
    [ring/ring-core "1.6.0-beta1"] ; Web application library https://github.com/ring-clojure/ring
    [http-kit "2.2.0-beta1"] ; Development Web server http://http-kit.org/
    [compojure "1.5.1"] ; Web routing https://github.com/weavejester/compojure
    [jumblerg/ring.middleware.cors "1.0.1"] ; CORS library https://github.com/jumblerg/ring.middleware.cors
    [raven-clj "1.4.2"] ; Clojure interface to Sentry error reporting https://github.com/sethtrain/raven-clj
    [enlive "1.1.6"] ; HTML Templating system for Clojure https://github.com/cgrand/enlive
    [com.taoensso/carmine "2.14.0-alpha1"] ; Redis client for Clojure https://github.com/ptaoussanis/carmine
    [clj-time "0.12.0"] ; Clojure date/time library https://github.com/clj-time/clj-time
    [environ "1.0.3"] ; Get environment settings from different sources https://github.com/weavejester/environ
    [cheshire "5.6.3"] ; JSON de/encoding https://github.com/dakrone/cheshire
    [org.clojure/data.xml "0.1.0-beta1"] ; XML parser/encoder https://github.com/clojure/data.xml
    [clj-http "3.1.0"] ; HTTP client https://github.com/dakrone/clj-http
    ;; Client-side
    [org.clojure/clojurescript "1.9.93"] ; ClojureScript compiler https://github.com/clojure/clojurescript
    [jayq "2.5.4"] ; ClojureScript wrapper for jQuery https://github.com/ibdknox/jayq
    [hiccups "0.3.0"] ; ClojureScript implementation of Hiccup https://github.com/teropa/hiccups
    [cljs-uuid "0.0.4"] ; ClojureScript UUID https://github.com/davesann/cljs-uuid
  ]

  :plugins [
    [lein-ring "0.9.7"] ; common ring tasks https://github.com/weavejester/lein-ring
    [lein-environ "1.0.3"] ; Get environment settings from lein project https://github.com/weavejester/environ
  ]

  :profiles {

    :uberjar {
      :aot :all
    }

    :qa {
      :env {
        :hot-reload "false"
      }
      :dependencies [
        [midje "1.9.0-alpha2"] ; Example-based testing https://github.com/marick/Midje
        [ring-mock "0.1.5"] ; Test Ring requests https://github.com/weavejester/ring-mock
      ]
      :plugins [
        [lein-midje "3.2"] ; Example-based testing https://github.com/marick/lein-midje
        [jonase/eastwood "0.2.3"] ; Clojure linter https://github.com/jonase/eastwood
        [lein-kibit "0.1.2"] ; Static code search for non-idiomatic code https://github.com/jonase/kibit
      ]
    }

    :dev [:qa {
      :env ^:replace {
        :hot-reload "true" ; reload code when changed on the file system
      }
      :dependencies [
        [aprint "0.1.3"] ; Pretty printing in the REPL (aprint thing) https://github.com/razum2um/aprint
      ]
      :plugins [
        [lein-cljsbuild "1.1.3"] ; ClojureScript compiler https://github.com/emezeske/lein-cljsbuild
        [lein-bikeshed "0.3.0"] ; Check for code smells https://github.com/dakrone/lein-bikeshed
        [lein-checkall "0.1.1"] ; Runs bikeshed, kibit and eastwood https://github.com/itang/lein-checkall
        [lein-pprint "1.1.2"] ; pretty-print the lein project map https://github.com/technomancy/leiningen/tree/master/lein-pprint
        [lein-ancient "0.6.10"] ; Check for outdated dependencies https://github.com/xsc/lein-ancient
        [lein-spell "0.1.0"] ; Catch spelling mistakes in docs and docstrings https://github.com/cldwalker/lein-spell
        [lein-deps-tree "0.1.2"] ; Print a tree of project dependencies https://github.com/the-kenny/lein-deps-tree
        [lein-cljfmt "0.5.3"] ; Code formatting https://github.com/weavejester/cljfmt
      ]
      ;; REPL injections
      :injections [
        (require '[aprint.core :refer (aprint ap)]
                 '[clojure.stacktrace :refer (print-stack-trace)]
                 '[clojure.test :refer :all]
                 '[clj-time.core :as t]
                 '[clj-time.format :as f]
                 '[clojure.string :as s])
      ]
    }]

    :prod {
      :env {
        :hot-reload "false"
      }
    }

  }

  :aliases {
    "build-pages" ["run" "-m" "posthere.static-templating/export"] ; build the static HTML pages
    "build" ["with-profile" "prod" "do" "clean," "cljsbuild" "once," "build-pages," "uberjar"]
    "test!" ["with-profile" "qa" "midje"] ; run all tests
    "run!" ["with-profile" "prod" "run"] ; start a POSThere.io server in production
    "spell!" ["spell" "-n"] ; check spelling in docs and docstrings
    "bikeshed!" ["bikeshed" "-v" "-m" "120"] ; code check with max line length warning of 120 characters
    "ancient" ["ancient" ":all" ":allow-qualified"] ; check for out of date dependencies
  }

  ;; ----- Code check configuration -----

  :eastwood {
    ;; Enable some linters that are disabled by default
    :add-linters [:unused-namespaces :unused-private-vars :unused-locals]

    ;; More extensive lintering that will have a few false positives
    ;; :add-linters [:unused-namespaces :unused-private-vars :unused-locals :unused-fn-args]

    ;; Exclude testing namespaces
    :tests-paths ["test"]
    :exclude-namespaces [:test-paths]
  }

  ;; ----- ClojureScript -----

  :cljsbuild {
    :builds
      [{
      :source-paths ["src/posthere/cljs"] ; CLJS source code path
      ;; Google Closure (CLS) options configuration
      :compiler {
        :output-to "resources/public/js/posthere.js" ; generated JS script filename
        :optimizations :simple ; JS optimization directive
        :pretty-print true ; generated JS code prettyfication
      }}]
  }

  ;; ----- Web Application -----

  :ring {
    :handler posthere.app/app
    :reload-paths ["src"] ; work around issue https://github.com/weavejester/lein-ring/issues/68
  }

  :resource-paths ["resources"]

  :main ^:skip-aot posthere.app
)

(defproject posthere.io "1.0.3-SNAPSHOT"
  :description "Debug all the POST Requests."
  :url "http://posthere.io/"
  :license {
    :name "Mozilla Public License v2.0"
    :url "http://www.mozilla.org/MPL/2.0/"
  }
  :support {
    :name "Sean Johnson"
    :email "sean@snootymonkey.com"
  }

  :min-lein-version "2.5.1" ; highest version supported by Travis-CI as of 2/17/2015

  :dependencies [
    ;; Server-side
    [org.clojure/clojure "1.9.0-alpha10"] ; Lisp on the JVM http://clojure.org/documentation
    [org.clojure/core.match "0.3.0-alpha4"] ; Erlang-esque pattern matching https://github.com/clojure/core.match
    [defun "0.3.0-alapha"] ; Erlang-esque pattern matching for Clojure functions https://github.com/killme2008/defun
    [ring/ring-devel "1.6.0-beta4"] ; Web application library https://github.com/ring-clojure/ring
    [ring/ring-core "1.6.0-beta4"] ; Web application library https://github.com/ring-clojure/ring
    [http-kit "2.2.0"] ; Development Web server http://http-kit.org/
    [compojure "1.5.1"] ; Web routing https://github.com/weavejester/compojure
    [jumblerg/ring.middleware.cors "1.0.1"] ; CORS library https://github.com/jumblerg/ring.middleware.cors
    [raven-clj "1.4.2"] ; Clojure interface to Sentry error reporting https://github.com/sethtrain/raven-clj
    [enlive "1.1.6"] ; HTML Templating system for Clojure https://github.com/cgrand/enlive
    [com.taoensso/carmine "2.14.0-alpha1"] ; Redis client for Clojure https://github.com/ptaoussanis/carmine
    [clj-time "0.12.0"] ; Clojure date/time library https://github.com/clj-time/clj-time
    [environ "1.0.3"] ; Get environment settings from different sources https://github.com/weavejester/environ
    [cheshire "5.6.3"] ; JSON de/encoding https://github.com/dakrone/cheshire
    [org.clojure/data.xml "0.1.0-beta1"] ; XML parser/encoder https://github.com/clojure/data.xml
    [clj-http "3.1.0"] ; HTTP client https://github.com/dakrone/clj-http
    ;; Client-side
    [org.clojure/clojurescript "1.9.93"] ; ClojureScript compiler https://github.com/clojure/clojurescript
    [jayq "2.5.4"] ; ClojureScript wrapper for jQuery https://github.com/ibdknox/jayq
    [hiccups "0.3.0"] ; ClojureScript implementation of Hiccup https://github.com/teropa/hiccups
    [cljs-uuid "0.0.4"] ; ClojureScript UUID https://github.com/davesann/cljs-uuid
  ]

  :plugins [
    [lein-ring "0.9.7"] ; common ring tasks https://github.com/weavejester/lein-ring
    [lein-environ "1.0.3"] ; Get environment settings from lein project https://github.com/weavejester/environ
  ]

  :profiles {

    :uberjar {
      :aot :all
    }

    :qa {
      :env {
        :hot-reload "false"
      }
      :dependencies [
        [midje "1.9.0-alpha3"] ; Example-based testing https://github.com/marick/Midje
        [ring-mock "0.1.5"] ; Test Ring requests https://github.com/weavejester/ring-mock
      ]
      :plugins [
        [lein-midje "3.2"] ; Example-based testing https://github.com/marick/lein-midje
        [jonase/eastwood "0.2.3"] ; Clojure linter https://github.com/jonase/eastwood
        [lein-kibit "0.1.2"] ; Static code search for non-idiomatic code https://github.com/jonase/kibit
      ]
    }

    :dev [:qa {
      :env ^:replace {
        :hot-reload "true" ; reload code when changed on the file system
      }
      :dependencies [
        [aprint "0.1.3"] ; Pretty printing in the REPL (aprint thing) https://github.com/razum2um/aprint
      ]
      :plugins [
        [lein-cljsbuild "1.1.3"] ; ClojureScript compiler https://github.com/emezeske/lein-cljsbuild
        [lein-bikeshed "0.3.0"] ; Check for code smells https://github.com/dakrone/lein-bikeshed
        [lein-checkall "0.1.1"] ; Runs bikeshed, kibit and eastwood https://github.com/itang/lein-checkall
        [lein-pprint "1.1.2"] ; pretty-print the lein project map https://github.com/technomancy/leiningen/tree/master/lein-pprint
        [lein-ancient "0.6.10"] ; Check for outdated dependencies https://github.com/xsc/lein-ancient
        [lein-spell "0.1.0"] ; Catch spelling mistakes in docs and docstrings https://github.com/cldwalker/lein-spell
        [lein-deps-tree "0.1.2"] ; Print a tree of project dependencies https://github.com/the-kenny/lein-deps-tree
        [lein-cljfmt "0.5.3"] ; Code formatting https://github.com/weavejester/cljfmt
      ]
      ;; REPL injections
      :injections [
        (require '[aprint.core :refer (aprint ap)]
                 '[clojure.stacktrace :refer (print-stack-trace)]
                 '[clojure.test :refer :all]
                 '[clj-time.core :as t]
                 '[clj-time.format :as f]
                 '[clojure.string :as s])
      ]
    }]

    :prod {
      :env {
        :hot-reload "false"
      }
    }

  }

  :aliases {
    "build-pages" ["run" "-m" "posthere.static-templating/export"] ; build the static HTML pages
    "build" ["with-profile" "prod" "do" "clean," "cljsbuild" "once," "build-pages," "uberjar"]
    "test!" ["with-profile" "qa" "midje"] ; run all tests
    "run!" ["with-profile" "prod" "run"] ; start a POSThere.io server in production
    "spell!" ["spell" "-n"] ; check spelling in docs and docstrings
    "bikeshed!" ["bikeshed" "-v" "-m" "120"] ; code check with max line length warning of 120 characters
    "ancient" ["ancient" ":all" ":allow-qualified"] ; check for out of date dependencies
  }

  ;; ----- Code check configuration -----

  :eastwood {
    ;; Enable some linters that are disabled by default
    :add-linters [:unused-namespaces :unused-private-vars :unused-locals]

    ;; More extensive lintering that will have a few false positives
    ;; :add-linters [:unused-namespaces :unused-private-vars :unused-locals :unused-fn-args]

    ;; Exclude testing namespaces
    :tests-paths ["test"]
    :exclude-namespaces [:test-paths]
  }

  ;; ----- ClojureScript -----

  :cljsbuild {
    :builds
      [{
      :source-paths ["src/posthere/cljs"] ; CLJS source code path
      ;; Google Closure (CLS) options configuration
      :compiler {
        :output-to "resources/public/js/posthere.js" ; generated JS script filename
        :optimizations :simple ; JS optimization directive
        :pretty-print true ; generated JS code prettyfication
      }}]
  }

  ;; ----- Web Application -----

  :ring {
    :handler posthere.app/app
    :reload-paths ["src"] ; work around issue https://github.com/weavejester/lein-ring/issues/68
  }

  :resource-paths ["resources"]

  :main ^:skip-aot posthere.app
)

Update dependencies.

Update dependencies.


(defproject funcool/futura "0.1.0-alpha1"
  :description "A basic building blocks for async programming."
  :url "https://github.com/funcool/futura"
  :license {:name "BSD (2 Clause)"
            :url "http://opensource.org/licenses/BSD-2-Clause"}
  :dependencies [[cats "0.4.0"]
                 [manifold "0.1.0"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [org.reactivestreams/reactive-streams "1.0.0.RC5"]]
  :deploy-repositories {"releases" :clojars
                        "snapshots" :clojars}
  :source-paths ["src"]
  :test-paths ["test"]
  :jar-exclusions [#"\.swp|\.swo|user.clj"]
  :javac-options ["-target" "1.8" "-source" "1.8" "-Xlint:-options"]
  :profiles {:dev {:dependencies [[org.clojure/clojure "1.7.0-beta2"]]
                   :codeina {:sources ["src"]
                             :language :clojure
                             :output-dir "doc/api"}
                   :plugins [[funcool/codeina "0.1.0-SNAPSHOT"
                              :exclusions [org.clojure/clojure]]]}})

(defproject funcool/futura "0.1.0-SNAPSHOT"
  :description "A basic building blocks for async programming."
  :url "https://github.com/funcool/futura"
  :license {:name "BSD (2 Clause)"
            :url "http://opensource.org/licenses/BSD-2-Clause"}
  :dependencies [[cats "0.4.0"]
                 [manifold "0.1.0"]
                 [org.clojure/core.async "0.1.346.0-17112a-alpha"]
                 [org.reactivestreams/reactive-streams "1.0.0.RC5"]]
  :deploy-repositories {"releases" :clojars
                        "snapshots" :clojars}
  :source-paths ["src"]
  :test-paths ["test"]
  :jar-exclusions [#"\.swp|\.swo|user.clj"]
  :javac-options ["-target" "1.8" "-source" "1.8" "-Xlint:-options"]
  :profiles {:dev {:dependencies [[org.clojure/clojure "1.7.0-beta2"]]
                   :codeina {:sources ["src"]
                             :language :clojure
                             :output-dir "doc/api"}
                   :plugins [[funcool/codeina "0.1.0-SNAPSHOT"
                              :exclusions [org.clojure/clojure]]]}})

Set version to 0.1.0-SNAPSHOT

Set version to 0.1.0-SNAPSHOT


(defproject my-money "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url "http://example.com/FIXME"

  :dependencies [[bouncer "1.0.1"]
                 [buddy "2.0.0"]
                 [clj-time "0.15.1"]
                 [cljs-ajax "0.8.0"]
                 [cljsjs/react-chartjs-2 "2.7.4-0" :exclusions [cljsjs/react]]
                 [compojure "1.6.1"]
                 [conman "0.8.3"]
                 [cprop "0.1.13"]
                 [funcool/bide "1.6.0"]
                 [luminus-immutant "0.2.4"]
                 [luminus-migrations "0.6.1"]
                 [luminus-nrepl "0.1.5"]
                 [metosin/ring-http-response "0.9.1"]
                 [metosin/muuntaja "0.6.3"]
                 [mount "0.1.15"]
                 [org.clojure/clojure "1.10.1"]
                 [org.clojure/clojurescript "1.10.520" :scope "provided"]
                 [org.clojure/data.csv "0.1.4"]
                 [org.clojure/tools.cli "0.4.1"]
                 [org.clojure/tools.logging "0.4.1"]
                 [org.postgresql/postgresql "42.2.5"]
                 [org.webjars/bootstrap "4.2.1"]
                 [org.webjars/font-awesome "5.6.3"]
                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
                 [reagent "0.8.1"]
                 [reagent-utils "0.3.2"]
                 [ring-middleware-format "0.7.2"]
                 [ring-webjars "0.2.0"]
                 [ring/ring-defaults "0.3.2"]
                 [selmer "1.12.5"]
                 [webjure/tuck "20181204"]]

  :min-lein-version "2.0.0"

  :jvm-opts ["-server" "-Dconf=.lein-env"]
  :source-paths ["src/clj" "src/cljc"]
  :resource-paths ["resources" "target/cljsbuild"]
  :target-path "target/%s/"
  :main my-money.core
  :migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}

  :plugins [[migratus-lein "0.6.8"]
            [lein-cljsbuild "1.1.7"]
            [lein-immutant "2.1.0"]]
  :clean-targets ^{:protect false}
  [:target-path [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]]
  :figwheel
  {:http-server-root "public"
   :nrepl-port 7002
   :css-dirs ["resources/public/css"]
   :nrepl-middleware [cider.piggieback/wrap-cljs-repl]}
  :repl-options {:port 7000}
  :profiles
  {:uberjar {:omit-source true
             :prep-tasks ["compile" ["cljsbuild" "once" "min"]]
             :cljsbuild
             {:builds
              {:min
               {:source-paths ["src/cljc" "src/cljs" "env/prod/cljs"]
                :compiler
                {:output-to "target/cljsbuild/public/js/app.js"
                 :optimizations :advanced
                 :pretty-print false
                 :closure-warnings
                 {:externs-validation :off :non-standard-jsdoc :off}
                 :externs ["react/externs/react.js"]}}}}

             :aot :all
             :uberjar-name "my-money.jar"
             :source-paths ["env/prod/clj"]
             :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:dependencies [[prone "1.6.1"]
                                 [ring/ring-mock "0.3.2"]
                                 [ring/ring-devel "1.7.1"]
                                 [pjstadig/humane-test-output "0.9.0"]
                                 [binaryage/devtools "0.9.10"]
                                 [cider/piggieback "0.4.0"]
                                 [doo "0.1.11"]
                                 [figwheel-sidecar "0.5.18"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.23.0"]
                                 [lein-doo "0.1.11"]
                                 [lein-figwheel "0.5.18"]
                                 [org.clojure/clojurescript "1.10.439"]
                                 [lein-nvd "0.6.0"]
                                 [lein-ancient "0.6.15"]]
                  :cljsbuild
                  {:builds
                   {:app
                    {:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                     :compiler
                     {:main "my-money.app"
                      :asset-path "/js/out"
                      :output-to "target/cljsbuild/public/js/app.js"
                      :output-dir "target/cljsbuild/public/js/out"
                      :source-map true
                      :optimizations :none
                      :pretty-print true
                      :process-shim true}}}}
                  :doo {:build "test"
                        :paths {:karma "./node_modules/karma/bin/karma"}}
                  :source-paths ["env/dev/clj" "test/clj"]
                  :resource-paths ["env/dev/resources"]
                  :repl-options {:init-ns user}
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:resource-paths ["env/test/resources"]
                  :cljsbuild
                  {:builds
                   {:test
                    {:source-paths ["src/cljc" "src/cljs" "test/cljs"]
                     :compiler
                     {:output-to "target/test.js"
                      :main "my-money.doo-runner"
                      :optimizations :none
                      :pretty-print true
                      :process-shim true
                      :npm-deps {:karma "3.1.1"
                                 :karma-cljs-test "0.1.0"
                                 :karma-chrome-launcher "2.2.0"}
                      :install-deps true}}}}}

   :profiles/dev {}
   :profiles/test {}}
  :aliases {"fronttests-once" ["with-profile" "test" "doo" "chrome-headless" "once"]
            "fronttests" ["with-profile" "test" "doo" "chrome-headless"]})

(defproject my-money "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url "http://example.com/FIXME"

  :dependencies [[bouncer "1.0.1"]
                 [buddy "2.0.0"]
                 [clj-time "0.15.1"]
                 [cljs-ajax "0.8.0"]
                 [cljsjs/react-chartjs-2 "2.7.4-0" :exclusions [cljsjs/react]]
                 [compojure "1.6.1"]
                 [conman "0.8.3"]
                 [cprop "0.1.13"]
                 [funcool/bide "1.6.0"]
                 [luminus-immutant "0.2.4"]
                 [luminus-migrations "0.6.1"]
                 [luminus-nrepl "0.1.5"]
                 [metosin/ring-http-response "0.9.1"]
                 [metosin/muuntaja "0.6.3"]
                 [mount "0.1.15"]
                 [org.clojure/clojure "1.10.1"]
                 [org.clojure/clojurescript "1.10.520" :scope "provided"]
                 [org.clojure/data.csv "0.1.4"]
                 [org.clojure/tools.cli "0.4.1"]
                 [org.clojure/tools.logging "0.4.1"]
                 [org.postgresql/postgresql "42.2.5"]
                 [org.webjars/bootstrap "4.2.1"]
                 [org.webjars/font-awesome "5.6.3"]
                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
                 [reagent "0.8.1" :exclusions [cljsjs/react cljsjs/react-dom]]
                 [cljsjs/react "16.9.0-0"]
                 [cljsjs/react-dom "16.9.0-0"]
                 [reagent-utils "0.3.2"]
                 [ring-middleware-format "0.7.2"]
                 [ring-webjars "0.2.0"]
                 [ring/ring-defaults "0.3.2"]
                 [selmer "1.12.5"]
                 [webjure/tuck "20181204"]]

  :min-lein-version "2.0.0"

  :jvm-opts ["-server" "-Dconf=.lein-env"]
  :source-paths ["src/clj" "src/cljc"]
  :resource-paths ["resources" "target/cljsbuild"]
  :target-path "target/%s/"
  :main my-money.core
  :migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}

  :plugins [[migratus-lein "0.6.8"]
            [lein-cljsbuild "1.1.7"]
            [lein-immutant "2.1.0"]]
  :clean-targets ^{:protect false}
  [:target-path [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]]
  :figwheel
  {:http-server-root "public"
   :nrepl-port 7002
   :css-dirs ["resources/public/css"]
   :nrepl-middleware [cider.piggieback/wrap-cljs-repl]}
  :repl-options {:port 7000}
  :profiles
  {:uberjar {:omit-source true
             :prep-tasks ["compile" ["cljsbuild" "once" "min"]]
             :cljsbuild
             {:builds
              {:min
               {:source-paths ["src/cljc" "src/cljs" "env/prod/cljs"]
                :compiler
                {:output-to "target/cljsbuild/public/js/app.js"
                 :optimizations :advanced
                 :pretty-print false
                 :closure-warnings
                 {:externs-validation :off :non-standard-jsdoc :off}
                 :externs ["react/externs/react.js"]}}}}

             :aot :all
             :uberjar-name "my-money.jar"
             :source-paths ["env/prod/clj"]
             :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:dependencies [[prone "1.6.1"]
                                 [ring/ring-mock "0.3.2"]
                                 [ring/ring-devel "1.7.1"]
                                 [pjstadig/humane-test-output "0.9.0"]
                                 [binaryage/devtools "0.9.10"]
                                 [cider/piggieback "0.4.0"]
                                 [doo "0.1.11"]
                                 [figwheel-sidecar "0.5.18"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.23.0"]
                                 [lein-doo "0.1.11"]
                                 [lein-figwheel "0.5.18"]
                                 [org.clojure/clojurescript "1.10.439"]
                                 [lein-nvd "0.6.0"]
                                 [lein-ancient "0.6.15"]]
                  :cljsbuild
                  {:builds
                   {:app
                    {:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                     :compiler
                     {:main "my-money.app"
                      :asset-path "/js/out"
                      :output-to "target/cljsbuild/public/js/app.js"
                      :output-dir "target/cljsbuild/public/js/out"
                      :source-map true
                      :optimizations :none
                      :pretty-print true
                      :process-shim true}}}}
                  :doo {:build "test"
                        :paths {:karma "./node_modules/karma/bin/karma"}}
                  :source-paths ["env/dev/clj" "test/clj"]
                  :resource-paths ["env/dev/resources"]
                  :repl-options {:init-ns user}
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:resource-paths ["env/test/resources"]
                  :cljsbuild
                  {:builds
                   {:test
                    {:source-paths ["src/cljc" "src/cljs" "test/cljs"]
                     :compiler
                     {:output-to "target/test.js"
                      :main "my-money.doo-runner"
                      :optimizations :none
                      :pretty-print true
                      :process-shim true
                      :npm-deps {:karma "3.1.1"
                                 :karma-cljs-test "0.1.0"
                                 :karma-chrome-launcher "2.2.0"}
                      :install-deps true}}}}}

   :profiles/dev {}
   :profiles/test {}}
  :aliases {"fronttests-once" ["with-profile" "test" "doo" "chrome-headless" "once"]
            "fronttests" ["with-profile" "test" "doo" "chrome-headless"]})

Update React to newer version than what reagent comes with


(defproject workshop "0.8.4"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [org.clojure/core.async "0.2.374"]
                 [org.onyxplatform/onyx "0.8.4"]
                 [org.slf4j/slf4j-api "1.7.12"]
                 [org.slf4j/slf4j-nop "1.7.12"]]
  :profiles {:dev {:dependencies [[org.clojure/tools.namespace "0.2.10"]
                                  [pjstadig/humane-test-output "0.7.0"]]
                   :plugins [[lein-update-dependency "0.1.2"]
                             [lein-set-version "0.4.1"]]
                   :source-paths ["env/dev" "src"]
                   :injections [(require 'pjstadig.humane-test-output)
                                (pjstadig.humane-test-output/activate!)]}})

(defproject workshop "0.8.5"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [org.clojure/core.async "0.2.374"]
                 [org.onyxplatform/onyx "0.8.5"]
                 [org.slf4j/slf4j-api "1.7.12"]
                 [org.slf4j/slf4j-nop "1.7.12"]]
  :profiles {:dev {:dependencies [[org.clojure/tools.namespace "0.2.10"]
                                  [pjstadig/humane-test-output "0.7.0"]]
                   :plugins [[lein-update-dependency "0.1.2"]
                             [lein-set-version "0.4.1"]]
                   :source-paths ["env/dev" "src"]
                   :injections [(require 'pjstadig.humane-test-output)
                                (pjstadig.humane-test-output/activate!)]}})

Upgrade to 0.8.5.

Upgrade to 0.8.5.


;; this is to allow the insecure `usethesource` repository
(require 'cemerick.pomegranate.aether)
(cemerick.pomegranate.aether/register-wagon-factory!
  "http" #(org.apache.maven.wagon.providers.http.HttpWagon.))

(defproject io.lacuna/bifurcan "0.2.0-alpha5"
  :java-source-paths ["src"]
  :dependencies []
  :test-selectors {:default   #(not
                                 (some #{:benchmark :stress}
                                   (cons (:tag %) (keys %))))
                   :benchmark :benchmark
                   :stress    :stress
                   :all       (constantly true)}
  :profiles {:low-mem {:jvm-opts ^:replace ["-server" "-Xmx1g" "-XX:MaxDirectMemorySize=2g" "-XX:+UseG1GC"]}
             :bench   {:jvm-opts ^:replace ["-server" "-Xmx10g" "-XX:+UseG1GC"]}
             :dev     {:dependencies [;; for tests
                                      [org.clojure/clojure "1.10.0"]
                                      [org.clojure/test.check "0.10.0"]
                                      [criterium "0.4.5"]
                                      [potemkin "0.4.5"]
                                      [proteus "0.1.6"]
                                      [byte-streams "0.2.4"]
                                      [byte-transforms "0.1.4"]
                                      [eftest "0.5.9"]
                                      [virgil "0.1.9"]

                                      ;; for comparative in-memory benchmarks
                                      [io.usethesource/capsule "0.6.3"]
                                      [org.pcollections/pcollections "3.1.2"]
                                      [io.vavr/vavr "0.10.2"]
                                      [org.scala-lang/scala-library "2.13.1"]
                                      [org.functionaljava/functionaljava "4.8.1"]
                                      [org.organicdesign/Paguro "3.1.2"]

                                      ;; for comparative durable benchmarks
                                      [org.rocksdb/rocksdbjni "6.4.6"]
                                      [com.sleepycat/je "18.3.12"]
                                      [org.lmdbjava/lmdbjava "0.7.0"]
                                      ]}}
  :aliases {"partest"              ["run" "-m" "bifurcan.run-tests"]
            "benchmark"            ["run" "-m" "bifurcan.benchmark-test" "benchmark"]
            "benchmark-collection" ["run" "-m" "bifurcan.benchmark-test" "benchmark-collection"]
            "benchmark-databases"  ["with-profile" "low-mem,dev" "run" "-m" "bifurcan.durable-benchmark-test" "benchmark"]}
  :jvm-opts ^:replace ["-server"
                       "-XX:+UseG1GC"
                       "-XX:-OmitStackTraceInFastThrow"
                       "-ea:io.lacuna..."
                       "-Xmx4g"

                       #_"-XX:+UnlockDiagnosticVMOptions"
                       #_"-XX:+PrintAssembly"
                       #_"-XX:CompileCommand=print,io.lacuna.bifurcan.nodes.Util::mergeState"
                       #_"-XX:CompileCommand=dontinline,io.lacuna.bifurcan.nodes.Util::mergeState"
                       ]

  :repositories {"usethesource" "http://nexus.usethesource.io/content/repositories/public/"}

  ;; deployment
  :url "https://github.com/lacuna/bifurcan"
  :description "impure functional data structures"
  :license {:name "MIT License"}
  :javac-options ["-target" "1.8" "-source" "1.8"]
  :deploy-repositories {"releases"  {:url   "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
                                     :creds :gpg}
                        "snapshots" {:url   "https://oss.sonatype.org/content/repositories/snapshots/"
                                     :creds :gpg}}

  ;; Maven properties for the Maven God
  :scm {:url "git@github.com:lacuna/bifurcan.git"}
  :pom-addition [:developers [:developer
                              [:name "Zach Tellman"]
                              [:url "http://ideolalia.com"]
                              [:email "ztellman@gmail.com"]
                              [:timezone "-8"]]]
  :classifiers {:javadoc {:java-source-paths ^:replace []
                          :source-paths      ^:replace []
                          :resource-paths    ^:replace ["javadoc"]}
                :sources {:source-paths   ^:replace ["src"]
                          :resource-paths ^:replace []}})

;; this is to allow the insecure `usethesource` repository
(require 'cemerick.pomegranate.aether)
(cemerick.pomegranate.aether/register-wagon-factory!
  "http" #(org.apache.maven.wagon.providers.http.HttpWagon.))

(defproject io.lacuna/bifurcan "0.2.0-alpha6"
  :java-source-paths ["src"]
  :dependencies []
  :test-selectors {:default   #(not
                                 (some #{:benchmark :stress}
                                   (cons (:tag %) (keys %))))
                   :benchmark :benchmark
                   :stress    :stress
                   :all       (constantly true)}
  :profiles {:low-mem {:jvm-opts ^:replace ["-server" "-Xmx1g" "-XX:MaxDirectMemorySize=2g" "-XX:+UseG1GC"]}
             :bench   {:jvm-opts ^:replace ["-server" "-Xmx10g" "-XX:+UseG1GC"]}
             :dev     {:dependencies [;; for tests
                                      [org.clojure/clojure "1.10.0"]
                                      [org.clojure/test.check "0.10.0"]
                                      [criterium "0.4.5"]
                                      [potemkin "0.4.5"]
                                      [proteus "0.1.6"]
                                      [byte-streams "0.2.4"]
                                      [byte-transforms "0.1.4"]
                                      [eftest "0.5.9"]
                                      [virgil "0.1.9"]

                                      ;; for comparative in-memory benchmarks
                                      [io.usethesource/capsule "0.6.3"]
                                      [org.pcollections/pcollections "3.1.2"]
                                      [io.vavr/vavr "0.10.2"]
                                      [org.scala-lang/scala-library "2.13.1"]
                                      [org.functionaljava/functionaljava "4.8.1"]
                                      [org.organicdesign/Paguro "3.1.2"]

                                      ;; for comparative durable benchmarks
                                      [org.rocksdb/rocksdbjni "6.4.6"]
                                      [com.sleepycat/je "18.3.12"]
                                      [org.lmdbjava/lmdbjava "0.7.0"]
                                      ]}}
  :aliases {"partest"              ["run" "-m" "bifurcan.run-tests"]
            "benchmark"            ["run" "-m" "bifurcan.benchmark-test" "benchmark"]
            "benchmark-collection" ["run" "-m" "bifurcan.benchmark-test" "benchmark-collection"]
            "benchmark-databases"  ["with-profile" "low-mem,dev" "run" "-m" "bifurcan.durable-benchmark-test" "benchmark"]}
  :jvm-opts ^:replace ["-server"
                       "-XX:+UseG1GC"
                       "-XX:-OmitStackTraceInFastThrow"
                       "-ea:io.lacuna..."
                       "-Xmx4g"

                       #_"-XX:+UnlockDiagnosticVMOptions"
                       #_"-XX:+PrintAssembly"
                       #_"-XX:CompileCommand=print,io.lacuna.bifurcan.nodes.Util::mergeState"
                       #_"-XX:CompileCommand=dontinline,io.lacuna.bifurcan.nodes.Util::mergeState"
                       ]

  :repositories {"usethesource" "http://nexus.usethesource.io/content/repositories/public/"}

  ;; deployment
  :url "https://github.com/lacuna/bifurcan"
  :description "impure functional data structures"
  :license {:name "MIT License"}
  :javac-options ["-target" "1.8" "-source" "1.8"]
  :deploy-repositories {"releases"  {:url   "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
                                     :creds :gpg}
                        "snapshots" {:url   "https://oss.sonatype.org/content/repositories/snapshots/"
                                     :creds :gpg}}

  ;; Maven properties for the Maven God
  :scm {:url "git@github.com:lacuna/bifurcan.git"}
  :pom-addition [:developers [:developer
                              [:name "Zach Tellman"]
                              [:url "http://ideolalia.com"]
                              [:email "ztellman@gmail.com"]
                              [:timezone "-8"]]]
  :classifiers {:javadoc {:java-source-paths ^:replace []
                          :source-paths      ^:replace []
                          :resource-paths    ^:replace ["javadoc"]}
                :sources {:source-paths   ^:replace ["src"]
                          :resource-paths ^:replace []}})

mark 0.2.0-alpha6

mark 0.2.0-alpha6


(defproject org.eamonn.funcgo/fgolib "0.2.3"
  :description "Library that mimics the standard Go library"
  :url "http://funcgo.org"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.5.1"]
                 [org.eamonn.funcgo/funcgo-lein-plugin "0.2.5"]
                 [midje "1.5.1" :scope "test"]]
  :plugins [[lein-midje "3.1.1"]
            [org.eamonn.funcgo/funcgo-lein-plugin "0.2.5"]])

(defproject org.eamonn.funcgo/fgolib "0.2.4"
  :description "Library that mimics the standard Go library"
  :url "http://funcgo.org"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.eamonn.funcgo/funcgo-lein-plugin "0.2.6"]
                 [midje "1.6.3" :scope "test"]]
  :plugins [[lein-midje "3.1.1"]
            [org.eamonn.funcgo/funcgo-lein-plugin "0.2.6"]])

Update library versions.

Update library versions.


(defproject dda/dda-managed-vm "0.3.1-SNAPSHOT"
  :description "The managed vm desktop crate"
  :url "https://www.domaindrivenarchitecture.org"
  :license {:name "Apache License, Version 2.0"
            :url "https://www.apache.org/licenses/LICENSE-2.0.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [dda/dda-pallet "0.5.5-SNAPSHOT"]
                 [dda/dda-user-crate "0.6.2-SNAPSHOT"]
                 [dda/dda-serverspec-crate "0.2.2-SNAPSHOT"]
                 [dda/dda-git-crate "0.1.3-SNAPSHOT"]
                 [dda/dda-backup-crate "0.6.1-SNAPSHOT"]
                 [keypin "0.7.1"]]
  :repositories [["snapshots" :clojars]
                 ["releases" :clojars]]
  :deploy-repositories [["snapshots" :clojars]
                        ["releases" :clojars]]
  :profiles {:uberjar
             {:aot :all
              :main main}
             :dev
             {:source-paths ["integration"]
              :resource-paths ["dev-resources"]
              :dependencies
              [[org.clojure/test.check "0.10.0-alpha2"]
               [org.domaindrivenarchitecture/pallet-aws "0.2.8.2"]
               [com.palletops/pallet "0.8.12" :classifier "tests"]
               [org.domaindrivenarchitecture/dda-pallet-commons "0.3.2" :classifier "tests"]
               [ch.qos.logback/logback-classic "1.2.3"]
               [org.slf4j/jcl-over-slf4j "1.8.0-alpha2"]]
              :plugins
              [[com.palletops/pallet-lein "0.8.0-alpha.1"]
               [lein-sub "0.3.0"]]}
             :leiningen/reply
             {:dependencies [[org.slf4j/jcl-over-slf4j "1.8.0-alpha2"]]
              :exclusions [commons-logging]}}
  :local-repo-classpath true
  :classifiers {:tests {:source-paths ^:replace ["test" "integration"]
                        :resource-paths ^:replace ["dev-resources"]}})

(defproject dda/dda-managed-vm "0.3.1-SNAPSHOT"
  :description "The managed vm desktop crate"
  :url "https://www.domaindrivenarchitecture.org"
  :license {:name "Apache License, Version 2.0"
            :url "https://www.apache.org/licenses/LICENSE-2.0.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [dda/dda-pallet "0.5.5"]
                 [dda/dda-user-crate "0.6.2"]
                 [dda/dda-serverspec-crate "0.2.2"]
                 [dda/dda-git-crate "0.1.3"]
                 [dda/dda-backup-crate "0.6.1"]
                 [keypin "0.7.1"]]
  :repositories [["snapshots" :clojars]
                 ["releases" :clojars]]
  :deploy-repositories [["snapshots" :clojars]
                        ["releases" :clojars]]
  :profiles {:uberjar
             {:aot :all
              :main main}
             :dev
             {:source-paths ["integration"]
              :resource-paths ["dev-resources"]
              :dependencies
              [[org.clojure/test.check "0.10.0-alpha2"]
               [org.domaindrivenarchitecture/pallet-aws "0.2.8.2"]
               [com.palletops/pallet "0.8.12" :classifier "tests"]
               [org.domaindrivenarchitecture/dda-pallet-commons "0.3.2" :classifier "tests"]
               [ch.qos.logback/logback-classic "1.2.3"]
               [org.slf4j/jcl-over-slf4j "1.8.0-alpha2"]]
              :plugins
              [[com.palletops/pallet-lein "0.8.0-alpha.1"]
               [lein-sub "0.3.0"]]}
             :leiningen/reply
             {:dependencies [[org.slf4j/jcl-over-slf4j "1.8.0-alpha2"]]
              :exclusions [commons-logging]}}
  :local-repo-classpath true
  :classifiers {:tests {:source-paths ^:replace ["test" "integration"]
                        :resource-paths ^:replace ["dev-resources"]}})

prepare release

prepare release


(defproject revue "0.0.1"
  :description "REVUE: REVersible User Experiences"

  :url "https://github.com/hoelzl/Revue"

  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :pom-addition [:developers [:developer
                              [:id "mhoelzl"]
                              [:name "Matthias Hoelzl"]
                              [:url "https://github.com/hoelzl"]
                              [:email "tc@xantira.com"]]]
  :repositories [["local" "file:///Users/tc/.m2/repository"]]

  :exclusions [org.clojure/clojure org.clojure/clojurescript]
  :jar-exclusions [#"\.cljx|\.swp|\.swo|\.DS_Store"]
  :source-paths ["src/cljx"]
  :test-paths ["target/test-classes"]
  :dependencies [[org.clojure/clojure "1.7.0-alpha2"]
                 [org.clojure/clojurescript "0.0-2371"]
                 [org.clojure/tools.reader "0.8.9"]
                 ;;[weasel "0.4.0-SNAPSHOT"]
                 ]

  :cljx {:builds [{:source-paths ["src/cljx"]
                   :output-path "target/classes"
                   :rules :clj}

                  {:source-paths ["src/cljx"]
                   :output-path "target/classes"
                   :rules :cljs}

                  {:source-paths ["test/cljx"]
                   :output-path "target/test-classes"
                   :rules :clj}

                  {:source-paths ["test/cljx"]
                   :output-path "target/test-classes"
                   :rules :cljs}]}

  :prep-tasks [["cljx" "once"] "javac" "compile"]

  :cljsbuild {:test-commands {"node" ["node" :node-runner "target/testable.js"]}
              :builds {:test-js
                       {:source-paths ["target/classes" "target/test-classes"]
                        :compiler {:output-to "target/testable.js"
                                   :optimizations :advanced
                                   :pretty-print true
                                   :libs [""]}}
                       :release-js
                       {:source-paths ["target/classes"]
                        :compiler {:output-dir "target/release"
                                   :output-to "target/release/revue.js"
                                   :source-map "target/release/revue.map"
                                   :optimizations :advanced
                                   :pretty-print false
                                   :libs [""]}}}}

  :profiles {:dev {:plugins [[com.cemerick/austin "0.2.0-SNAPSHOT"]
                             [com.cemerick/piggieback "0.1.4-SNAPSHOT"]
                             [com.cemerick/clojurescript.test "0.3.1"
                              :exclusions [com.google.guava/guava]]
                             [org.clojars.cemerick/cljx "0.5.0-SNAPSHOT"]
                             [lein-cljsbuild "1.0.4-SNAPSHOT"]]
                   :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
                   :dependencies [[com.cemerick/double-check "0.5.8-SNAPSHOT"]]
                   ;; :injections [(require '[weasel.repl :as repl])
                   ;;              (defn start-weasel []
                   ;;                (if-not (repl/alive?)
                   ;;                  (repl/connect "ws://localhost:9001")))]
                   :aliases {"cleantest" ["do" "clean," "cljx" "once," "test,"
                                          "cljsbuild" "test"]
                             "jtest" ["do" "cljx" "once," "test"]
                             "jstest" ["do" "cljx" "once," "cljsbuild" "test"]
                             "deploy!" ["do" "clean," "cljx" "once," "deploy" "clojars"]}}})

(defproject revue "0.0.1"
  :description "REVUE: REVersible User Experiences"

  :url "https://github.com/hoelzl/Revue"

  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :pom-addition [:developers [:developer
                              [:id "mhoelzl"]
                              [:name "Matthias Hoelzl"]
                              [:url "https://github.com/hoelzl"]
                              [:email "tc@xantira.com"]]]
  :repositories [["local" "file:///Users/tc/.m2/repository"]]

  :exclusions [org.clojure/clojure org.clojure/clojurescript]
  :jar-exclusions [#"\.cljx|\.swp|\.swo|\.DS_Store"]
  :source-paths ["src/cljx"]
  :test-paths ["target/test-classes"]
  :dependencies [[org.clojure/clojure "1.7.0-alpha2"]
                 [org.clojure/clojurescript "0.0-2371"]
                 [org.clojure/tools.reader "0.8.9"]
                 ;;[weasel "0.4.0-SNAPSHOT"]
                 ]

  :cljx {:builds [{:source-paths ["src/cljx"]
                   :output-path "target/classes"
                   :rules :clj}

                  {:source-paths ["src/cljx"]
                   :output-path "target/classes"
                   :rules :cljs}

                  {:source-paths ["test/cljx"]
                   :output-path "target/test-classes"
                   :rules :clj}

                  {:source-paths ["test/cljx"]
                   :output-path "target/test-classes"
                   :rules :cljs}]}

  :prep-tasks [["cljx" "once"] "javac" "compile"]

  :cljsbuild {:test-commands {"node" ["node" :node-runner "target/testable.js"]}
              :builds {:test-js
                       {:source-paths ["target/classes" "target/test-classes"]
                        :compiler {:output-to "target/testable.js"
                                   :optimizations :advanced
                                   :pretty-print true
                                   :libs [""]}}
                       :release-js
                       {:source-paths ["target/classes"]
                        :compiler {:output-dir "target/release"
                                   :output-to "target/release/revue.js"
                                   :source-map "target/release/revue.map"
                                   :optimizations :advanced
                                   :pretty-print false
                                   :libs [""]}}}}

  :profiles {:dev {:plugins [[com.cemerick/austin "0.2.0-SNAPSHOT"]
                             [com.cemerick/piggieback "0.1.4-SNAPSHOT"]
                             [com.cemerick/clojurescript.test "0.3.1"
                              :exclusions [com.google.guava/guava]]
                             [org.clojars.cemerick/cljx "0.5.0-SNAPSHOT"]
                             [lein-cljsbuild "1.0.4-SNAPSHOT"]]
                   :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
                   :dependencies [[com.cemerick/double-check "0.5.8-SNAPSHOT"]]
                   ;; :injections [(require '[weasel.repl :as repl])
                   ;;              (defn start-weasel []
                   ;;                (if-not (repl/alive?)
                   ;;                  (repl/connect "ws://localhost:9001")))]
                   :aliases {"cleantest" ["do" "clean," "cljx" "once," "test,"
                                          "cljsbuild" "test"]
                             "jtest" ["do" "cljx" "once," "test"]
                             "jstest" ["do" "cljx" "once," "cljsbuild" "test"]
                             "deploy" ["do" "clean," "cljx" "once," "deploy" "clojars"]}}})

Rename deploy! target to deploy

Rename deploy! target to deploy