Define a shape spec.

Define a shape spec.

--- frontend/src/uxbox/main/data/shapes.cljs
+++ frontend/src/uxbox/main/data/shapes.cljs
@@ -24,218 +24,6 @@
             [uxbox.util.rlocks :as rlocks]
             [uxbox.util.uuid :as uuid]
             [uxbox.util.workers :as uw]))
-
-(s/def ::x1 number?)
-(s/def ::y1 number?)
-(s/def ::x2 number?)
-(s/def ::y2 number?)
-(s/def ::type keyword?)
-
-(s/def ::rect-shape (s/keys :req-un [::x1 ::y1 ::x2 ::y2 ::type]))
-
-;; --- Shapes CRUD
-
-(deftype AddShape [data]
-  udp/IPageUpdate
-  ptk/UpdateEvent
-  (update [_ state]
-    (let [shape (geom/setup-proportions data)
-          page (l/focus ul/selected-page state)]
-      (impl/assoc-shape-to-page state shape page))))
-
-(defn add-shape
-  [data]
-  (AddShape. data))
-
-(defn delete-shape
-  "Remove the shape using its id."
-  [id]
-  (reify
-    udp/IPageUpdate
-    ptk/UpdateEvent
-    (update [_ state]
-      (let [shape (get-in state [:shapes id])]
-        (impl/dissoc-shape state shape)))))
-
-(defn update-shape
-  "Just updates in place the shape."
-  [{:keys [id] :as shape}]
-  (reify
-    udp/IPageUpdate
-    ptk/UpdateEvent
-    (update [_ state]
-      (update-in state [:shapes id] merge shape))))
-
-;; --- Shape Transformations
-
-(declare align-point)
-
-(def ^:private canvas-coords
-  (gpt/point c/canvas-start-x
-             c/canvas-start-y))
-
-(declare apply-temporal-displacement)
-
-(defn initial-align-shape
-  [id]
-  (reify
-    ptk/WatchEvent
-    (watch [_ state s]
-      (let [{:keys [x1 y1] :as shape} (->> (get-in state [:shapes id])
-                                           (geom/shape->rect-shape state))
-            point1 (gpt/point x1 y1)
-            point2 (gpt/add point1 canvas-coords)]
-        (->> (align-point point2)
-             (rx/map #(gpt/subtract % canvas-coords))
-             (rx/map (fn [{:keys [x y] :as pt}]
-                       (apply-temporal-displacement id (gpt/subtract pt point1)))))))))
-
-(defn update-rotation
-  [sid rotation]
-  {:pre [(number? rotation)
-         (>= rotation 0)
-         (>= 360 rotation)]}
-  (reify
-    udp/IPageUpdate
-    ptk/UpdateEvent
-    (update [_ state]
-      (update-in state [:shapes sid]
-                 geom/rotate rotation))))
-
-(defn update-size
-  "A helper event just for update the position
-  of the shape using the width and height attrs
-  instread final point of coordinates."
-  [sid opts]
-  {:pre [(uuid? sid)]}
-  (reify
-    udp/IPageUpdate
-    ptk/UpdateEvent
-    (update [_ state]
-      (update-in state [:shapes sid] geom/resize-dim opts))))
-
-;; --- Apply Temporal Displacement
-
-(deftype ApplyTemporalDisplacement [id delta]
-  udp/IPageUpdate
-  ptk/UpdateEvent
-  (update [_ state]
-    (let [shape (get-in state [:shapes id])
-          displ (:tmp-displacement shape (gpt/point 0 0))
-          delta (gpt/add displ delta)]
-      (assoc-in state [:shapes id :tmp-displacement] delta))))
-
-(defn apply-temporal-displacement
-  [id pt]
-  {:pre [(uuid? id) (gpt/point? pt)]}
-  (ApplyTemporalDisplacement. id pt))
-
-;; --- Apply Displacement
-
-;; TODO: move to shapes-impl ns.
-
-(deftype ApplyDisplacement [id]
-  udp/IPageUpdate
-  ptk/UpdateEvent
-  (update [_ state]
-    (let [{:keys [tmp-displacement type] :as shape} (get-in state [:shapes id])
-          xfmt  (gmt/translate-matrix tmp-displacement)]
-
-      (if (= type :group)
-        (letfn [(update-item [state id]
-                  (let [{:keys [type items] :as shape} (get-in state [:shapes id])]
-                    (if (= type :group)
-                      (reduce update-item state items)
-                      (update-in state [:shapes id]
-                                 (fn [shape]
-                                   (as-> (dissoc shape :tmp-displacement) $
-                                     (geom/transform state $ xfmt)))))))]
-          (-> (reduce update-item state (:items shape))
-              (update-in [:shapes id] dissoc :tmp-displacement)))
-
-        (update-in state [:shapes id] (fn [shape]
-                                        (as-> (dissoc shape :tmp-displacement) $
-                                          (geom/transform state $ xfmt))))))))
-
-(defn apply-displacement
-  [id]
-  {:pre [(uuid? id)]}
-  (ApplyDisplacement. id))
-
-;; --- Apply Temporal Resize Matrix
-
-(deftype ApplyTemporalResizeMatrix [id mx]
-  udp/IPageUpdate
-  ptk/UpdateEvent
-  (update [_ state]
-    (assoc-in state [:shapes id :tmp-resize-xform] mx)))
-
-(defn apply-temporal-resize-matrix
-  "Attach temporal resize matrix transformation to the shape."
-  [id mx]
-  (ApplyTemporalResizeMatrix. id mx))
-
-;; --- Apply Resize Matrix
-
-(declare apply-resize-matrix)
-
-(deftype ApplyResizeMatrix [id]
-  udp/IPageUpdate
-  ptk/UpdateEvent
-  (update [_ state]
-    (let [{:keys [type tmp-resize-xform]
-           :or {tmp-resize-xform (gmt/matrix)}
-           :as shape} (get-in state [:shapes id])]
-      (if (= type :group)
-        (letfn [(update-item [state id]
-                  (let [{:keys [type items] :as shape} (get-in state [:shapes id])]
-                    (if (= type :group)
-                      (reduce update-item state items)
-                      (update-in state [:shapes id]
-                                 (fn [shape]
-                                   (as-> (dissoc shape :tmp-resize-xform) $
-                                     (geom/transform state $ tmp-resize-xform)))))))]
-          (-> (reduce update-item state (:items shape))
-              (update-in [:shapes id] dissoc :tmp-resize-xform)))
-        (update-in state [:shapes id] (fn [shape]
-                                        (as-> (dissoc shape :tmp-resize-xform) $
-                                          (geom/transform state $ tmp-resize-xform))))))))
-
-(defn apply-resize-matrix
-  "Apply definitivelly the resize matrix transformation to the shape."
-  [id]
-  {:pre [(uuid? id)]}
-  (ApplyResizeMatrix. id))
-
-(defn update-position
-  "Update the start position coordenate of the shape."
-  [sid {:keys [x y] :as opts}]
-  (reify
-    ptk/UpdateEvent
-    (update [_ state]
-      (update-in state [:shapes sid] geom/absolute-move opts))))
-
-(defn update-text
-  [sid {:keys [content]}]
-  {:pre [(string? content)]}
-  (reify
-    udp/IPageUpdate
-    ptk/UpdateEvent
-    (update [_ state]
-      (assoc-in state [:shapes sid :content] content))))
-
-;; --- Update Shape Attrs
-
-(declare UpdateAttrs)
-
-(deftype UpdateAttrs [id attrs]
-  ptk/WatchEvent
-  (watch [_ state stream]
-    (println "update-attrs" id attrs)
-    (let [{:keys [type] :as shape} (get-in state [:shapes id])]
-      (if (= type :group)
-        (rx/from-coll (map #(UpdateAttrs. % attrs) (:items shape)))
-        (rx/of #(update-in % [:shapes id] merge attrs))))))

 (s/def ::fill-color us/color?)
 (s/def ::fill-opacity number?)
@@ -258,8 +46,12 @@
 (s/def ::hidden boolean?)
 (s/def ::blocked boolean?)
 (s/def ::locked boolean?)
-
-(s/def ::shape-attrs
+(s/def ::x1 number?)
+(s/def ::y1 number?)
+(s/def ::x2 number?)
+(s/def ::y2 number?)
+
+(s/def ::attributes
   (s/keys :opt-un [::fill-color
                    ::fill-opacity
                    ::line-height
@@ -274,6 +66,8 @@
                    ::stroke-color
                    ::stroke-opacity
                    ::rx ::ry
+                   ::x1 ::x2
+                   ::y1 ::y2
                    ::proportion-lock
                    ::proportion
                    ::collapsed
@@ -281,10 +75,229 @@
                    ::blocked
                    ::locked]))

+(s/def ::id uuid?)
+(s/def ::page uuid?)
+(s/def ::type #{:rect
+                :group
+                :path
+                :circle
+                :image
+                :text})
+
+(s/def ::shape
+  (s/merge (s/keys ::req-un [::id ::page ::type]) ::attributes))
+
+(s/def ::rect-like-shape
+  (s/keys :req-un [::x1 ::y1 ::x2 ::y2 ::type]))
+
+;; --- Shapes CRUD
+
+(deftype AddShape [data]
+  udp/IPageUpdate
+  ptk/UpdateEvent
+  (update [_ state]
+    (let [shape (geom/setup-proportions data)
+          page (l/focus ul/selected-page state)]
+      (impl/assoc-shape-to-page state shape page))))
+
+(defn add-shape
+  [data]
+  (AddShape. data))
+
+(defn delete-shape
+  "Remove the shape using its id."
+  [id]
+  (reify
+    udp/IPageUpdate
+    ptk/UpdateEvent
+    (update [_ state]
+      (let [shape (get-in state [:shapes id])]
+        (impl/dissoc-shape state shape)))))
+
+(defn update-shape
+  "Just updates in place the shape."
+  [{:keys [id] :as shape}]
+  (reify
+    udp/IPageUpdate
+    ptk/UpdateEvent
+    (update [_ state]
+      (update-in state [:shapes id] merge shape))))
+
+;; --- Shape Transformations
+
+(declare align-point)
+
+(def ^:private canvas-coords
+  (gpt/point c/canvas-start-x
+             c/canvas-start-y))
+
+(declare apply-temporal-displacement)
+
+(defn initial-align-shape
+  [id]
+  (reify
+    ptk/WatchEvent
+    (watch [_ state s]
+      (let [{:keys [x1 y1] :as shape} (->> (get-in state [:shapes id])
+                                           (geom/shape->rect-shape state))
+            point1 (gpt/point x1 y1)
+            point2 (gpt/add point1 canvas-coords)]
+        (->> (align-point point2)
+             (rx/map #(gpt/subtract % canvas-coords))
+             (rx/map (fn [{:keys [x y] :as pt}]
+                       (apply-temporal-displacement id (gpt/subtract pt point1)))))))))
+
+(defn update-rotation
+  [sid rotation]
+  {:pre [(number? rotation)
+         (>= rotation 0)
+         (>= 360 rotation)]}
+  (reify
+    udp/IPageUpdate
+    ptk/UpdateEvent
+    (update [_ state]
+      (update-in state [:shapes sid]
+                 geom/rotate rotation))))
+
+(defn update-size
+  "A helper event just for update the position
+  of the shape using the width and height attrs
+  instread final point of coordinates."
+  [sid opts]
+  {:pre [(uuid? sid)]}
+  (reify
+    udp/IPageUpdate
+    ptk/UpdateEvent
+    (update [_ state]
+      (update-in state [:shapes sid] geom/resize-dim opts))))
+
+;; --- Apply Temporal Displacement
+
+(deftype ApplyTemporalDisplacement [id delta]
+  udp/IPageUpdate
+  ptk/UpdateEvent
+  (update [_ state]
+    (let [shape (get-in state [:shapes id])
+          displ (:tmp-displacement shape (gpt/point 0 0))
+          delta (gpt/add displ delta)]
+      (assoc-in state [:shapes id :tmp-displacement] delta))))
+
+(defn apply-temporal-displacement
+  [id pt]
+  {:pre [(uuid? id) (gpt/point? pt)]}
+  (ApplyTemporalDisplacement. id pt))
+
+;; --- Apply Displacement
+
+;; TODO: move to shapes-impl ns.
+
+(deftype ApplyDisplacement [id]
+  udp/IPageUpdate
+  ptk/UpdateEvent
+  (update [_ state]
+    (let [{:keys [tmp-displacement type] :as shape} (get-in state [:shapes id])
+          xfmt  (gmt/translate-matrix tmp-displacement)]
+
+      (if (= type :group)
+        (letfn [(update-item [state id]
+                  (let [{:keys [type items] :as shape} (get-in state [:shapes id])]
+                    (if (= type :group)
+                      (reduce update-item state items)
+                      (update-in state [:shapes id]
+                                 (fn [shape]
+                                   (as-> (dissoc shape :tmp-displacement) $
+                                     (geom/transform state $ xfmt)))))))]
+          (-> (reduce update-item state (:items shape))
+              (update-in [:shapes id] dissoc :tmp-displacement)))
+
+        (update-in state [:shapes id] (fn [shape]
+                                        (as-> (dissoc shape :tmp-displacement) $
+                                          (geom/transform state $ xfmt))))))))
+
+(defn apply-displacement
+  [id]
+  {:pre [(uuid? id)]}
+  (ApplyDisplacement. id))
+
+;; --- Apply Temporal Resize Matrix
+
+(deftype ApplyTemporalResizeMatrix [id mx]
+  udp/IPageUpdate
+  ptk/UpdateEvent
+  (update [_ state]
+    (assoc-in state [:shapes id :tmp-resize-xform] mx)))
+
+(defn apply-temporal-resize-matrix
+  "Attach temporal resize matrix transformation to the shape."
+  [id mx]
+  (ApplyTemporalResizeMatrix. id mx))
+
+;; --- Apply Resize Matrix
+
+(declare apply-resize-matrix)
+
+(deftype ApplyResizeMatrix [id]
+  udp/IPageUpdate
+  ptk/UpdateEvent
+  (update [_ state]
+    (let [{:keys [type tmp-resize-xform]
+           :or {tmp-resize-xform (gmt/matrix)}
+           :as shape} (get-in state [:shapes id])]
+      (if (= type :group)
+        (letfn [(update-item [state id]
+                  (let [{:keys [type items] :as shape} (get-in state [:shapes id])]
+                    (if (= type :group)
+                      (reduce update-item state items)
+                      (update-in state [:shapes id]
+                                 (fn [shape]
+                                   (as-> (dissoc shape :tmp-resize-xform) $
+                                     (geom/transform state $ tmp-resize-xform)))))))]
+          (-> (reduce update-item state (:items shape))
+              (update-in [:shapes id] dissoc :tmp-resize-xform)))
+        (update-in state [:shapes id] (fn [shape]
+                                        (as-> (dissoc shape :tmp-resize-xform) $
+                                          (geom/transform state $ tmp-resize-xform))))))))
+
+(defn apply-resize-matrix
+  "Apply definitivelly the resize matrix transformation to the shape."
+  [id]
+  {:pre [(uuid? id)]}
+  (ApplyResizeMatrix. id))
+
+(defn update-position
+  "Update the start position coordenate of the shape."
+  [sid {:keys [x y] :as opts}]
+  (reify
+    ptk/UpdateEvent
+    (update [_ state]
+      (update-in state [:shapes sid] geom/absolute-move opts))))
+
+(defn update-text
+  [sid {:keys [content]}]
+  {:pre [(string? content)]}
+  (reify
+    udp/IPageUpdate
+    ptk/UpdateEvent
+    (update [_ state]
+      (assoc-in state [:shapes sid :content] content))))
+
+;; --- Update Shape Attrs
+
+(declare UpdateAttrs)
+
+(deftype UpdateAttrs [id attrs]
+  ptk/WatchEvent
+  (watch [_ state stream]
+    (println "update-attrs" id attrs)
+    (let [{:keys [type] :as shape} (get-in state [:shapes id])]
+      (if (= type :group)
+        (rx/from-coll (map #(UpdateAttrs. % attrs) (:items shape)))
+        (rx/of #(update-in % [:shapes id] merge attrs))))))
+
 (defn update-attrs
   [id attrs]
-  {:pre [(uuid? id) (us/valid? ::shape-attrs attrs)]}
-  (let [atts (us/extract attrs ::shape-attrs)]
+  {:pre [(uuid? id) (us/valid? ::attributes attrs)]}
+  (let [atts (us/extract attrs ::attributes)]
     (UpdateAttrs. id attrs)))

 ;; --- Shape Proportions
@@ -484,7 +497,7 @@
 (defn select-shapes-by-selrect
   "Select shapes that matches the select rect."
   [selrect]
-  {:pre [(us/valid? ::rect-shape selrect)]}
+  {:pre [(us/valid? ::rect-like-shape selrect)]}
   (SelectShapesBySelrect. selrect))

 ;; --- Update Interaction


Tests for functions existence from the utils module

--- test/zg/utils_test.clj
+++ test/zg/utils_test.clj
@@ -27,3 +27,44 @@
 ; Tests for various functions existence
 ;

+(deftest test-third-existence
+    "Check that the zg.utils/third definition exists."
+    (testing "if the zg.utils/third definition exists."
+        (is (callable? 'zg.utils/third))))
+
+
+(deftest test-substring-existence
+    "Check that the zg.utils/substring definition exists."
+    (testing "if the zg.utils/substring definition exists."
+        (is (callable? 'zg.utils/substring))))
+
+
+(deftest test-startsWith-existence
+    "Check that the zg.utils/startsWith definition exists."
+    (testing "if the zg.utils/startsWith definition exists."
+        (is (callable? 'zg.utils/startsWith))))
+
+
+(deftest test-endsWith-existence
+    "Check that the zg.utils/endsWith definition exists."
+    (testing "if the zg.utils/endsWith definition exists."
+        (is (callable? 'zg.utils/endsWith))))
+
+
+(deftest test-contains-existence
+    "Check that the zg.utils/contains definition exists."
+    (testing "if the zg.utils/contains definition exists."
+        (is (callable? 'zg.utils/contains))))
+
+
+(deftest test-replaceAll-existence
+    "Check that the zg.utils/replaceAll definition exists."
+    (testing "if the zg.utils/replaceAll definition exists."
+        (is (callable? 'zg.utils/replaceAll))))
+
+
+(deftest test-get-exception-message-existence
+    "Check that the zg.utils/get-exception-message definition exists."
+    (testing "if the zg.utils/get-exception-message definition exists."
+        (is (callable? 'zg.utils/get-exception-message))))
+


fixed n in test

fixed n in test

--- test/meo/client_store_search_test.cljc
+++ test/meo/client_store_search_test.cljc
@@ -47,7 +47,7 @@
                                     :put-fn        (fn [_])
                                     :msg-payload   {:query-id :query-1}})
           updated-query (second send-to-self)
-          expected-query (assoc-in (update-in st/open-tasks-query [:n] + 50) [:incremental] true)]
+          expected-query (assoc-in (update-in st/open-tasks-query [:n] + 25) [:incremental] true)]
       (testing
         "send properly updated query, with increased number of results"
         (is (= updated-query


(MAINT) Close datasource in max connection jdbc pool tests

Previously, the max connections jdbc pool-construction tests did not
close the connection pool data source before falling out of scope.
Depending upon timing, this could cause the tests to fail on
attempting to drop temp databases which are still busy being used
by the connection pool.

This commit wraps usage of the data source in each of the max
connections tests with `with-open` calls, allowing the connection pool
to be closed off before any calls to drop the temporary databases occur
(and, therefore, for the tests to complete successfully).

--- test/puppetlabs/puppetdb/jdbc_test.clj
+++ test/puppetlabs/puppetdb/jdbc_test.clj
@@ -54,19 +54,21 @@
   (testing "max connections setting defaults to 25"
     (call-with-antonym-test-database
       (fn []
-        (let [pool (-> *db*
-                       defaulted-read-db-config
-                       subject/pooled-datasource)]
-          (is (= 25 (.getMaximumPoolSize (:datasource pool))))))))
+        (with-open [data-source (-> *db*
+                                    defaulted-read-db-config
+                                    subject/pooled-datasource
+                                    :datasource)]
+          (is (= 25 (.getMaximumPoolSize data-source)))))))

   (testing "max connections setting takes effect"
     (call-with-antonym-test-database
       (fn []
-        (let [pool (-> *db*
-                       defaulted-read-db-config
-                       (assoc :maximum-pool-size 5)
-                       subject/pooled-datasource)]
-          (is (= 5 (.getMaximumPoolSize (:datasource pool)))))))))
+        (with-open [data-source (-> *db*
+                                    defaulted-read-db-config
+                                    (assoc :maximum-pool-size 5)
+                                    subject/pooled-datasource
+                                    :datasource)]
+          (is (= 5 (.getMaximumPoolSize data-source))))))))

 (deftest-antonyms query-to-vec
   (testing "query string only"


Handle 404 errors in site routes

Handle 404 errors in site routes

--- mtg-pairings-server/src/clj/mtg_pairings_server/middleware/error.clj
+++ mtg-pairings-server/src/clj/mtg_pairings_server/middleware/error.clj
@@ -4,14 +4,15 @@
             [cheshire.core :as json]
             [schema.utils :as su]
             [taoensso.timbre :as log]
-            [mtg-pairings-server.util.sql :as sql-util]))
+            [mtg-pairings-server.util.sql :as sql-util])
+  (:import (clojure.lang ExceptionInfo)))

 (defn error-response [^Exception e]
-  {:status 500
-   :body   (cond-> {:message (.getMessage e)
-                    :type    (.getName (class e))}
-             (env :dev) (assoc :data (ex-data e))
-             true (json/generate-string))
+  {:status  500
+   :body    (cond-> {:message (.getMessage e)
+                     :type    (.getName (class e))}
+              (env :dev) (assoc :data (ex-data e))
+              true (json/generate-string))
    :headers {:content-type "application/json"}})

 (defn request-validation-error-handler [e data req]
@@ -26,11 +27,21 @@
       (log/error e "SQL assertion error")
       (error-response e))))

+(defn handle-error [e]
+  (log/error e "Unhandled exception")
+  (error-response e))
+
 (defn wrap-errors
   [handler]
   (fn [request]
     (try
       (handler request)
+      (catch ExceptionInfo e
+        (let [{:keys [type sql-util/found?]} (ex-data e)]
+          (if (and (= type ::sql-util/assertion)
+                   (not found?))
+            {:status 404
+             :body   "Not found"}
+            (handle-error e))))
       (catch Exception e
-        (log/error e "Unhandled exception")
-        (error-response e)))))
+        (handle-error e)))))


test cases

test cases

--- cloc-web/test/cloc_web/core_test.clj
+++ cloc-web/test/cloc_web/core_test.clj
@@ -6,7 +6,8 @@
             [clj-http.client :as client]
             [cheshire.core :as cheshire]
             [cloc-web.auth :refer [jwt-token]]
-            [clj-time.core :refer [days]])
+            [clj-time.core :refer [days]]
+            [clojure.xml :as xml])
   (:import [java.io Closeable]))

 (defonce ^:const port 50002)
@@ -30,6 +31,9 @@
   (f)
   (-> (r/table "users")
       r/delete
+      (r/run @db-conn))
+  (-> (r/table "result")
+      r/delete
       (r/run @db-conn)))

 (defmacro scenario [aside & body] `(do ~@body))
@@ -159,3 +163,24 @@
             (= 200)
             (and (= "SUM" (get-display-lang "github/0of/target")))
             is)))))
+
+(deftest get-svg-non-existent-user
+  (scenario "register repo and insert record"
+    (-> (r/table "users")
+        (r/insert {:id "github/0of/target"
+                   :user "0of"
+                   :filter "*"
+                   :lang "SUM"})
+        (r/run @db-conn))
+
+    (-> (r/table "result")
+        (r/insert {"Clojure" {"code" 1891
+                              "lang" "Clojure"
+                              "total" 2394}
+                   "code" 1891
+                   "id" "0of/target/master"
+                   "total" 2394})
+        (r/run @db-conn)))
+
+  (let [svg-doc (xml/parse (:body (client/get (str url "/0of/target/master/svg_badge") {:as :stream})))]
+    (is (= "2394" (get-in svg-doc [:content 1 :content 1 :content 0])))))


+TODO

+TODO

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -23,8 +23,8 @@
    #?(:cljs [babel.logjs :as log])
    [dag_unify.core :refer (copy dissoc-paths fail? get-in ref? strip-refs unify)]))

-
-;; TODO: move all patterns into here eventually.
+;; TODO: move all patterns into here eventually
+;;   (preposition-plus-article, adjectives/patterns,etc).
 (defonce patterns
   (map :g
        (misc/compile-morphology)))


fix bug when cloning workspace with no auth domain (#770)

* fix bug when cloning workspace with no auth domain

--- src/cljs/main/broadfcui/page/workspace/summary/workspace_cloner.cljs
+++ src/cljs/main/broadfcui/page/workspace/summary/workspace_cloner.cljs
@@ -82,9 +82,12 @@
              attributes (if (or (:description props) (not (clojure.string/blank? desc)))
                           {:description desc}
                           {})
+             selected-auth-domain-index (int (:selected-auth-domain @state))
              auth-domain (if (:auth-domain props)
                            {:authorizationDomain {:membersGroupName (:auth-domain props)}}
-                           {:authorizationDomain {:membersGroupName (nth (:groups @state) (int (:selected-auth-domain @state)))}})]
+                           (when (> selected-auth-domain-index 0)
+                             {:authorizationDomain
+                              {:membersGroupName (nth (:groups @state) selected-auth-domain-index)}}))]
          (swap! state assoc :working? true :validation-error nil :error nil)
          (endpoints/call-ajax-orch
           {:endpoint (endpoints/clone-workspace (:workspace-id props))


dsets.clj: remember potential starts for better numbering

--- clojure/org/gavrog/clojure/dsets.clj
+++ clojure/org/gavrog/clojure/dsets.clj
@@ -8,51 +8,59 @@
             (for [j (indices ds) :when (or (< j (dec i)) (> j (inc i)))]
               (orbit ds [i j] D))))

-(defn- better-start? [ds D]
+(defn- compare-with-start [ds D]
   (loop [o2n {D 1}
          n2o {1 D}
          n 1
          free (into (sorted-set) (for [i (indices ds)] [i 1]))]
     (if (empty? free)
-      false
+      0
       (let [[i D] (first free)
             oDi (s ds i (n2o D))]
         (if (nil? oDi)
-          false
+          0
           (let [Di (or (o2n oDi) (inc n))
                 d (- Di (s ds i D))
                 free (if (<= Di n)
                        free
                        (into free (for [j (indices ds)] [j Di])))]
-            (cond (neg? d) true
-                  (pos? d) false
+            (cond (nil? (s ds i D)) 0
+                  (neg? d) -1
+                  (pos? d) 1
                   :else (recur (assoc o2n oDi Di)
                                (assoc n2o Di oDi)
                                (max n Di)
                                (disj free [i D] [i Di])))))))))

-(defn- best? [ds]
-  (not-any? (partial better-start? ds) (rest (elements ds))))
+(defn- best? [ds alt-starts]
+  (let [results (into {} (for [D alt-starts] [D (compare-with-start ds D)]))]
+    [(not-any? #(neg? (results %)) alt-starts)
+     (apply disj alt-starts (filter #(pos? (results %)) alt-starts))]))

 (defn dsets [dim max-size]
   (let [idcs (range (inc dim))
-        still-good? (fn [ds i D]
-                      (and (orbits-okay? ds i D)
-                           (or (-> ds size (mod 3) (> 0)) (best? ds))))]
+        still-good? orbits-okay?]
     (make-backtracker
       {:root [(dsymbol (str "1 " dim))
-              (into (sorted-set) (for [i idcs] [i 1]))]
-       :extract (fn [[ds free]]
-                  (when (and (empty? free) (best? ds)) (canonical ds)))
-       :children (fn [[ds free]]
+              (into (sorted-set) (for [i idcs] [i 1]))
+              #{}]
+       :extract (fn [[ds free alt-starts]]
+                  (when (and (empty? free) (first (best? ds alt-starts)))
+                    (canonical ds)))
+       :children (fn [[ds free alt-starts]]
                    (when (seq free)
                      (let [[i D] (first free)
                            adding (for [[j E] free :when (= i j)] [E free])
                            extending (when (< (size ds) max-size)
                                        (let [E (inc (size ds))]
                                          [[E (into free (for [j idcs]
-                                                          [j E]))]]))]
+                                                          [j E]))]]))
+                           alt-starts (if (seq extending)
+                                        (conj alt-starts (inc (size ds)))
+                                        alt-starts)]
                        (for [[E free] (concat adding extending)
                              :let [ds (glue ds i D E)]
-                             :when (still-good? ds i D)]
-                         [ds (disj free [i D] [i E])]))))})))
+                             :when (still-good? ds i D)
+                             :let [[okay? alt-starts] (best? ds alt-starts)]
+                             :when okay?]
+                         [ds (disj free [i D] [i E]) alt-starts]))))})))


Add a string->color utility function

Add a string->color utility function

--- src/chat/client/views/helpers.cljs
+++ src/chat/client/views/helpers.cljs
@@ -15,14 +15,26 @@
         idx (.indexOf s suffix)]
     (and (not= -1 idx) (= idx pos))))

-(defn id->color [id]
-  ; normalized is approximately evenly distributed between 0 and 1
-  (let [normalized (-> id
-                       str
-                       (.substring 33 36)
-                       (js/parseInt 16)
-                       (/ 4096))]
-    (str "hsl(" (* 360 normalized) ",70%,35%)")))
+(defn decimal->color [decimal]
+ (str "hsl(" (int (* 360 (mod decimal 1))) ",71%,35%)") )
+
+(defn string->color [string]
+  (-> string
+      char-array
+      (->> (map int)
+           (apply +))
+      (/ 213)
+      decimal->color))
+
+(defn id->color [uuid]
+  (-> uuid
+      str
+      (.substring 33 36)
+      (js/parseInt 16)
+      (/ 4096)
+      ; at this point, we have a decimal between 0 and 1
+      ; approximately evenly distributed
+      decimal->color))

 (defn format-date
   "Turn a Date object into a nicely formatted string"


Adjust 401 for browser

Adjust 401 for browser

--- src/cider_ci/auth/anti_forgery.clj
+++ src/cider_ci/auth/anti_forgery.clj
@@ -40,9 +40,10 @@
         (= x-csrf-header-token token)))))

 (def response-401
-  (let [msg "Mutating requests must either authenticate
-            with basic authentication or provide a valid
-            X-CSRF-TOKEN header!"]
+  (let [msg (str "Basic realm=\"Cider-CI; "
+                 "mutating requests must either authenticate "
+                 "with basic authentication or provide a valid "
+                 "X-CSRF-TOKEN header!")]
     response-401 {:status 401
                   :body msg
                   :headers {"WWW-Authenticate" msg}}))
@@ -65,6 +66,8 @@
   (fn [request]
     (process request handler)))

+;{"git_url": "https://github.com/cider-ci/cider-ci_deploy.git", "name": "CI Deploy"}
+
 ;#### debug ###################################################################
 ;(logging-config/set-logger! :level :debug)
 ;(logging-config/set-logger! :level :info)


Bump the timeout, some builds were hitting it

--- src/circle/backend/action/bash.clj
+++ src/circle/backend/action/bash.clj
@@ -66,7 +66,7 @@
   (let [name (or name (action-name command))
         bash-command (emit-bash command environment pwd)
         relative-timeout (or relative-timeout (time/minutes 20))
-        absolute-timeout (or absolute-timeout (time/hours 1))]
+        absolute-timeout (or absolute-timeout (time/hours 2))]
     (action/action :name name
                    :type type
                    :command (str command)


fixing indentation in nametags, penitance for a faulty terminal

--- src/clj/ku_expo/utils/nametags.clj
+++ src/clj/ku_expo/utils/nametags.clj
@@ -58,8 +58,8 @@
      [:spacer]]))

 (def listing-template
-(pdf/template
-[:paragraph
+  (pdf/template
+    [:paragraph
      [:chunk {:style :bold} "Student: "] $name "\n"
      [:chunk {:style :bold} "Sponsor: "] $teacher_name "\n"
      [:chunk {:style :bold} "Division: "] $division "\n"
@@ -68,38 +68,38 @@
      [:spacer]]))

 (defn get-listings
-[division]
-(for [[teacher group] (sort-by #(key %) (group-by #(:teacher_name %) (stringify (map collapse-rows (get-scheduled-students division)))))]
-[[:table
-{:num-cols 2
-:width 100
-:widths [48 48]
-:border false
-:cell-border false}
-(for [student (listing-template (sort-by #(:name %) group))]
-[:cell {:align :left} student])]
-[:pagebreak]]))
+  [division]
+  (for [[teacher group] (sort-by #(key %) (group-by #(:teacher_name %) (stringify (map collapse-rows (get-scheduled-students division)))))]
+    [[:table
+      {:num-cols 2
+       :width 100
+       :widths [48 48]
+       :border false
+       :cell-border false}
+      (for [student (listing-template (sort-by #(:name %) group))]
+        [:cell {:align :left} student])]
+     [:pagebreak]]))

 (defn make-listings
-[division name]
-(let [tables (get-listings division)] (pdf/pdf (conj tables (first tables)) name)))
+  [division name]
+  (let [tables (get-listings division)] (pdf/pdf (conj tables (first tables)) name)))

 (defn get-tables
-[division]
-(for [group (partition-all 8 (student-template (sort-by :teacher_name (stringify (map collapse-rows (get-scheduled-students division))))))]
-       [[:table
-        {:num-cols 2
-        :width 100
-        :widths [48 48]
-        :border false
-        :cell-border false}
-       (for [student group]
-         [:cell {:align :left} student])]
-       [:pagebreak]]))
+  [division]
+  (for [group (partition-all 8 (student-template (sort-by :teacher_name (stringify (map collapse-rows (get-scheduled-students division))))))]
+    [[:table
+      {:num-cols 2
+       :width 100
+       :widths [48 48]
+       :border false
+       :cell-border false}
+      (for [student group]
+        [:cell {:align :left} student])]
+     [:pagebreak]]))

 (defn make-nametags
   [division name]
-(let [tables (get-tables division)]
-  (pdf/pdf (conj tables (first tables))
-    name)))
+  (let [tables (get-tables division)]
+    (pdf/pdf (conj tables (first tables))
+             name)))


move selected tab into player, yay abstraction

--- src/cljc/western_music/lib/ui.cljc
+++ src/cljc/western_music/lib/ui.cljc
@@ -14,10 +14,7 @@
 (s/def :data/ui
   (s/keys :req [:ui/player
                 :ui/nation
-                :ui/composer
-                :ui/selected-tab]))
-
-(s/def :ui/selected-tab #{:selection :queue})
+                :ui/composer]))

 (s/def :ui/nation
   (s/keys :req [:ui.nation/mouse-on
@@ -34,7 +31,8 @@
                        :player/track-list
                        :player/paused
                        :player/playing
-                       :player/shuffle-memory])
+                       :player/shuffle-memory
+                       :player/selected-tab])
          (fn [{playing :player/playing q :player/queue}]
            (if playing
              (contains? (into #{} (map :track/id) q) (:track/id playing))
@@ -49,6 +47,8 @@
 (s/def :player/track-list ::spec/track-list)

 (s/def :player/playing (s/nilable ::spec/track))
+
+(s/def :player/selected-tab #{:selection :queue})

 (def all-data-spec (s/keys :req [:data/raw :data/ui]))

@@ -60,8 +60,8 @@
                         :track-list []
                         :paused true
                         :playing nil
-                        :shuffle-memory nil}
-       :selected-tab :selection
+                        :shuffle-memory nil
+                        :selected-tab :selection}
        :nation #:ui.nation{:mouse-on nil
                            :selected nil}
        :composer nil})
@@ -227,7 +227,7 @@
       (:ui.nation/mouse-on (:ui/nation ui))))

 (defn set-tab [ui tab]
-  (assoc ui :ui/selected-tab tab))
+  (assoc-in ui [:ui/player :player/selected-tab] tab))

 (defn focus-nation [ui nation]
   (assoc-in ui [:ui/nation :ui.nation/mouse-on] nation))
@@ -235,7 +235,7 @@
 (defn select-nation [ui nation]
   (assoc-in ui [:ui/nation :ui.nation/selected] nation))

-(def selected-tab :ui/selected-tab)
+(def selected-tab (comp :player/selected-tab :ui/player))

 (def composer :ui/composer)


Added progress bar to password reset

Added progress bar to password reset

--- src/cljs/salava/user/ui/reset.cljs
+++ src/cljs/salava/user/ui/reset.cljs
@@ -9,14 +9,13 @@
             [salava.user.ui.input :as input]))

 (defn send-password-reset-link [state]
+  (swap! state assoc :reset-status "in-progress")
   (let [email (:email @state)]
     (ajax/POST
       (path-for "/obpv1/user/reset/")
       {:params  {:email email}
        :handler (fn [data]
-                  (do
-                    (swap! state assoc :reset-link-sent (:status data))
-                    (swap! state assoc :form-display "none")))})))
+                  (swap! state assoc :reset-status (:status data)))})))

 (defn content [state]
   (let [email-atom (cursor state [:email])]
@@ -25,11 +24,13 @@
             :class "panel"}
       [:div.panel-body
        (cond
-         (= "success" (:reset-link-sent @state)) [:div {:class "alert alert-success" :role "alert"}
-                                                  (t :user/Passwordresetlinksent) ": " (:email @state)]
-         (= "error" (:reset-link-sent @state)) [:div {:class "alert alert-warning" :role "alert"}
-                                                (t :user/Errorsendingresetlink)])
-       [:form {:style {:display (:form-display @state)}}
+         (= "in-progress" (:reset-status @state)) [:div.text-center
+                                                   [:progress]]
+         (= "success" (:reset-status @state)) [:div {:class "alert alert-success" :role "alert"}
+                                               (t :user/Passwordresetlinksent) ": " (:email @state)]
+         (= "error" (:reset-status @state)) [:div {:class "alert alert-warning" :role "alert"}
+                                             (t :user/Errorsendingresetlink)])
+       [:form {:style {:display (if (:reset-status @state) "none" "block")}}
         [:div.form-group
          [:label {:for "input-email"} (t :user/Emailaddress)]
          [input/text-field {:name "email" :atom email-atom}]]
@@ -40,8 +41,7 @@

 (defn handler [site-navi params]
   (let [state (atom {:email ""
-                     :reset-link-sent nil
-                     :form-display "block"})
+                     :reset-status nil})
         lang (:lang params)]
     (if (and lang (some #(= lang %) (session/get :languages)))
       (session/assoc-in! [:user :language] lang))


fix 78

fix 78

--- stuf/src/sandbox/4clojure.clj
+++ stuf/src/sandbox/4clojure.clj
@@ -333,7 +333,8 @@
 ;;#(->> % (group-by sort) vals (filter second) (map set) set)

 ;;78 Reimplement Trampoline
-(def f #(loop [res (apply % %&)]
+#(loop [res (apply % %&)]
    (if (fn? res)
-     (recur (g))
-
+     (recur (res))
+     res))
+


cleaning up

cleaning up

--- test/celestial/test/tasks.clj
+++ test/celestial/test/tasks.clj
@@ -3,8 +3,7 @@
     slingshot.test
     expectations.scenarios
     [celestial.common :only (config)]
-    [celestial.dnsmasq :only (add-host)]
-    [celestial.tasks :only (resolve- reload post-create-hooks)])
+    [celestial.tasks :only (resolve- post-create-hooks)])
   (:import clojure.lang.ExceptionInfo)
  )


Added dot form tests

Added dot form tests

--- test/cljs/cljs/core_test.cljs
+++ test/cljs/cljs/core_test.cljs
@@ -726,5 +726,22 @@
   (assert (= (assoc fred :lastname "Flintstone") {:firstname "Fred" :lastname "Flintstone"}))
   (assert (= (assoc fred :wife :ethel) {:firstname "Fred" :lastname "Mertz" :wife :ethel}))
   (assert (= (dissoc ethel :husband) {:firstname "Ethel" :lastname "Mertz"}))
+
+  ;; dot
+  (let [s "abc"]
+    (assert (= 3 (.-length s)))
+    (assert (= 3 (. s -length)))
+    (assert (= 3 (. (str 138) -length)))
+    (assert (= 3 (. "abc" -length)))
+    (assert (= "bc" (.substring s 1)))
+    (assert (= "bc" (.substring "abc" 1)))
+    (assert (= "bc" (. s substring 1)))
+    (assert (= "bc" (. s (substring 1))))
+    (assert (= "bc" (. s (substring 1 3))))
+    (assert (= "bc" (.substring s 1 3)))
+    (assert (= "ABC" (. s (toUpperCase))))
+    (assert (= "ABC" (. "abc" (toUpperCase))))
+    (assert (= "BC" (. (.toUpperCase s) substring 1)))
+    (assert (= 3 (.-length (. (.toUpperCase s) substring 1)))))

   :ok)


Add some fake gensym to make the test work

--- test/desdemona/query_test.clj
+++ test/desdemona/query_test.clj
@@ -94,10 +94,16 @@
     (is (thrown? IllegalArgumentException
                  (#'q/dsl->logic '(= (:ip x) "10.0.0.1" "10.0.0.2")))))
   (testing "linking events"
-    (is (= '(fresh [s#]
-              (clojure.core.logic/featurec x {:ip s#})
-              (clojure.core.logic/featurec y {:ip s#}))
-           (#'q/dsl->logic '(= (:ip x) (:ip y)))))))
+    (let [gensym-count (atom 0)
+          fake-gensym (fn [& args]
+                        (->> (swap! gensym-count inc)
+                             (str "fake-gensym-")
+                             (symbol )))]
+      (with-redefs [clojure.core/gensym fake-gensym]
+        (is (= '(clojure.core.logic/fresh [fake-gensym-1]
+                  (clojure.core.logic/featurec x {:ip fake-gensym-1})
+                  (clojure.core.logic/featurec y {:ip fake-gensym-1}))
+               (#'q/dsl->logic '(= (:ip x) (:ip y)))))))))

 (def events
   [{:ip "10.0.0.1"}


Add test for commutative dual

Add test for commutative dual


0.7.1-SNAPSHOT

--- storm-kafka/project.clj
+++ storm-kafka/project.clj
@@ -1,11 +1,11 @@
-(defproject storm/storm-kafka "0.7.0-SNAPSHOT"
+(defproject storm/storm-kafka "0.7.1-SNAPSHOT"
   :source-path "src/clj"
   :java-source-path "src/jvm"
   :javac-options {:debug "true" :fork "true"}
   :dependencies [[storm/kafka "0.6.0"
                    :exclusions [org.apache.zookeeper/zookeeper
                                 log4j/log4j]]]
-  :dev-dependencies [[storm "0.7.0"]
+  :dev-dependencies [[storm "0.7.1"]
                      [org.clojure/clojure "1.2.0"]]
   :jvm-opts ["-Djava.library.path=/usr/local/lib:/opt/local/lib:/usr/lib"]
 )


:bug: Fix unexpected error on calculating thumnail size.

--- common/uxbox/common/geom/shapes.cljc
+++ common/uxbox/common/geom/shapes.cljc
@@ -651,11 +651,16 @@

 (defn fix-invalid-rect-values
   [rect-shape]
-  (letfn [(check [num] (if (or (nil? num) (mth/nan? num)) 0 num))
+  (letfn [(check [num]
+            (if (or (nil? num) (mth/nan? num) (= ##Inf num) (= ##-Inf num)) 0 num))
           (to-positive [num] (if (< num 1) 1 num))]
     (-> rect-shape
         (update :x check)
         (update :y check)
+        (update :x1 check)
+        (update :y1 check)
+        (update :x2 check)
+        (update :y2 check)
         (update :width (comp to-positive check))
         (update :height (comp to-positive check)))))


32, not 10 hotspots

32, not 10 hotspots

--- src/riemann/jvm_profiler/stack.clj
+++ src/riemann/jvm_profiler/stack.clj
@@ -109,7 +109,7 @@
        persistent!
        (sort-by (comp :time val))
        reverse
-       (take 10)))
+       (take 32)))

 (defn new-agg-state
   "New state of an AggSample. Takes a time in nanos."


[search] Wrap search results to avoid suprious timeout errors

--- src/braid/search/core.cljc
+++ src/braid/search/core.cljc
@@ -79,9 +79,9 @@
                (list
                  [::search-ws [query group-id]]
                  15000
-                 (fn [reply]
-                   (if (seq reply)
-                     (dispatch [::set-results! query reply])
+                 (fn [{:keys [results]}]
+                   (if results
+                     (dispatch [::set-results! query results])
                      (dispatch [::set-error!!]))))}))

           ::clear-search!
@@ -156,4 +156,4 @@
                                                           :group-id group-id
                                                           :query query})]
                     (when ?reply-fn
-                      (?reply-fn search-results))))))}))))
+                      (?reply-fn {:results search-results}))))))}))))


(reduce justin clojars-tasks)

(reduce justin clojars-tasks)

--- src/cake/tasks/clojars.clj
+++ src/cake/tasks/clojars.clj
@@ -11,15 +11,15 @@

 (defn get-latest-version [library-name]
   (let [response (http-get-text-seq clojars-all-jars-url)
-	lib-name (symbol library-name)]
+        lib-name (symbol library-name)]
     (second (last (filter #(= (first %) lib-name)
-			  (for [line response]
-			    (read-string line)))))))
+                          (for [line response]
+                            (read-string line)))))))

-(defn clojars-install
+(defn install
   ([library-name dev]
      (if-let [version (get-latest-version library-name)]
-       (clojars-install library-name version dev)
+       (install library-name version dev)
        (println "Can't find version of" library-name "on clojars.org\r\n"
                 "If the library is in another repository, please provide a version argument.")))
   ([library-name library-version dev]
@@ -40,38 +40,28 @@
            (log "Added" library-name library-version "to your" (str to ".")))
          (println "Neither" (first s-to) "nor" (last s-to) "were found in your project.clj.")))))

-(defn clojars-search [term]
+(defn search [terms]
   (let [response (http-get-text-seq clojars-all-jars-url)]
-    (println "\n\nLibraries on Clojars.org that contain the term: " term)
+    (apply println "\nLibraries on Clojars.org that contain: " terms)
     (println "--------------------------------------------------------------------------------")
-    (doseq [entry (for [line response :when (.contains line term)]
-		    (read-string line))]
+    (doseq [entry (for [line response :when (every? #(.contains line %) terms)]
+                    (read-string line))]
       (println "  " (first entry) "  " (second entry)))
-    (println "\n\n")))
-
-(defn clojars-versions [library-name]
-  (let [response (http-get-text-seq clojars-all-jars-url)]
-    (println "\n\nAvailable versions for library: " library-name)
-    (println "--------------------------------------------------------------------------------")
-    (doseq [entry (filter #(= (first %) (symbol library-name))
-			  (for [line response]
-			    (read-string line)))]
-      (println "  " (first entry) "  " (second entry)))
-    (println "\n\n")))
+    (println)))

 (defn get-pom-dir
   ([library-name version]
      (let [id-str (if (.contains library-name "/")
-		    (str "./" library-name "/" version "/")
-		    (str "./" library-name "/" library-name "/" version "/"))]
+                    (str "./" library-name "/" version "/")
+                    (str "./" library-name "/" library-name "/" version "/"))]
        id-str)))

 (defn get-pom-locations
   ([library-name version]
      (let [response (http-get-text-seq clojars-all-poms-url)
-	   pom-dir (get-pom-dir library-name version)]
+           pom-dir (get-pom-dir library-name version)]
        (for [line response :when (.startsWith line pom-dir)]
-	 line))))
+         line))))

 (defn get-latest-pom-location
   ([library-name version]
@@ -90,83 +80,81 @@
     (second desc)))

 (defn description-text [xml-seq]
-  (-> (apply str
-	     (for [line xml-seq
-		   :when (.contains line "<description>")]
-	       line))
+  (-> (apply str (for [line xml-seq :when (.contains line "<description>")]
+                   line))
       (extract-description-text)))

 (defn get-library-dependencies
   [library-name version]
   (let [pom-xml (clojure.xml/parse
-		 (java.io.ByteArrayInputStream.
-		  (.getBytes (apply str (get-latest-pom-file library-name version)))))
-	deps-xml (filter #(= (:tag %) :dependencies) (:content pom-xml))
-	deps-seq (partition 3 (for [x (xml-seq deps-xml)
-				    :when (or (= (:tag x) :artifactId)
-					      (= (:tag x) :groupId)
-					      (= (:tag x) :version))]
-				(hash-map (:tag x) (first (:content x)))))]
+                 (java.io.ByteArrayInputStream.
+                  (.getBytes (apply str (get-latest-pom-file library-name version)))))
+        deps-xml (filter #(= (:tag %) :dependencies) (:content pom-xml))
+        deps-seq (partition 3 (for [x (xml-seq deps-xml)
+                                    :when (or (= (:tag x) :artifactId)
+                                              (= (:tag x) :groupId)
+                                              (= (:tag x) :version))]
+                                (hash-map (:tag x) (first (:content x)))))]
     (into #{} (for [v deps-seq] (apply merge v)))
     (map :content (:content (first deps-xml)))))

-(defn print-library-dependencies
+(defn print-dependencies
   [library-name version]
-  (println (str "\n\nDependencies for: " library-name "  " version))
+  (println (str "Dependencies for: " library-name "  " version))
   (println "--------------------------------------------------------------------------------")
   (doseq [d (get-library-dependencies library-name version)]
     (let [dep (apply merge (map #(hash-map (:tag %) (first (:content %))) d))]
-      (println (str (:groupId dep) "/" (:artifactId dep) "  " (:version dep)))))
-  (println "\n\n"))
+      (println (str (:groupId dep) "/" (:artifactId dep) "  " (:version dep))))))

-(defn clojars-describe
+(defn print-description
+  [library-name version]
+  (let [pom-xml-seq (get-latest-pom-file library-name version)
+        desc-text   (description-text pom-xml-seq)]
+    (println (str "Description for library: " library-name "  " version))
+    (println "--------------------------------------------------------------------------------")
+    (println desc-text)))
+
+(defn print-all-versions [library-name]
+  (let [response (http-get-text-seq clojars-all-jars-url)]
+    (println "Available versions for library: " library-name)
+    (println "--------------------------------------------------------------------------------")
+    (doseq [entry (filter #(= (first %) (symbol library-name))
+                          (for [line response]
+                            (read-string line)))]
+      (println "  " (first entry) "  " (second entry)))))
+
+(defn describe
   ([library-name]
-     (clojars-describe library-name (get-latest-version library-name)))
+     (describe library-name (get-latest-version library-name)))
   ([library-name version]
-     (let [pom-xml-seq (get-latest-pom-file library-name version)
-	   desc-text (description-text pom-xml-seq)]
-       (println (str "\n\nDescription for library: " library-name "  " version))
-       (println "--------------------------------------------------------------------------------")
-       (println desc-text)
-       (println "")
-       (when desc-text
-	 (print-library-dependencies library-name version)))))
-
-(deftask dependencies
-  "Look up the dependencies of a library on clojars."
-  {[library-name version] :dependencies}
-  (if (nil? library-name)
-    (println "Usage: cake dependencies <library-name> [version]")
-    (print-library-dependencies library-name version)))
+     (println)
+     (print-description  library-name version) (println)
+     (print-dependencies library-name version) (println)
+     (print-all-versions library-name)         (println)))

 (deftask describe
   "Describe a library on clojars."
-  {[library-name] :describe}
+  {[library-name version] :describe}
   (if (nil? library-name)
     (println "Usage: cake describe <library-name>")
-    (clojars-describe library-name)))
-
-(deftask versions
-  "List all available versions of a library on clojars."
-  {[library-name] :versions}
-  (if (nil? library-name)
-    (println "Usage: cake versions <library-name>")
-    (clojars-versions library-name)))
+    (if version
+      (describe library-name version)
+      (describe library-name))))

 (deftask search
   "Search clojars.org for libraries."
   {terms :search}
   (if (nil? terms)
     (println "Usage: cake search <terms>")
-    (->> terms (s/join " ") clojars-search)))
+    (search terms)))

-(deftask add-dep
+(deftask add
   "Install a library from into your project."
   "The library will be added to the :deps or :dependencies vector in your project.clj.
    If you pass the --dev option, it'll be added to :dev-deps or :dev-dependencies."
-  {[library-name version] :add-dep [dev] :dev}
+  {[library-name version] :add [dev] :dev}
   (if (nil? library-name)
-    (println "Usage: cake add-dep <library-name> [version] [--dev]")
+    (println "Usage: cake add <library-name> [version] [--dev]")
     (if version
-      (clojars-install library-name version dev)
-      (clojars-install library-name dev))))
+      (install library-name version dev)
+      (install library-name dev))))


Handle toc indenting generically

Handle toc indenting generically

--- src/catalog/layout/fop.clj
+++ src/catalog/layout/fop.clj
@@ -76,18 +76,18 @@
       (set/subset? items (set layout/subgenres))
       (keep items layout/subgenres))))

-(defn- toc-entry [items path to-depth]
+(defn- toc-entry [items path to-depth indent-depth]
   (let [depth (count path)]
     [:fo:block (-> {:text-align-last "justify" :role "TOCI"}
-                   (cond-> (<= depth 2) (assoc :start-indent "1em")))
+                   (cond-> (>= depth indent-depth) (assoc :start-indent "1em")))
      [:fo:basic-link {:internal-destination (hash path)}
       (inline {:role "Reference"} (layout/translations (last path)))
       " " [:fo:leader {:leader-pattern "dots" :role "NonStruct"}] " "
       [:fo:page-number-citation {:ref-id (hash path) :role "Reference"}]]
      (when (and (map? items) (< depth to-depth))
-       (keep #(toc-entry (% items) (conj path %) to-depth) (order (keys items))))]))
-
-(defn toc [items path to-depth & {:keys [heading? editorial? recommendation-at-end? single-recommendation?]}]
+       (keep #(toc-entry (% items) (conj path %) to-depth indent-depth) (order (keys items))))]))
+
+(defn toc [items path to-depth indent-depth & {:keys [heading? editorial? recommendation-at-end? single-recommendation?]}]
   (when (map? items)
     [:fo:block {:line-height "150%"
                 :role "TOC"}
@@ -101,7 +101,7 @@
                                                       :recommendation
                                                       :recommendations)] entries)
                      :else entries)]
-       (keep #(toc-entry (get items %) (conj path %) to-depth) entries))]))
+       (keep #(toc-entry (get items %) (conj path %) to-depth indent-depth) entries))]))

 (defn- to-url
   "Return an url given a `record-id`"
@@ -298,7 +298,7 @@
 (defn format-sexp [items fmt level]
   (when-let [items (fmt items)]
     [(heading (level-to-h level) fmt [fmt])
-     (toc items [fmt] 3)
+     (toc items [fmt] 3 4)
      (set-marker (layout/translations fmt))
      (case fmt
        (:hörfilm :ludo) (entries-sexp items)
@@ -425,7 +425,7 @@

       (let [subitems (get items fmt)]
         [:fo:flow {:flow-name "xsl-region-body"}
-         (toc subitems [fmt] 3 :heading? true :editorial? true :single-recommendation? true)
+         (toc subitems [fmt] 3 3 :heading? true :editorial? true :single-recommendation? true)
          (heading :h1 :editorial [fmt :editorial])
          (md-to-fop (slurp "/home/eglic/src/catalog/samples/editorial.md"))
          (heading :h1 :recommendation [fmt :recommendation])
@@ -448,7 +448,7 @@

     (let [subitems (get items fmt)]
       [:fo:flow {:flow-name "xsl-region-body"}
-       (toc subitems [fmt] 3 :heading? true :editorial? true :recommendation-at-end? true)
+       (toc subitems [fmt] 3 3 :heading? true :editorial? true :recommendation-at-end? true)
        (block {:break-before "odd-page"}) ;; the very first format should start on recto
        (heading :h1 :editorial [fmt :editorial])
        (heading :h1 :hörbuch [fmt :hörbuch])
@@ -470,7 +470,7 @@
     (header :verso)

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


re-implementation of (analyze) that uses a 'replace-patterns' list of from/to/unify triples

--- src/babel/francais/morphology.cljc
+++ src/babel/francais/morphology.cljc
@@ -527,194 +527,197 @@
     suffix))

 (def replace-patterns
-  [[#"^([aeéiou].*)é" "s'$1er"
+  [
+   ;; pronouns: e.g.: "t'" => "te"
+   [#"^([lmst])" "$1e" :top]
+   [#"^(l)" "$1a" :top]
+
+   ;; <reflexive past>: e.g. "amusé" => "s'amuser"
+   [#"^([aeéiou].*)é$" "s'$1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :sing
                                  :gender :masc}}}}}]
-   [#"^([aeéiou].*)és" "s'$1er"
+   [#"^([aeéiou].*)és$" "s'$1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :plur
                                  :gender :masc}}}}}]
-   [#"^([aeéiou].*)ée" "s'$1er"
+   [#"^([aeéiou].*)ée$" "s'$1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :sing
                                  :gender :fem}}}}}]
-   [#"^([aeéiou].*)ées" "s'$1er"
+   [#"^([aeéiou].*)ées$" "s'$1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :plur
                                  :gender :fem}}}}}]
-   [#"^([^aeéiou].*)é" "se $1er"
+   [#"^([^aeéiou].*)é$" "se $1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :sing
                                  :gender :masc}}}}}]
-   [#"^([^aeéiou].*)és" "se $1er"
+   [#"^([^aeéiou].*)és$" "se $1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :plur
                                  :gender :masc}}}}}]
-   [#"^([^aeéiou].*)ée" "se $1er"
+   [#"^([^aeéiou].*)ée$" "se $1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :sing
                                  :gender :fem}}}}}]
-   [#"^([^aeéiou].*)ées" "se $1er"
+   [#"^([^aeéiou].*)ées$" "se $1er"
     {:synsem {:infl :past-p
               :subcat {:1 {:agr {:number :plur
                                  :gender :fem}}}}}]
+   ;; </reflexive past>
+
+   ;; <past>: e.g. "parlé" => "parler"
+   [#"^([aeéiou].*)é$" "$1er"
+    {:synsem {:infl :past-p
+              :subcat {:1 {:agr {:number :sing
+                                 :gender :masc}}}}}]
+   [#"^([aeéiou].*)és$" "$1er"
+    {:synsem {:infl :past-p
+              :subcat {:1 {:agr {:number :plur
+                                 :gender :masc}}}}}]
+   [#"^([aeéiou].*)ée$" "$1er"
+    {:synsem {:infl :past-p
+              :subcat {:1 {:agr {:number :sing
+                                 :gender :fem}}}}}]
+   [#"^([aeéiou].*)ées$" "$1er"
+    {:synsem {:infl :past-p
+              :subcat {:1 {:agr {:number :plur
+                                 :gender :fem}}}}}]
+   ;; </past>
+
+   ;; <reflexive present -er and -ir type verbs>
+   [#"^([aeéiou]\S+)e$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :sing
+                                 :person :1st}}}
+              :infl :present}}]
+
+   [#"^([aeéiou]\S+)es$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :sing
+                                 :person :2nd}}}
+              :infl :present}}]
+
+   [#"^([aeéiou]\S+)e$" "s'$1er"
+    {:synsem {:subcat {:1 {:agr {:number :sing
+                                 :person :3rd}}}
+              :infl :present}}]
+
+   [#"^([^aeéiou]\S+)e$" "se $1er"
+    {:synsem {:subcat {:1 {:agr {:number :sing
+                                 :person :1st}}}
+              :infl :present}}]
+
+   [#"^([^aeéiou]\S+)es$" "se $1er"
+    {:synsem {:subcat {:1 {:agr {:number :sing
+                                 :person :2nd}}}
+              :infl :present}}]
+
+   [#"^([^aeéiou]\S+)e$" "se $1er"
+    {:synsem {:subcat {:1 {:agr {:number :sing
+                                 :person :3rd}}}
+              :infl :present}}]
+   ;; </reflexive present -er and -ir type verbs>
+
+   ;; <present non-reflexive>
+   ;; <-er verbs>
+   [#"^(\S+)e$" "$1er" {:synsem {:subcat {:1 {:agr {:number :sing
+                                                    :person :1st}}}
+                                 :infl :present}}]
+
+   [#"^(\S+)es$" "$1er" {:synsem {:subcat {:1 {:agr {:number :sing
+                                                   :person :2nd}}}
+                                :infl :present}}]
+
+   [#"^(\S+)e$" "$1er" {:synsem {:subcat {:1 {:agr {:number :sing
+                                                    :person :3rd}}}
+                                 :infl :present}}]
+
+   [#"^(\S+)ons$" "$1er" {:synsem {:subcat {:1 {:agr {:number :plur
+                                                    :person :1st}}}
+                                 :infl :present}}]
+
+   [#"^(\S+)ez$" "$1er" {:synsem {:subcat {:1 {:agr {:number :plur
+                                                   :person :2nd}}}
+                                :infl :present}}]
+
+   [#"^(\S+)ent$" "$1er" {:synsem {:subcat {:1 {:agr {:number :plur
+                                                    :person :3rd}}}
+                                 :infl :present}}]
+   ;; </-er verbs>
+
+   ;; <ir verbs>
+   [#"^(\S+)e$" "$1ir" {:synsem {:subcat {:1 {:agr {:number :sing
+                                                    :person :1st}}}
+                                 :infl :present}}]
+
+   [#"^(\S+)es$" "$1ir" {:synsem {:subcat {:1 {:agr {:number :sing
+                                                   :person :2nd}}}
+                                :infl :present}}]
+
+   [#"^(\S+)e$" "$1ir" {:synsem {:subcat {:1 {:agr {:number :sing
+                                                    :person :3rd}}}
+                                 :infl :present}}]
+
+   [#"^(\S+)ons$" "$1ir" {:synsem {:subcat {:1 {:agr {:number :plur
+                                                    :person :1st}}}
+                                 :infl :present}}]
+
+   [#"^(\S+)ez$" "$1ir" {:synsem {:subcat {:1 {:agr {:number :plur
+                                                   :person :2nd}}}
+                                :infl :present}}]
+
+   [#"^(\S+)ent$" "$1ir" {:synsem {:subcat {:1 {:agr {:number :plur
+                                                    :person :3rd}}}
+                                 :infl :present}}]
+   ;; </ir verbs>
+   ;; </present non-reflexive>
+
    ])

-;; used for parsing: TODO: unify with generation
-(def pattern-to-structure
-  {
-   #"^([jlmst])$" [{:replace-with "e" ;; j' -> je,m' -> me, s' -> se, etc
-              :structure :top}]
-   #"^(\S+)ée$" [{:replace-with "er" ;; allée -> aller
-                  :structure {:synsem {:infl :past-p
-                                       :subcat {:1 {:agr {:number :sing
-                                                          :gender :fem}}}}}}]
-   #"^([^aeéiou]\S+)ées$" [{:replace-with "er" ;; allées -> aller
-                            :structure {:synsem {:infl :past-p
-                                                 :subcat {:1 {:agr {:number :plur
-                                                                    :gender :fem}}}}}}]
-   #"^([aeéiou]\S+)é$" [{:replace-with "er" ;; amusé -> s'amuser
-                         :structure {:synsem {:infl :past-p
-                                              :subcat {:1 {:agr {:number :sing
-                                                                 :gender :masc}}}}}}]
-   #"^(\S+)é$" [{:replace-with "er" ;; allé -> aller
-                 :structure {:synsem {:infl :past-p
-                                      :subcat {:1 {:agr {:number :sing
-                                                         :gender :masc}}}}}}]
-   #"^([aeéiou]\S+)és$" [{:replace-with "er" ;; amusés -> s'amuser
-                          :replace-pattern "se $1"
-                          :structure {:synsem {:infl :past-p
-                                               :subcat {:1 {:agr {:number :plur
-                                                                  :gender :masc}}}}}}]
-   #"^(\S+)és$" [{:replace-with "er" ;; allés -> aller
-                  :structure {:synsem {:infl :past-p
-                                       :subcat {:1 {:agr {:number :plur
-                                                          :gender :masc}}}}}}]
-   ;; -er and -ir type verbs
-   #"^([aeéiou]\S+)e$" [;; reflexive verbs beginning with a vowel: (e.g. "s'amuser") : 1st singular
-                       {:replace-with "er"
-                        :replace-pattern "s'$1"
-                        :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                                :person :1st}}}
-                                             :infl :present}}}
-                       ;; reflexive verbs beginning with a vowel: (e.g. "s'amuser") : 3rd singular
-                       {:replace-with "er"
-                        :replace-pattern "s'$1"
-                        :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                                :person :3rd}}}
-                                             :infl :present}}}]
-
-   #"^(\S+)e$" [;; reflexive verbs beginning with a non-vowel: (e.g. "se lever") : 1st singular
-                {:replace-with "er"
-                 :replace-pattern "se $1"
-                 :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                         :person :1st}}}
-                                      :infl :present}}}
-                ;; reflexive verbs beginning with a non-vowel: (e.g. "se lever") : 3rd singular
-                {:replace-with "er"
-                 :replace-pattern "se $1"
-                 :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                         :person :3rd}}}
-                                      :infl :present}}}
-
-                ;; non-reflexive verbs: 1st singular
-                {:replace-with "er" ;; parle -> parler
-                 :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                         :person :1st}}}
-                                      :infl :present}}}
-
-                ;; non-reflexive verbs: 3rd singular
-                {:replace-with "er" ;; parle -> parler
-                 :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                         :person :3rd}}}
-                                      :infl :present}}}
-
-                {:replace-with "ir" ;; dorme -> dormir
-                 :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                         :person :1st}}}
-                                      :infl :present}}}
-
-                {:replace-with "ir" ;; dorme -> dormir
-                 :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                         :person :3rd}}}
-                                      :infl :present}}}
-                ]
-
-   ;; -er and -ir type verbs
-   #"^([aeéiou]\S+)es$" [;; reflexive verbs beginning with a vowel: (e.g. "s'amuser") : 2nd singular
-                       {:replace-with "er"
-                        :replace-pattern "s'$1"
-                        :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                                :person :2nd}}}
-                                             :infl :present}}}
-                       {:replace-with "er" ;; parle -> parler
-                        :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                                :person :2nd}}}
-                                             :infl :present}}}
-                       {:replace-with "ir" ;; dorme -> dormir
-                        :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                                :person :2nd}}}
-                                             :infl :present}}}]
-
-   ;; -er and -ir type verbs
-   #"^(\S+)es$" [;; reflexive verbs beginning with a vowel: (e.g. "s'amuser") : 2nd singular
-                 {:replace-with "er"
-                  :replace-pattern "s'$1"
-                  :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                          :person :2nd}}}
-                                       :infl :present}}}
-
-                 ;; reflexive verbs beginning with a non-vowel: (e.g. "se lever") : 2nd singular
-                 {:replace-with "er"
-                  :replace-pattern "se $1"
-                  :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                          :person :2nd}}}
-                                       :infl :present}}}
-                 {:replace-with "er" ;; parle -> parler
-                  :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                          :person :2nd}}}
-                                       :infl :present}}}
-                 {:replace-with "ir" ;; dorme -> dormir
-                  :structure {:synsem {:subcat {:1 {:agr {:number :sing
-                                                          :person :2nd}}}
-                                       :infl :present}}}]
-
-   }
-  )
-
-(defn find-structure-from-pattern [patterns surface-form]
-  (if (not (empty? patterns))
-    (if (re-find (first patterns) surface-form)
-      (map (fn [each]
-             (merge {:pattern (first patterns)}
-                    each))
-           (get pattern-to-structure (first patterns)))
-      (find-structure-from-pattern (rest patterns) surface-form))))
+(defn possible-lexemes [surface-form]
+  (filter #(not (nil? %))
+          (map
+           (fn [replace-pattern]
+             (let [ ;; regular expression that matches the surface form
+                   from (nth replace-pattern 0)
+
+                   ;; expression that is used by string/replace along with the first regexp and the surface form,
+                   ;; to create the lexical string
+                   to (nth replace-pattern 1)
+
+                   ;; unifies with the lexical entry to create the inflected form.
+                   unify-with (nth replace-pattern 2)
+
+                   lex (if (re-matches from surface-form)
+                         (do
+                           (log/info (str "MATCHED SURFACE FORM: " surface-form " with from:"
+                                          from " and to: " to "; unify-with: " unify-with))
+                           (string/replace surface-form from to)))]
+               (if (re-matches from surface-form)
+                 {:from from
+                  :to to
+                  :lex lex})))
+           replace-patterns)))

 (defn analyze [surface-form lexicon]
-  "return the map incorporating the lexical information about a surface form.
-   The function tries to analyze the surface form into a lexical form, and then
-   looks up the hypothesized lexeme using lookup-fn."
-  (let [matches (find-structure-from-pattern (keys pattern-to-structure)
-                                             surface-form)]
-    (cond
-     (not (empty? matches))
-     (concat
-      (mapcat (fn [match]
-                (map (fn [lexeme]
-                       (unifyc
-                        lexeme
-                        (:structure match)))
-                     (let [replace-pattern (if (:replace-pattern match)
-                                             (:replace-pattern match)
-                                             "$1")]
-                       (get lexicon (str (string/replace surface-form (:pattern match) replace-pattern)
-                                         (:replace-with match))))))
-              matches)
-      (get lexicon surface-form))
-
-     true
-     (get lexicon surface-form))))
-
-
+  "Analyze a single surface form into a set of lexical forms."
+  (concat (if (get lexicon surface-form)
+            (get lexicon surface-form))
+          (mapcat
+           (fn [replace-pattern]
+             (let [ ;; regular expression that matches the surface form
+                   from (nth replace-pattern 0)]
+               (if (re-matches from surface-form)
+                 (let [;; expression that is used by string/replace along with the first regexp and the surface form,
+                       ;; to create the lexical string
+                       to (nth replace-pattern 1)
+
+                       ;; unifies with the lexical entry to create the inflected form.
+                       unify-with (nth replace-pattern 2)
+
+                       lex (string/replace surface-form from to)]
+                   (filter (fn [result] (not (= :fail result)))
+                           (map (fn [lexical-entry]
+                                  (unifyc unify-with lexical-entry))
+                                (get lexicon lex)))))))
+           replace-patterns)))


Delegated rendering workflow to renderer abstraction.

--- src/fm/simrunner/gui/rendering.clj
+++ src/fm/simrunner/gui/rendering.clj
@@ -1,38 +1,34 @@
 (ns
   ^{:doc

-  "Rendering the the SimRunner UI."
+  "Rendering the the SimRunner ui."

     :author "Frank Mosebach"}
   fm.simrunner.gui.rendering
   (:import
     (java.io File))
   (:require
-    [fm.simrunner.gui (core :as gui)
-                      (toc :as toc)]))
+    [fm.simrunner.gui (toc :as toc)
+                      (renderer :as rdr)]))

-(defn- start-rendering! [{app-state :state} before]
-  (swap! app-state before))
-
-(defn- stop-rendering! [{app-state :state} after]
-  (swap! app-state after))
-
-(defn- render-messages [{:keys [view model]}]
+(defn- render-messages [{:keys [view model] :as ui}]
   (let [console (toc/console view)
         console (-> console :contents :text-area :widget)]
     (doseq [message (:messages model)]
       (doto console
         (.append message)
-        (.append "\n")))))
+        (.append "\n")))
+    ui))

 (defn- update-button [button actions locked?]
   (let [action (-> button meta :action)]
     (doto (:widget button)
       (.setEnabled (boolean (and (not locked?) (actions action)))))))

-(defn- render-actions [{:keys [view model locked?]}]
+(defn- render-actions [{:keys [view model locked?]:as ui}]
   (doseq [button (toc/buttons view)]
-    (update-button button (:actions model) locked?)))
+    (update-button button (:actions model) locked?))
+  ui)

 (defmulti set-value {:private true} (fn [input value locked?]
                                       [(type input) (type value)]))
@@ -74,74 +70,68 @@
         value (get values id)]
     (set-value input value locked?)))

-(defn- render-values [{:keys [view model locked?]}]
+(defn- render-values [{:keys [view model locked?] :as ui}]
   (doseq [input (toc/inputs view)]
-    (update-input input (:values model) locked?)))
+    (update-input input (:values model) locked?))
+  ui)

 (defn- render-ui [ui]
-  (io! "Do not update the ui in a transaction!"
-    (render-messages ui)
-    (render-actions ui)
-    (render-values ui)))
+  (-> ui render-messages render-actions render-values))

-(defn- start-rendering [app-state]
-  (if (-> app-state :ui :dirty?)
-    (update-in app-state [:ui] assoc :rendering? true :dirty? false)
-    app-state))
+(defn- start-rendering [ui]
+  (if (:dirty? ui)
+    (assoc ui :rendering? true :dirty? false)
+    ui))

-(defn- before-rendering [before]
-  (if before
-    (comp start-rendering before)
-    start-rendering))
+(defn- begin [app-state tasks]
+ (update-in app-state [:ui] (apply comp start-rendering tasks)))

 (defn- drop-messages [messages rendered-messages]
   (into [] (drop (count rendered-messages) messages)))

-(defn- stop-rendering [app-state rendered-state]
-  (let [rendered-messages (-> rendered-state :ui :model :messages)]
-    (-> app-state
-        (assoc-in [:ui :rendering?] false)
-        (update-in [:ui :model :messages] drop-messages rendered-messages))))
+(defn- stop-rendering [app-ui rendered-ui]
+  (let [rendered-messages (get-in rendered-ui [:model :messages])]
+    (-> app-ui
+        (assoc :rendering? false)
+        (update-in [:model :messages] drop-messages rendered-messages))))

-(defn- after-rendering [after rendered-state]
-  (if after
-    (fn [app-state]
-      (after app-state rendered-state)
-      (stop-rendering app-state rendered-state))
-    (fn [app-state]
-      (stop-rendering app-state rendered-state))))
+(defn- end [app-state ui]
+  (update-in app-state [:ui] stop-rendering ui))

-(defn- render-app! [app & {:keys [before after]}]
-  (gui/gui-do
-    (let [app-state (start-rendering! app (before-rendering before))]
-      (when (-> app-state :ui :rendering?)
-        (try
-          (render-ui (:ui app-state))
-          (finally
-            (stop-rendering! app (after-rendering after app-state))))))))
+(deftype AppRenderCycle [app tasks]
+  rdr/RenderCycle
+  (rdr/begin [self _]
+    (:ui (swap! (:state app) begin tasks)))
+  (rdr/render [self ui]
+    (if (:rendering? ui)
+      (render-ui ui)
+      ui))
+  (rdr/end [self ui]
+    (swap! (:state app) end ui)
+    ui))

-(defn render! [app]
- (render-app! app))
+(defn render! [app & tasks]
+ (rdr/render! (AppRenderCycle. app tasks)))

-(defn lock [app-state]
-  (update-in app-state [:ui] assoc :dirty? true :locked? true))
+(defn lock [ui]
+  (assoc ui :dirty? true :locked? true))

 (defn lock! [app]
-  (render-app! app :before lock))
+  (render! app lock))

-(defn unlock [app-state]
-  (update-in app-state [:ui] assoc :dirty? true :locked? false))
+(defn unlock [ui]
+  (assoc ui :dirty? true :locked? false))

 (defn unlock! [app]
-  (render-app! app :before unlock))
+  (render! app unlock))

-(defn add-messages [app-state messages]
+(defn add-messages [ui messages]
   (if (seq messages)
-    (-> app-state
-        (update-in [:ui :model :messages] #(reduce conj % messages))
-        (assoc-in [:ui :dirty?] true))
-    app-state))
+    (-> ui
+        (update-in [:model :messages] #(reduce conj % messages))
+        (assoc :dirty? true))
+    ui))

 (defn log-messages! [app & messages]
-  (render-app! app :before #(add-messages % messages)))
+  (render! app #(add-messages % messages)))


Add exstra currency ids

Add exstra currency ids

--- src/clj/stripe/schema.cljc
+++ src/clj/stripe/schema.cljc
@@ -43,9 +43,8 @@
      (s/either inner (Channel inner))))

 (def CurrencyID
-  "Currently only USD is supported, because we're located in the
-  US. Generalize if Stripe opens this up."
-  (s/eq "usd"))
+  "Right now just these two are supported."
+  (s/enum "usd" "cad"))

 (s/defschema Metadata
   "Metadata feature supported by the Stripe API. Keyword keys are converted to strings on the way over.


Hide multiplayer tip when selection is active

--- src/clj/zetawar/views.cljs
+++ src/clj/zetawar/views.cljs
@@ -216,7 +216,8 @@
        [:p.hidden-xs.hidden-sm
         (translate :select-target-or-destination-tip)])
      ;; TODO: only display when starting faction is active
-     (when (= round 1)
+     (when (and (= round 1)
+                (not @(subs/selected-hex conn)))
        [:p.hidden-xs.hidden-sm
         {:dangerouslySetInnerHTML {:__html (translate :multiplayer-tip)}}])]))


Support for S-expressions evaluation

Support for S-expressions evaluation

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -18,6 +18,7 @@
 (require '[clj-mrazik.core     :as core])
 (require '[clj-mrazik.dyncfg   :as dyncfg])
 (require '[clj-mrazik.schedule :as schedule])
+(require '[clj-mrazik.dictionary :as dictionary])

 (defn load-data-file
     [filename]
@@ -85,6 +86,16 @@
     [input]
     (factorial (Integer/parseInt (subs input 0 (dec (count input))))))

+(defn s-expression
+    [input]
+    (try
+        (eval (read-string input))
+        (catch Exception e "sorry vole, error")))
+
+(defn is-s-expression?
+    [input]
+    (and (.startsWith input "(") (.endsWith input ")")))
+
 (defn print-prime-factors
     [input]
     (str input " = " (clojure.string/join " x " (primefactors (Integer/parseInt input)))))
@@ -129,6 +140,7 @@
                               (is-number? input)      (print-prime-factors input)
                               (is-two-numbers? input) (print-gcd input)
                               (is-factorial? input)   (print-factorial input)
+                              (is-s-expression? input) (s-expression input)
                               :else                   (random-message)))]
         (str prefix response)))


a few more fixes for URLs without params

--- src/cljs/easynxc/core.cljs
+++ src/cljs/easynxc/core.cljs
@@ -100,11 +100,11 @@

 (defn update-params! [k v]
   (let [url (url/url js/window.location.search)
-        nxc ((:query url) k)
+        nxc (if (:query url) ((:query url) k))
         new-url (if nxc
                   (update-in url [:query] dissoc k)
                   (assoc-in url [:query k] v))
-        query (str/replace (str new-url) #"^://" "")]
+        query (if (not= {} (:query new-url)) (str/replace (str new-url) #"^://" "") "?")]
     (.pushState js/window.history nil nil query)))

 ;; -------------------------


scroll-to-bottom on will-receive-props b/c browser scrolls to top when a dom element is moved

--- src/chat/client/views/threads.cljs
+++ src/chat/client/views/threads.cljs
@@ -64,8 +64,8 @@
       om/IDidMount
       (did-mount [_]
         (scroll-to-bottom owner thread))
-      om/IDidUpdate
-      (did-update [_ _ _]
+      om/IWillReceiveProps
+      (will-receive-props [_ _]
         (scroll-to-bottom owner thread))
       om/IRender
       (render [_]


simplify de-duping of sql migrators

simplify de-duping of sql migrators

--- joplin.jdbc/src/joplin/jdbc/database.clj
+++ joplin.jdbc/src/joplin/jdbc/database.clj
@@ -13,22 +13,8 @@
         (merge uri)
         (merge target))))

-(defn- remove-duplicates
-  "Remove duplicates that can occur when working with checked out dependencies"
-  [migrations]
-  (loop [[migration & migrations] migrations
-         added? #{}
-         out []]
-    (if (nil? migration)
-      out
-      (if (get added? (:id migration))
-        (recur migrations added? out)
-        (recur migrations
-               (conj added? (:id migration))
-               (conj out migration))))))
-
 (defn- get-sql-migrations [path]
-  (remove-duplicates
+  (distinct
    (or (seq (load-directory path))
        (seq (load-resources path))
        (seq (load-resources (drop-first-part path "/"))))))


Minor cosmetic changes on shapes events.

--- frontend/src/uxbox/main/data/shapes.cljs
+++ frontend/src/uxbox/main/data/shapes.cljs
@@ -490,7 +490,7 @@

 ;; --- Update Interaction

-(defrecord UpdateInteraction [shape interaction]
+(deftype UpdateInteraction [shape interaction]
   udp/IPageUpdate
   ptk/UpdateEvent
   (update [_ state]
@@ -505,7 +505,7 @@

 ;; --- Delete Interaction

-(defrecord DeleteInteracton [shape id]
+(deftype DeleteInteracton [shape id]
   udp/IPageUpdate
   ptk/UpdateEvent
   (update [_ state]
@@ -518,7 +518,7 @@

 ;; --- Path Modifications

-(defrecord UpdatePath [id index delta]
+(deftype UpdatePath [id index delta]
   ptk/UpdateEvent
   (update [_ state]
     (update-in state [:shapes id :points index] gpt/add delta)))
@@ -529,7 +529,7 @@
   {:pre [(uuid? id) (number? index) (gpt/point? delta)]}
   (UpdatePath. id index delta))

-(defrecord InitialPathPointAlign [id index]
+(deftype InitialPathPointAlign [id index]
   ptk/WatchEvent
   (watch [_ state s]
     (let [shape (get-in state [:shapes id])
@@ -550,7 +550,7 @@

 ;; --- Start shape "edition mode"

-(defrecord StartEditionMode [id]
+(deftype StartEditionMode [id]
   ptk/UpdateEvent
   (update [_ state]
     (assoc-in state [:workspace :edition] id))
@@ -566,7 +566,7 @@

 ;; --- Events (implicit) (for selected)

-(defrecord DeselectAll []
+(deftype DeselectAll []
   ptk/UpdateEvent
   (update [_ state]
     (-> state
@@ -635,10 +635,10 @@
   [opts]
   (reify
     ptk/WatchEvent
-    (watch [_ state s]
-      (rx/from-coll
-       (->> (get-in state [:workspace :selected])
-            (map #(update-fill-attrs % opts)))))))
+    (watch [_ state stream]
+      (->> (get-in state [:workspace :selected])
+           (map #(update-fill-attrs % opts))
+           (rx/from-coll)))))

 (defn update-selected-shapes-stroke
   "Update the fill related attributed on
@@ -650,7 +650,6 @@
       (rx/from-coll
        (->> (get-in state [:workspace :selected])
             (map #(update-stroke-attrs % opts)))))))
-

 ;; --- Move Selected Layer


move pretty print

move pretty print

--- src/clj/battlebots/utils/arena.clj
+++ src/clj/battlebots/utils/arena.clj
@@ -91,11 +91,6 @@
                   (recur (inc x) (+ y y-step) (+ error (- delta-x delta-y)) (conj res pt))
                   (recur (inc x) y            (- error delta-y) (conj res pt)))))))))))

-
-(defn pretty-print-arena
-  [arena]
-  (doseq [a (apply map vector arena)] (println (map :display a))))
-
 (defn get-arena-area
   [arena [posx posy] radius]
   (let [[xdim ydim] (get-arena-dimensions arena)
@@ -153,3 +148,7 @@
                (+ posy (mod (+ posy radius)) y-bound)
                (+ posy radius))]
       (map #(subvec % y1 y2) (subvec arena x1 x2)))))
+
+(defn pretty-print-arena
+  [arena]
+  (doseq [a (apply map vector arena)] (println (map :display a))))


Switch images to https

Switch images to https

--- src/clj/clojuredocs/site/intro.clj
+++ src/clj/clojuredocs/site/intro.clj
@@ -62,7 +62,7 @@
       " takes a bit to get your head around. Stick with it, and you won't be disappointed."]]
     [:div.col-md-6
      [:p "But don't take our word for it, here's what XKCD has to say:"]
-     [:p [:img {:src "http://imgs.xkcd.com/comics/lisp_cycles.png"}]]
+     [:p [:img {:src "https://imgs.xkcd.com/comics/lisp_cycles.png"}]]
      [:p "Seems like more than a few, these days. Happy coding!"]]
     [:div.col-md-12.used-by
      [:h3 "Clojure in Production"]
@@ -70,23 +70,23 @@
       (for [{:keys [src url]}
             [{:src "https://g.twimg.com/Twitter_logo_blue.png"
               :url "https://twitter.com"}
-             {:src "http://www.akamai.com/images/img/bg/akamai-logo.png"
+             {:src "https://upload.wikimedia.org/wikipedia/en/8/8b/Akamai_logo.svg"
               :url "http://www.akamai.com/"}
-             {:src "http://www.climate.com/preso/assets/imgs/shared/logos/tcc_logo_marcom.png"
+             {:src "https://upload.wikimedia.org/wikipedia/en/2/22/The_Climate_Corporation_Logo2.jpg"
               :url "http://www.climate.com/"}
-             {:src "http://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Netflix_logo.svg/200px-Netflix_logo.svg.png"
+             {:src "https://upload.wikimedia.org/wikipedia/commons/thumb/6/69/Netflix_logo.svg/200px-Netflix_logo.svg.png"
               :url "https://www.netflix.com"}
-             {:src "http://www.factual.com/assets/factual_logo_small-9d5ae614ae5422b251648ca62d6b4e51.png"
+             {:src "https://www.factual.com/assets/factual_logo_small-9d5ae614ae5422b251648ca62d6b4e51.png"
               :url "http://www.factual.com"}
              {:src "https://www.simple.com/img/logo-a2236763875.png"
               :url "https://simple.com"}
-             {:src "http://upload.wikimedia.org/wikipedia/commons/c/cc/Groupon_logo.png"
+             {:src "https://upload.wikimedia.org/wikipedia/commons/c/cc/Groupon_logo.png"
               :url "http://www.groupon.com/"}
              {:src "https://d1lpkba4w1baqt.cloudfront.net/heroku-logo-light-234x60.png"
               :url "https://www.heroku.com"}
-             {:src "http://img.brightcove.com/logo-corporate-new.png"
+             {:src "https://img.brightcove.com/logo-corporate-new.png"
               :url "http://www.brightcove.com"}
-             {:src "http://f.cl.ly/items/3D0u2W0H322U1V2Z2u0P/80x50_orange.png"
+             {:src "https://upload.wikimedia.org/wikipedia/en/9/92/SoundCloud_logo.svg"
               :url "https://soundcloud.com"}]]
         [:li [:a {:href url} [:img {:src src}]]])]]]
    [:div.row


fixed typos

fixed typos

--- src/clj/swarmpit/event/channel.clj
+++ src/clj/swarmpit/event/channel.clj
@@ -30,7 +30,7 @@

 (defn list
   ([event]
-   "Get subscribed channel list based on given event"
+   "Get subscribed channels based on given event"
    (->> (filter #(rule/match? % event) rule/list)
         (map #(rule/subscription % event))
         (map #(subscribers %))
@@ -38,7 +38,7 @@
         (filter #(some? %))
         (map #(str %))))
   ([]
-   "Get susbcribed channel list"
+   "Get subscribed channels"
    (->> (keys @hub)
         (map #(str %)))))


Minor: docstring for re-render function

Minor: docstring for re-render function

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -117,6 +117,9 @@
                                           :color "green"))))

 (defn re-render!
+  "Adds a green semi-transparent overlay to the screen, then
+  lines up a re-rendering (we need to yield control back to
+  the browser so that the overlay actually get rendered)"
   [new-state]
   (add-overlay-rectangle!
    0 0


Fix bind implementation for try monad.

Fix bind implementation for try monad.

--- src/cljx/cats/monad/exception.cljx
+++ src/cljx/cats/monad/exception.cljx
@@ -114,12 +114,11 @@

 #+clj
 (defmacro try-on
-  [& body]
+  "Wraps a computation and return success of failure."
+  [expr]
   `(try
-     (let [r# (do ~@body)]
-       (if (try? r#)
-         r#
-         (success r#)))
+     (let [r# ~expr]
+       (success r#))
      (catch Throwable e#
        (failure e#))))

@@ -167,6 +166,6 @@

    (mbind [_ s f]
      (if (success? s)
-       (try-on (f (.-v s)))
+       (f (.-v s))
        s))))


Reduce safety timeout to 1ms

Reduce safety timeout to 1ms

--- src/com/wsscode/pathom/parser.cljc
+++ src/com/wsscode/pathom/parser.cljc
@@ -274,7 +274,7 @@
     (go
       ; sometimes the watcher is too fast and finish the process before we get the change to register
       ; the watcher. This timeout ensures that in those cases we still flush out the watched key
-      (<! (async/timeout 10))
+      (<! (async/timeout 1))
       (when (contains? @(get env :com.wsscode.pathom.core/entity) key)
         (trace env {::pt/event ::flush-watcher-safeguard :key key})
         (async/put! ch {::provides #{key}})


Handling - in clojure namespaces correctly now

--- jvm-runner/src/clojure/codewars/util.clj
+++ jvm-runner/src/clojure/codewars/util.clj
@@ -25,6 +25,7 @@
   (let [{:keys [:extension]} (get language-data language)]
     (-> class-name
         name
+        (clojure.string/replace "-" "_")
         ;; TODO: not platform independent...
         (clojure.string/replace "." "/")
         (str "." extension)


release 0.3.25

release 0.3.25

--- project.clj
+++ project.clj
@@ -3,7 +3,7 @@
   [path]
   (str "resources/public/js/lib/" path))

-(defproject onaio/hatti "0.3.25-SNAPSHOT"
+(defproject onaio/hatti "0.3.25"
   :description "A cljs dataview from your friends at Ona.io"
   :license "Apache 2, see LICENSE"
   :url "https://github.com/onaio/hatti"


Updated core.asyn and clojurescript version.

--- project.clj
+++ project.clj
@@ -3,9 +3,10 @@
   :url "https://github.com/tedfoye/clojuroids"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
+  :repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"}
   :dependencies [[org.clojure/clojure "1.6.0"]
-                 [org.clojure/core.async "0.1.303.0-886421-alpha"]
-                 [org.clojure/clojurescript "0.0-2280"]
+                 [org.clojure/core.async "0.1.319.0-6b1aca-alpha"]
+                 [org.clojure/clojurescript "0.0-2307"]
                  [compojure "1.1.8"]
                  [javax.servlet/javax.servlet-api "3.1.0"]]
   :plugins [[lein-ring "0.8.11"]


clearing ring plugin for now

clearing ring plugin for now

--- project.clj
+++ project.clj
@@ -26,7 +26,7 @@

   :plugins  [[lein-tarsier "0.10.0"]  [lein-ring "0.7.3"]]

-  :ring {:handler celestial.api/app :auto-reload? true}
+  ;:ring {:handler celestial.api/app :auto-reload? true}

   :aot [proxmox.provider
         celestial.puppet-standalone


Fix merge conflict.

Fix merge conflict.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clojush "2.16.1-1-SNAPSHOT"
+(defproject clojush "2.16.2-1-SNAPSHOT"
   :description "The Push programming language and the PushGP genetic programming
                 system implemented in Clojure.
                 See http://pushlanguage.com"


version

version

--- project.clj
+++ project.clj
@@ -16,7 +16,7 @@
   :dependencies [[org.clojure/clojure "1.8.0"]

                  ;; command line
-                 [com.zensols.tools/actioncli "0.0.9"]
+                 [com.zensols.tools/actioncli "0.0.10"]

                  ;; write dataset report
                  [com.zensols.tools/misc "0.0.3"]


1.0.0-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject org.roman01la/cljss "0.1.0-SNAPSHOT"
+(defproject org.roman01la/cljss "1.0.0-SNAPSHOT"
   :description "Clojure Style Sheets"
   :url "https://github.com/roman01la/cljss"
   :license {:name "Eclipse Public License"


Version 1.6.1

Version 1.6.1

--- project.clj
+++ project.clj
@@ -1,6 +1,6 @@
 (def http-async-client-version "1.3.0")

-(defproject puppetlabs/pcp-broker "1.6.1-SNAPSHOT"
+(defproject puppetlabs/pcp-broker "1.6.1"
   :description "PCP fabric messaging broker"
   :url "https://github.com/puppetlabs/pcp-broker"
   :license {:name "Apache License, Version 2.0"


Updated dependencies

Updated dependencies

--- project.clj
+++ project.clj
@@ -18,12 +18,12 @@
   :javac-target     "1.7"
   :dependencies [
                   [org.clojure/clojure                          "1.6.0"]
-                  [org.clojure/data.json                        "0.2.5"]
+                  [org.clojure/data.json                        "0.2.6"]
                   [org.clojure/tools.cli                        "0.3.1"]
                   [org.clojure/tools.logging                    "0.3.1"]
                   [clojurewerkz/neocons                         "3.0.0"]
-                  [ch.qos.logback/logback-classic               "1.1.2"]
-                  [io.aviso/pretty                              "0.1.16"]
+                  [ch.qos.logback/logback-classic               "1.1.3"]
+                  [io.aviso/pretty                              "0.1.17"]
                   [org.ow2.asm/asm                              "4.1"]     ; WARNING: DO NOT CHANGE THIS AS CLOJURE ITSELF EMBEDS ASM 4.1!!!!
                   [net.java.truevfs/truevfs-kernel-impl         "0.10.8"]  ; Ugh TrueVFS' dependencies are crap
                   [net.java.truevfs/truevfs-access              "0.10.8"]


Fix test script.

Fix test script.

--- project.clj
+++ project.clj
@@ -10,7 +10,7 @@
   {:dev {:global-vars {*warn-on-reflection* false}
          :jvm-opts ["-Dclojure.compiler.direct-linking=true"]
          :aliases {"test-all"
-                   ["with-profile" "1.8:dev,1.7:dev,1.6:dev,1.5:dev,dev" "test"]}
+                   ["with-profile" "dev,1.8:dev,1.7:dev,1.6:dev,1.5:dev" "test"]}
          :plugins [[lein-ancient "0.6.10"]]
          :dependencies [[org.postgresql/postgresql "9.4.1208"]
                         [com.h2database/h2 "1.4.192"]


release 2.4.1

release 2.4.1

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject babel "2.4.1-SNAPSHOT"
+(defproject babel "2.4.1"
   :description "A library for natural language generation and parsing"
   :url "http://github.com/ekoontz/babel"
   :license {:name "Eclipse Public License"


project change group to day8.re-frame/http-fx

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject re-frame-http-fx "0.0.1-SNAPSHOT"
+(defproject day8.re-frame/http-fx "0.0.1-SNAPSHOT"
   :description  "A re-frame effects handler for performing Ajax tasks"
   :url          "https://github.com/Day8/re-frame-http-fx.git"
   :license      {:name "MIT"}
@@ -25,8 +25,17 @@
                                       :macosx  "open"
                                       :linux   "xdg-open"}}}

-  :deploy-repositories [["releases" :clojars {:sign-releases false}]
-                        ["snapshots" :clojars {:sign-releases false}]]
+  :deploy-repositories [["releases"  {:sign-releases false :url "https://clojars.org/repo"}]
+                        ["snapshots" {:sign-releases false :url "https://clojars.org/repo"}]]
+
+  :release-tasks [["vcs" "assert-committed"]
+                  ["change" "version" "leiningen.release/bump-version" "release"]
+                  ["vcs" "commit"]
+                  ["vcs" "tag" "v" "--no-sign"]
+                  ["deploy"]
+                  ["change" "version" "leiningen.release/bump-version"]
+                  ["vcs" "commit"]
+                  ["vcs" "push"]]

   :npm {:dependencies [[karma                 "1.0.0"]
                        [karma-cljs-test       "0.1.0"]


Add tag type for whidbey.

Add tag type for whidbey.

--- project.clj
+++ project.clj
@@ -15,4 +15,6 @@
   :codox {:metadata {:doc/format :markdown}
           :source-uri "https://github.com/greglook/clj-multihash/blob/master/{filepath}#L{line}"
           :doc-paths ["doc/extra"]
-          :output-path "doc/api"})
+          :output-path "doc/api"}
+
+  :whidbey {:tag-types {'multihash.core.Multihash {'data/hash 'multihash.core/base58}}})


Fix issue with lein deploy

Fix issue with lein deploy

- More info: https://github.com/technomancy/leiningen/issues/1890

--- project.clj
+++ project.clj
@@ -19,6 +19,8 @@
                  [com.taoensso/sente "1.8.1"]
                  [re-frame "0.7.0"]
                  [cljsjs/react-grid-layout "0.12.4-0"]]
+  :deploy-repositories [["releases" :clojars]
+                        ["snapshots" :clojars]]

   :plugins [[lein-cljsbuild "1.1.1"]
             [lein-environ "1.0.1"]]


lein-release plugin: preparing 0.1.3 release

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject yetibot.core "0.1.3-SNAPSHOT"
+(defproject yetibot.core "0.1.3"
   :description "Core yetibot utilities, extracted for shared use among yetibot
                 and its various plugins"
   :url "https://github.com/devth/yetibot.core"


Update dependencies

Update dependencies

--- project.clj
+++ project.clj
@@ -7,9 +7,9 @@
             :distribution :repo}

   :dependencies [[org.clojure/clojure "1.7.0"]
-                 [potemkin "0.4.2" :exclusions [org.clojure/clojure]]
-                 [com.rpl/specter "0.9.0" :exclusions [org.clojure/clojure org.clojure/clojurescript]]
-                 [environ "1.0.1" :exclusions [org.clojure/clojure]]
+                 [potemkin "0.4.3" :exclusions [org.clojure/clojure]]
+                 [com.rpl/specter "0.9.2" :exclusions [org.clojure/clojure org.clojure/clojurescript]]
+                 [environ "1.0.2" :exclusions [org.clojure/clojure]]
                  [commons-codec/commons-codec "1.10"]]

   :repl-options {:init (do (require 'such.doc)