revert changes to layout, format code

revert changes to layout, format code

--- src/clj/salava/core/layout.clj
+++ src/clj/salava/core/layout.clj
@@ -13,8 +13,7 @@
             [salava.page.main :as p]
             [salava.gallery.db :as g]
             [hiccup.page :refer [html5 include-css include-js]]
-   [salava.extra.application.db :as app]
-   salava.core.restructure))
+            salava.core.restructure))

 (def asset-css
   ["/assets/bootstrap/css/bootstrap.min.css"
@@ -24,18 +23,15 @@
    "/css/rateit/rateit.css"
    "/css/simplemde.min.css"])

-
 (def asset-js
   ["/assets/jquery/jquery.min.js"
    "/assets/bootstrap/js/bootstrap.min.js"
    "/assets/leaflet/leaflet.js"
    "/js/ckeditor/ckeditor.js"])

-
 (defn with-version [ctx resource-name]
   (let [version (get-in ctx [:config :core :asset-version])]
     (str resource-name "?_=" (or version (System/currentTimeMillis)))))
-

 (defn css-list [ctx]
   (let [plugins (get-in ctx [:config :core :plugins])
@@ -52,17 +48,15 @@
            (concat asset-css)
            (map #(with-version ctx %))))))

-
 (defn js-list [ctx]
-    (map #(with-version ctx %) (conj asset-js "/js/salava.js")))
-
+  (map #(with-version ctx %) (conj asset-js "/js/salava.js")))

 (defn context-js [ctx]
   (let [site-name (get-in ctx [:config :core :site-name])
         share     {:site-name (get-in ctx [:config :core :share :site-name] site-name)
                    :hashtag   (get-in ctx [:config :core :share :hashtag] (->> (split site-name #" ")
                                                                                (map capitalize)
-                                                                               join)) }
+                                                                               join))}
         ctx-out   {:plugins         {:all (map plugin-str (get-in ctx [:config :core :plugins]))}
                    :user            (:user ctx)
                    :flash-message   (:flash-message ctx)
@@ -77,10 +71,8 @@
                    :footer          (get-in ctx [:config :extra/theme :footer] nil)
                    :factory-url     (get-in ctx [:config :factory :url])
                    :show-terms?     (get-in ctx [:config :core :show-terms?] false)
-                   :filter-options  (first (mapcat #(get-in ctx [:config % :filter-options] []) (get-plugins ctx)))
-                   }]
+                   :filter-options  (first (mapcat #(get-in ctx [:config % :filter-options] []) (get-plugins ctx)))}]
     (str "function salavaCoreCtx() { return " (json/write-str ctx-out) "; }")))
-

 (defn include-meta-tags [ctx tags]
   (if tags
@@ -102,38 +94,36 @@
                    (cons (map (fn [f] (f ctx)) (plugin-fun (get-plugins ctx) "layout" "html-attributes"))))]
     (apply merge attrib)))

-
 (defn main-view
   ([ctx] (main-view ctx nil))
   ([ctx meta-tags]
    (let [favicons (favicon ctx)
          attrib (html-attributes ctx)]
-    (html5 {:dir (:dir attrib)}
-     [:head
-      [:title (get-in ctx [:config :core :site-name])]
-      [:meta {:charset "utf-8"}]
-      [:meta {:http-equiv "X-UA-Compatible" :content "IE=edge"}]
-      [:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
-      [:meta {:property "og:sitename" :content (get-in ctx [:config :core :site-name])}]
-      (seq (include-meta-tags ctx meta-tags))
-      (when (:json-oembed meta-tags)
-        (:json-oembed meta-tags))
-      (apply include-css (css-list ctx))
-      [:link {:type "text/css" :href "/css/custom.css" :rel "stylesheet" :media "screen"}]
-      [:link {:type "text/css" :href "/css/print.css" :rel "stylesheet" :media "print"}]
-      [:link {:type "text/css", :href "https://fonts.googleapis.com/css?family=Halant:300,400,600,700|Dosis:300,400,600,700,800|Gochi+Hand|Coming+Soon|Oswald:400,300,700|Dancing+Script:400,700|Archivo+Black|Archivo+Narrow|Open+Sans:700,300,600,800,400|Open+Sans+Condensed:300,700|Cinzel:400,700&subset=latin,latin-ext", :rel "stylesheet"}]
-      [:link {:rel "shortcut icon" :href (:icon favicons)}]
-      [:link {:rel "icon" :type "image/png" :href  (:png favicons)}]
+     (html5 {:dir (:dir attrib)}
+            [:head
+             [:title (get-in ctx [:config :core :site-name])]
+             [:meta {:charset "utf-8"}]
+             [:meta {:http-equiv "X-UA-Compatible" :content "IE=edge"}]
+             [:meta {:name "viewport" :content "width=device-width, initial-scale=1.0"}]
+             [:meta {:property "og:sitename" :content (get-in ctx [:config :core :site-name])}]
+             (seq (include-meta-tags ctx meta-tags))
+             (when (:json-oembed meta-tags)
+               (:json-oembed meta-tags))
+             (apply include-css (css-list ctx))
+             [:link {:type "text/css" :href "/css/custom.css" :rel "stylesheet" :media "screen"}]
+             [:link {:type "text/css" :href "/css/print.css" :rel "stylesheet" :media "print"}]
+             [:link {:type "text/css", :href "https://fonts.googleapis.com/css?family=Halant:300,400,600,700|Dosis:300,400,600,700,800|Gochi+Hand|Coming+Soon|Oswald:400,300,700|Dancing+Script:400,700|Archivo+Black|Archivo+Narrow|Open+Sans:700,300,600,800,400|Open+Sans+Condensed:300,700|Cinzel:400,700&subset=latin,latin-ext", :rel "stylesheet"}]
+             [:link {:rel "shortcut icon" :href (:icon favicons)}]
+             [:link {:rel "icon" :type "image/png" :href  (:png favicons)}]

-      [:script {:type "text/javascript"} (context-js ctx)]]
-     [:body {:class (if (and (nil? (get-in ctx [:user])) (nil? (:no-anon meta-tags))) "anon")}
-      [:div#app]
-      "<!--[if lt IE 10]>"
-      (include-js "/assets/es5-shim/es5-shim.min.js" "/assets/es5-shim/es5-sham.min.js")
-      "<![endif]-->"
-      (include-js "/assets/es6-shim/es6-shim.min.js" "/assets/es6-shim/es6-sham.min.js")
-      (apply include-js (js-list ctx))]))))
-
+             [:script {:type "text/javascript"} (context-js ctx)]]
+            [:body {:class (if (nil? (get-in ctx [:user])) "anon")}
+             [:div#app]
+             "<!--[if lt IE 10]>"
+             (include-js "/assets/es5-shim/es5-shim.min.js" "/assets/es5-shim/es5-sham.min.js")
+             "<![endif]-->"
+             (include-js "/assets/es6-shim/es6-shim.min.js" "/assets/es6-shim/es6-sham.min.js")
+             (apply include-js (js-list ctx))]))))

 (defn main-response [ctx current-user flash-message meta-tags]
   (let [user (if current-user (-> (u/user-information ctx (:id current-user))
@@ -146,34 +136,22 @@

 (defn main [ctx path]
   (GET path []
-    :no-doc true
-    :summary "Main HTML layout"
-    :current-user current-user
-    :flash-message flash-message
-    (main-response ctx current-user flash-message nil)))
+       :no-doc true
+       :summary "Main HTML layout"
+       :current-user current-user
+       :flash-message flash-message
+       (main-response ctx current-user flash-message nil)))

 (defn main-meta [ctx path plugin]
   (GET path []
-    :no-doc true
-    :path-params [id :- s/Any]
-    :summary "Main with meta tags"
-    :current-user current-user
-    :flash-message flash-message
-    (let [meta-tags (case plugin
-                      :badge (b/meta-tags ctx id)
-                      :page (p/meta-tags ctx id)
-                      :user (u/meta-tags ctx id)
-                      :gallery (g/meta-tags ctx id))]
-      (main-response ctx current-user flash-message meta-tags))))
-
-(defn main-meta+
- "Process plugin paths with meta-tags and no path id."
- [ctx path plugin]
- (GET path []
-   :no-doc true
-   :summary "Main with meta tags"
-   :current-user current-user
-   :flash-message flash-message
-   (let [meta-tags (case plugin
-                    :application (app/meta-tags ctx))]
-     (main-response ctx current-user flash-message meta-tags))))
+       :no-doc true
+       :path-params [id :- s/Any]
+       :summary "Main with meta tags"
+       :current-user current-user
+       :flash-message flash-message
+       (let [meta-tags (case plugin
+                         :badge (b/meta-tags ctx id)
+                         :page (p/meta-tags ctx id)
+                         :user (u/meta-tags ctx id)
+                         :gallery (g/meta-tags ctx id))]
+         (main-response ctx current-user flash-message meta-tags))))


Update URL for Clojure cheatsheet to place where it should be longer term

--- src/clj_ns_browser/browser.clj
+++ src/clj_ns_browser/browser.clj
@@ -387,7 +387,7 @@
           :handler (fn [a] (future (clj-ns-browser.web/browse-url "http://clojuredocs.org")))))
 (add-app-action :go-cheatsheet-action
   (action :name "Clojure CheatSheet..."
-          :handler (fn [a] (future (clj-ns-browser.web/browse-url "http://homepage.mac.com/jafingerhut/files/cheatsheet-clj-1.3.0-v1.4-tooltips/cheatsheet-full.html")))))
+          :handler (fn [a] (future (clj-ns-browser.web/browse-url "http://jafingerhut.github.com/cheatsheet-clj-1.3/cheatsheet-tiptip-no-cdocs-summary.html")))))
 (add-app-action :go-jira-action
   (action :name "JIRA..."
           :handler (fn [a] (future (clj-ns-browser.web/browse-url


add comment for example document usage

add comment for example document usage

--- src/cljx/transom/document.cljx
+++ src/cljx/transom/document.cljx
@@ -70,3 +70,17 @@
 (defn patch!
   [doc edit version]
   (swap! doc patch edit version))
+
+(comment
+  (def pizza (document))
+  (get @pizza :state)
+  (get @pizza :history)
+  (deref pizza)
+  (update! pizza [] {:foo "bar" :diff "please" :bar "baz"})
+  (update! pizza [:foo] "barbies")
+  (transact! pizza [:foo] (fn [foo] (str "what is the deal " foo " are the best")))
+  (transact! pizza [] (fn [old] (assoc old :vec ["a"])))
+  (transact! pizza [:vec] (fn [v] (vec (remove #(= % "a") v))))
+  (transact! pizza [:vec] (fn [v] (into v ["foo" "bar" ",,"])))
+  (apply transom/compose nil (:history @pizza))
+  )


fix dom-node? for nil case

fix dom-node? for nil case

--- src/clojure/freactive/dom.cljs
+++ src/clojure/freactive/dom.cljs
@@ -17,7 +17,7 @@
 ;  (-get-virtual-dom [x] spec))

 (defn- dom-node? [x]
-  (> (.-nodeType x) 0))
+  (and x (> (.-nodeType x) 0)))

 (defn- get-attr [dom-node attr-name]
   (when (.-getAttribute dom-node)


Preserve existing jvm-opts

Preserve existing jvm-opts

--- src/clojure/nightcode/lein.clj
+++ src/clojure/nightcode/lein.clj
@@ -113,13 +113,15 @@

 (defn start-process-directly
   [process path func]
-  (let [project-map (-> (read-project-clj path)
+  (let [jvm-opts (conj (:jvm-opts (read-project-clj path))
+                       (str "-agentlib:jdwp="
+                            "transport=dt_socket,"
+                            "server=y,"
+                            "suspend=n,"
+                            "address=7896"))
+        project-map (-> (read-project-clj path)
                         (assoc :eval-in :trampoline
-                               :jvm-opts [(str "-agentlib:jdwp="
-                                               "transport=dt_socket,"
-                                               "server=y,"
-                                               "suspend=n,"
-                                               "address=7896")]))
+                               :jvm-opts jvm-opts))
         forms leiningen.core.eval/trampoline-forms
         profiles leiningen.core.eval/trampoline-profiles]
     (reset! forms [])


When sandboxed, don't run REPL in a separate process

--- src/clojure/nightcode/repl.clj
+++ src/clojure/nightcode/repl.clj
@@ -1,6 +1,7 @@
 (ns nightcode.repl
   (:require [nightcode.editors :as editors]
             [nightcode.lein :as lein]
+            [nightcode.sandbox :as sandbox]
             [nightcode.shortcuts :as shortcuts]
             [nightcode.ui :as ui]
             [seesaw.core :as s]))
@@ -9,7 +10,9 @@
   "Starts a REPL process."
   [process in-out]
   (lein/stop-process! process)
-  (->> (lein/start-process-indirectly! process nil "clojure.main")
+  (->> (if (sandbox/get-dir)
+         (clojure.main/repl)
+         (lein/start-process-indirectly! process nil "clojure.main"))
        (lein/start-thread! in-out)))

 (defn create-pane
@@ -18,10 +21,13 @@
   (let [process (atom nil)
         run! (fn [& _]
                (s/request-focus! (-> console .getViewport .getView))
-               (run-repl! process (ui/get-io! console)))]
+               (run-repl! process (ui/get-io! console)))
+        pane (s/config! console :id :repl-console)]
     ; start the repl
     (run!)
     ; create a shortcut to restart the repl
-    (doto (s/config! console :id :repl-console)
-      shortcuts/create-hints!
-      (shortcuts/create-mappings! {:repl-console run!}))))
+    (when-not (sandbox/get-dir)
+      (shortcuts/create-hints! pane)
+      (shortcuts/create-mappings! pane {:repl-console run!}))
+    ; return the repl pane
+    pane))


switched from selmer to hiccup

switched from selmer to hiccup

--- resources/leiningen/new/closp/clj/service/auth.clj
+++ resources/leiningen/new/closp/clj/service/auth.clj
@@ -21,7 +21,7 @@
 (defn unauthorized-handler
   [request _]
   (let [current-url (:uri request)]
-    (redirect (format "/user/login?next=%s" current-url))))
+    (redirect (format "/user/login?nexturl=%s" current-url))))

 (def auth-backend
   (session-backend {:unauthorized-handler unauthorized-handler}))


Change http link to use https for fonts

Change http link to use https for fonts

--- src/cornwalltechjam/layout.clj
+++ src/cornwalltechjam/layout.clj
@@ -57,7 +57,7 @@
     [:title {} title]
     [:link {:rel "shortcut icon", :href "/assets/img/favicon.png"}]
     [:meta {:name "description", :content description}]
-    [:link {:href "http://fonts.googleapis.com/css?family=Lato:100,300,400|Open+Sans:400italic,400,600|Muli:300|Indie+Flower:400|Oswald:400,700,300" :rel "stylesheet"}]
+    [:link {:href "https://fonts.googleapis.com/css?family=Lato:100,300,400|Open+Sans:400italic,400,600|Muli:300|Indie+Flower:400|Oswald:400,700,300" :rel "stylesheet"}]
     [:link {:href "/assets/css/bootstrap.min.css", :rel "stylesheet"}]
     [:link {:href "/assets/css/bootstrap-switch.min.css", :rel "stylesheet"}]
     [:link {:href "/assets/css/font-awesome.min.css", :rel "stylesheet"}]


clean leftover debug line

clean leftover debug line

--- src/ctia/stores/es/mapping.clj
+++ src/ctia/stores/es/mapping.clj
@@ -668,6 +668,3 @@
          exploit-target-mapping
          sighting-mapping
          identity-mapping))
-
-
-(keys  incident-mapping)


Use uniform-rand fn for advanced damage calculations

--- src/dungeon_crusade/combat.clj
+++ src/dungeon_crusade/combat.clj
@@ -90,104 +90,104 @@
 (defn calc-dmg
   [attacker-race attack defender-race defender-body-part]
   (condp vec-match? [attacker-race attack defender-race defender-body-part]
-    [:bat        :bite         :human      :abdomen]   (+  (rand)  0.5)
-    [:bat        :bite         :human      :arm]       (+  (rand)  0.5)
-    [:bat        :bite         :human      :face]      (+  (rand)  0.5)
-    [:bat        :bite         :human      :foot]      (+  (rand)  0.5)
-    [:bat        :bite         :human      :head]      (+  (rand)  0.5)
-    [:bat        :bite         :human      :leg]       (+  (rand)  0.5)
-    [:bat        :bite         :human      :neck]      (+  (rand)  0.9)
-    [:bird       :bite         :human      :*]         (+  (* (rand) 0.5)  0.5)
-    [:bird       :claw         :human      :abdomen]   (+  (rand)  0.5)
-    [:bird       :claw         :human      :face]      (+  (rand)  0.8)
-    [:bird       :claw         :human      :neck]      (+  (rand)  0.7)
-    [:bird       :claw         :human      :*]         (+  (rand)  0.5)
-    [:boar       :bite         :human      :abdomen]   (+  (* 2.0 (rand))  0.5)
-    [:boar       :bite         :human      :arm]       (+  (rand)  0.5)
-    [:boar       :bite         :human      :face]      (+  (rand)  1.5)
-    [:boar       :bite         :human      :foot]      (+  (rand)  0.5)
-    [:boar       :bite         :human      :head]      (+  (rand)  1.5)
-    [:boar       :bite         :human      :leg]       (+  (rand)  0.8)
-    [:boar       :bite         :human      :neck]      (+  (rand)  1.5)
-    [:boar       :gore         :human      :abdomen]   (+  (rand)  2.5)
-    [:boar       :gore         :human      :arm]       (+  (rand)  1.5)
-    [:boar       :gore         :human      :face]      (+  (rand)  3.5)
-    [:boar       :gore         :human      :foot]      (+  (rand)  1.5)
-    [:boar       :gore         :human      :head]      (+  (rand)  3.5)
-    [:boar       :gore         :human      :leg]       (+  (rand)  2.5)
-    [:boar       :gore         :human      :neck]      (+  (rand)  3.5)
-    [:centipede  :bite         :human      :*]         (+  (* (rand) 0.5)  0.5)
-    [:clam       :clamp        :human      :*]         (+  (* (rand) 0.2)  0.1)
-    [:fish       :bite         :human      :*]         (+  (* (rand) 0.5)  0.2)
-    [:frog       :claw         :human      :*]         (+  (* (rand) 0.3)  0.1)
-    [:gecko      :bite         :human      :*]         (+  (* (rand) 0.2)  0.1)
-    [:human      :punch        :bat        :body]      (+  (rand)  0.5)
+    [:bat        :bite         :human      :abdomen]   (uniform-random 0.5 1.5)
+    [:bat        :bite         :human      :arm]       (uniform-random 0.5 1.5)
+    [:bat        :bite         :human      :face]      (uniform-random 0.5 1.5)
+    [:bat        :bite         :human      :foot]      (uniform-random 0.5 1.5)
+    [:bat        :bite         :human      :head]      (uniform-random 0.5 1.5)
+    [:bat        :bite         :human      :leg]       (uniform-random 0.5 1.5)
+    [:bat        :bite         :human      :neck]      (uniform-random 0.9 1.9)
+    [:bird       :bite         :human      :*]         (uniform-random 0.5 0.9)
+    [:bird       :claw         :human      :abdomen]   (uniform-random 0.5 1.5)
+    [:bird       :claw         :human      :face]      (uniform-random 0.8 1.8)
+    [:bird       :claw         :human      :neck]      (uniform-random 0.7 1.7)
+    [:bird       :claw         :human      :*]         (uniform-random 0.5 1.5)
+    [:boar       :bite         :human      :abdomen]   (uniform-random 0.5 2.5)
+    [:boar       :bite         :human      :arm]       (uniform-random 0.5 3.5)
+    [:boar       :bite         :human      :face]      (uniform-random 0.5 2.5)
+    [:boar       :bite         :human      :foot]      (uniform-random 0.5 1.5)
+    [:boar       :bite         :human      :head]      (uniform-random 1.5 3.5)
+    [:boar       :bite         :human      :leg]       (uniform-random 0.9 1.8)
+    [:boar       :bite         :human      :neck]      (uniform-random 1.5 2.5)
+    [:boar       :gore         :human      :abdomen]   (uniform-random 2.5 4.5)
+    [:boar       :gore         :human      :arm]       (uniform-random 1.5 2.5)
+    [:boar       :gore         :human      :face]      (uniform-random 3.5 4.5)
+    [:boar       :gore         :human      :foot]      (uniform-random 1.5 2.5)
+    [:boar       :gore         :human      :head]      (uniform-random 3.5 4.5)
+    [:boar       :gore         :human      :leg]       (uniform-random 2.5 3.5)
+    [:boar       :gore         :human      :neck]      (uniform-random 3.5 4.5)
+    [:centipede  :bite         :human      :*]         (uniform-random 0.5 0.9)
+    [:clam       :clamp        :human      :*]         (uniform-random 0.1 0.3)
+    [:fish       :bite         :human      :*]         (uniform-random 0.2 1.7)
+    [:frog       :claw         :human      :*]         (uniform-random 0.1 0.5)
+    [:gecko      :bite         :human      :*]         (uniform-random 0.1 0.3)
+    [:human      :punch        :bat        :body]      (uniform-random 0.5 1.5)
     [:human      :punch        :bat        #{:face
-                                             :head}]   (+  (rand)  0.8)
-    [:human      :punch        :bat        :leg]       (+  (rand)  0.2)
-    [:human      :punch        :bat        :wing]      (+  (rand)  0.8)
-    [:human      :punch        :bird       :beak]      (+  (rand)  0.5)
-    [:human      :punch        :bird       :body]      (+  (rand)  0.5)
-    [:human      :punch        :bird       :head]      (+  (rand)  0.5)
-    [:human      :punch        :bird       :leg]       (+  (* (rand) 0.5) 0.5)
-    [:human      :punch        :bird       :tail]      (+  (rand)  0.5)
-    [:human      :punch        :bird       :wing]      (+  (rand) 1.5)
-    [:human      :punch        :boar       :body]      (+  (rand)  0.5)
-    [:human      :punch        :boar       :eye]       (+  (rand)  2.5)
-    [:human      :punch        :boar       :face]      (+  (rand)  0.9)
-    [:human      :punch        :boar       :head]      (+  (rand)  0.3)
-    [:human      :punch        :boar       :leg]       (+  (rand)  0.7)
-    [:human      :punch        :boar       :snout]     (+  (rand)  0.7)
-    [:human      :punch        :boar       :tail]      (+  (* (rand) 0.6)  0.1)
+                                             :head}]   (uniform-random 0.8 1.8)
+    [:human      :punch        :bat        :leg]       (uniform-random 0.2 0.5)
+    [:human      :punch        :bat        :wing]      (uniform-random 0.8 1.8)
+    [:human      :punch        :bird       :beak]      (uniform-random 0.5 1.5)
+    [:human      :punch        :bird       :body]      (uniform-random 0.5 1.5)
+    [:human      :punch        :bird       :head]      (uniform-random 0.5 1.5)
+    [:human      :punch        :bird       :leg]       (uniform-random 0.5 1.0)
+    [:human      :punch        :bird       :tail]      (uniform-random 0.5 1.5)
+    [:human      :punch        :bird       :wing]      (uniform-random 1.5 2.5)
+    [:human      :punch        :boar       :body]      (uniform-random 0.5 1.5)
+    [:human      :punch        :boar       :eye]       (uniform-random 2.5 3.5)
+    [:human      :punch        :boar       :face]      (uniform-random 0.9 1.9)
+    [:human      :punch        :boar       :head]      (uniform-random 0.3 1.3)
+    [:human      :punch        :boar       :leg]       (uniform-random 0.7 1.7)
+    [:human      :punch        :boar       :snout]     (uniform-random 0.7 1.7)
+    [:human      :punch        :boar       :tail]      (uniform-random 0.1 1.1)
     [:human      :punch        :centipede  #{:body
-                                             :head}]   (+  (rand)  0.9)
-    [:human      :punch        :centipede  :leg]       (+  (* (rand) 0.2)  0.1)
-    [:human      :punch        :clam       :shell]     (+  (rand)  0.5)
+                                             :head}]   (uniform-random 0.9 1.9)
+    [:human      :punch        :centipede  :leg]       (uniform-random 0.1 0.5)
+    [:human      :punch        :clam       :shell]     (uniform-random 0.5 1.5)
     [:human      :punch        :fish       #{:body
-                                             :head}]   (+  (rand)  0.5)
+                                             :head}]   (uniform-random 0.5 1.5)
     [:human      :punch        :fish       #{:fin
-                                             :tail}]   (+  (* (rand) 0.6) 0.5)
-    [:human      :punch        :frog       :*]         (+  (rand)  0.5)
-    [:human      :punch        :gecko      :*]         (+  (rand)  0.5)
+                                             :tail}]   (uniform-random 0.5 1.1)
+    [:human      :punch        :frog       :*]         (uniform-random 0.5 1.5)
+    [:human      :punch        :gecko      :*]         (uniform-random 0.5 1.5)
     [:human      :punch        :monkey     #{:arm
-                                             :leg}]       (+  (rand)  0.5)
+                                             :leg}]    (uniform-random 0.5 1.5)
     [:human      :punch        :monkey     #{:body
                                              :face
                                              :head
-                                             :neck}]   (+  (rand)  0.5)
-    [:human      :punch        :monkey     :tail]      (+  (* (rand) 0.5)  0.5)
+                                             :neck}]   (uniform-random 0.5 1.5)
+    [:human      :punch        :monkey     :tail]      (uniform-random 0.2 1.0)
     [:human      :punch        :octopus    #{:body
-                                             :head}]   (+  (rand)  1.5)
-    [:human      :punch        :octopus    :tentacle]  (+  (rand)  0.5)
+                                             :head}]   (uniform-random 1.5 2.9)
+    [:human      :punch        :octopus    :tentacle]  (uniform-random 0.5 1.5)
     [:human      :punch        :parrot     #{:body
                                              :face
-                                             :head}]   (+  (rand)  0.5)
+                                             :head}]   (uniform-random 0.5 1.5)
     [:human      :punch        :parrot     #{:leg
-                                             :tail}]   (+  (* (rand) 0.7)  0.5)
-    [:human      :punch        :parrot     :wing]      (+  (rand)  0.8)
+                                             :tail}]   (uniform-random 0.5 1.3)
+    [:human      :punch        :parrot     :wing]      (uniform-random 0.8 1.8)
     [:human      :punch        :rat        #{:body
                                              :face
                                              :head
-                                             :neck}]   (+  (rand)  0.5)
+                                             :neck}]   (uniform-random 0.5 1.5)
     [:human      :punch        :rat        #{:leg
-                                             :tail}]   (+  (* (rand) 0.7)  0.5)
+                                             :tail}]   (uniform-random 0.5 1.2)
     [:human      :punch        :scorpion   #{:abdomen
                                              :head
-                                             :tail}]   (+  (rand)  0.9)
+                                             :tail}]   (uniform-random 0.9 1.9)
     [:human      :punch        :scorpion   #{:claw
-                                             :leg}]    (+  (rand)  0.5)
+                                             :leg}]    (uniform-random 0.5 1.5)
     [:human      :punch        :sea-snake  #{:body
-                                             :head}]   (+  (rand)  0.9)
+                                             :head}]   (uniform-random 0.9 1.9)
     [:human      :punch        :shark      #{:body
                                              :head
-                                             :nose}]   (+  (rand)  0.5)
+                                             :nose}]   (uniform-random 0.5 1.5)
     [:human      :punch        :shark      #{:fin
-                                             :tail}]   (+  (* (rand) 0.6)  0.5)
+                                             :tail}]   (uniform-random 0.5 1.1)
     [:human      :punch        :snake      #{:body
                                              :head
-                                             :tail}]   (+  (rand)  0.5)
+                                             :tail}]   (uniform-random 0.5 1.5)
     [:human      :punch        :spider     #{:abdomen
-                                             :face}]   (+  (rand)  0.5)
+                                             :face}]   (uniform-random 0.5 1.5)
     [:human      :punch        :spider     #{:leg}]    (uniform-rand 0.5 1.5)
     [:human      :punch        :squid      #{:body
                                              :head


Doc strings for all files in config.clj module

--- src/emender_jenkins/config.clj
+++ src/emender_jenkins/config.clj
@@ -36,6 +36,7 @@
         update-configuration))

 (defn assoc-in-if-not-nil
+    "Assoc new (updated) value into the configuration map, but only when new value exists."
     [input selector value]
     (if value
         (assoc-in input selector value)
@@ -54,22 +55,27 @@
     (pprint/pprint configuration))

 (defn get-api-prefix
+    "Read prefix for API calls from the configuration passed via HTTP request."
     [request]
     (-> request :configuration :api :prefix))

 (defn verbose?
+    "Read verbose mode settings from the configuration passed via HTTP request."
     [request]
     (-> request :configuration :config :verbose))

 (defn get-version
+    "Read service version from the configuration passed via HTTP request."
     [request]
     (-> request :configuration :info :version))

 (defn get-jenkins-url
+    "Read Jenkins URL from the configuration passed via HTTP request."
     [request]
     (-> request :configuration :jenkins :jenkins-url))

 (defn get-jenkins-auth
+    "Read Jenkins auth string from the configuration passed via HTTP request."
     [request]
     (-> request :configuration :jenkins :jenkins-auth))


Delete process-lisp.clj

Delete process-lisp.clj

--- src/iyye/bios/process-lisp.clj
+++ src/iyye/bios/process-lisp.clj
@@ -1,46 +0,0 @@
-; Iyye - AI agent
-; Copyright (C) 2016-2017  Sasha Yumzya
-
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU Affero General Public License as
-; published by the Free Software Foundation, either version 3 of the
-; License, or (at your option) any later version.
-
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-; GNU Affero General Public License for more details.
-
-; You should have received a copy of the GNU Affero General Public License
-; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-(ns iyye.bios.process-lisp
-   (:require [clojure.string :as str]
-             [iyye.bios.parse-lisp :as parse]
-             [iyye.bios.ioframes :as ioframes]
-             [iyye.bios.words :as words]))
-
-(defn process-control [tree input IO]
-  (let [cmd (first tree)
-        params (for [cur (rest tree)] (if (seq? cur) (process-control cur "substr" IO) cur))]
-    ;    (println "processing" cmd)
-    (if cmd
-      (dorun (words/action cmd params IO))
-      (ioframes/process-output IO (str "failed to parse: " input)))))
-
-(defn process-lispy-ctrl-input [IO input]
-  (let [tree (parse/get-syntax-tree input)]
-    (future (Thread/sleep 1000)
-            (process-control tree input IO))))
-
-(defn process-lispy-input [IO input]
-  (if (= \# (first input))
-    (process-lispy-ctrl-input IO (subs input 1))
-    (future (Thread/sleep 1000) (ioframes/process-output IO "parsing lispy sentences not implemented yet"))))
-
-(defn process-input [IO input]
-   (if (= input "What is answer to life, the universe and everything?")
-     (future (Thread/sleep 1000) ( ioframes/process-output IO "42" ))
-     (if (= \# (first input))
-       (process-lispy-input IO (subs input 1))
-       (future (Thread/sleep 1000) (ioframes/process-output IO "parsing sentences not implemented" )))))


Pre-unstash

Pre-unstash

--- src/leiningen/new/onyx_app.clj
+++ src/leiningen/new/onyx_app.clj
@@ -50,7 +50,7 @@
              (= args "bare") (into bare-files)))))
 ["Dockerfile" "script/run-container.sh" "script/run-peers.sh" "script/build.sh"]
 (defn files-to-render [opts]
-  (cond -> ["README.md" ".gitignore"
+  (cond-> ["README.md" ".gitignore"
             "LICENSE"   "project.clj"
             "env/dev/user.clj"
             "env/dev/onyx-app/sample_input.clj"


Add build-prs-only option to project settings

--- src-cljs/frontend/components/project_settings.cljs
+++ src-cljs/frontend/components/project_settings.cljs
@@ -544,6 +544,11 @@
                                      "If you have SSH keys, sensitive env vars or AWS credentials stored in your project settings and "
                                      "untrusted forks can make pull requests against your repo, then this option "
                                      "isn't for you!"])})
+            (describe-flag {:flag :build-prs-only
+                             :title "Only build pull requests"
+                             :blurb [:p
+                                     "By default, we will build all the commits for this project. Once turned on, we will only build branches "
+                                     "that have associated pull requests open. Note: This feature is always turned off for your default branch."]})
             (describe-flag {:flag :osx-code-signing-enabled
                             :title "Code Signing Support"
                             :blurb [:p


Show a feature flag for cocoapods caching

--- src-cljs/frontend/components/project_settings.cljs
+++ src-cljs/frontend/components/project_settings.cljs
@@ -375,7 +375,7 @@
             (describe-flag {:flag :junit
                             :title "JUnit support"
                             :blurb [:p
-                                    "This flag enables collection of test data via junit xml or cucumber json files,"
+                                    "This flag enables collection of test data via junit xml or cucumber json files,"
                                     " which we use to better display test results and make parallel builds more"
                                     " efficient.  It also adds the necessary flags for collecting this to automatically"
                                     " inferred ruby or python test commands, though for RSpec of Minitest you'll need"
@@ -413,7 +413,15 @@
                            :blurb [:p
                                    "If this option is selected, then CircleCI will run builds for this project "
                                    "on Mac OSX rather than Linux. Select this if you have an iOS application "
-                                   "that you want to build using CircleCI."]})]]])))))
+                                   "that you want to build using CircleCI."]})
+            (describe-flag {:flag :smart-cocoapods-caching
+                           :title "Smart CocoaPods Caching"
+                           :blurb [:p
+                                   "Enable aggressive caching of CocoaPods to remove the need to call the `pod install`
+                                   command on every build. This feature is under active development and might cause
+                                   spurious build failures from time to time."]})
+
+            ]]])))))

 (defn dependencies [project-data owner]
   (reify


Be more explicit about the provided secrets

--- src-cljs/frontend/components/project_settings.cljs
+++ src-cljs/frontend/components/project_settings.cljs
@@ -661,7 +661,7 @@
                             :title "Pass secrets to forked pull requests"
                             :blurb (list
                                     [:p
-                                     "Run builds of fork pull request changes with this project's configuration and secrets. "]
+                                     "Run builds of fork pull request changes with this project's configuration, environment variables, and secrets. "]
                                     [:p
                                      "There are serious security concerns with this setting (see "
                                      [:a (open-ext {:href "https://circleci.com/docs/fork-pr-builds/"}) "the documentation"] " for details.) "


Fix ... and _ not being quoted when returned to CLJS

--- src/main/app_macros/props.cljc
+++ src/main/app_macros/props.cljc
@@ -42,7 +42,11 @@
                  (= 2 (count %))
                  (value? (second %)))
     :name  #(first %)
-    :query #(-> [(keyword (:name %)) (:target %)])}
+    :query #(-> [(keyword (:name %))
+                 (let [target (:target %)]
+                   (cond
+                     (= target '_) ''_
+                     :else target))])}
    {:type  :join
     :test  #(and (map? %)
                  (= 1 (count %)))
@@ -50,7 +54,7 @@
     :query #(-> {(keyword (:name %))
                  (let [target (:target %)]
                    (cond
-                     (= target '...) '...
+                     (= target '...) ''...
                      (number? target) target
                      :else `(~'om.next/get-query ~target)))})}])


Remove redundant aside icons

Remove redundant aside icons

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -515,14 +515,16 @@

             [:hr]

-           [:a.aside-item (open-ext {:title "Documentation"
+           ;; TODO -ac Remove entirely
+            #_[:a.aside-item (open-ext {:title "Documentation"
                                      :data-placement "right"
                                      :data-trigger "hover"
                                      :href "https://circleci.com/docs/"})
               [:i.material-icons "description"]
               [:div.nav-label "Docs"]]

-            [:a.aside-item (merge (common/contact-support-a-info owner)
+           ;; TODO -ac Remove entirely
+            #_ [:a.aside-item (merge (common/contact-support-a-info owner)
                                  {:title "Support"
                                   :data-placement "right"
                                   :data-trigger "hover"
@@ -530,7 +532,8 @@
               [:i.material-icons "chat"]
               [:div.nav-label "Support"]]

-            (when-not (config/enterprise?)
+           ;; TODO -ac Remove entirely
+            #_(when-not (config/enterprise?)
               [:a.aside-item (open-ext {:data-placement "right"
                                         :data-trigger "hover"
                                         :title "Changelog"
@@ -548,7 +551,8 @@
                 [:i.material-icons "build"]
                 [:div.nav-label "Admin"]])

-            [:a.aside-item.push-to-bottom {:data-placement "right"
+           ;; TODO -ac Remove entirely
+            #_ [:a.aside-item.push-to-bottom {:data-placement "right"
                                            :data-trigger "hover"
                                            :title "Logout"
                                            :href "/logout"}


CMR-227: Added tests for collection time psa.

--- test/cmr/system_int_test/search/collection_psa_search_test.clj
+++ test/cmr/system_int_test/search/collection_psa_search_test.clj
@@ -358,6 +358,75 @@
            ;; only max range provided
            "datetime,bravo," nil 17 [coll1 coll2]

-           "datetime,charlie," 44 45 [coll2]))
-
-    ))
+           "datetime,charlie," 44 45 [coll2]))))
+
+
+(deftest time-psas-search-test
+  (let [psa1 (dc/psa "alpha" :time (d/make-time 10 false))
+        psa2 (dc/psa "bravo" :time (d/make-time 23 false))
+        psa3 (dc/psa "charlie" :time (d/make-time 45 false))
+        coll1 (d/ingest "PROV1" (dc/collection {:product-specific-attributes [psa1 psa2]}))
+        coll2 (d/ingest "PROV1" (dc/collection {:product-specific-attributes [psa2 psa3]}))]
+    (index/refresh-elastic-index)
+
+    (testing "search by value"
+      (are [v n items]
+           (d/refs-match?
+             items (search/find-refs :collection {"attribute[]" (str v (d/make-time n))}))
+           "time,alpha," 10 [coll1]
+           "time,alpha," 11 []
+           "time,bravo," 23 [coll1 coll2]
+           "time,charlie," 45 [coll2]))
+
+    (testing "search by value legacy parameters"
+      (are [v n items]
+           (d/refs-match? items
+                          (search/find-refs :collection (search/csv->tuples (str v (d/make-time n)))))
+           "time,alpha," 10 [coll1]
+           "time,alpha," 11 []
+           "time,bravo," 23 [coll1 coll2]
+           "time,charlie," 45 [coll2]))
+
+    (testing "search by range"
+      (are [v min-n max-n items]
+           (let [min-v (d/make-time min-n)
+                 max-v (d/make-time max-n)
+                 full-value (str v min-v "," max-v)]
+             (d/refs-match? items (search/find-refs :collection {"attribute[]" full-value})))
+
+           ;; inside range
+           "time,alpha," 9 11 [coll1]
+           ;; beginning edge of range
+           "time,alpha," 10 11 [coll1]
+           ;; ending edge of range
+           "time,alpha," 9 10 [coll1]
+
+           ;; only min range provided
+           "time,bravo," 20 nil [coll1 coll2]
+
+           ;; only max range provided
+           "time,bravo," nil 24 [coll1 coll2]
+
+           "time,charlie," 44 45 [coll2]))
+
+    (testing "search by range legacy parameters"
+      (are [v min-n max-n items]
+           (let [min-v (d/make-time min-n)
+                 max-v (d/make-time max-n)
+                 full-value (str v min-v "," max-v)]
+             (d/refs-match? items (search/find-refs :collection (search/csv->tuples full-value) {:snake-kebab? false})))
+
+           ;; inside range
+           "time,alpha," 9 11 [coll1]
+           ;; beginning edge of range
+           "time,alpha," 10 11 [coll1]
+           ;; ending edge of range
+           "time,alpha," 9 10 [coll1]
+
+           ;; only min range provided
+           "time,bravo," 20 nil [coll1 coll2]
+
+           ;; only max range provided
+           "time,bravo," nil 24 [coll1 coll2]
+
+           "time,charlie," 44 45 [coll2]))))


Do not sort replies by votes, preserve the original order.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -75,11 +75,10 @@
                                (-> reply
                                 (assoc :votes reply-votes)
                                 (assoc :votes-count (count reply-votes)))))
-                              (:replies poll))
-            sorted-replies (sort-by (juxt :votes-count :created-at) updated-replies)]
+                              (:replies poll))]
         (-> poll
          ;; Replace replies with new sorted ones
-         (assoc :replies sorted-replies)
+         (assoc :replies updated-replies)
          ;; Update the total count
          (assoc :total-votes-count (reduce + (map :votes-count updated-replies)))))
       poll))
@@ -447,8 +446,7 @@
   (let [user-has-voted? (some #(when (= % (:user-id user)) %) (:replies poll))

         updated-poll-replies (mapv (partial update-reply (:user-id user) reply-id add?) (:replies poll))
-        sorted-replies (reverse (sort-by (juxt :votes-count :created-at) updated-poll-replies))
-        updated-poll (merge poll {:replies sorted-replies :total-votes-count (reduce + (map :votes-count sorted-replies))})
+        updated-poll (merge poll {:replies updated-poll-replies :total-votes-count (reduce + (map :votes-count updated-poll-replies))})
         filtered-polls (filterv #(not= (:poll-uuid %) (:poll-uuid poll)) (:polls entry))
         final-entry (assoc entry :polls (vec (conj filtered-polls updated-poll)))
         updated-entry (entry-res/update-entry-no-user! conn (:uuid entry) final-entry)]


The key :moving-board can be empty, get it out of the if-let or it will fail the whole update.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -153,12 +153,11 @@
   (timbre/info "Updating entry for:" entry-for)
   (if-let* [org (:existing-org ctx)
             board (:existing-board ctx)
-            old-board (:moving-board ctx)
             user (:user ctx)
             entry (:existing-entry ctx)
             updated-entry (:updated-entry ctx)
             updated-result (entry-res/update-entry! conn (:uuid updated-entry) updated-entry user)]
-    (do
+    (let [old-board (:moving-board ctx)]
       ;; If we are moving the entry from a draft board, check if we need to remove the board itself.
       (when old-board
         (let [remaining-entries (entry-res/list-all-entries-by-board conn (:uuid old-board))]


Re-organize structure

Re-organize structure

--- src/ji/core.cljs
+++ src/ji/core.cljs
@@ -25,24 +25,29 @@
 (defn card-selector
   "todo: general partition/chunking buffer"
   [card-chan control-chan]
-  (let [c (chan)]
+  (let [out (chan)]
     (go
-      (loop [cs #{}]
+      (loop [cs #{}
+             paused? false]
         (let [[v sc] (alts! [card-chan control-chan])]
           (if (= sc control-chan)
-            (recur #{}) ;; currently only reset
-            (let [cs' (conj cs v)]
-              (cond
-                (= cs cs') (recur (disj cs v))
-                (<= 3 (count cs')) (do
-                                    (>! c cs')
-                                    (recur #{}))
-                :else (recur cs')))))))
-    c))
+            (condp = v
+              ;nil (close! out)
+              :pause (recur cs true)
+              :unpause (recur cs false)
+              :reset (recur #{} paused?))
+            (cond
+              ;(nil? v) (close! out)
+              paused? (recur cs paused?)
+              (cs v) (recur (disj cs v) paused?)
+              (<= 2 (count cs)) (do (>! out (conj cs v))
+                                    (recur #{} paused?))
+              :else (recur (conj cs v) paused?))))))
+    out))

 (defn add-card!
-  [card parent-el out]
+  [parent-el out card]
   (let [el (card-tmpl card)
         eh #(put! out card)]
     (dom/append! parent-el el)
@@ -52,8 +57,8 @@
      :unsubscribe #(dom/unlisten! el :click eh)}))

 (defn add-cards!
-  [cards parent-el out]
-  (map #(add-card! % parent-el out) cards))
+  [parent-el out cards]
+  (doall (for [card cards] (add-card! parent-el out card))))

 (defn render-solutions!
   [sets]
@@ -63,47 +68,48 @@
     (doseq [s sets]
       (dom/append! el (node [:div.set (map card-tmpl s)])))))

-(defn init []
-  (let [[board deck] (->> (new-deck) (shuffle) (separate 12))
-        control (chan)
-        card-sel (chan)
-        set-sel (card-selector card-sel control)
-        valid-sets (chan)
-        board (doall (map #(add-card! % (sel1 :#board) card-sel) board))
-
+(defn valid-sets-chan
+  [set-sel]
+  (let [out (chan)
         clear-selection #(doseq [el (sel :.card.selected)]
-                           (dom/remove-class! el "selected"))
-        ]
-
+                           (dom/remove-class! el "selected"))]
     (go-loop
       (let [cs (<! set-sel)]
         (clear-selection)
         (when (is-set? cs)
-          (>! valid-sets cs))))
+          (>! out cs))))
+    out))

-    (go
-      (loop [deck deck
-             board board]
-        (let [solutions (solve-board (map :card board))]
-         (render-solutions! solutions))
+(defn game-loop
+  [{:keys [deck board]} control card-sel valid-sets]
+  (go
+    (loop [deck deck
+           board board]
+      (let [solutions (solve-board (map :card board))]
+        (render-solutions! solutions))
+      (let [card-unsubs (hash-by :card :unsubscribe board) ;; todo
+            card-els (hash-by :card :el board) ;; todo
+            cs (<! valid-sets)]
+        (doseq [card cs :let [el (card-els card)] ]
+          ((card-unsubs card))
+          (dom/remove! el))
+        (dom/append! (sel1 :#set-history)
+                     (node [:li.set (map card-tmpl cs)]))
+        (recur (drop 3 deck)
+               (concat (remove #(cs (:card %)) board)
+                       (add-cards! (sel1 :#board) card-sel (take 3 deck))))))))

-        (let [card-unsubs (hash-by :card :unsubscribe board) ;; todo
-              card-els (hash-by :card :el board) ;; todo
-              cs (<! valid-sets)]
-          (doseq [card cs :let [el (card-els card)] ]
-            ((card-unsubs card))
-            (dom/remove! el))
-          (dom/append! (sel1 :#set-history)
-                       (node [:li.set (map card-tmpl cs)]))
-          (recur (drop 3 deck)
-                 (concat (remove #(cs (:card %)) board)
-                         (add-cards! (take 3 deck) (sel1 :#board) card-sel))))
-        ))
+(defn init []
+  (let [control (chan)
+        card-sel (chan)
+        valid-sets (valid-sets-chan (card-selector card-sel control))
+        [board deck] (->> (new-deck) (shuffle) (separate 12))
+        board (add-cards! (sel1 :#board) card-sel board)]
+    (dom/listen! [(sel1 :#content) :.card] :click
+                 #(-> (.-target %)
+                      (dom/closest :.card)
+                      (dom/toggle-class! "selected")))

-    (dom/listen! [(sel1 :#content) :.card]
-                 :click
-                 #(dom/toggle-class! (dom/closest (.-target %) :.card) "selected"))
-
-    ))
+    (game-loop {:deck deck :board board} control card-sel valid-sets)))

 (init)


Now we can use core.async threads.

Now we can use core.async threads.

--- src/onyx/coordinator/async.clj
+++ src/onyx/coordinator/async.clj
@@ -302,16 +302,16 @@
         :failure-mult failure-mult
         :shutdown-mult shutdown-mult

-        :born-peer-thread (future (born-peer-ch-loop log sync born-peer-ch-tail offer-ch-head dead-peer-ch-head))
-        :dead-peer-thread (future (dead-peer-ch-loop log dead-peer-ch-tail evict-ch-head offer-ch-head))
-        :planning-thread (future (planning-ch-loop log queue planning-ch-tail offer-ch-head))
-        :ack-thread (future (ack-ch-loop log sync ack-ch-tail))
-        :evict-thread (future (evict-ch-loop log sync evict-ch-tail offer-ch-head shutdown-ch-head))
-        :offer-thread (future (offer-ch-loop log sync revoke-delay offer-ch-tail ack-ch-head completion-ch-head offer-revoke-ch-head))
-        :offer-revoke-thread (future (offer-revoke-ch-loop log sync offer-revoke-ch-tail evict-ch-head))
-        :completion-thread (future (completion-ch-loop log sync queue completion-ch-tail offer-ch-head))
-        :failure-thread (future (failure-ch-loop failure-ch-tail))
-        :shutdown-thread (future (shutdown-ch-loop sync shutdown-ch-tail)))))
+        :born-peer-thread (thread (born-peer-ch-loop log sync born-peer-ch-tail offer-ch-head dead-peer-ch-head))
+        :dead-peer-thread (thread (dead-peer-ch-loop log dead-peer-ch-tail evict-ch-head offer-ch-head))
+        :planning-thread (thread (planning-ch-loop log queue planning-ch-tail offer-ch-head))
+        :ack-thread (thread (ack-ch-loop log sync ack-ch-tail))
+        :evict-thread (thread (evict-ch-loop log sync evict-ch-tail offer-ch-head shutdown-ch-head))
+        :offer-thread (thread (offer-ch-loop log sync revoke-delay offer-ch-tail ack-ch-head completion-ch-head offer-revoke-ch-head))
+        :offer-revoke-thread (thread (offer-revoke-ch-loop log sync offer-revoke-ch-tail evict-ch-head))
+        :completion-thread (thread (completion-ch-loop log sync queue completion-ch-tail offer-ch-head))
+        :failure-thread (thread (failure-ch-loop failure-ch-tail))
+        :shutdown-thread (thread (shutdown-ch-loop sync shutdown-ch-tail)))))

   (stop [component]
     (prn "Stopping Coordinator")


Bad formatting

Bad formatting

--- src/onyx/peer/virtual_peer.clj
+++ src/onyx/peer/virtual_peer.clj
@@ -86,8 +86,7 @@
           (>!! outbox-ch entry)

           (let [outbox-loop-ch (thread (outbox-loop id log outbox-ch))
-                processing-loop-ch (thread (processing-loop id log messenger origin inbox-ch outbox-ch restart-ch kill-ch completion-ch opts monitoring task-component-fn))
-                ]
+                processing-loop-ch (thread (processing-loop id log messenger origin inbox-ch outbox-ch restart-ch kill-ch completion-ch opts monitoring task-component-fn))]
             (assoc component
                    :outbox-loop-ch outbox-loop-ch
                    :processing-loop-ch processing-loop-ch


Remove extra store log entry

Remove extra store log entry

--- src/onyx/peer/window_state.clj
+++ src/onyx/peer/window_state.clj
@@ -268,7 +268,6 @@
                                          monitoring
                                          (- (System/currentTimeMillis) start-time)))
         log-entry (keep second rs)]
-    (state-extensions/store-log-entry state-log task-event success-fn log-entry)))
     (when-not (empty? log-entry)
       (state-extensions/store-log-entry state-log task-event success-fn log-entry))))


Fix issues with retry-ch implementation

Fix issues with retry-ch implementation

--- src/onyx/plugin/bookkeeper.clj
+++ src/onyx/plugin/bookkeeper.clj
@@ -64,12 +64,14 @@
 ;; read BookKeeper log plugin

 (defn close-read-ledgers-resources
-  [{:keys [bookkeeper/producer-ch bookkeeper/commit-ch bookkeeper/read-ch bookkeeper/shutdown-ch] :as event} lifecycle]
+  [{:keys [bookkeeper/producer-ch bookkeeper/commit-ch bookkeeper/read-ch bookkeeper/retry-ch bookkeeper/shutdown-ch] :as event} lifecycle]
   (info "Closing read ledger resources:" (:onyx.core/task event))
   (close! shutdown-ch)
   (close! read-ch)
+  (close! retry-ch)
   ;; Drain the read-ch to unblock the producer
   (while (poll! read-ch))
+  (while (poll! retry-ch))
   (close! commit-ch)
   (let [timeout-ms 15000]
     (when-not (= producer-ch (second (alts!! [producer-ch (timeout timeout-ms)])))
@@ -181,7 +183,7 @@
             (default-value :bookkeeper/ledger-end-id Double/POSITIVE_INFINITY)
             (default-value :bookkeeper/no-recovery-empty-read-back-off 500)
             (default-value :checkpoint/key task-id))
-        {:keys [read-ch shutdown-ch commit-ch error]} pipeline
+        {:keys [read-ch shutdown-ch retry-ch commit-ch error]} pipeline
         ;; decrement because we are going to store this as a checkpoint and then inc after recover
         checkpoint-key (:checkpoint/key defaulted-task-map)
         _ (set-starting-offset! log task-map checkpoint-key (dec ledger-start-id))
@@ -208,6 +210,7 @@
                           (reset! error e)
                           (fatal e "BookKeeper plugin: error reading."))))]
     {:bookkeeper/read-ch read-ch
+     :bookkeeper/retry-ch retry-ch
      :bookkeeper/shutdown-ch shutdown-ch
      :bookkeeper/commit-ch commit-ch
      :bookkeeper/producer-ch producer-ch
@@ -255,6 +258,7 @@
                  (all-done? batch)
                  (or (not (empty? @pending-messages))
                      (not (empty? batch)))
+                 (zero? (count (.buf retry-ch)))
                  (zero? (count (.buf read-ch))))
         (when-not (:checkpoint/key (:onyx.core/task-map event))
           (>!! commit-ch {:status :complete}))
@@ -291,7 +295,7 @@
         batch-size (:onyx/batch-size task-map)
         batch-timeout (or (:onyx/batch-timeout task-map) (:onyx/batch-timeout defaults))
         read-ch (chan (or (:bookkeeper/read-buffer task-map) 1000))
-        retry-ch (chan max-pending)
+        retry-ch (chan (* 2 max-pending))
         error (atom nil)
         commit-ch (chan (sliding-buffer 1))
         shutdown-ch (chan 1)


more tests

more tests

--- dada-core/src/test/clojure/org/dada/core/test_clojure.clj
+++ dada-core/src/test/clojure/org/dada/core/test_clojure.clj
@@ -3,6 +3,8 @@
      [clojure test]
      )
     )
+
+(set! *warn-on-reflection* true)

 ;; test the speed of various bits of clojure to help ascertain which way DADA should do things

@@ -62,8 +64,41 @@
 ;;(deftest assoc-vs-conj
 ;;  (is (faster 1 (reduce (fn [r i] (assoc r i i)) {} (range 3000000)) (reduce (fn [r i] (conj r [i i])) {} (range 3000000)))))

-;; surely some mistake (on my part) here - I can look up a field in a record 100o x faster than I can in an array - I expected it to be fater, but...
+;; surely some mistake (on my part) here - I can look up a field in a record 100o x faster than I can in an array - I expected it to be faster, but...
+;; this is down to reflection - investigate how to use an Object array efficiently
+;; type hint was wrong - but why ?
 (deftest record-vs-array-access
   (let [^Value r (Value. 0)
-	^{:tag (type (into-array Object []))} a (into-array Object [0])]
-    (is (faster 1000000 (.v r) (aget a 0)))))
+ 	^objects a (into-array Object [0])]
+    (is (faster 1000000000 (.v r) (aget a 0)))))
+
+;; but accessing a record field still appears to be 10 times faster than an array - is the int being boxed on the way out ?
+(deftest record-vs-int-array-access
+  (let [^Value r (Value. 0)
+	^ints a (int-array [0])]
+    (is (faster 1000000000 (.v r) (aget a 0)))))
+
+;; no it's not autoboxing slowing down the int-array test - array access is slower than record access - by a factor of 10
+(deftest record-vs-object-array-access
+  (let [^Value r (Value. 0)
+	^objects a (object-array [0])]
+    (is (faster 1000000000 (.v r) (aget a 0)))))
+
+(defrecord Foo (^int a))
+(defrecord Bar (^Integer a))
+
+;; int is faster (5x) - to be expected
+(deftest record-int-vs-integer
+  (let [f (Foo. 1)
+	b (Bar. 1)]
+    (is (faster 1000000000 (.a b)  (.a f)))))
+
+;; interesting - reading an int out of a record and pssing it into
+;; another fn (causing it to be auto-boxed) is still 5-10x faster than
+;; just reading an Integer out of a record and passing it straight
+;; into the same fn...
+(deftest record-boxed-int-vs-integer
+  (let [f (Foo. 1)
+	b (Bar. 1)]
+    (is (faster 1000000000 (identity (.a b))  (identity (.a f))))))
+


fix up camelcase names in envgen metadata

--- src/overtone/sc/machinery/ugen/metadata/envgen.clj
+++ src/overtone/sc/machinery/ugen/metadata/envgen.clj
@@ -78,11 +78,11 @@
               {:name "gate",
                :default 1.0
                :doc "this triggers the envelope and holds it open while
-                     > 0. If the Env is fixed-length (e.g. Env.linen,
-                     Env.perc), the gate argument is used as a simple
-                     trigger. If it is an sustaining envelope (e.g. Env.adsr,
-                     Env.asr), the envelope is held open until the gate
-                     becomes 0, at which point is released."}
+               > 0. If the Env is fixed-length (e.g. perc), the gate
+               argument is used as a simple trigger. If it is an
+               sustaining envelope (e.g. adsr, asr), the envelope is
+               held open until the gate becomes 0, at which point is
+               released." }

               {:name "level-scale",
                :default 1.0
@@ -140,10 +140,10 @@
               {:name "action", :default 0 :doc "done action"}],

        :rates #{:kr}
-       :doc "A linear envelope generator, rises to susLevel over
-             attackTime seconds and after the gate goes non-positive
-             falls over releaseTime to finally perform an option
-             doneAction"}
+       :doc "A linear envelope generator, rises to sus-level over
+             attack-time seconds and after the gate goes non-positive
+             falls over release-time to finally perform the (optional)
+             action"}

       ;; TODO figure out what an IEnvGen is and write init
       {:name "IEnvGen"


support irregular conditional: use :future-stem

--- src/babel/francais/morphology/verbs.clj
+++ src/babel/francais/morphology/verbs.clj
@@ -28,6 +28,9 @@
         stem (if re-type
                ;; prendre -> prend
                (string/replace infinitive #"re$" "")
+               stem)
+        stem (if (get-in word [:future-stem])
+               (get-in word [:future-stem])
                stem)
         last-stem-char-is-i (re-find #"ir$" infinitive)
         last-stem-char-is-e (re-find #"er$" infinitive)


Override padding in text input

Override padding in text input

Signed-off-by: Gheorghe Pinzaru <742a0a3885ab52ea1795e48e261ec4223e194612@gmail.com>

--- src/status_im/ui/components/search_input/view.cljs
+++ src/status_im/ui/components/search_input/view.cljs
@@ -17,7 +17,9 @@
                        :on-cancel       on-cancel
                        :auto-correct    false
                        :auto-capitalize :none
-                       :input-style     {:height 36}
+                       :input-style     {:height         36
+                                         :padding-top    2
+                                         :padding-bottom 2}
                        :before          {:icon      :main-icons/search
                                          :style     {:padding-horizontal 8}
                                          :on-press  #(.focus ^js @input-ref)


Simplify drawtools sidebar main data structure.

--- src/uxbox/main/ui/workspace/sidebar/drawtools.cljs
+++ src/uxbox/main/ui/workspace/sidebar/drawtools.cljs
@@ -64,31 +64,30 @@
    :content "Hello world"})

 (def +draw-tools+
-  {:rect
-   {:icon i/box
+  [{:icon i/box
     :help (tr "ds.help.rect")
     :shape +draw-tool-rect+
     :priority 1}
-   :circle
    {:icon i/circle
     :help (tr "ds.help.circle")
     :shape +draw-tool-circle+
     :priority 2}
-   :line
    {:icon i/line
     :help (tr "ds.help.line")
     :shape +draw-tool-line+
     :priority 3}
-   :text
    {:icon i/text
     :help (tr "ds.help.text")
     :shape +draw-tool-text+
     :priority 4}
-   :path
    {:icon i/curve
     :help (tr "ds.help.path")
     :shape +draw-tool-path+
-    :priority 5}})
+    :priority 5}
+   {:icon i/pencil
+    :help (tr "ds.help.path")
+    :shape (assoc +draw-tool-path+ :free true)
+    :priority 6}])

 ;; --- Draw Toolbox (Component)

@@ -110,11 +109,11 @@
       [:span (tr "ds.draw-tools")]
       [:div.tool-window-close {:on-click close} i/close]]
      [:div.tool-window-content
-      (for [[key props] tools
+      (for [[i props] (map-indexed vector tools)
             :let [selected? (= drawing (:shape props))]]
         [:div.tool-btn.tooltip.tooltip-hover
          {:alt (:help props)
           :class (when selected? "selected")
-          :key (name key)
+          :key (str i)
           :on-click (partial select-for-draw (:shape props))}
          (:icon props)])]]))


CMR-387: Changed code to use map->Orbit.

--- src/cmr/umm/test/generators/spatial.clj
+++ src/cmr/umm/test/generators/spatial.clj
@@ -61,9 +61,10 @@
 (def orbits
   "A generator returning an Orbit record for a spatial domain."
   (ext-gen/model-gen
-    g/->Orbit
-    longitude
-    latitude
-    orbit-directions
-    latitude
-    orbit-directions))+    g/map->Orbit
+    (gen/hash-map
+      :ascending-crossing longitude
+      :start-lat latitude
+      :start-direction orbit-directions
+      :end-lat latitude
+      :end-direction orbit-directions)))


(PE-3142) Make cp-shared-config-files copy the full directory structure

This means upstream projects need to put shared conf in ext/config/conf.d
instead of ext/config/shared. This makes sense anyway since it mirrors where
they'll end up.

--- src/puppetlabs/ezbake/core.clj
+++ src/puppetlabs/ezbake/core.clj
@@ -14,7 +14,7 @@

 (def template-dir-prefix "./template")
 (def staging-dir "./target/staging")
-(def shared-config-prefix "ext/config/shared/")
+(def shared-config-prefix "ext/config/conf.d/")
 (def docs-prefix "ext/docs/")
 (def terminus-prefix "puppet/indirector")

@@ -173,19 +173,18 @@
              (fs/file staging-dir "ext" "debian" (format "%s.default.erb"
                                                          (:name lein-project)))))

-(defn get-out-dir-for-shared-config-file
-  [dep jar-entry]
-  (let [rel-path (relativize shared-config-prefix (File. (.getName jar-entry)))]
-    (if-let [parent (.getParent rel-path)]
-      (fs/file staging-dir "ext" "config" "conf.d" parent)
-      (fs/file staging-dir "ext" "config" "conf.d"))))
+(defn- get-config-files-in
+  [jar]
+  (deputils/find-files-in-dir-in-jar jar shared-config-prefix))

 (defn cp-shared-config-files
-  [lein-project]
-  (mapv (partial relativize staging-dir)
-        (deputils/cp-files-of-type lein-project "shared config"
-                                   shared-config-prefix
-                                   get-out-dir-for-shared-config-file)))
+  [dependencies]
+  (let [files (for [{:keys [project jar]} dependencies]
+                [project jar (get-config-files-in jar)])]
+    (doseq [[project jar config-files] files]
+      (deputils/cp-files-from-jar config-files jar staging-dir))
+    ;; Return just a list of the files
+    (mapcat last files)))

 (defn cp-project-config-file
   [project-config-dir config-file]
@@ -290,9 +289,8 @@
 (defn cp-terminus-files
   "Stage all terminus files. Returns a sequence zipping project names and
   their terminus files."
-  [lein-project]
-  (let [dependencies (deputils/get-dependencies-with-jars lein-project)
-        files (for [{:keys [project jar]} dependencies
+  [dependencies]
+  (let [files (for [{:keys [project jar]} dependencies
                     :let [terminus-files (get-terminus-files-in jar)]
                     :when (not (empty? terminus-files))]
                 [project terminus-files jar])]
@@ -418,9 +416,10 @@
   (clean)
   (cp-template-files template-dir)
   (cp-shared-files)
-  (let [config-files (cp-shared-config-files lein-project)
+  (let [dependencies (deputils/get-dependencies-with-jars lein-project)
+        config-files (cp-shared-config-files dependencies)
         config-files (cp-project-config-files project config-files)
-        terminus-files (cp-terminus-files lein-project)]
+        terminus-files (cp-terminus-files dependencies)]
     (cp-doc-files lein-project)
     (cp-project-file project-file)
     (rename-redhat-spec-file lein-project)


Work even when no default show exists.

Work even when no default show exists.

--- src/afterglow/effects/params.clj
+++ src/afterglow/effects/params.clj
@@ -340,7 +340,7 @@
   Step parameters are always frame-dynamic."
   {:doc/format :markdown}
   [& {:keys [interval fade-fraction starting]
-      :or {interval :beat fade-fraction 0 starting (metro-snapshot (:metronome *show*))}}]
+      :or {interval :beat fade-fraction 0 starting (when *show* (metro-snapshot (:metronome *show*)))}}]
   {:pre [(#{:beat :bar :phrase} interval) (util/float<= 0 fade-fraction 1) (satisfies? rhythm/ISnapshot starting)]}
   (let [phase-key (keyword (str (name interval) "-phase"))
         origin (dec (+ (interval starting) (math/round (phase-key starting))))


Properly resolve param formulas with >1 arg

--- src/afterglow/effects/params.clj
+++ src/afterglow/effects/params.clj
@@ -1016,7 +1016,7 @@
     (result-type [this]
       param-type)
     (resolve-non-frame-dynamic-elements [this show snapshot head]
-      (build-param-formula param-type calc-fn
-                           (map #(resolve-unless-frame-dynamic % show snapshot head) input-params)))))
+      (apply build-param-formula param-type calc-fn
+             (map #(resolve-unless-frame-dynamic % show snapshot head) input-params)))))

 ;; TODO: some kind of random parameter?


changed rendering function of om tag and user pills to render the reagent implementation

--- src/chat/client/views/pills.cljs
+++ src/chat/client/views/pills.cljs
@@ -1,10 +1,24 @@
 (ns chat.client.views.pills
   (:require [om.core :as om]
             [om.dom :as dom]
+            [braid.ui.views.pills :refer [tag-pill-view user-pill-view]]
+            [chat.client.reagent-adapter :refer [reagent->react subscribe]]
             [chat.client.dispatcher :refer [dispatch!]]
             [chat.client.store :as store]
             [chat.client.views.helpers :refer [id->color user-cursor]]
             [chat.client.routes :as routes]))
+
+(defn tag-pill-view-temp [props]
+  [tag-pill-view (props :tag) subscribe])
+
+(defn user-pill-view-temp [props]
+  [user-pill-view (props :user) subscribe])
+
+(def TagPillView
+  (reagent->react tag-pill-view-temp))
+
+(def UserPillView
+  (reagent->react user-pill-view-temp))

 (defn subscribe-button [tag]
   (if (store/is-subscribed-to-tag? (tag :id))
@@ -21,34 +35,10 @@
   (reify
     om/IRender
     (render [_]
-      (dom/a #js {:className (str "tag pill"
-                                  (if (store/is-subscribed-to-tag? (tag :id))
-                                    " on"
-                                    " off"))
-                  :tabIndex -1
-                  :style #js {:backgroundColor (id->color (tag :id))
-                              :color (id->color (tag :id))
-                              :borderColor (id->color (tag :id))}
-                  :href (routes/tag-page-path {:group-id (routes/current-group)
-                                               :tag-id (tag :id)})}
-        (dom/span #js {:className "name"} "#" (tag :name))))))
+      (TagPillView. #js {:tag tag}))))

 (defn user-view [user owner]
   (reify
     om/IRender
     (render [_]
-      (if-let [cur (user-cursor (user :id))]
-        (let [user (om/observe owner cur)]
-          (dom/a #js {:className (str "user pill" (case (user :status)
-                                                    :online " on"
-                                                    " off"))
-                      :tabIndex -1
-                      :style #js {:backgroundColor (id->color (user :id))
-                                  :color (id->color (user :id))
-                                  :borderColor (id->color (user :id))}
-                      :href (routes/user-page-path {:group-id (routes/current-group)
-                                                    :user-id (user :id)})}
-            (dom/span #js {:className "name"} (str "@" (user :nickname)))
-            #_(dom/div #js {:className (str "status " ((fnil name "") (user :status)))})))
-        (dom/a #js {:className "user pill" :tabIndex -1 :href "#"}
-          (dom/span #js {:className "name"} "????"))))))
+      (UserPillView. #js {:user user}))))


Display contact bar for user not in contacts

Signed-off-by: Julien Eluard <c768e13f1ba4c3ebed2909a1fc1e4b50bb021a2f@gmail.com>

--- src/status_im/chat/screen.cljs
+++ src/status_im/chat/screen.cljs
@@ -37,7 +37,8 @@
 (defview add-contact-bar []
   (letsubs [chat-id          [:get-current-chat-id]
             pending-contact? [:current-contact :pending?]]
-    (when pending-contact?
+    (when (or (nil? pending-contact?) ; user not in contact list
+              pending-contact?)
       [react/touchable-highlight
        {:on-press #(re-frame/dispatch [:add-contact chat-id])}
        [react/view style/add-contact
@@ -59,7 +60,7 @@
       [toolbar/actions [{:icon      :icons/options
                          :icon-opts {:color :black}
                          :handler   #(on-options chat-id name group-chat public?)}]]]
-     [add-contact-bar]]))
+     (when-not (or public? group-chat) [add-contact-bar])]))

 (defmulti message-row (fn [{{:keys [type]} :row}] type))


update 004.clj using partial

update 004.clj using partial

--- 004.clj
+++ 004.clj
@@ -1,9 +1,11 @@
-(defn digit [n base]
+(defn digit [base n]
   (if (< n base) (list n)
-    (cons (rem n base) (digit (quot n base) base))))
+    (cons (rem n base) (digit base (quot n base)))))
+
+(def digit10 (partial digit 10))

 (defn isPanlindrome? [n]
-  (let [num-digit (digit n 10)]
+  (let [num-digit (digit10 n)]
     (= num-digit (reverse num-digit))))

 (defn prod [lst]


Locks: remove unnecessary `pexpire` fallback

--- src/taoensso/carmine/locks.clj
+++ src/taoensso/carmine/locks.clj
@@ -40,10 +40,9 @@
                   "if redis.call('setnx', _:lkey, _:uuid) == 1 then
                     redis.call('pexpire', _:lkey, _:lock-timeout-ms)
                     return 1
-                  elseif redis.call('ttl', _:lkey) < 0 then
-                    redis.call('pexpire', _:lkey, _:lock-timeout-ms)
-                  end
-                  return 0"
+                  else
+                    return 0
+                  end"
                   {:lkey            (lkey lock-name)}
                   {:uuid            uuid
                    :lock-timeout-ms lock-timeout-ms})
@@ -97,7 +96,7 @@
   lock when successful. Returns {:result <body's result>} on successful release,
   or nil if the lock could not be acquired. If the lock is successfully acquired
   but expires before being released, throws an exception."
-  [lock-name & [lock-timeout-ms wait-timeout-ms & body]]
+  [lock-name lock-timeout-ms wait-timeout-ms & body]
   `(when-let [uuid# (acquire-lock ~lock-name ~lock-timeout-ms ~wait-timeout-ms)]
      (try
        {:result (do ~@body)} ; Wrapped to distinguish nil body result


add PersistentVector$ChunkedSeq serializer

--- src/clj/carbonite/serializer.clj
+++ src/clj/carbonite/serializer.clj
@@ -14,7 +14,7 @@
             PersistentHashMap MapEntry PersistentStructMap
             PersistentVector PersistentHashSet Ratio ArraySeq
             Cons PersistentList PersistentList$EmptyList Var
-            LazySeq IteratorSeq StringSeq]))
+            LazySeq IteratorSeq StringSeq PersistentVector$ChunkedSeq]))

 (defn clj-print
   "Use the Clojure pr-str to print an object into the Output using
@@ -120,7 +120,8 @@
    ;; list/seq collections
    (map #(vector % (ClojureSeqSerializer.))
         [Cons PersistentList$EmptyList PersistentList
-         LazySeq IteratorSeq ArraySeq])
+         LazySeq IteratorSeq ArraySeq
+         PersistentVector$ChunkedSeq])

    ;; other seqs
    [[StringSeq (StringSeqSerializer.)]]


Bumped spot prices.

Bumped spot prices.

--- src/clj/forma/hadoop/cluster.clj
+++ src/clj/forma/hadoop/cluster.clj
@@ -91,7 +91,7 @@
    :price spot-price})

 (def cluster-profiles
-  {"large"           (mk-profile 4 2 0.50 "us-east-1/ami-08f40561" "m1.large")
+  {"large"           (mk-profile 4 2 1.20 "us-east-1/ami-08f40561" "m1.large")
    "high-memory"     (mk-profile 30 24 1.50 "us-east-1/ami-08f40561" "m2.4xlarge")
    "cluster-compute" (mk-profile 22 16 1.20 "us-east-1/ami-1cad5275" "cc1.4xlarge")})


Fix UI issues with Step 1.2 and 4.3. Fix log messages for Underworld Contacts, Data Folding.

--- src/clj/game/cards-resources.clj
+++ src/clj/game/cards-resources.clj
@@ -113,36 +113,33 @@
                  :effect (effect (trash card {:cause :ability-cost}) (damage-prevent :meat 3))}]}

    "Daily Casts"
-   (let [ability (req (gain state :runner :credit 2)
-                      (when (zero? (:counter card))
-                        (trash state :runner card {:unpreventable true})))]
+   (let [ability {:once :per-turn
+                  :label "Take 2 [Credits] (start of turn)"
+                  :msg "gain 2 [Credits]"
+                  :req (req (:runner-phase-12 @state))
+                  :counter-cost 2
+                  :effect (req (gain state :runner :credit 2)
+                               (when (zero? (:counter card))
+                                 (trash state :runner card {:unpreventable true})))}]
    {:data {:counter 8
            :counter-type "Credit"}
     :flags {:drip-economy true}
-    :abilities [{:once :per-turn
-                 :label "Take 2 [Credits] (start of turn)"
-                 :msg "gain 2 [Credits]"
-                 :req (req (:runner-phase-12 @state))
-                 :counter-cost 2
-                 :effect ability}]
-    :events {:runner-turn-begins {:once :per-turn
-                                  :msg "gain 2 [Credits]"
-                                  :counter-cost 2
-                                  :effect ability}}})
+    :abilities [ability]
+    :events {:runner-turn-begins ability}})

    "Data Dealer"
    {:abilities [{:cost [:click 1 :forfeit] :effect (effect (gain :credit 9))
                  :msg (msg "gain 9 [Credits]")}]}

    "Data Folding"
-   {:flags {:drip-economy true}
-    :abilities [{:label "Gain 1 [Credits]"
-                 :once :per-turn
-                 :req (req (and (>= (:memory runner) 2) (:runner-phase-12 @state)))
-                 :effect (effect (gain :credit 1))}]
-    :events {:runner-turn-begins {:msg "gain 1 [Credits]" :req (req (>= (:memory runner) 2))
-                                  :once :per-turn
-                                  :effect (effect (gain :credit 1))}}}
+   (let [ability {:label "Gain 1 [Credits] (start of turn)"
+                  :msg "gain 1 [Credits]"
+                  :once :per-turn
+                  :req (req (and (>= (:memory runner) 2) (:runner-phase-12 @state)))
+                  :effect (effect (gain :credit 1))}]
+    {:flags {:drip-economy true}
+    :abilities [ability]
+    :events {:runner-turn-begins ability}})

    "Data Leak Reversal"
    {:req (req (some #{:hq :rd :archives} (:successful-run runner-reg)))
@@ -815,14 +812,14 @@
                  :cost [:click 2] :effect (effect (move target :hand) (shuffle! :deck))}]}

    "Underworld Contact"
+   (let [ability {:label "Gain 1 [Credits] (start of turn)"
+                  :msg "gain 1 [Credits]"
+                  :once :per-turn
+                  :req (req (and (>= (:link runner) 2) (:runner-phase-12 @state)))
+                  :effect (effect (gain :credit 1))}]
    {:flags {:drip-economy true}
-    :abilities [{:label "Gain 1 [Credits]"
-                 :once :per-turn
-                 :req (req (and (>= (:link runner) 2) (:runner-phase-12 @state)))
-                 :effect (effect (gain :credit 1))}]
-    :events {:runner-turn-begins {:msg "gain 1 [Credits]" :req (req (>= (:link runner) 2))
-                                  :once :per-turn
-                                  :effect (effect (gain :credit 1))}}}
+    :abilities [ability]
+    :events {:runner-turn-begins ability}})

    "Utopia Shard"
    {:abilities [{:effect (effect (trash-cards :corp (take 2 (shuffle (:hand corp))))


Add dec filter to Selmer

Add dec filter to Selmer

--- src/clj/sparqlab/routes/home.clj
+++ src/clj/sparqlab/routes/home.clj
@@ -12,6 +12,8 @@
             [clojure.string :as string]))

 (add-filter! :markdown (fn [s] [:safe (md-to-html-string s)]))
+
+(add-filter! :dec dec)

 (def a-year
   "One year in seconds"


Removed last-modified from tropes collection

I need to look into if I can get the request contest, since the same API
is used to return a random trope and we do want that one to vary from
call to call.

Partially reverts commit 2afc444

--- src/clj/tropology/routes/api.clj
+++ src/clj/tropology/routes/api.clj
@@ -59,7 +59,6 @@
                         (let [{{{label :category, name :name} :params} :request} request
                               code (lower-case (str label "/" name))]
                           (api/tropes-from-node code)))
-             :last-modified (default-last-modified)
              :handle-ok (fn [request]
                           (select-keys request [:title :description :references :code :display :image :url]))
              :available-media-types ["application/transit+json"


Layout fixes

Layout fixes

--- src/cljs/hyphen_keeper/core.cljs
+++ src/cljs/hyphen_keeper/core.cljs
@@ -29,47 +29,49 @@
 (defn load-hyphenation-patterns!
   [spelling word]
   (ajax/GET "/api/words"
-            :params {:spelling spelling :search word}
-            :handler (fn [hyphenations] (swap! app-state assoc :hyphenations
-                                               (into (sorted-map)
-                                                     (map (fn [{:keys [word] :as pattern}] [word pattern])
-                                                          hyphenations))))
-            :error-handler (fn [details]
-                             (.warn js/console
-                                    (str "Failed to refresh hyphenation patterns from server: " details)))
-            :response-format :json
-            :keywords? true))
+   :params {:spelling spelling :search word}
+   :handler (fn [hyphenations]
+              (swap! app-state assoc :hyphenations
+                     (into (sorted-map)
+                           (map (fn [{:keys [word] :as pattern}] [word pattern])
+                                hyphenations))))
+   :error-handler (fn [details]
+                    (.warn js/console
+                           (str "Failed to refresh hyphenation patterns from server: " details)))
+   :response-format :json
+   :keywords? true))

 (defn add-hyphenation-pattern!
   [pattern]
   (ajax/POST "/api/words"
-             :params pattern
-             :handler (fn [] (load-hyphenation-patterns! @spelling @word))
-             :error-handler (fn [details]
-                              (.warn js/console
-                                     (str "Failed to add hyphenation pattern: " details)))
-             :format :json))
+   :params pattern
+   :handler (fn [] (load-hyphenation-patterns! @spelling @word))
+   :error-handler (fn [details]
+                    (.warn js/console
+                           (str "Failed to add hyphenation pattern: " details)))
+   :format :json))

 (defn remove-hyphenation-pattern!
   [pattern]
   (ajax/DELETE (str "/api/words/" (:word pattern))
-               :params pattern
-               :handler (fn [] (remove-hyphenation! pattern))
-               :error-handler (fn [details]
-                                (.warn js/console
-                                       (str "Failed to remove hyphenation pattern: " details)))
-               :format :json))
+   :params pattern
+   :handler (fn [] (remove-hyphenation! pattern))
+   :error-handler (fn [details]
+                    (.warn js/console
+                           (str "Failed to remove hyphenation pattern: " details)))
+   :format :json))

 (defn lookup-hyphenation-pattern!
   [spelling word]
   (ajax/GET "/api/hyphenate"
-            :params {:word word :spelling spelling}
-            :handler (fn [hyphenated] (do
-                                        (swap! app-state assoc :suggested-hyphenation hyphenated)
-                                        (swap! app-state assoc :hyphenation hyphenated)))
-            :error-handler (fn [details]
-                             (.warn js/console
-                                    (str "Failed to lookup hyphenation patterns for word: " details)))))
+   :params {:word word :spelling spelling}
+   :handler (fn [hyphenated]
+              (do
+                (swap! app-state assoc :suggested-hyphenation hyphenated)
+                (swap! app-state assoc :hyphenation hyphenated)))
+   :error-handler (fn [details]
+                    (.warn js/console
+                           (str "Failed to lookup hyphenation patterns for word: " details)))))

 (defn hyphenation-pattern-ui [{:keys [word hyphenation]}]
   [:tr


choose language on top

choose language on top

--- src/cljs/just_married/views.cljs
+++ src/cljs/just_married/views.cljs
@@ -27,16 +27,11 @@

         (into
          [:ul {:class "nav navbar-nav"}]
-         (for [s SECTIONS]
-           [:li [:a {:href (str "#" (first s))} (second s)]]))
+         (for [[href name] SECTIONS]
+           [:li [:a {:href (str "#" href)} name]]))

         [:ul {:class "nav navbar-right"}
-         [:div {:class "bfh-selectbox bfh-languages"
-                :data-language "en_GB"
-                :data-available "en_GB,it_IT"
-                :data-flags true}
-          [:input {:type "hidden" :value ""}]]]]])))
-
+         (lang-selection current-language)]]])))

 (defn story
   []
@@ -117,7 +112,6 @@
   (fn []
     [:g
      [navbar]
-     [lang-selection]
      [add-to-calendar]
      ;; lang selection could be moved into the header potentially?
      [story]


Forgot to (declare do-move).

Forgot to (declare do-move).

--- src/clojure/clj_chess/board.cljc
+++ src/clojure/clj_chess/board.cljc
@@ -152,6 +152,8 @@
   "Tests whether the board position is checkmate."
   [board]
   (.isMate board))
+
+(declare do-move)

 (defn move-is-checkmate?
   "Tests whether the move is a mate in one."


Fix concurrency issue when processing XSLT. Saxon XSLT transformers are not thread safe.

--- src/cmr/search/services/xslt.clj
+++ src/cmr/search/services/xslt.clj
@@ -6,28 +6,36 @@
            java.io.StringReader
            java.io.StringWriter
            javax.xml.transform.stream.StreamSource
-           javax.xml.transform.stream.StreamResult))
+           javax.xml.transform.stream.StreamResult
+           javax.xml.transform.Templates))

 (def xsl-transformer-cache-name
-  :xsl-transformers)
+  "This is the name of the cache to use for XSLT transformer templates. Templates are thread
+  safe but transformer instances are not.
+  http://www.onjava.com/pub/a/onjava/excerpt/java_xslt_ch5/?page=9"
+  :xsl-transformer-templates)

 (defn context->xsl-transformer-cache
   [context]
   (get-in context [:system :caches xsl-transformer-cache-name]))

-(defn- xsl->transformer
-  "Returns the xsl transformer for the given xsl file"
+(defn- xsl->transformer-template
+  "Returns the xsl transformer template for the given xsl file"
   [xsl]
   (let [xsl-resource (new StreamSource (io/file xsl))
         factory (TransformerFactory/newInstance)]
-    (.newTransformer factory xsl-resource)))
+    (.newTemplates factory xsl-resource)))

 (defn transform
   "Transforms the given xml by appling the given xsl"
   [context xml xsl]
-  (let [transformer (cache/cache-lookup
-                      (context->xsl-transformer-cache context) xsl #(xsl->transformer xsl))
+  (let [^Templates template (cache/cache-lookup
+                              (context->xsl-transformer-cache context)
+                              xsl
+                              #(xsl->transformer-template xsl))
+        transformer (.newTransformer template)
         source (new StreamSource (new StringReader xml))
         result (new StreamResult (new StringWriter))]
     (.transform transformer source result)
     (.toString (.getWriter result))))
+


CMR-586: Added call to get-latest-concepts.

--- src/cmr/transmit/transformer.clj
+++ src/cmr/transmit/transformer.clj
@@ -14,7 +14,7 @@
   given format."
   [context concept-tuples format]
   (let [conn (config/context->app-connection context :transformer)
-        mime-type (format mt/format->mime-type)
+        mime-type (mt/format->mime-type format)
         tuples-json-str (json/encode concept-tuples)
         request-url (str (conn/root-url conn) "/concepts")
         response (client/post request-url {:body tuples-json-str
@@ -36,4 +36,33 @@
       (errors/internal-error! (str "Get concept revisions failed. Transformer app response status code: "
                                    status
                                    " "
+                                   response)))))
+
+(deftracefn get-latest-formatted-concepts
+  "Ask the transformer app for the latest version of the concepts given by the concept-ids in the
+  given format."
+  [context concept-ids format]
+  (let [conn (config/context->app-connection context :transformer)
+        mime-type (mt/format->mime-type format)
+        ids-json-str (json/encode concept-ids)
+        request-url (str (conn/root-url conn) "/latest-concepts")
+        response (client/post request-url {:body ids-json-str
+                                           :content-type :json
+                                           :accept mime-type
+                                           :throw-exceptions false
+                                           :headers (ch/context->http-headers context)
+                                           :connection-manager (conn/conn-mgr conn)})
+        status (:status response)]
+    (case status
+      404
+      (let [err-msg "Unable to find all concepts."]
+        (errors/throw-service-error :not-found err-msg))
+
+      200
+      (json/decode (:body response) true)
+
+      ;; default
+      (errors/internal-error! (str "Get concept revisions failed. Transformer app response status code: "
+                                   status
+                                   " "
                                    response)))))


update library versions

update library versions

--- kafka-clj/project.clj
+++ kafka-clj/project.clj
@@ -38,10 +38,10 @@
                  [net.jpountz.lz4/lz4 "1.3.0"]
                  [org.clojure/tools.logging "0.3.1"]
                  [clj-tcp "0.4.9"]
-                 [fmap-clojure "LATEST" :exclusions [org.clojure/tools.logging]]
-                 [fun-utils "0.5.8-SNAPSHOT" :exclusions [org.clojure/tools.logging]]
-                 [clj-tuple "0.1.7"]
-                 [thread-load "0.2.0-SNAPSHOT" :exclusions [org.clojure/clojure]]
+                 ;[fmap-clojure "LATEST" :exclusions [org.clojure/tools.logging]]
+                 [fun-utils "0.6.1" :exclusions [org.clojure/tools.logging]]
+                 [clj-tuple "0.2.2"]
+                 ;[thread-load "0.2.0-SNAPSHOT" :exclusions [org.clojure/clojure]]
                  [com.codahale.metrics/metrics-core "3.0.1"]
                  [metrics-clojure "2.5.1"]
                  [org.clojure/core.async "0.2.374"]
@@ -49,7 +49,7 @@

                  [org.openjdk.jol/jol-core "0.4"]

-                 [org.clojure/clojure "1.6.0" :scope "provided"]
+                 [org.clojure/clojure "1.8.0" :scope "provided"]
                  [org.apache.zookeeper/zookeeper "3.4.6" :scope "provided"
                   :exclusions [io.netty/netty]]
                  [org.apache.kafka/kafka_2.10 "0.8.1.1" :scope "provided"


Add failing test case for join.cljs

Add failing test case for join.cljs

--- src/aurora/join.cljs
+++ src/aurora/join.cljs
@@ -354,6 +354,17 @@
       (alength (time(all-join-results join-itr)))
       ))

+  (let [tree (tree 10)
+        _ (dotimes [i 10]
+            (let [i (+ i 0)]
+              (.assoc! tree #js [i i] (* 2 i))))
+        j (time (join-iterator #js [(magic-iterator tree #js [0 nil nil 1 nil nil])
+                                    (magic-iterator tree #js [nil 0 nil nil 1 nil])
+                                    (magic-iterator tree #js [nil nil 0 nil nil 1])]))
+        ]
+    (time (all-join-results j))
+  )
+
   (let [tree1 (tree 10)
         _ (doseq [x [#js [0 1 4]
                      #js [0 1 6]


fix breakage from dag_unify upgrade to latest release 1.5.1

--- src/babel/index.cljc
+++ src/babel/index.cljc
@@ -7,8 +7,7 @@
    #?(:clj [clojure.tools.logging :as log])
    #?(:cljs [babel.logjs :as log])
    [dag_unify.core :refer [fail? dissoc-paths get-in label-of
-                           remove-top-values-log strip-refs
-                           unifyc]]))
+                           strip-refs unify]]))

 (defn exception [error-string]
   #?(:clj
@@ -44,26 +43,26 @@
      {(get-in (first phrases) [:rule])
       {:comp
        (filter (fn [lex]
-                 (not (fail? (unifyc (first phrases)
+                 (not (fail? (unify (first phrases)
                                      {:comp lex}))))
                lexicon)

        :comp-phrases
        (filter (fn [comp-phrase]
-                 (not (fail? (unifyc (first phrases)
+                 (not (fail? (unify (first phrases)
                                      {:comp comp-phrase}))))
                all-phrases)

        :head-phrases
        (filter (fn [head-phrase]
-                 (not (fail? (unifyc (first phrases)
+                 (not (fail? (unify (first phrases)
                                      {:head head-phrase}))))
                all-phrases)

        :head
        (filter (fn [lex]
                  (log/debug (str "trying lexeme: " lex))
-                 (not (fail? (unifyc (first phrases)
+                 (not (fail? (unify (first phrases)
                                      {:head lex}))))
                lexicon)}}
      (build-lex-sch-index (rest phrases) lexicon all-phrases))))
@@ -75,7 +74,7 @@
        {spec
         (filter #(not (fail? %))
                 (map (fn [each-phrase]
-                       (unifyc each-phrase spec))
+                       (unify each-phrase spec))
                      ;; TODO: possibly: remove-paths such as (subcat) from head: would make it easier to call with lexemes:
                      ;; e.g. "generate a sentence whose head is the word 'mangiare'" (i.e. user passes the lexical entry as
                      ;; head param of (lightning-bolt)".
@@ -117,7 +116,7 @@
     (conj (build-lex-sch-index grammar
                                (map (fn [lexeme]
                                       (log/debug (str "trying(ci) lexeme: " lexeme))
-                                      (unifyc lexeme
+                                      (unify lexeme
                                               {:phrasal false}))
                                     lexicon)
                                grammar)
@@ -136,15 +135,15 @@
   (cond (seq? spec)
         (map show-spec spec)
         true
-        (remove-top-values-log (dissoc-paths spec '((:english :initial)
-                                                    (:italiano :initial)
-                                                    (:synsem :essere)
-                                                    (:synsem :agr)
-                                                    (:synsem :pronoun)
-                                                    (:synsem :sem :tense)
-                                                    (:synsem :sem :obj :tense)
-                                                    (:synsem :sem :mod)
-                                                    (:synsem :infl))))))
+        (strip-refs (dissoc-paths spec '((:english :initial)
+                                         (:italiano :initial)
+                                         (:synsem :essere)
+                                         (:synsem :agr)
+                                         (:synsem :pronoun)
+                                         (:synsem :sem :tense)
+                                         (:synsem :sem :obj :tense)
+                                         (:synsem :sem :mod)
+                                         (:synsem :infl))))))

 (defn map-subset-by-path2 [vals-at-path lexemes path]
   (if (not (empty? vals-at-path))


Possible to "miss" the ball, and scores.

--- src/canvas/main.cljs
+++ src/canvas/main.cljs
@@ -13,6 +13,14 @@
 (def SCALE-W 800)
 (def SCALE-H 450)

+(def PLAYER_1_COLOR "dodgerblue")
+(def PLAYER_2_COLOR "peru")
+
+(def SCORE_FONT "60px Helvetica")
+(def SCORE_COLOR "#555")
+
+(def BALL_COLOR "lime")
+
 (def KEYBOARD
   {40 :down
    38 :up
@@ -54,7 +62,8 @@
 (defrecord Rect [x y width height color])
 (defrecord Frame [x y width height color frame-width])
 (defrecord Paddle [x y width height vy color])
-(defrecord Ball [x y radius vx vy fill-color])
+(defrecord Ball [x y radius vx vy fill-color oob?])
+(defrecord Score [score x y font color])

 ;;-----------------------------------------------------------------------------
 ;; Drawable Objects
@@ -62,6 +71,15 @@

 (defprotocol IDrawable
   (draw! [_ ctx]))
+
+(extend-type Score
+  IDrawable
+  (draw! [{:keys [score x y font color] :as Score} ctx]
+    (aset ctx "font" font)
+    (aset ctx "fillStyle" color)
+    (aset ctx "textAlign" "center")
+    (.fillText ctx (str score) x y)
+    ctx))

 (extend-type Paddle
   IDrawable
@@ -110,11 +128,18 @@

 (extend-type Ball
   IMovable
-  (move [{:keys [x y vx vy radius] :as ball}]
-    (let [low radius
-          vx (if (< low x (- SCALE-W radius)) vx (* -1 vx))
-          vy (if (< low y (- SCALE-H radius)) vy (* -1 vy))]
-      (assoc ball :x (+ x vx) :y (+ y vy) :vx vx :vy vy))))
+  (move [{:keys [x y vx vy radius oob?] :as ball}]
+    (when-not oob?
+      (cond
+        (= x radius)
+        (assoc ball :oob? false :x -100)
+        ;;
+        (= x (- SCALE-W radius))
+        (assoc ball :oob? false :x (+ SCALE-W 100))
+        ;;
+        :else
+        (let [vy (if (< radius y (- SCALE-H radius)) vy (* -1 vy))]
+          (assoc ball :x (+ x vx) :y (+ y vy) :vy vy))))))

 ;;-----------------------------------------------------------------------------
 ;; Controllable Objects
@@ -145,11 +170,17 @@
   (atom {:current-paddle :paddle-1
          ;; use div behind canvas
          :background (Rect. 0 0 SCALE-W SCALE-H "black")
-          ;; use div behind canvas
+         ;; use div behind canvas
+
          :border     (Frame. 0 0 SCALE-W SCALE-H "#333" 2)
-         :paddle-1   (Paddle. 20 (- SCALE-H 120) 20 100 10 "dodgerblue")
-         :paddle-2   (Paddle. (- SCALE-W 40) 20 20 100 10 "peru")
-         :ball       (Ball. 400 225 13 3 2 "lime")}))
+
+         :score-1    (Score. 0 200 60 SCORE_FONT SCORE_COLOR)
+         :score-2    (Score. 0 (- SCALE-W 200) 60 SCORE_FONT SCORE_COLOR)
+
+         :paddle-1   (Paddle. 20 (- SCALE-H 120) 20 100 10 PLAYER_1_COLOR)
+         :paddle-2   (Paddle. (- SCALE-W 40) 20 20 100 10 PLAYER_2_COLOR)
+
+         :ball       (Ball. 400 225 13 3 2 BALL_COLOR false)}))

 ;;-----------------------------------------------------------------------------
 ;; Animation
@@ -187,9 +218,31 @@
     (assoc state :ball (assoc ball :vx (* -1 (:vx ball))))
     state))

+(defn score-phase!
+  [{:keys [ball score-1 score-2] :as state}]
+  (if (<= 0 (:x ball) SCALE-W)
+    state
+    (let [{:keys [x vx radius]} ball
+          {score1 :score} score-1
+          {score2 :score} score-2
+          p1? (> x SCALE-W)
+          p2? (< x 0)
+          s1 (assoc score-1 :score (if p1? (inc score1) score1))
+          s2 (assoc score-2 :score (if p2? (inc score2) score2))
+          ball (cond
+                 p2? (assoc ball :x (- SCALE-W 25) :y (/ SCALE-H 2))
+                 p1? (assoc ball :x 25 :y (/ SCALE-H 2))
+                 :else ball)]
+      (assoc state :score-1 s1 :score-2 s2 :ball ball))))
+
 (defn animate-loop!
   [state ctx]
-  (swap! state #(-> % move-phase! collision-phase!))
+  ;; if start-mode:
+  ;; ...
+  ;; if play-mode:
+  (swap! state #(-> % move-phase! collision-phase! score-phase!))
+  ;; if win-mode:
+  ;; ...
   (draw-phase! state ctx)
   (.requestAnimationFrame js/window (partial animate-loop! state ctx)))


Bump ClojureScript to 1.8.40

Bump ClojureScript to 1.8.40

--- build.boot
+++ build.boot
@@ -1,5 +1,5 @@
-(def clojure-dep '[org.clojure/clojure "1.7.0"])
-(def clojurescript-dep '[org.clojure/clojurescript "1.7.228"])
+(def clojure-dep '[org.clojure/clojure "1.8.0"])
+(def clojurescript-dep '[org.clojure/clojurescript "1.8.40"])

 (set-env!
  :source-paths #{"dev"}


update heredoc

update heredoc

--- build.boot
+++ build.boot
@@ -10,7 +10,7 @@
                  [pandeiro/boot-http           "0.6.3"]
                  [clj-tagsoup                  "0.3.0"]
                  [markdown-clj                 "0.9.74"]
-                 [tailrecursion/boot-heredoc   "0.1.0"]
+                 [tailrecursion/boot-heredoc   "0.1.1"]
                  [org.python/jython-standalone "2.7.0"]
                  [org.pygments/pygments        "2.0.2"]]
  :resource-paths #{"assets"}


Use latest Cljs pre-release

Use latest Cljs pre-release

--- build.boot
+++ build.boot
@@ -4,10 +4,10 @@
   :source-paths #{"src/cljs" "src/less" "src/scss" "test/clj"}
   :resource-paths #{"src/clj" "src/cljc"}
   :dependencies '[[org.clojure/clojure    "1.7.0"]
-                  [org.clojure/clojurescript "1.7.48"]
+                  [org.clojure/clojurescript "1.7.166"]

                   [boot/core              "2.3.0"      :scope "test"]
-                  [adzerk/boot-cljs       "1.7.48-5"   :scope "test"]
+                  [adzerk/boot-cljs       "1.7.166-1"  :scope "test"]
                   [adzerk/boot-cljs-repl  "0.2.0"      :scope "test"]
                   [adzerk/boot-reload     "0.4.0"      :scope "test"]
                   [adzerk/boot-test       "1.0.4"      :scope "test"]


Fix repo url on build.boot.

Fix repo url on build.boot.

--- build.boot
+++ build.boot
@@ -54,8 +54,8 @@
   (comp (pom :project     'funcool/promesa
              :version     +version+
              :description "A promise library for ClojureScript"
-             :url         "https://github.com/funcool/promise"
-             :scm         {:url "https://github.com/funcool/promise"}
+             :url         "https://github.com/funcool/promesa"
+             :scm         {:url "https://github.com/funcool/promesa"}
              :license     {"BSD (2 Clause)" "http://opensource.org/licenses/BSD-2-Clause"})
         (jar)))