Fix add-column dsl.

Fix add-column dsl.

--- src/suricatta/dsl.clj
+++ src/suricatta/dsl.clj
@@ -721,8 +721,8 @@
   (defer
     (let [step (-unwrap step)
           name (-field name)
-          type (make-datatype opts)
-          type (.defaulted type true)]
+          type (cond-> (make-datatype opts)
+                 default (.defaultValue default))]
       (.column step name type))))

 (defn alter-column


Added sample data

Added sample data

--- src/tango/export2.clj
+++ src/tango/export2.clj
@@ -4,22 +4,18 @@
             [clj-time.core :as t]
             [clojure.data.xml :as xml]
             [clojure.xml :as cxml]
+            [clojure.pprint :as cpp]
             [clojure.zip :as zip]
             [clojure.data.zip.xml :as zx]
             [taoensso.timbre :as log]
             ))

-;; Provides useful Timbre aliases in this ns
-(log/refer-timbre)
-
-(defn get-xml-from-file [xml-file-path]
-  (xml/parse (java.io.FileInputStream. xml-file-path)))
-
+;; Sample data
 (def class-results [{:class-name "Disco Freestyle B-klass J Po"
                      :result {:round "S"
                               :adjudicators [{:number 2}
-                                            {:number 4}
-                                            {:number 5}]
+                                             {:number 4}
+                                             {:number 5}]
                               :dances [{:name "X-Quick Forward"}
                                        {:name "Quick"}]
                               :result-array [{:dancer-number 30
@@ -29,6 +25,121 @@
                                              {:dancer-number 32
                                               :marks [false false true]}]}}
                     ])
+
+(def activities-with-result
+[{:activity/name "Hiphop Singel Guld J1",
+  :round/name "Semifinal",
+  :round/panel
+  {:adjudicator-panel/adjudicators
+   [{:adjudicator/number 0}
+    {:adjudicator/number 1}
+    {:adjudicator/number 5}]},
+  :round/dances [{:dance/name "Medium"}],
+  :result/_activity
+  [{:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 143}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 141}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 144}}]}
+ {:activity/name "Hiphop Singel Brons J1",
+  :round/name "Direct Final",
+  :round/panel
+  {:adjudicator-panel/adjudicators
+   [{:adjudicator/number 2}
+    {:adjudicator/number 3}
+    {:adjudicator/number 4}]},
+  :round/dances [{:dance/name "Medium"}]}
+ {:activity/name "Hiphop Singel Brons U",
+  :round/name "Direct Final",
+  :round/panel
+  {:adjudicator-panel/adjudicators
+   [{:adjudicator/number 0}
+    {:adjudicator/number 1}
+    {:adjudicator/number 5}]},
+  :round/dances [{:dance/name "Medium"}]}
+ {:activity/name "Hiphop Singel Brons B2",
+  :round/name "Semifinal",
+  :round/panel
+  {:adjudicator-panel/adjudicators
+   [{:adjudicator/number 2}
+    {:adjudicator/number 3}
+    {:adjudicator/number 4}]},
+  :round/dances
+  [{:dance/name "Medium"}
+   {:dance/name "Medium"}
+   {:dance/name "Medium"}]}
+ {:activity/name "Hiphop Singel Silver B2",
+  :round/name "Semifinal",
+  :round/panel
+  {:adjudicator-panel/adjudicators
+   [{:adjudicator/number 0}
+    {:adjudicator/number 1}
+    {:adjudicator/number 5}]},
+  :round/dances
+  [{:dance/name "Medium"}
+   {:dance/name "Medium"}
+   {:dance/name "Medium"}
+   {:dance/name "Medium"}],
+  :result/_activity
+  [{:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 83}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 84}}
+
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 85}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 82}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 80}}
+   {:result/mark-x false,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 86}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 0},
+    :result/participant {:participant/number 89}}
+   {:result/mark-x false,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 83}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 85}}
+   {:result/mark-x false,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 84}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 82}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 87}}
+   {:result/mark-x true,
+    :result/adjudicator {:adjudicator/number 1},
+    :result/participant {:participant/number 89}}]}
+ {:activity/name "Hiphop Singel Brons U",
+  :round/name "Presentation",
+  :round/panel
+  {:adjudicator-panel/adjudicators
+   [{:adjudicator/number 0}
+    {:adjudicator/number 1}
+    {:adjudicator/number 5}]},
+  :round/dances [{:dance/name "Medium"} {:dance/name "Medium"}]}]
+
+;; Provides useful Timbre aliases in this ns
+(log/refer-timbre)
+
+(defn get-xml-from-file [xml-file-path]
+  (xml/parse (java.io.FileInputStream. xml-file-path)))
+

 (defn get-dance-count-from-class-node [class-node]
   (let [dance-list-node (first (filter #(= (:tag %) :DanceList) (:content class-node)))]


core: mapcat

core: mapcat

--- data/core.clj
+++ data/core.clj
@@ -1366,3 +1366,9 @@
                      (cons (map first ss) (step (map rest ss)))))))]
      (map #(apply f %) (step (conj colls c3 c2 c1))))))

+(defn mapcat
+  "Returns the result of applying concat to the result of applying map
+  to f and colls.  Thus function f should return a collection."
+  {:added "1.0"}
+  [f & colls]
+  (apply concat (apply map f colls)))


Add make-handler helper

Add make-handler helper

--- src/transit/write.clj
+++ src/transit/write.clj
@@ -584,8 +584,13 @@
     ;; can we configure JsonGenerator to automatically flush writes?
     (flush-writer m)))

-
-
-
-
-
+(defn make-handler
+  [tag-fn rep-fn str-rep-fn]
+  (reify Handler
+    (tag [_ o] (tag-fn o))
+    (rep [_ o] (rep-fn o))
+    (str-rep [_ o] (str-rep-fn o))))
+
+
+
+


Deadlines now declared as inst events

Deadlines now declared as inst events

--- src/tropic/instal.clj
+++ src/tropic/instal.clj
@@ -438,7 +438,10 @@
   (let [header (str "\n% INST EVENTS: " (reduce str (:label trope)) " ----------")
         nm (inst-name (:label trope))
         snms (map inst-name (map :verb (map :when (:situations trope))))
-        onms (map inst-name (map :verb (map :obligation (filter :obligation (:events trope)))))
+        ;; dnms (map inst-name (map #(:verb (:deadline (:obligation %))) (filter :obligation (:events trope))))
+        dnms (map inst-name (remove nil? (map #(:verb (:deadline (:obligation %))) (filter :obligation (:events trope)))))
+        obnms (map inst-name (map :verb (map :obligation (filter :obligation (:events trope)))))
+        onms (concat dnms obnms)
         params (get-all-params trope)
         sparams (map get-when-params (:situations trope))
         oparams (map get-dead-params (map :obligation (filter :obligation (:events trope))))


Pushing just in case

Pushing just in case

--- src/tropic/instal.clj
+++ src/tropic/instal.clj
@@ -522,6 +522,12 @@

 (defn bridge [tropes]
   (let [header "institution trope_bridge;\n\n"
+        ievents (map-indexed (fn [i t] (if-let [s (:subtrope t)]
+                                         (let [subtrope (first (filter #(= (:label %) s) tropes))]
+                                           (if (> i 0)
+                                             {:subtrope subtrope
+                                              :trigger (nth events (dec i))}
+                                             {:subtrope subtrope})))))
         subtropes (into [] (set (mapcat #(get-subtropes % tropes) tropes)))
         bmake (fn [strope]
                 (let [inst (str (inst-start-name (:label strope)) "("


experiment with server shutdown

experiment with server shutdown

--- src/web_sink/core.clj
+++ src/web_sink/core.clj
@@ -115,7 +115,8 @@
               :cookies true
               :proxy true
               :session {:flash true :store (cookie-store)}
-              :security {:anti-forgery true}))))
+              ;:security {:anti-forgery true}
+              ))))

 (def a-minute 60000)

@@ -128,7 +129,7 @@
     (.setStopTimeout  server a-minute)
     (.setStopAtShutdown server true)))
 ;since the port can be acquired only once we create and start the server with defonce
-(defonce wserver (run-jetty app {:port 3001 :join? false :configurator conf}))
+;(defonce wserver (run-jetty app {:port 3001 :join? false :configurator conf}))
 ;(defonce wserver (run-jetty app-handler {:port 3001 :join? false}))
 ;(defonce srv_start (new java.util.Date))

@@ -139,7 +140,9 @@
   [& args]
   ;(println app)
   (println "Dr. Bubo" " - " (now))
-  (clojure.repl/set-break-handler! #(.stop wserver)))
+  (run-jetty app {:port 3001 :join? false :configurator conf})
+  ;(clojure.repl/set-break-handler! #(.stop wserver))
+  )

 (defn -main
   [& args]


use named session store

use named session store

--- src/osmium/core.clj
+++ src/osmium/core.clj
@@ -10,6 +10,7 @@
             [ring.middleware.params :as params]
             [ring.middleware.edn :refer [wrap-edn-params]]
             [ring.middleware.session :as session]
+            [ring.middleware.session.memory :as memory-store]
             [ring.util.response :as response]
             [ring.adapter.jetty :as jetty]
             [compojure.core :refer :all]
@@ -19,7 +20,8 @@
             [osmium.db :as db]
             [osmium.book :as book]
             [osmium.web :as web]
-            [osmium.user :as user]))
+            [osmium.user :as user])
+  (:import [ring.middleware.session.memory MemoryStore]))

 ;;  ======================================================================
 ;; Routes
@@ -38,27 +40,27 @@
      (if (web/logged-in? session)
        (response/redirect "/")
        (web/log-in session)))
-   (POST "/login" {params :params}
+   (POST "/login" {params :params session :session}
      (let [user (user/login db (map-keys keyword params))]
        (if-let [error (:error user)]
-         (web/error-page {:error error})
+         (web/error-page session {:error error})
          (-> (response/redirect "/")
              (assoc-in [:session :user] user)))))
    (GET "/logout" _
      (-> (response/redirect "/")
          (assoc :session {})))
    (GET "/signup" {session :session} (web/sign-up session))
-   (POST "/signup" {params :params}
+   (POST "/signup" {params :params session :session}
      (let [new-user (user/signup! db (map-keys keyword params))]
        (if-let [error (:error new-user)]
-         (web/error-page error)
+         (web/error-page session error)
          (-> (format "/user/%s" (:user/email new-user))
              response/redirect
              (assoc :session {:user new-user})))))
-   (POST "/update-pass" {params :params}
+   (POST "/update-pass" {params :params session :session}
      (let [new-user (user/update-password! db (map-keys keyword params))]
        (if-let [error (:error new-user)]
-         (web/error-page error)
+         (web/error-page session error)
          (response/redirect (format "/user/%s" (:user/email new-user))))))
    (GET "/book" {session :session}
      (if-not (web/logged-in? session)
@@ -69,7 +71,7 @@
        (response/status (response/response "Not authorized") 401)
        (let [new-book (book/new-book! db (map-keys (partial keyword "book") params))]
          (if-let [error (:error new-book)]
-           (web/error-page error)
+           (web/error-page session error)
            (response/redirect (format "/book/%s" (:db/id new-book)))))))
    (GET "/book/:id" {params :params session :session}
      (let [book (book/by-id db (Long. (:id params)))
@@ -100,14 +102,24 @@
       (handler req)
       (catch Exception e
         {:status 500
-         :body (web/error-page (:session req) nil)}))))
+         :body (web/error-page (:session req) (pr-str e))}))))
+
+(extend-type MemoryStore
+  component/Lifecycle
+  (start [c] c)
+  (stop [c]
+    (reset! (:session-map c) {})
+    c))
+
+(defn new-session-store []
+  (memory-store/memory-store (atom {})))

 ;; ======================================================================
 ;; Server

-(defn app-handler [db]
+(defn app-handler [session-store db]
   (-> (main-routes db)
-      session/wrap-session
+      (session/wrap-session {:store session-store})
       wrap-edn-params
       params/wrap-params
       wrap-exceptions))
@@ -115,11 +127,11 @@
 (defn start-jetty [handler port]
   (jetty/run-jetty handler {:port (Integer. port) :join? false}))

-(defrecord Server [db port jetty]
+(defrecord Server [session-store db port jetty]
   component/Lifecycle
   (start [component]
     (println "Start server at port:" port)
-    (assoc component :jetty (start-jetty (app-handler db) port)))
+    (assoc component :jetty (start-jetty (app-handler session-store db) port)))
   (stop [component]
     (println "Stop server")
     (when jetty
@@ -131,7 +143,8 @@
         uri (or db-uri "datomic:mem://localhost:4334/osmium")]
     (component/system-map
      :db (db/map->Datomic {:uri uri})
-     :server (component/using (map->Server {:port http-port}) [:db]))))
+     :session-store (new-session-store)
+     :server (component/using (map->Server {:port http-port}) [:db :session-store]))))

 (defonce system (atom (new-system {})))


Increment version number

Increment version number

--- template/project.clj
+++ template/project.clj
@@ -1,4 +1,4 @@
-(defproject play-clj/lein-template "0.3.7"
+(defproject play-clj/lein-template "0.3.7.1"
   :description "A template for making play-clj projects"
   :url "https://github.com/oakes/play-clj"
   :license {:name "Public Domain"


Mark deftest-slow to bamreader-medium-file

--- test/cljam/t_bam.clj
+++ test/cljam/t_bam.clj
@@ -100,7 +100,7 @@
     (is (thrown? IOException (bam/reader invalid-file-2 :ignore-index true)))
     (is (thrown? IOException (bam/reader not-found-file :ignore-index true)))))

-(deftest bamreader-medium-file
+(deftest-slow bamreader-medium-file
   (with-before-after {:before (prepare-cache!)
                       :after (clean-cache!)}
     (with-open [rdr (bam/reader medium-bam-file :ignore-index true)]


Bumps version to 1.58.7-SNAPSHOT

Bumps version to 1.58.7-SNAPSHOT

--- scheduler/project.clj
+++ scheduler/project.clj
@@ -13,7 +13,7 @@
 ;; See the License for the specific language governing permissions and
 ;; limitations under the License.
 ;;
-(defproject cook "1.58.6"
+(defproject cook "1.58.7-SNAPSHOT"
   :description "This launches jobs on a Mesos cluster with fair sharing and preemption"
   :license {:name "Apache License, Version 2.0"}
   :dependencies [[org.clojure/clojure "1.10.3"]


Reduced verbosity of some major-action tests.

--- test-cljs/test.cljs
+++ test-cljs/test.cljs
@@ -99,11 +99,11 @@
     (is (= 1 (count (gw/seqof-charactermajoractions character1)))) "Character 1 has one available major action"
     (is (= 1 (count (gw/seqof-charactermajoractions character2)))) "Character 2 has one available major action"

-    (is (= 1 (count (possibletargets gamewithbothcharacters testid1))) "Melee actions target adjacent enemies")
-    (is (= 0 (count (possibletargets gamewithfarcharacters testid1))) "Melee actions can't hit non-adjacent enemies")
+    (is (= 1 (counttargets  gamewithbothcharacters testid1)) "Melee actions target adjacent enemies")
+    (is (= 0 (counttargets  gamewithfarcharacters testid1)) "Melee actions can't hit non-adjacent enemies")

-    (is (= 1 (count (possibletargets (gw/advanceturn gamewithbothcharacters) testid2))) "Ranged actions can hit adjacent enemies")
-    (is (= 1 (count (possibletargets (gw/advanceturn gamewithfarcharacters) testid2))) "Ranged actions can hit non-adjacent enemies")
-    (is (= 0 (count (possibletargets (gw/advanceturn gamewithreallyfarcharacters) testid2))) "Ranged actions have a maximum range")
+    (is (= 1 (counttargets  (gw/advanceturn gamewithbothcharacters) testid2)) "Ranged actions can hit adjacent enemies")
+    (is (= 1 (counttargets  (gw/advanceturn gamewithfarcharacters) testid2)) "Ranged actions can hit non-adjacent enemies")
+    (is (= 0 (counttargets  (gw/advanceturn gamewithreallyfarcharacters) testid2)) "Ranged actions have a maximum range")
     ))


Revert "add drop-db for database"

Revert "add drop-db for database"

This reverts commit 4902866facf4e008831ca9bd9de9adc144194c2c.

--- src/karras.clj
+++ src/karras.clj
@@ -65,9 +65,6 @@
 (defn mongo-db
   [#^Mongo connection db-name]
   (.getDB connection (keyword-str db-name)))
-
-(defn drop-db [#^DBObject db]
-  (.dropDatabase db))

 (defn collection
   "Returns a DBCollection."


Roll project.clj to 0.5.9

Roll project.clj to 0.5.9


fix artifact name

fix artifact name


Remove storage colors and select first collection with content on workspace

--- frontend/src/uxbox/main/ui/workspace/colorpalette.cljs
+++ frontend/src/uxbox/main/ui/workspace/colorpalette.cljs
@@ -27,7 +27,7 @@
   [local collections]
   (if-let [selected (:selected @local)]
     (first (filter #(= selected (:id %)) collections))
-    (first collections)))
+    (first (filter #(and (:id %) (> (count (:colors %)) 0)) collections))))

 (mx/defc palette-items
   {:mixins [mx/static]}
@@ -54,8 +54,9 @@
   (let [local (:rum/local own)
         collections (->> (mx/react collections-ref)
                          (vals)
+                         (filter :id)
                          (sort-by :name))
-        collection (get-selected-collection local collections)]
+        selected-collection (get-selected-collection local collections)]
     (letfn [(select-collection [event]
               (let [value (read-string (dom/event->value event))]
                 (swap! local assoc :selected value :position 0)))
@@ -66,8 +67,9 @@
         [:select.input-select {:on-change select-collection}
          (for [collection collections]
            [:option {:key (str (:id collection))
-                     :value (pr-str (:id collection))}
-            (:name collection "Storage")])]
+                     :value (pr-str (:id collection))
+                     :selected (when (= collection selected-collection) "selected")}
+            (:name collection)])]
         #_[:div.color-palette-buttons
            [:div.btn-palette.edit.current i/pencil]
            [:div.btn-palette.create i/close]]]
@@ -76,9 +78,9 @@
           {:on-click #(swap! local update :position dec)}
           {:class :disabled})
         i/arrow-slide]
-       (palette-items (:colors collection) (:position @local))
+       (palette-items (:colors selected-collection) (:position @local))
        [:span.right-arrow
-        (if (< (* (+ 1 (:position @local)) 10) (count (:colors collection)))
+        (if (< (* (+ 1 (:position @local)) 10) (count (:colors selected-collection)))
           {:on-click #(swap! local update :position inc)}
           {:class :disabled})
         i/arrow-slide]


Linting also about constructors with too many parameters

--- src/app/linter.clj
+++ src/app/linter.clj
@@ -10,7 +10,10 @@
 (defrecord Check [operation params message])

 (def checks
-  [(Check. classesWithManyConstructorsOp {:threshold 4} "This class has too many constructors (#1#). Considers the Builder pattern")])
+  [(Check. classesWithManyConstructorsOp {:threshold 4}
+     "This class has too many constructors (#1#). Consider using static factory methods or the Builder pattern")
+   (Check. constructorsWithManyParametersOp {:threshold 6}
+     "This constructor has too many parameters (#1#). Consider using the Builder pattern")])

 (defn replaceParamsInMessage [message result]
   (clojure.string/replace message "#1#" (toString (nth result 1))))


More color tweaking.

More color tweaking.

--- src/cbfg/core.cljs
+++ src/cbfg/core.cljs
@@ -195,7 +195,7 @@
                          (if (= :put wait-kind)
                            ["<line x1='500' y1='" (actx-y actx)
                             "' x2='600' y2='" (ch-y ch)
-                            "' stroke='#afa' stroke-width='1' marker-end='url(#triangle)'/>"]
+                            "' stroke='#faa' stroke-width='1' marker-end='url(#triangle)'/>"]
                            ["<line x1='600' y1='" (ch-y ch)
                             "' x2='500' y2='" (actx-y actx)
                             "' stroke='#faa' stroke-width='1' marker-end='url(#triangle)'/>"])))
@@ -212,7 +212,7 @@
                  :take ["<g transform='translate(600," (ch-y (:ch delta)) ")'>"
                         "<line class='delta' x1='0' y1='0' x2='-100' y2='"
                         (- (actx-y (:actx delta)) (ch-y (:ch delta)))
-                        "' stroke='red' stroke-width='1' marker-end='url(#triangle)'/>"
+                        "' stroke='green' stroke-width='1' marker-end='url(#triangle)'/>"
                         "</g>"]
                  :actx-new nil
                  :actx-remove nil


117 todo added

117 todo added

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -1473,7 +1473,7 @@
      ~@body))

 ;;
-;; locators
+;; locators TODO: drop or refactor
 ;;

 (defn use-locator [driver locator]


Adding dpkg and rpm fpm builds

Adding dpkg and rpm fpm builds

--- src/fatty/core.clj
+++ src/fatty/core.clj
@@ -90,10 +90,18 @@
 (defn build-deb
   "Builds a deb"
   [project-name version os-data]
-  (let [status (sh "./debian/build-deb" project-name version (os-data :machine))]
+  (let [status (sh "fpm" "-s" "dir" "-t" "deb" "-v" version "-n" project-name "/opt/opscode" "-m" "Opscode, Inc." "--post-install" "./debian/postinst" "--post-uninstall" "./debian/postrm" "--description" "The full stack install of Opscode Chef" "--url" "http://www.opscode.com")]
     (log-sh-result status
                    (str "Created debian package")
                    (str "Failed to create debian package"))))
+
+(defn build-rpm
+  "Builds a rpm"
+  [project-name version os-data]
+  (let [status (sh "fpm" "-s" "dir" "-t" "rpm" "-v" version "-n" project-name "/opt/opscode" "-m" "Opscode, Inc." "--post-install" "./debian/postinst" "--post-uninstall" "./debian/postrm" "--description" "The full stack install of Opscode Chef" "--url" "http://www.opscode.com")]
+    (log-sh-result status
+                   (str "Created rpm package")
+                   (str "Failed to create rpm package"))))

 (defn build-tarball
   "Builds a tarball of the entire mess"
@@ -142,7 +150,9 @@
       (build-tarball project-name ((projects project-name) :version) os-and-machine)
       (build-makeself project-name ((projects project-name) :version) os-and-machine)
       (if (or (= (os-and-machine :platform) "debian") (= (os-and-machine :platform) "ubuntu"))
-        (build-deb project-name ((projects project-name) :version) os-and-machine)))))
+        (build-deb project-name ((projects project-name) :version) os-and-machine))
+      (if (or (= (os-and-machine :platform) "redhat") (= (os-and-machine :platform) "centos") (= (os-and-machine :platform) "fedora"))
+        (build-rpm project-name ((projects project-name) :version) os-and-machine)))))

 (defn -main
   "Main entry point when run from command line"


changes to accommodate lein-story

changes to accommodate lein-story

--- src/story/core.clj
+++ src/story/core.clj
@@ -56,7 +56,7 @@
     [org.pegdown.ast WikiLinkNode])

   ;; To run from the commandline this namespace must be compiled with a `-main`
-  ;; method. When run from the REPL or from Leiningen `gen-class` does nothing.
+  ;; method.
   (:gen-class))

 ;; A few of the top level variables use these utility functions.
@@ -825,6 +825,11 @@
   "Take a list of file paths and an output stream, and render each file to the
   stream as HTML."
   [in-paths out]
+  (when-let [d (and
+                 (or (string? out)
+                     (instance? java.io.File out))
+                 (fs/dirname out))]
+    (fs/mkdirs d))
   (with-out-stream out
     (render-files in-paths)))

@@ -883,16 +888,55 @@

                 :else line))))))))

+
+;; ## Entry points
+;;
+;; There are two entry functions and one [[-main]] function for commandline
+;; use.
+;;
+;; The first entry function is for writing a production tree (all required
+;; files sans test sections).
 (defn write-production-tree
   "Write the contents of in-paths with recursive included and required files
   and directories to outdir, with any test code commented."
   [in-paths outdir]
   (when (fs/exists? outdir)
     (fs/deltree outdir))
-  (fs/mkdir outdir)
+  (fs/mkdirs outdir)
   (doseq [p in-paths]
     (write-production-file p outdir)))

+;; The second entry function is for building documentation. It takes a map of
+;; options, an output file, and a list of files to process. The options are all
+;; optional but at least one input file must be provided.
+;;
+;; The options are:
+;;
+;; ~~~~
+;; :comment     String           single line comment syntax
+;; :brushes     ISeq of Strings  paths to SyntaxHighlighter brush files
+;; :theme       String           path to a SyntaxHighlighter theme file
+;; :language    String           SyntaxHighlighter language name
+;; :stylesheet  String           path to a CSS file
+;; :verbose     boolean          whether to use verbose output
+;; ~~~~
+;;
+;; For the brush, theme, and stylesheet options the program first tries to read
+;; from the filesystem and if that fails because the file is not found then an
+;; attempt is made to read from the program's resources. The resources contain
+;; the standard SyntaxHighlighter brushes and themes under their normal file
+;; names including an additional `shBrushClojure.js` and `shThemeClojure.css`.
+;;
+;; Additional brushes may be added by the program as a result of file includes
+;; and file suffixes.
+(defn story [opts out-file & in-files]
+  (binding [*settings* {:theme (or (:theme opts) (:theme *settings*))
+                        :stylesheet (:stylesheet opts)
+                        :static-brushes (:brush opts)
+                        :verbose? (:verbose opts)}]
+    (binding [*single-comment* (or (:comment opts) *single-comment*)]
+      (binding [*language* (canonical-lang (or (:language opts) *language*))]
+          (process-files in-files out-file)))))

 ;; ## Commandline
 ;;
@@ -915,16 +959,7 @@
                   :default false :flag true]
                  ["-h" "--help" "Show this help" :default false :flag true])]

-    ;; For the brush, theme, and stylesheet options the program first tries to
-    ;; read from the filesystem and if that fails because the file is not found
-    ;; then an attempt is made to read from the program's resources. The
-    ;; resources contain the standard SyntaxHighlighter brushes and themes
-    ;; under their normal file names including an additional
-    ;; `shBrushClojure.js` and `shThemeClojure.css`.
-    ;;
     ;; Multiple brushes can be used by repeating the `-b` or `--brush` options.
-    ;; Additional brushes may be added by the program as a result of file
-    ;; includes and file suffixes.
     ;;
     ;; If present, the `-p` or `--production` option prevents documentation
     ;; generation, and instead writes a production tree to the supplied
@@ -933,17 +968,10 @@
     (if (or (not (seq tail)) (:help amap))
       (do (println (str usage "\n" banner))
         (System/exit 1))
-      (binding [*settings* {:theme (or (:theme amap) (:theme *settings*))
-                            :stylesheet (:stylesheet amap)
-                            :static-brushes (:brush amap)
-                            :verbose? (:verbose amap)}]
-        (binding [*single-comment* (or (:comment amap) *single-comment*)]
-          (binding [*language* (canonical-lang (or (:language amap) *language*))]
-
-            ;; When no output file is given, the program renders to
-            ;; standard-out.
-            (if-let [dir (:production amap)]
-              (write-production-tree tail dir)
-              (if (= 1 (count tail))
-                (process-files tail *out*)
-                (process-files (butlast tail) (last tail))))))))))
+      (if-let [dir (:production amap)]
+        (write-production-tree tail dir)
+
+        ;; When no output file is given, the program renders to standard-out.
+        (if (= 1 (count tail))
+          (apply story amap *out* tail)
+          (apply story amap (last tail) (butlast tail)))))))


[hotfix] Set number of Mesos agent CPUs to 8

This commits sets the number of CPUs on a Mesos agent to 8 which is the same
as the number assigned vcores to a NodeManager in the Yarn case. This allows
to spawn 3 Mesos tasks on an agent if there is enough memory. This will give
us the same number of TMs possible as in the Yarn case.

--- flink-jepsen/src/jepsen/flink/mesos.clj
+++ flink-jepsen/src/jepsen/flink/mesos.clj
@@ -68,7 +68,8 @@
                         (str "--log_dir=" log-dir)
                         (str "--master=" (zookeeper-uri test zk-namespace))
                         (str "--recovery_timeout=30secs")
-                        (str "--work_dir=" slave-dir)]))
+                        (str "--work_dir=" slave-dir)
+                        (str "--resources='cpus:8'")]))

 (defn create-mesos-master-supervised-service!
   [test node]


Add bunyan-middleware

Add bunyan-middleware

--- mern_utils/project.clj
+++ mern_utils/project.clj
@@ -21,6 +21,7 @@
                        [bcrypt-nodejs "0.0.3"]
                        [body-parser  "1.15.0"]
                        [bunyan "1.8.1"]
+                       [bunyan-request "1.2.0"]
                        [connect-flash "0.1.1"]
                        [cookie-parser  "1.4.1"]
                        [cors "2.7.1"]


An example profiles.clj

An example profiles.clj

Make sure that actual values do not end up in version control!

use the command `git update-index --assume-unchanged profiles.clj`


launching responsibility is moved to system ns.

--- cljx/plongeur-cljs/src/plongeur/core.cljs
+++ cljx/plongeur-cljs/src/plongeur/core.cljs
@@ -5,21 +5,18 @@
             [plongeur.model  :as m]
             [plongeur.view   :as v]
             [plongeur.sigma-driver :as sig]
-            [kierros.quiescent-dom-driver   :as dom]
-            [kierros.sente-websocket-driver :as ws]
-            [kierros.local-storage-driver   :as st]))
+            [kierros.quiescent-dom-driver :as dom]
+            [kierros.sente-client-driver :as ws]
+            [kierros.local-storage-driver :as st]))

 (enable-console-print!)
-
-(defn on-js-reload [] (print "on-js-reload"))

 (defn plongeur-main
   "Cycle main."
   [{dom-event-chan       :DOM
     sigma-event-chan     :SIGMA
     saved-state-chan     :STORAGE
-    websocket-event-chan :WEB
-    }]
+    websocket-event-chan :WEB}]
   (let [sigma-chan         (chan 10)
         intent-chans       (-> (i/intents)
                                (assoc :sigma-ctrl sigma-chan))
@@ -27,9 +24,12 @@
         states-chan        (m/model saved-state-chan intent-chans)
         states-mult        (mult states-chan)

-        pickle-states-chan (->> (sliding-buffer 1) (chan) (tap states-mult))
+        pickle-states-chan (->> (map #(dissoc % :transient))
+                                (chan 10)
+                                (tap states-mult))

-        view-states-chan   (->> (chan 10) (tap states-mult))
+        view-states-chan   (->> (chan 10)
+                                (tap states-mult))

         request-chan       (chan 10)

@@ -39,10 +39,9 @@
      :STORAGE pickle-states-chan
      :WEB     request-chan}))

-(cycle/run
-  plongeur-main
-  {:DOM     (dom/make-dom-driver "plongeur-app")
-   :SIGMA   (sig/make-sigma-driver)
-   :STORAGE (st/make-storage-driver "plongeur" m/default-state)
-   ;:WEB    (ws/make-websocket-driver "/chsk")
-   })+(defn launch-plongeur []
+  (cycle/run plongeur-main
+             {:DOM     (dom/make-dom-driver "plongeur-app")
+              ;:WEB    (ws/make-websocket-driver "/chsk")
+              :SIGMA   (sig/make-sigma-driver)
+              :STORAGE (st/make-storage-driver "plongeur" m/default-state)}))


Patch up lifecycles test to avoid c.a.s. collision.

--- test/onyx/peer/lifecycle_exception_test.clj
+++ test/onyx/peer/lifecycle_exception_test.clj
@@ -43,8 +43,6 @@
 (defn after-batch [event lifecycle]
   (when (= @exception-thrower :after-batch)
     (reset! exception-thrower nil)
-    (>!! @in-chan :done)
-    (close! @in-chan)
     (throw (ex-info "Threw exception in after-batch" {})))
   {})

@@ -52,7 +50,9 @@
   {})

 (defn handle-exception [event lifecycle phase e]
-  :restart)
+  (if (not= phase :lifecycle/after-batch)
+    :restart
+    :kill))

 (defn inject-in-ch [event lifecycle]
   {:core.async/chan @in-chan})
@@ -129,6 +129,8 @@
         (doseq [n (range n-messages)]
           (>!! @in-chan {:n n}))

-        (feedback-exception! peer-config job-id (:log (:env test-env)))
-        ;; Made it to the end with a successful job completion.
-        (is true)))))
+        (try
+          (feedback-exception! peer-config job-id (:log (:env test-env)))
+          (is false)
+          (catch Throwable t
+            (is (= "Threw exception in after-batch" (.getMessage t)))))))))


allow custom default-handler to ring-router

--- modules/reitit-ring/src/reitit/ring.cljc
+++ modules/reitit-ring/src/reitit/ring.cljc
@@ -18,8 +18,9 @@
 (defn ring-handler
   "Creates a ring-handler out of a ring-router.
   Supports both 1 (sync) and 3 (async) arities."
-  [router]
-  (let [default-handler (constantly nil)]
+  ([router]
+    (ring-handler router (constantly nil)))
+  ([router default-handler]
     (with-meta
       (fn
         ([request]


[#7] Add first survey definition test

[#7] Add first survey definition test

--- api/test/api/datastore/survey_test.clj
+++ api/test/api/datastore/survey_test.clj
@@ -19,3 +19,20 @@
         (is (= 2 (count surveys-1)))
         (is (= 2 (count surveys-2)))
         (is (= 0 (count surveys-3)))))))
+
+(deftest survey-definition-test
+  (ds/with-local-api
+    (let [user-id (user/id "akvo.flow.user.test@gmail.com")
+          survey-id "148412306"
+          survey (survey/by-id user-id survey-id)
+          form (first (:forms survey))
+          question-group (first (:question-groups form))
+          question (first (:questions question-group))]
+      (are [x required-keys] (= (disj (set (keys x))
+                                      :modified-at
+                                      :created-at)
+                                required-keys)
+        survey #{:id :name :forms}
+        form #{:id :name :question-groups}
+        question-group #{:id :name :repeatable? :questions}
+        question #{:id :name :type :order}))))


Added remove selected node function with filter-tree and with key-press 'd'.

--- evermind.web/src/evermind/web/core.cljs
+++ evermind.web/src/evermind/web/core.cljs
@@ -88,6 +88,15 @@
                    (fn [c] (select-node c selected))
                    children)))))

+(defn handle-key-press [k data]
+  (case k
+    100 ; d
+    (om/transact! data [:mindmap]
+                  (fn [m]
+                    (d/filter-tree
+                      m
+                      (fn [c] (not (-> c :attributes :selected))))))
+    data))

 (defn mindmap-view [data owner]
   (reify
@@ -106,8 +115,10 @@
     om/IRenderState
     (render-state [this {:keys [select]}]
         (let [mindmap (update-node (:mindmap data))]
-          (dom/div nil
-            (dom/svg #js {:id "mindmap-svg" :viewBox "0 0 100 100"}
+          (dom/div #js {:tabIndex 0
+                        :onKeyPress #(handle-key-press (.-charCode %) data)}
+            (dom/svg #js {:id "mindmap-svg"
+                          :viewBox "0 0 100 100"}
               (om/build node-view mindmap {:init-state {:select select}})))))))

 (om/root mindmap-view app-state {:target (. js/document (getElementById "app"))})


Some internal renames/restructurings on the Ekeko side of things.

--- EkekoAspectJ/src/damp/ekeko/aspectj/ajdt.clj
+++ EkekoAspectJ/src/damp/ekeko/aspectj/ajdt.clj
@@ -46,7 +46,7 @@
                             [(v- ?keyword) (fresh [?keywords]
                                                   (equals ?keywords (map (fn [^Class c]
                                                                        (astnode/ekeko-keyword-for-class c))
-                                                                     (astnode/ajdt-node-classes)))
+                                                                     astnode/ajdt-node-classes))
                                                   (contains ?keywords ?keyword)
                                                   (ast ?keyword ?node))])]))


Made leading-candidate fn faster.

Made leading-candidate fn faster.

--- src/luhnybin/core.clj
+++ src/luhnybin/core.clj
@@ -48,13 +48,15 @@

 ;; Find any candidates at the ste start of a string or char seq,
 ;; sorted longest to shortest.
+
 (defn- leading-candidates [chars]
-  (loop [cs (vec (take-while ccchars chars)) acc []]
-    (let [len (num-digits cs)]
-      (cond
-        (>  len 16) (recur (pop cs) acc)
-        (>= len 14) (recur (pop cs) (conj acc cs))
-        :else acc))))
+  (loop [[head & tail] (take-while ccchars chars) seen [] acc '()]
+    (let [seen (if head (conj seen head) seen)
+          len  (num-digits seen)
+          acc  (if (>= len 14) (conj acc seen) acc)]
+      (if (or (= len 16) (nil? tail) (empty? tail))
+        acc
+        (recur tail seen acc)))))

 ;; ### The Main Public API: Process Strings, Files, or Streams


Fix compatibility with latest sablono version.

--- frontend/uxbox/ui/dashboard/projects.cljs
+++ frontend/uxbox/ui/dashboard/projects.cljs
@@ -198,10 +198,10 @@
       [:div.project-th-actions
        [:div.project-th-icon.pages
         i/page
-        [:span 0]]
+        [:span "0"]]
        [:div.project-th-icon.comments
         i/chat
-        [:span 0]]
+        [:span "0"]]
        [:div.project-th-icon.delete
         {:on-click #(do
                       (dom/stop-propagation %)


Update project identifier to be consistent with the way om is doing it.

--- Clojure/project.clj
+++ Clojure/project.clj
@@ -1,4 +1,4 @@
-(defproject ambly "0.1.0-SNAPSHOT"
+(defproject org.omcljs/ambly "0.1.0-SNAPSHOT"
   :description "ClojureScript REPL into embedded JavaScriptCore."
   :url "https://github.com/omcljs/ambly"
   :license {:name "Eclipse Public License"


-todo: single update

-todo: single update

--- src/rex/dispatch.cljs
+++ src/rex/dispatch.cljs
@@ -6,17 +6,18 @@
                                 get-watchers
                                 action]
   (let [old-store-value (get-store)]
-    ;; TODO: single update
-    (doseq [reducer (get-reducers)]
-      (let [{name :name
-             reduce-fn :fn} reducer]
-        (update-store (fn [store-value]
-                        (reduce-fn store-value action)))))
+    (update-store (fn [initial-state]
+                    (reduce (fn [state reducer]
+                              (let [{name :name
+                                     reduce-fn :fn} reducer]
+                                (reduce-fn state action)))
+                            initial-state
+                            (get-reducers))))
     (let [new-store-value (get-store)]
-      (doseq [watcher (get-watchers)]
-        (let [{callback :fn} watcher]
-          (callback old-store-value
-                    new-store-value))))
+            (doseq [watcher (get-watchers)]
+              (let [{callback :fn} watcher]
+                (callback old-store-value
+                          new-store-value))))
     (get-store)))

 (defn- dispatch-using-middlewares [get-store


Add basic query preparation

Add basic query preparation

--- src/subman/models.clj
+++ src/subman/models.clj
@@ -27,10 +27,14 @@
   "Delete all documents"
   [] (esd/delete-by-query-across-all-types index (q/match-all)))

+(defn- prepare-query
+  "Prepare query for search"
+  [query] (clojure.string/replace query #"\." " "))
+
 (defn search
   "Search for documents"
   [query] (->> (esd/search index "subtitle"
-                           :query (q/fuzzy-like-this :like_text query)
+                           :query (q/fuzzy-like-this :like_text (prepare-query query))
                            :size 100)
                :hits
                :hits


Add 'in' reification to interval

Add 'in' reification to interval

--- src/tick/interval.clj
+++ src/tick/interval.clj
@@ -102,7 +102,8 @@

 (extend-protocol t/ITimeReify
   Interval
-  (on [i date] (interval (t/on (t/beginning i) date) (t/on (t/end i) date))))
+  (on [i date] (interval (t/on (t/beginning i) date) (t/on (t/end i) date)))
+  (in [i zone] (interval (t/in (t/beginning i) zone) (t/in (t/end i) zone))))

 (defn bounds [& args]
   (interval


save data with newlines instead of spaces

--- src/todos/storage.clj
+++ src/todos/storage.clj
@@ -15,7 +15,12 @@
   "Save data to data-file-name."
   [data-to-save]
   (try (do
-         (spit data-file-name data-to-save)
+         (spit data-file-name
+               (clojure.string/replace
+                 (str data-to-save)
+                 #"\s+"
+                 "\n"
+                 ))
          (println "data saved.")
          true)
        (catch Exception e


repositioned save

repositioned save

--- src/vineyard/core.clj
+++ src/vineyard/core.clj
@@ -19,12 +19,12 @@
                           (string/join ", "))]
       (str fn-name "(" arg-string ")"))))

+(extend-type clojure.lang.PersistentVector
+  Compile
+  (compile [coll]
+    (str/join "\n" (map compile coll))))
+
 (defn save [program path]
   (let [before (slurp (io/resource "before.js"))
         after  (slurp (io/resource "after.js"))]
     (spit path (str before program after))))
-
-(extend-type clojure.lang.PersistentVector
-  Compile
-  (compile [coll]
-    (str/join "\n" (map compile coll))))


add rss feed

add rss feed

--- src/yablog/server.clj
+++ src/yablog/server.clj
@@ -4,12 +4,15 @@
             [compojure.core :refer :all]
             [compojure.route :as route]
             [hiccup.core :as hiccup]
+            hiccup.util
             [hiccup.page :as hpage]
+            [clj-time.core :as time]
             [clj-time.format :as ftime]
             [yablog.page :as page]
             [yablog.conf :as conf]
             [yablog.time :as ytime]
             [clojure.walk :as w]
+            [clojure.xml :as xml]
             [texticlj.core :as tx]))

 (def date-formatter (ftime/formatters :rfc822))
@@ -17,13 +20,16 @@
 (defn format-time [t]
   (ftime/unparse date-formatter t))

-(defn hiccup-entry [page]
+(defn hiccup-entry-body [page]
   (with-open [r (io/reader (:pathname page))]
     (page/read-headers r)
-    (into [:div {:class "entry"}
-           [:h1 {:class "title"} (or (:subject page) (:title page))]
-           [:h2 {:class "date"} (format-time (:date page))]]
-          (tx/to-hiccup (slurp r)))))
+    (tx/to-hiccup (slurp r))))
+
+(defn hiccup-entry [page]
+  (into [:div {:class "entry"}
+         [:h1 {:class "title"} (or (:subject page) (:title page))]
+         [:h2 {:class "date"} (format-time (:date page))]]
+        (hiccup-entry-body page)))

 (defn recent-posts-box [req]
   (let [pages (page/recent-pages 10 (:pages req))]
@@ -89,9 +95,69 @@
                           slug (:pages request))]
     [:article (hiccup-entry p)]))

+(defn rss-item [post]
+  {:tag :item,
+   :attrs nil,
+   :content
+   [{:tag :title,
+     :attrs nil,
+     :content [(page/title post)]}
+    {:tag :link,
+     :attrs nil,
+     :content
+     [(page/url post)]}                 ;XXX absoluteize this?
+    {:tag :description,
+     :attrs nil,
+     :content
+     [(hiccup.util/escape-html (hiccup/html (hiccup-entry-body post)))]}
+    {:tag :author, :attrs nil, :content ["Daniel Barlow"]}
+    {:tag :pubDate,
+     :attrs nil,
+     :content [(format-time (:date post))]}
+    {:tag :guid,
+     :attrs nil,
+     :content [(page/url post)]
+     }
+    {:tag :dc:date,
+     :attrs nil,
+     :content [(ftime/unparse (ftime/formatters :date-time-no-ms)
+                              (:date post))]}
+    ]})
+
+(defn rss-posts [posts]
+  {:tag :rss,
+   :attrs
+   {:version "2.0",
+    :xmlns:content "http://purl.org/rss/1.0/modules/content/",
+    :xmlns:dc "http://purl.org/dc/elements/1.1/",
+    :xmlns:trackback
+    "http://madskills.com/public/xml/rss/module/trackback/",
+    :xmlns:itunes "http://www.itunes.com/dtds/podcast-1.0.dtd"},
+   :content
+   [{:tag :channel,
+     :attrs nil,
+     :content
+     (into
+      [{:tag :title, :attrs nil, :content ["diary at Telent Netowrks"]}
+       {:tag :link, :attrs nil, :content ["http://ww.telent.net/"]}
+       {:tag :description,
+        :attrs nil,
+        :content ["Geeky stuff about what I do.  By Daniel Barlow"]}]
+      (map rss-item posts))
+     }]})
+
+(defn handle-rss [req]
+  (let [recent (page/recent-pages 10 (:pages req))
+        xml (rss-posts recent)
+        body (with-out-str (xml/emit xml))]
+    #_ (clojure.pprint/pprint xml)
+    {:status 200
+     :headers {"Content-Type" "application/rss+xml; charset=utf-8"}
+     :body body}))

 (defroutes handler
   (GET "/" [] (stylify recent-entries))
+  (GET "/news.rss" [] handle-rss)
   (GET "/static/*" request
        (let [f (-> request :route-params :*)]
          (io/file (conf/static-folder (:conf request)) f)))


Updated project.clj for ring-httpcore-adapter to 0.3.0-beta1

--- ring-httpcore-adapter/project.clj
+++ ring-httpcore-adapter/project.clj
@@ -1,7 +1,7 @@
-(defproject ring/ring-httpcore-adapter "0.2.5"
+(defproject ring/ring-httpcore-adapter "0.3.0-beta1"
   :description "Ring HttpCore adapter."
   :url "http://github.com/mmcgrana/ring"
-  :dependencies [[ring/ring-core "0.2.5"]
+  :dependencies [[ring/ring-core "0.3.0-beta1"]
                  [org.apache.httpcomponents/httpcore "4.0.1"]
                  [org.apache.httpcomponents/httpcore-nio "4.0.1"]]
   :dev-dependencies [[lein-clojars "0.6.0"]])


start printing results before tests are finished, switch to ABQ


Add async state transformation test.

Add async state transformation test.

--- test/potok/tests.cljs
+++ test/potok/tests.cljs
@@ -26,6 +26,18 @@

       (ptk/emit! store (->IncrementBy 1)))))

+
+(t/deftest asynchronous-state-transformation-test
+  (t/async done
+    (let [store (ptk/store {:state {:counter 0}})]
+      (-> (rx/take 1 store)
+          (rx/subscribe (fn [{:keys [counter]}]
+                          (t/is (= counter 2)))
+                        nil
+                        done))
+
+      (ptk/emit! store (->AsyncIncrementBy 2)))))
+
 (set! *main-cli-fn* #(t/run-tests))

 (defmethod t/report [:cljs.test/default :end-run-tests]


Fix move-camera

Fix move-camera

--- common/src/play_clj/core_render.clj
+++ common/src/play_clj/core_render.clj
@@ -64,7 +64,7 @@
 (defn move-camera
   [{:keys [^Camera camera]} x y]
   (fn []
-    (when x (set! (. camera x) x))
-    (when y (set! (. camera y) y))
+    (when x (set! (. (. camera position) x) x))
+    (when y (set! (. (. camera position) y) y))
     (.update camera)
     nil))


tweak dvtable to take options and sort by default

--- user.clj
+++ user.clj
@@ -7,6 +7,7 @@
   (pp/pprint  (seq  (.getURLs  (java.lang.ClassLoader/getSystemClassLoader))))
 )

+;TODO: macroize so it can sit in front of a call like apply
 (defn spy "Simple print debugging" [arg]
   (doto arg prn))

@@ -45,12 +46,15 @@

 (defn dvtable
   "dynamic vars for a namespace mapped to their values"
-  ([] (dvtable *ns*))
-  ([nsname]
-   (table.core/table
-     (cons
-       ["Var" "Value"]
-       (map #(identity [% (deref %)]) (ns-dynamic-vars nsname))))))
+   [& options]
+   (let [opts (apply hash-map options)]
+     (apply
+       table.core/table
+       (cons
+         ["Var" "Value"]
+         (map #(identity [% (deref %)]) (ns-dynamic-vars (get opts :ns *ns*))))
+       :sort true
+       options)))

 (set! clojure.core/*print-length* 100)


Rename BidiRouteProtector to BidiRoutesProtector

--- modules/entrance/src/modular/entrance.clj
+++ modules/entrance/src/modular/entrance.clj
@@ -15,7 +15,7 @@
 (ns modular.entrance
   (:require
    [bidi.bidi :as bidi :refer (path-for resolve-handler unresolve-handler ->WrapMiddleware)]
-   [modular.bidi :refer (BidiRoutesContributor routes context)]
+   [modular.bidi :as modbidi :refer (BidiRoutesContributor routes context)]
    [schema.core :as s]
    [ring.middleware.cookies :refer (wrap-cookies)]
    [ring.middleware.params :refer (wrap-params)]
@@ -43,9 +43,13 @@
 (defprotocol FailedAuthorizationHandler
   (failed-authorization [_ request]))

-;; Only users with valid credentials are allowed through a checkpoint.
-(defprotocol BidiRouteProtector
+;; Certain objects can provide protection for routes
+(defprotocol BidiRoutesProtector
   (protect-routes [_ routes]))
+
+;; Tag that a BidiRoutesContributor is protected
+;; TODO Rename BidiRoutesContributor to BidiRoutesProvider
+;;(defprotocol BidiRoutesProtected)

 (defn wrap-authorization
   "Ring middleware to pre-authorize a request through an authorizer. If
@@ -245,7 +249,7 @@
   (routes [this] (:routes this))
   (context [this] context)

-  BidiRouteProtector
+  BidiRoutesProtector
   (protect-routes [this routes]
     (println "protecting routes:" routes)
     (protect routes


Version Update

Version Update

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

--- src/conexp.clj
+++ src/conexp.clj
@@ -13,6 +13,6 @@

 (dorun (map immigrate *conexp-namespaces*))

-(def *conexp-version* 1258614005579)
+(def *conexp-version* 1258749450039)

 nil


Use transducer per #329 review suggestion

--- modules/reitit-core/src/reitit/impl.cljc
+++ modules/reitit-core/src/reitit/impl.cljc
@@ -90,8 +90,8 @@
             (remove (fn [[[_ route-data] conflicts]]
                       (and (:conflicting route-data)
                            (every? (comp :conflicting second)
-                                   conflicts)))
-                    path-conflicting))
+                                   conflicts))))
+            path-conflicting)
       (not-empty)))

 (defn conflicting-paths [conflicts]


copy changes to subdomain trial page when logged in

--- src-cljs/frontend/components/outer.cljs
+++ src-cljs/frontend/components/outer.cljs
@@ -77,9 +77,9 @@
              "Grab your domain to get started. "]
             (if (utils/logged-in? owner)
               [:p.outer-form-copy
-               "Numbers and hyphens will work but start your team name with a letter. "
-               "You'll have two free weeks of unlimited access. "
-               "(Solo teams work too!) "]
+               "Your team domain needs more than 3 characters, starting with a letter. "
+               "Don't have any teammates? "
+               "That's okay, solo teams are also welcome! "]
               [:p.outer-form-copy
                "To get started, you'll just need to sign in with your Google account. "
                "After that, we'll ask you to create a name for your team domain. "])
@@ -133,7 +133,7 @@
                                 (str (str (:team/subdomain team) "." config/hostname)
                                      " is ready, let's go!")]

-                    :else "Start your team.")]]
+                    :else "Start for free.")]]

             (when error
               [:div.error error])


Accessibility Improvements

Accessibility Improvements

--- src/cljs/salava/profile/ui/profile.cljs
+++ src/cljs/salava/profile/ui/profile.cljs
@@ -31,35 +31,35 @@
      [ph/field-after blocks state nil]]))

 (defn edit-profile-content [state]
- (fn []
-  [:div (if (= 0 @(cursor state [:active-index]))
-         [:div#page-edit
-           [pe/action-buttons state]
-           [:div.panel.thumbnail
-            [:div.panel-heading
-             [:h1 (t :profile/Personalinformation)]]
-            [:div.panel-body
-             [pe/edit-profile state]]]
-           [profile-blocks state]]
-         @(cursor state [:tab-content]))]))
+  (fn []
+    [:div (if (= 0 @(cursor state [:active-index]))
+            [:div#page-edit
+             [pe/action-buttons state]
+             [:div.panel.thumbnail
+              [:div.panel-heading
+               [:h1 (t :profile/Personalinformation)]]
+              [:div.panel-body
+               [pe/edit-profile state]]]
+             [profile-blocks state]]
+            @(cursor state [:tab-content]))]))

 (defn view-profile [state]
   (let [blocks (cursor state [:blocks])]
     [:div;#profile
      (if (= 0 @(cursor state [:active-index]))
-      [:div#page-view
+       [:div#page-view
         [:div {:id (str "theme-" (or @(cursor state [:theme]) 0))
-                  :class "page-content"}
-            [:div.panel
-             [:div.panel-left
-              [:div.panel-right
-               [:div.panel-content
-                [:div.panel-body
-                 [userinfoblock state]
-                 (into [:div];#profile]
-                       (for [index (range (count @blocks))]
-                         (ph/block (cursor blocks [index]) state index)))]]]]]]]
-      @(cursor state [:tab-content]))]))
+               :class "page-content"}
+         [:div.panel
+          [:div.panel-left
+           [:div.panel-right
+            [:div.panel-content
+             [:div.panel-body
+              [userinfoblock state]
+              (into [:div];#profile]
+                    (for [index (range (count @blocks))]
+                      (ph/block (cursor blocks [index]) state index)))]]]]]]]
+       @(cursor state [:tab-content]))]))

 (defn theme-selection [theme-atom themes]
   (reduce (fn [r theme]
@@ -67,7 +67,9 @@
                      [:a {:href "#" :on-click #(do
                                                  (.preventDefault %)
                                                  (reset! theme-atom (js/parseInt (:id theme))))
-                          :alt (t (:name theme)) :title (t (:name theme))}[:div {:class (str "panel-right theme-container" (if (= @theme-atom (:id theme)) " selected"))} " "]]]))
+                          :alt (t (:name theme)) :title (t (:name theme))
+                          :aria-label (str (t :page/Selecttheme) " " (:id theme))}
+                      [:div {:class (str "panel-right theme-container" (if (= @theme-atom (:id theme)) " selected"))} " "]]]))
           [:div {:id "theme-container"}] themes))

 (defn edit-theme [state]
@@ -114,7 +116,7 @@
        :content [edit-profile-content state]
        :theme [edit-theme state]
        :settings [edit-settings state]
-      :preview [view-profile state]
+       :preview [view-profile state]
        nil)]))

 (defn content [state]
@@ -129,13 +131,12 @@

 (defn init-data [user-id state]
   (ajax/GET
-    (path-for (str "/obpv1/profile/" user-id) true)
-    {:handler (fn [data]
+   (path-for (str "/obpv1/profile/" user-id) true)
+   {:handler (fn [data]
                (let [data-with-uuids (assoc data :blocks (vec (map #(assoc % :key (pe/random-key))
                                                                    (get data :blocks))))]
                  (swap! state assoc :permission "success" :edit {:active-tab :content} :edit-mode (session/get! :edit-mode false))
                  (swap! state merge data-with-uuids)))}))
-

 (defn handler [site-navi params]
   (let [user-id (:user-id params)
@@ -157,7 +158,7 @@
     (fn []
       (cond
         (= "initial" (:permission @state)) (layout/default site-navi [:div])
-        (and user (= "error" (:permission @state)))(layout/default-no-sidebar site-navi (err/error-content))
+        (and user (= "error" (:permission @state))) (layout/default-no-sidebar site-navi (err/error-content))
         (= "error" (:permission @state)) (layout/landing-page site-navi (err/error-content))
         (= (:id user) (js/parseInt user-id)) (layout/default site-navi (content state))
         (and (= "success" (:permission @state)) user) (layout/default-no-sidebar site-navi (content state))


Show current language in prompt

Show current language in prompt

--- src/cljs/salava/translator/ui/main.cljs
+++ src/cljs/salava/translator/ui/main.cljs
@@ -14,7 +14,7 @@

 (defn show-prompt [e lang key value]
-  (do (send-new lang key (js/prompt key value))
+  (do (send-new lang key (js/prompt (str lang " " key) value))
       (.preventDefault e)))


layout log title #20

layout log title
#20

--- src/cljs/swarmpit/component/layout.cljs
+++ src/cljs/swarmpit/component/layout.cljs
@@ -16,6 +16,7 @@
    :service-create-config "Services / Wizard"
    :service-create-image  "Services / Wizard"
    :service-info          "Services"
+   :service-log           "Services / Log"
    :service-edit          "Services / Edit"
    :network-list          "Networks"
    :network-create        "Networks / Create"


Allow setup native ratpack handlers directly.

--- src/clojure/catacumba/impl/handlers.clj
+++ src/clojure/catacumba/impl/handlers.clj
@@ -201,8 +201,10 @@
   metadata found on the given var or anonymous
   handler."
   (fn [handler & args]
-    (let [metadata (meta handler)]
-      (:handler-type metadata)))
+    (if (instance? Handler handler)
+      :catacumba/native
+      (let [metadata (meta handler)]
+        (:handler-type metadata))))
   :default :catacumba/default)

 (defn send!
@@ -258,6 +260,10 @@
                                (when (satisfies? IHandlerResponse response)
                                  (-handle-response response context))))))))

+(defmethod adapter :catacumba/native
+  [handler]
+  handler)
+
 (defmethod adapter :catacumba/blocking
   [handler]
   (reify Handler


semantic

semantic

--- src/clojure/zensols/cisql/directive.clj
+++ src/clojure/zensols/cisql/directive.clj
@@ -178,14 +178,6 @@
                    (format "%s: %s" vkey)
                    println)
               (conf/print-key-values))))}
-   {:name "rm"
-    :arg-count 1
-    :usage "<variable>"
-    :desc "delete user variable"
-    :help-section "variables"
-    :fn (fn [opts [name]]
-          (assert-no-query opts)
-          (conf/remove-config (keyword name)))}
    {:name "set"
     :arg-count "*"
     :usage "<variable> [value]"
@@ -206,6 +198,14 @@
                                 %)))]
             (conf/set-config key newval)
             (println (format "%s: %s -> %s" (name key) oldval newval))))}
+   {:name "rm"
+    :arg-count 1
+    :usage "<variable>"
+    :desc "delete user variable"
+    :help-section "variables"
+    :fn (fn [opts [name]]
+          (assert-no-query opts)
+          (conf/remove-config (keyword name)))}
    {:name "tg"
     :arg-count 1
     :usage "<variable>"


Fix return values of migrate and clean.

Fix return values of migrate and clean.

--- src/fhofherr/clj_db_util/migrations.clj
+++ src/fhofherr/clj_db_util/migrations.clj
@@ -12,7 +12,8 @@
   - `db` the database to connect to."
   [db & options]
   (log/info "Preparing to migrate database.")
-  (fw/migrate (db/dialect db) (db/db-spec db) options))
+  (fw/migrate (db/dialect db) (db/db-spec db) options)
+  db)

 (defn clean
   "Clean the database identified by`db`.
@@ -25,4 +26,5 @@

   - `db` the database to clean."
   [db & options]
-  (fw/clean (db/dialect db) (db/db-spec db) options))
+  (fw/clean (db/dialect db) (db/db-spec db) options)
+  db)


Tests for new features in Luxenburger base computation

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

--- src/conexp/tests/fca/implications.clj
+++ src/conexp/tests/fca/implications.clj
@@ -353,6 +353,36 @@
         0 contexts/test-ctx-04 1/5 1/2,
         1 contexts/test-ctx-01 1/5 1/2))

+(deftest test-luxenburger-basis-with-predicate
+  (with-testing-data [ctx [ctx-1
+                           contexts/test-ctx-01
+                           contexts/test-ctx-02
+                           contexts/test-ctx-04
+                           contexts/test-ctx-07
+                           contexts/test-ctx-08]
+                      cnt [0 1 2 3 4 5]
+                      cnf [0 1/2 9/10 1]]
+    (let [impls (luxenburger-basis ctx #(<= (count %) cnt) cnf)]
+      (forall [impl impls]
+        (and (<= (count (premise impl)) cnt)
+             (<= cnf (confidence impl ctx))))))
+
+  (with-testing-data [ctx [ctx-1
+                           contexts/test-ctx-01
+                           contexts/test-ctx-02
+                           contexts/test-ctx-04
+                           contexts/test-ctx-07
+                           contexts/test-ctx-08]
+                      cnt (range (inc (count (objects ctx))))]
+    (let [impls (luxenburger-basis ctx #(<= (count %) cnt) 0)
+          intes (set (filter #(<= (count %) cnt) (intents ctx)))
+          comps (union (set (map premise impls))
+                       (set (map #(union (premise %) (conclusion %)) impls)))]
+      (and (subset? comps intes)
+           (or (= comps intes)
+               (and (singleton? intes)
+                    (empty? comps)))))))
+
 (deftest test-ryssel-base
   (with-testing-data [ctx (random-contexts 10 15)]
     (let [base (ryssel-base ctx)]


added google analitycs script

added google analitycs script

--- src/ganelon/tutorial/pages/common.clj
+++ src/ganelon/tutorial/pages/common.clj
@@ -65,12 +65,20 @@
         " and " [:a {:href "http://mongohq.com"} "MongoHQ"] "."]
        ]]
      [:script "prettyPrint();"]
+     "<script>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+  ga('create', 'UA-40249846-1', 'tomeklipski.com');
+  ga('send', 'pageview');
+</script>"
      ]))

 (defn push-state [url]
   (ui/ui-operation "push-state" :url url))

-(def GITHUB-URL "https://github.com/tlipski/ganelon/blob/master/src/")
+(def GITHUB-URL "https://github.com/tlipski/ganelon-tutorial/blob/master/src/")
 (def GITHUB-LINE-PREFIX "#L")

 (defn split-wrapper-from-body [body]


Extend doc-changes from event-seq to parse and parse-str

--- src/main/clojure/clojure/data/xml.clj
+++ src/main/clojure/clojure/data/xml.clj
@@ -90,21 +90,22 @@

 Options:

-  :include-node? can be a subset of #{:element :characters :comment} default #{:element :characters}
-  :location-info pass false to skip generating location meta data
+  :include-node? subset of #{:element :characters :comment}, default #{:element :characters}
+  :location-info pass false to skip generating location meta data, default true

-See http://docs.oracle.com/javase/6/docs/api/javax/xml/stream/XMLInputFactory.html
-for documentation on options:
+See https://docs.oracle.com/javase/8/docs/api/javax/xml/stream/XMLInputFactory.html
+for documentation on xml options. These are the defaults:

-  {:allocator                      XMLInputFactory/ALLOCATOR
-   :coalescing                     XMLInputFactory/IS_COALESCING
-   :namespace-aware                XMLInputFactory/IS_NAMESPACE_AWARE
-   :replacing-entity-references    XMLInputFactory/IS_REPLACING_ENTITY_REFERENCES
-   :supporting-external-entities   XMLInputFactory/IS_SUPPORTING_EXTERNAL_ENTITIES
-   :validating                     XMLInputFactory/IS_VALIDATING
-   :reporter                       XMLInputFactory/REPORTER
-   :resolver                       XMLInputFactory/RESOLVER
-   :support-dtd                    XMLInputFactory/SUPPORT_DTD}"
+  {:allocator                    nil      ; XMLInputFactory/ALLOCATOR
+   :coalescing                   true     ; XMLInputFactory/IS_COALESCING
+   :namespace-aware              true     ; XMLInputFactory/IS_NAMESPACE_AWARE
+   :replacing-entity-references  true     ; XMLInputFactory/IS_REPLACING_ENTITY_REFERENCES
+   :supporting-external-entities false    ; XMLInputFactory/IS_SUPPORTING_EXTERNAL_ENTITIES
+   :validating                   false    ; XMLInputFactory/IS_VALIDATING
+   :reporter                     nil      ; XMLInputFactory/REPORTER
+   :resolver                     nil      ; XMLInputFactory/RESOLVER
+   :support-dtd                  true     ; XMLInputFactory/SUPPORT_DTD
+   }"
   {:arglists (list ['source '& parser-opts-arg])}
   [source & {:as opts}]
   (event-tree (event-seq source opts)))
@@ -114,21 +115,22 @@

 Options:

-  :include-node? can be a subset of #{:element :characters :comment} default #{:element :characters}
-  :location-info pass false to skip generating location meta data
+  :include-node? subset of #{:element :characters :comment}, default #{:element :characters}
+  :location-info pass false to skip generating location meta data, default true

-See http://docs.oracle.com/javase/6/docs/api/javax/xml/stream/XMLInputFactory.html
-for documentation on options:
+See https://docs.oracle.com/javase/8/docs/api/javax/xml/stream/XMLInputFactory.html
+for documentation on xml options. These are the defaults:

-  {:allocator                      XMLInputFactory/ALLOCATOR
-   :coalescing                     XMLInputFactory/IS_COALESCING
-   :namespace-aware                XMLInputFactory/IS_NAMESPACE_AWARE
-   :replacing-entity-references    XMLInputFactory/IS_REPLACING_ENTITY_REFERENCES
-   :supporting-external-entities   XMLInputFactory/IS_SUPPORTING_EXTERNAL_ENTITIES
-   :validating                     XMLInputFactory/IS_VALIDATING
-   :reporter                       XMLInputFactory/REPORTER
-   :resolver                       XMLInputFactory/RESOLVER
-   :support-dtd                    XMLInputFactory/SUPPORT_DTD}"
+  {:allocator                    nil      ; XMLInputFactory/ALLOCATOR
+   :coalescing                   true     ; XMLInputFactory/IS_COALESCING
+   :namespace-aware              true     ; XMLInputFactory/IS_NAMESPACE_AWARE
+   :replacing-entity-references  true     ; XMLInputFactory/IS_REPLACING_ENTITY_REFERENCES
+   :supporting-external-entities false    ; XMLInputFactory/IS_SUPPORTING_EXTERNAL_ENTITIES
+   :validating                   false    ; XMLInputFactory/IS_VALIDATING
+   :reporter                     nil      ; XMLInputFactory/REPORTER
+   :resolver                     nil      ; XMLInputFactory/RESOLVER
+   :support-dtd                  true     ; XMLInputFactory/SUPPORT_DTD
+   }"
   {:arglists (list ['string '& parser-opts-arg])}
   [s & opts]
   (apply parse (string-source s) opts))


Rename

Rename

--- src/net/sekao/nightcode/shortcuts.clj
+++ src/net/sekao/nightcode/shortcuts.clj
@@ -12,37 +12,37 @@
            [javafx.beans.value ChangeListener]
            [javafx.application Platform]))

-(def mappings {; project pane
-               :start "p"
-               :import-project "o"
-               :rename "m"
-               :remove "g"
-               :project-tree "↑ ↓ ↲"
-               ; editor pane
-               :up "u"
-               :save "s"
-               :undo "z"
-               :redo "Z"
-               :instarepl "l"
-               :find "f"
-               :replace "R"
-               :close "w"
-               ; build pane
-               :run "r"
-               :run-repl "X"
-               :reload "S"
-               :eval "e"
-               :build "b"
-               :test "t"
-               :stop "i"
-               :build-console "A"
-               ; directory pane
-               :new-file "n"
-               :edit "M"
-               :open-in-browser "F"
-               :cancel "C"})
+(def id->key-char {; project pane
+                   :start "p"
+                   :import-project "o"
+                   :rename "m"
+                   :remove "g"
+                   :project-tree "↑ ↓ ↲"
+                   ; editor pane
+                   :up "u"
+                   :save "s"
+                   :undo "z"
+                   :redo "Z"
+                   :instarepl "l"
+                   :find "f"
+                   :replace "R"
+                   :close "w"
+                   ; build pane
+                   :run "r"
+                   :run-repl "X"
+                   :reload "S"
+                   :eval "e"
+                   :build "b"
+                   :test "t"
+                   :stop "i"
+                   :build-console "A"
+                   ; directory pane
+                   :new-file "n"
+                   :edit "M"
+                   :open-in-browser "F"
+                   :cancel "C"})

-(def reverse-mappings (set/map-invert mappings))
+(def key-char->id (set/map-invert id->key-char))

 (fdef keyword->fx-id
   :args (s/cat :k keyword?)
@@ -72,12 +72,12 @@
   ([nodes]
    (doseq [node nodes]
      (when-let [id (.getId node)]
-       (when-let [text (get mappings (fx-id->keyword id))]
+       (when-let [text (get id->key-char (fx-id->keyword id))]
          (add-tooltip! node text)))))
   ([^Scene scene ids]
    (doseq [id ids]
      (let [control (.lookup scene (keyword->fx-id id))
-           text (get mappings id)]
+           text (get id->key-char id)]
        (when (and control text)
          (add-tooltip! control text))))))

@@ -100,7 +100,7 @@
   :args (s/cat :stage spec/stage?))
 (defn show-tooltips! [^Stage stage]
   (let [scene (.getScene stage)]
-    (doseq [id (keys mappings)]
+    (doseq [id (keys id->key-char)]
       (when-let [control (.lookup scene (keyword->fx-id id))]
         (show-tooltip! stage control)))))

@@ -112,14 +112,14 @@
 (fdef hide-tooltips!
   :args (s/cat :node (s/or :node spec/node? :stage spec/scene?)))
 (defn hide-tooltips! [node]
-  (doseq [id (keys mappings)]
+  (doseq [id (keys id->key-char)]
     (when-let [control (.lookup node (keyword->fx-id id))]
       (hide-tooltip! control))))

 (fdef run-shortcut!
   :args (s/cat :scene spec/scene? :actions map? :text string? :shift? spec/boolean?))
 (defn run-shortcut! [^Scene scene actions ^String text shift?]
-  (when-let [id (get reverse-mappings (if shift? (.toUpperCase text) text))]
+  (when-let [id (get key-char->id (if shift? (.toUpperCase text) text))]
     (when-let [action (get actions id)]
       (when-let [widget (some-> scene (.lookup (keyword->fx-id id)))]
         (when (and (not (.isDisabled widget)) (.isManaged widget))


Implemented Recruiting Trip

Implemented Recruiting Trip

--- src/clj/game/cards-operations.clj
+++ src/clj/game/cards-operations.clj
@@ -219,6 +219,22 @@
     :effect (req (doseq [c (filter #(= (:title target) (:title %)) (:discard corp))]
                    (move state side c :hand)))}

+   "Recruiting Trip"
+   (let [rthelp (fn rt [total left selected]
+                  (if (> left 0)
+                    {:prompt (str "Select a sysop (" (inc (- total left)) "/" total ")")
+                     :choices (req (filter #(and (has? % :subtype "Sysop")
+                                                 (not (some #{(:title %)} selected))) (:deck corp)))
+                     :msg (msg "put " (:title target) " into HQ")
+                     :effect (req (move state side target :hand)
+                                  (resolve-ability
+                                    state side
+                                    (rt total (dec left) (cons (:title target) selected))
+                                    card nil))}
+                    {}))]
+   {:prompt "How many sysops?" :choices :credit :msg (msg "search for " target " sysops")
+    :effect (effect (resolve-ability (rthelp target target []) card nil))})
+
    "Restoring Face"
    {:prompt "Choose a Sysop, Executive or Clone to trash"
     :msg (msg "trash " (:title target) " to remove 2 bad publicity")


GAWB-3092: Privacy policy update (#1141)

* Add privacy policy, update layout

* cleanup imports

--- src/cljs/main/broadfcui/auth.cljs
+++ src/cljs/main/broadfcui/auth.cljs
@@ -2,6 +2,7 @@
   (:require
    [dmohs.react :as react]
    [clojure.string :as string]
+   [broadfcui.common.links :as links]
    [broadfcui.common.style :as style]
    [broadfcui.components.buttons :as buttons]
    [broadfcui.components.spinner :refer [spinner]]
@@ -33,29 +34,117 @@

 (react/defc- Policy
   {:render
-   (fn []
-     [:div {:style {:maxWidth 600 :paddingTop "2em"}}
-      [:p {:style {:fontWeight "bold"}} "WARNING NOTICE"]
+   (fn [{:keys [props]}]
+     [:div {:style {:maxWidth 616 :backgroundColor "white"
+                    :padding "1.5rem" :margin "1rem auto"
+                    :border style/standard-line
+                    :fontSize (when (= (:context props) :logged-out) "88%")}}
+      (when (= (:context props) :policy-page)
+        (list
+         [:h3 {} "FireCloud Privacy Policy"]
+         [:p {}
+          "The following Privacy Policy discloses our information gathering and dissemination
+           practices for the Broad Institute FireCloud application accessed via the website "
+          (links/create-external {:href "https://portal.firecloud.org/"}
+                                 "https://portal.firecloud.org/")
+          ". By using the FireCloud, you agree to the collection and use of information in
+           accordance with this policy. This Privacy Policy is effective as of 1-19-2017."]
+         [:h4 {} "Information Gathering"]
+         [:p {}
+          "The Broad Institute FireCloud receives and stores information related to users’ Google
+           profiles, including names, email addresses, user IDs, and OAuth tokens. This information
+           is gathered as part of the standard Google sign-in process."]
+         [:p {}
+          "We also collect information that your browser sends whenever you visit the FireCloud
+           website (“Log Data”).  This Log Data may include information such as your computer’s
+           Internet Protocol (“IP”) address, browser type, browser version, which pages of the
+           FireCloud Portal that you visit, the time and date of your visit, the time spent on
+           individual pages, and other statistics.  This information may include any search terms
+           that you enter on the FireCloud (e.g., dataset name, method name, tag labels). We do not
+           link IP addresses to any personally identifying information.  User sessions will be
+           tracked, but users will remain anonymous."]
+         [:p {}
+          "In addition, we use web tools such as Google Analytics that collect, monitor, and analyze
+           the Log Data.  User information (i.e., name and email address) is not included in our
+           Google Analytics tracking, but can be internally linked within the FireCloud development
+           team."]
+         [:h4 {} "Use of Information"]
+         [:p {}
+          "FireCloud uses the information gathered above to enable integration with Google-based
+           services that require a Google account, such as Google Cloud Storage Platform. We may
+           also use this information to provide you with the services on FireCloud, improve
+           FireCloud, and to communicate with you (e.g., about new feature announcements, unplanned
+           site maintenance, and general notices). Web server logs are retained on a temporary basis
+           and then deleted completely from our systems. User information is stored in a
+           password-protected database, and OAuth tokens are only stored for the length of an active
+           session, are encrypted at rest, and are deleted upon sign out."]
+         [:p {}
+          "At no time do we disclose any user information to third parties."]
+         [:h4 {} "Publicly Uploaded Information"]
+         [:p {}
+          "Some features of FireCloud are public facing (e.g, publishing a workspace in the Data
+           Library) and allow you to upload information (such as new studies) that you may choose to
+           make publicly available. If you choose to upload content is public-facing, third parties
+           may access and use it. We do not sell any information that you provide to FireCloud; it
+           is yours. However, any information that you make publicly available may be accessed and
+           used by third parties, such as research organizations or commercial third parties."]
+         [:h4 {} "Security"]
+         [:p {}
+          "This site has security measures in place to prevent the loss, misuse, or alteration of
+           the information under our control. It is compliant with NIST-800-53 and has been audited
+           as per FISMA Moderate. The Broad Institute, however, is not liable for the loss, misuse,
+           or alteration of information on this site by any third party."]
+         [:h4 {} "Changes"]
+         [:p {}
+          "Although most changes are likely to be minor, we may change our Privacy Policy from time
+           to time. We will notify you of material changes to this Privacy Policy through the
+           FireCloud website at least 30 days before the change takes effect by posting a notice on
+           our home page or by sending an email to the email address associated with your user
+           account. For changes to this Privacy Policy that do not affect your rights, we encourage
+           you to check this page frequently."]
+         [:h4 {} "Third Party Sites"]
+         [:p {}
+          "Some FireCloud pages may link to third party websites or services that are not maintained
+           by the Broad Institute. The Broad Institute is not responsible for the privacy practices
+           or the content of any such third party websites or services."]
+         [:h4 {} "Contacting the FireCloud team"]
+         [:p {}
+          "If you have any questions about this privacy statement, the practices of this site, or
+          your dealings with this site, you can contact us through "
+          (links/create-external {:href "mailto:help@firecloud.org"} "help@firecloud.org")
+          " or our "
+          (links/create-external {:href (config/forum-url)} "User Forum")
+          "."]
+         [:hr]))
+      [:h3 {} "WARNING NOTICE"]
       [:p {}
        "You are accessing a US Government web site which may contain information that must be
-          protected under the US Privacy Act or other sensitive information and is intended for
-          Government authorized use only."]
+        protected under the US Privacy Act or other sensitive information and is intended for
+        Government authorized use only."]
       [:p {}
        "Unauthorized attempts to upload information, change information, or use of this web site
-          may result in disciplinary action, civil, and/or criminal penalties. Unauthorized users
-          of this website should have no expectation of privacy regarding any communications or
-          data processed by this website."]
+        may result in disciplinary action, civil, and/or criminal penalties. Unauthorized users
+        of this website should have no expectation of privacy regarding any communications or
+        data processed by this website."]
       [:p {}
        "Anyone accessing this website expressly consents to monitoring of their actions and all
-          communications or data transiting or stored on related to this website and is advised
-          that if such monitoring reveals possible evidence of criminal activity, NIH may provide
-          that evidence to law enforcement officials."]
-      [:p {:style {:fontWeight "bold"}} "WARNING NOTICE (when accessing controlled data)"]
+        communications or data transiting or stored on related to this website and is advised
+        that if such monitoring reveals possible evidence of criminal activity, NIH may provide
+        that evidence to law enforcement officials."]
+      [:h4 {} "WARNING NOTICE (when accessing controlled data)"]
       [:p {:style {:fontWeight "bold"}}
        "You are reminded that when accessing controlled access information you are bound by the
-          dbGaP TCGA "
-       [:a {:href "http://cancergenome.nih.gov/pdfs/Data_Use_Certv082014" :target "_blank"}
-        "DATA USE CERTIFICATION AGREEMENT (DUCA)"] "."]])})
+        dbGaP TCGA "
+       (links/create-external {:href "http://cancergenome.nih.gov/pdfs/Data_Use_Certv082014"}
+                              "DATA USE CERTIFICATION AGREEMENT (DUCA)")
+       "."]])})
+
+(react/defc- PolicyPage
+  {:render
+   (fn []
+     [:div {:style {:padding "1rem" :margin -20 :marginTop "1rem"
+                    :backgroundColor (:background-light style/colors)}}
+      [Policy {:context :policy-page}]])})

 (react/defc LoggedOut
   {:render
@@ -63,14 +152,16 @@
      ;; Google's code complains if the sign-in button goes missing, so we hide this component rather
      ;; than removing it from the page.
      [:div {:style {:display (when (:hidden? props) "none") :marginTop "2rem"}}
-      [buttons/Button {:text "Sign In" :onClick #(this :-handle-sign-in-click)}]
-      [:div {:style {:marginTop "2em" :maxWidth 600}}
-       [:div {} [:b {} "New user? FireCloud requires a Google account."]]
-       [:div {} "Please use the \"Sign In\" button above to sign-in with your Google Account.
-         Once you have successfully signed-in with Google, you will be taken to the FireCloud
-         registration page."]]
-      [:div {:style {:maxWidth 600 :paddingTop "2em" :fontSize "small"}}
-       [Policy]]])
+      [:div {:style {:margin "0 auto" :maxWidth 616}}
+       [:div {:style {:textAlign "center"}}
+        [buttons/Button {:text "Sign In" :onClick #(this :-handle-sign-in-click)}]]
+       [:div {:style {:margin "2rem 0"}}
+        [:div {} [:b {} "New user? FireCloud requires a Google account."]]
+        [:p {}
+         "Please use the \"Sign In\" button above to sign-in with your Google Account.
+          Once you have successfully signed-in with Google, you will be taken to the FireCloud
+          registration page."]]]
+      [Policy {:context :logged-out}]])
    :component-did-mount
    (fn [{:keys [props locals]}]
      (swap! locals assoc :refresh-token-saved? true)
@@ -193,7 +284,7 @@
   (nav/defpath
    :policy
    {:public? true
-    :component Policy
+    :component PolicyPage
     :regex #"policy"
     :make-props (fn [_] {})
     :make-path (fn [] "policy")}))


Catch any other completion errors

Catch any other completion errors

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -362,12 +362,14 @@
         (let [prefix (.getAlreadyEnteredText this comp)
               context (get-completion-context text-area prefix)]
           (when (and prefix context)
-            (for [symbol-str (compliment/completions prefix context)
-                  :when (some? symbol-str)]
-              (->> (str "
"
-                        (compliment/documentation symbol-str)
-                        "
")
-                   (BasicCompletion. this symbol-str nil))))))
+            (try
+              (for [symbol-str (compliment/completions prefix context)
+                    :when (some? symbol-str)]
+                (->> (str "
"
+                          (compliment/documentation symbol-str)
+                          "
")
+                     (BasicCompletion. this symbol-str nil)))
+              (catch Exception _)))))
       (isValidChar [ch]
         (or (Character/isLetterOrDigit ch)
             (contains? #{\* \+ \! \- \_ \? \/ \. \: \< \>} ch)))


calc updates

calc updates

--- src/clojush/experimental/calc.clj
+++ src/clojush/experimental/calc.clj
@@ -5,7 +5,9 @@
         [clojush.random]
         [clojush.util]
         [clojush.instructions.tag]
-        [clojure.math.numeric-tower]
+        [clojure.math.numeric-tower]
+        [clojush.globals]
+        [clojush.experimental.tagged-code-macros]
         ;[incanter.stats :as stats]
         ))

@@ -297,8 +299,15 @@
                                         (rest buttons))))))]
     ;(vec (apply concat test-errors))
     (let [all-errors (apply concat test-errors)]
-      (conj (vec all-errors) (count (filter #(not (zero? %)) all-errors))))
+      (conj
+        (conj (vec all-errors)
+              (* 10000.0 (count (filter #(> % 0.0001) all-errors))))
+        ;; size case
+        (* 0.0001 (count-points program))
+        )
+      )
     ))
+

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -309,9 +318,11 @@
                        ;'(signal_error)
                        [0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0]
                        [(tag-instruction-erc [:exec])]
-                       (for [t (vals button-entrypoints)]
-                         (fn [] (symbol (str "tag_exec_" (str t)))))
+                       ;(for [t (vals button-entrypoints)]
+                       ;  (fn [] (symbol (str "tag_exec_" (str t)))))
                        [(tagged-instruction-erc)]
+                       ;; allow code_append tag macros (taking 2 arguments and returning 1 result)
+                       [(tagged-code-macro-erc 'code_append @global-tag-limit 2 1)]
                        ;(repeat 46 'code_noop)
                        '(boolean_and
                           boolean_dup
@@ -525,7 +536,7 @@
    ;:decimation-ratio 0.01
    ;:tournament-size 1
    :population-size 1000 ;200 ;50
-   :max-generations 10001
+   :max-generations 100000
    :evalpush-limit 3000
    :tag-limit 10000
    :max-points 3000
@@ -538,7 +549,7 @@
    :reproduction-simplifications 10
    :ultra-probability 1.0
    :ultra-alternation-rate 0.005
-   :ultra-alignment-deviation 50
+   :ultra-alignment-deviation 5
    :ultra-mutation-rate 0.005
    :deletion-mutation-probability 0
    :parentheses-addition-mutation-probability 0
@@ -551,7 +562,8 @@
    :pop-when-tagging true
    :report-simplifications 0
    :print-history false
-   ;:use-bushy-code true
+   :use-bushy-code true
    :use-ultra-no-paren-mutation true
    :problem-specific-report calc-report-with-reset!
+   :reuse-errors false
   })


Extract the fetching of the meta data into a separate function

--- src/mdr2/rdf.clj
+++ src/mdr2/rdf.clj
@@ -11,14 +11,26 @@
 (defn- page-normal [production] 0)
 (defn- page-special [production] 0)

+(defn get-meta-data [production]
+  (merge
+   {:depth (depth production)
+    :files (files production)
+    :size (size production)
+    :page-front (page-front production)
+    :page-normal (page-normal production)
+    :page-special (page-special production)}
+   production))
+
 (defn- rdf-sexp [production]
   (let [{:keys [title creator subject description publisher date identifier source language rights
                 sourceDate sourceEdition sourcePublisher sourceRights sourceTitle
-                multimediaType multimediaContent narrator producedDate
+                multimediaType multimediaContent narrator producedDate
                 revision revisionDate revisionDescription
                 totalTime audioFormat type
                 footnotes prodnotes multi-volume sidebars
-                tocItems]} production]
+                tocItems
+                depth files size
+                page-front page-normal page-special]} production]
     [:rdf:DRF {:xmlns:rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                :xmlns:dc "http://purl.org/dc/elements/1.1/"
                :xmlns:ncc "http://www.daisy.org/publications/specifications/"
@@ -36,20 +48,20 @@
       [:dc:title title]
       [:dc:type type]
       [:ncc:charset "utf-8"]
-      [:ncc:depth (depth production)]
-      [:ncc:files (files production)]
+      [:ncc:depth depth]
+      [:ncc:files files]
       (when footnotes [:ncc:footnotes footnotes])
-      [:ncc:kByteSize (size production)]
+      [:ncc:kByteSize size]
       [:ncc:multimediaType multimediaType]
       [:ncc:narrator narrator]
-      [:ncc:pageFront (page-front production)]
-      [:ncc:pageNormal (page-normal production)]
-      [:ncc:pageSpecial (page-special production)]
+      [:ncc:pageFront page-front]
+      [:ncc:pageNormal page-normal]
+      [:ncc:pageSpecial page-special]
       (when prodnotes [:ncc:prodNotes prodnotes])
       [:ncc:producedDate producedDate]
       [:ncc:revisionDate revisionDate]
       (when multi-volume
-        [:ncc:setInfo (str (:number multi-volume)) " of " (:total multi-volume)])
+        [:ncc:setInfo (str (:number multi-volume) " of " (:total multi-volume))])
       (when sidebars [:ncc:sidebars sidebars])
       [:ncc:sourceDate sourceDate]
       [:ncc:sourcePublisher sourcePublisher]
@@ -64,10 +76,11 @@
       [:sbs:kostenstelle "FIXME:"]
       [:sbs:printPageNumber "FIXME:"]]]))

-(defn rdf
+(defn rdf
   "Create rdf for a given production"
   [production]
   (-> production
+      get-meta-data
       rdf-sexp
       xml/sexp-as-element
       xml/emit-str))


pass through cluster-opts

pass through cluster-opts

so the app can specify any cluster-opts,
and clean up statement tracing a bit too

--- src/er_cassandra/session/alia.clj
+++ src/er_cassandra/session/alia.clj
@@ -1,6 +1,7 @@
 (ns er-cassandra.session.alia
   (:require
    [plumbing.core :refer :all]
+   [taoensso.timbre :refer [trace debug info warn error]]
    [clojure.string :as str]
    [qbits.alia :as alia]
    [qbits.alia.policy.load-balancing :as lb]
@@ -13,22 +14,22 @@
     SpySession
     KeyspaceProvider]))

-(def ^:dynamic debug nil)
+(def ^:dynamic *trace* nil)

 (defmacro with-debug
   [& forms]
-  `(binding [debug true]
+  `(binding [*trace* true]
      ~@forms))

 (defn- execute*
   [alia-session statement opts]
   (aliam/execute
    alia-session
-   (if (string? statement)
-     statement
-     (do
-       (when debug
-         (prn statement))
+   (do
+     (when *trace*
+       (debug statement))
+     (if (string? statement)
+       statement
        (h/->raw statement)))
    opts))

@@ -36,26 +37,28 @@
   [alia-session statement opts]
   (aliam/execute-buffered
    alia-session
-   (if (string? statement)
-     statement
-     (do
-       (when debug
-         (prn statement))
+   (do
+     (when *trace*
+       (debug statement))
+     (if (string? statement)
+       statement
        (h/->raw statement)))
    opts))

-(defn- create-alia-session*
+(defnk ^:private create-alia-session*
   [contact-points
    datacenter
    keyspace
-   port]
-  (let [cluster (alia/cluster
-                 (assoc-when
-                  {:contact-points contact-points}
-                  :load-balancing-policy (when datacenter
-                                           (lb/dc-aware-round-robin-policy
-                                            datacenter))
-                  :port port))
+   :as args]
+  (let [cluster-args (dissoc args :keyspace :datacenter)
+        cluster-args (assoc-when
+                      cluster-args
+                      :load-balancing-policy (when datacenter
+                                               (lb/dc-aware-round-robin-policy
+                                                datacenter)))
+
+        _ (info "create-alia-session*" cluster-args)
+        cluster (alia/cluster cluster-args)
         alia-session (alia/connect cluster)]
     (alia/execute alia-session (str "USE " keyspace ";"))
     alia-session))
@@ -74,10 +77,10 @@
     (.close alia-session)))

 (defnk create-session
-  [contact-points datacenter keyspace {port nil}]
+  [contact-points datacenter keyspace :as args]
   (->AliaSession
    keyspace
-   (create-alia-session* contact-points datacenter keyspace port)))
+   (create-alia-session* args)))

 (defn mutated-tables
   [spy-session]
@@ -130,10 +133,10 @@
   (reset-spy-log [_] (reset! spy-log-atom [])))

 (defnk create-spy-session
-  [contact-points datacenter keyspace {port nil} {truncate-on-close nil}]
+  [contact-points datacenter keyspace {truncate-on-close nil} :as args]
   (->AliaSpySession
    keyspace
-   (create-alia-session* contact-points datacenter keyspace port)
+   (create-alia-session* (dissoc args :truncate-on-close))
    (atom [])
    truncate-on-close))


(PDB-4907) Don't time out fact path gc by default

Right now we're not sure what, if any, would be a good default, since
the fact-paths gc can take a long time in some cases.

--- src/puppetlabs/puppetdb/scf/storage.clj
+++ src/puppetlabs/puppetdb/scf/storage.clj
@@ -1693,8 +1693,7 @@
           (throw e)))))))

 (def fact-path-gc-lock-timeout-ms
-  (env-config-for-db-ulong "PDB_FACT_PATH_GC_SQL_LOCK_TIMEOUT_MS"
-                           (* 10 60 1000)))
+  (env-config-for-db-ulong "PDB_FACT_PATH_GC_SQL_LOCK_TIMEOUT_MS" nil))

 (defn garbage-collect!
   "Delete any lingering, unassociated data in the database"


Add launchdarkly flag for sidebar icon

Add launchdarkly flag for sidebar icon

--- src-cljs/frontend/components/aside.cljs
+++ src-cljs/frontend/components/aside.cljs
@@ -523,15 +523,16 @@
                   [:i.material-icons "receipt"]
                   [:div.nav-label "Changelog"]]))

-             [:a.aside-item {:data-placement "right"
-                             :data-trigger "hover"
-                             :title "What's New"
-                             :target "_blank"
-                             :href "https://circleci.com/beta-access/"
-                             :on-click #(aside-nav-clicked owner :changelog-icon-clicked)}
+
+             (when (ld/feature-on? "beta-sidebar-icon")
+               [:a.aside-item {:data-placement "right"
+                               :data-trigger "hover"
+                               :title "What's New"
+                               :target "_blank"
+                               :href "https://circleci.com/beta-access/"
+                               :on-click #(aside-nav-clicked owner :changelog-icon-clicked)}
                (icon/engine-2)
-               [:div.nav-label "What's New"]]
-
+               [:div.nav-label "What's New"]])

              (when (:admin user)
                [:a.aside-item {:class (when (= :admin-settings current-route) "current")


fix blog link target

fix blog link target

--- src-cljs/frontend/components/outer.cljs
+++ src-cljs/frontend/components/outer.cljs
@@ -195,7 +195,7 @@
    [:div.navigation
      [:a.navigation-link {:href "/home"    :role "button" :title "Home"} "Precursor"]
      [:a.navigation-link {:href "/pricing" :role "button" :title "Pricing"} "Pricing"]
-     [:a.navigation-link {:href "/blog"    :role "button" :title "Blog"} "Blog"]
+     [:a.navigation-link {:href "/blog"    :role "button" :title "Blog" :target "_self"} "Blog"]
      (om/build common/google-login {:source "Nav" :size :small})]))

 (def outer-components


display move-number for first moves in a variation

--- src/main/cljs/chessdojo/core.cljs
+++ src/main/cljs/chessdojo/core.cljs
@@ -35,15 +35,19 @@
     (reset! state new-game)
     (js/updateBoard new-fen)))

-(defn move-no [ply]
-  (when (odd? ply) (str (inc (quot ply 2)) ".")))
+(defn move-no
+  "Return a move-number for white moves and first moves in variations."
+  [ply is-first]
+  (cond
+    (odd? ply) (str (inc (quot ply 2)) ".")
+    (and is-first (even? ply)) (str (quot ply 2) "...")))

 ;; -------------------------
 ;; Views

-(defn move-view [move path focus]
+(defn move-view [move path focus is-first]
   [:span {:className (str "move" (when focus " focus")) :on-click #(update-board path)}
-   (str (move-no (first path)) (cn/san move))])
+   (str (move-no (first path) is-first) (cn/san move))])

 (defn comment-view [comment]
   [:span (str comment " ")])
@@ -56,7 +60,7 @@
        ^{:key (:path (meta node))} [variation-view node current-path (inc depth)]
        (let [move (:move node) path (:path (meta node)) comment (:comment node)]
          ^{:key path} [:span
-                       [move-view move path (= current-path path)]
+                       [move-view move path (= current-path path) (identical? (first nodes) node)]
                        [comment-view comment]
                        ]
          )


hash function seems to be stable now

hash function seems to be stable now

--- src/NoteHub/crossover/lib.clj
+++ src/NoteHub/crossover/lib.clj
@@ -5,13 +5,12 @@
 ; (doesn't work for UTF-16!)
 (defn hash [f s]
   (let [short-mod #(mod % 32767)
-        ; we cannot use Math/pow because it's imprecise
-        ; and differs on JVM and JS
-        pow (fn [n e]
-              (reduce #(short-mod (* % %2)) 1
-                      (repeat e n)))
-        char-codes (map #(f (str %)) s)]
+        char-codes (map f
+                        (filter #(not (contains? #{"\n" "\r"} %)) (map str s)))]
     (reduce
       #(short-mod (+ %
-                     (short-mod (* (first %2) (pow 31 (second %2))))))
+                     (short-mod (* (first %2)
+                                   ((if (odd? %)
+                                      bit-xor
+                                      bit-and) 16381 (second %2))))))
       0 (map list char-codes (range)))))


Change the event handler into something more sensible.

--- src/squelch/nodes/script_processor.cljs
+++ src/squelch/nodes/script_processor.cljs
@@ -15,12 +15,13 @@
 ; Event handlers:
 ; ---------------

-(defn get-on-audio-process
-  "Represents the EventHandler to be called."
-  [buffer-source]
-  (.-onaudioprocess buffer-source))
-
 (defn set-on-audio-process
-  "Represents the EventHandler to be called."
+  "Represents the EventHandler to be called. Instead of receiving the raw audio
+  event the function receives input and output audio buffers. The signature of
+  the handler should be [input-buffer output-buffer]."
   [buffer-source audio-process-fn]
-  (set! (.-onaudioprocess buffer-source) audio-process-fn))
+  (let [process-proxy (fn [audio-event]
+                        (let [input-buffer (.-inputBuffer audio-event)
+                              output-buffer (.-outputBuffer audio-event)]
+                          (audio-process-fn input-buffer output-buffer)))]
+    (set! (.-onaudioprocess buffer-source) process-proxy)))


Add example of do-it macro

Add example of do-it macro

--- src/test/clojure/examples/describe1.clj
+++ src/test/clojure/examples/describe1.clj
@@ -21,3 +21,8 @@
       (= 0.0000007 (+ 0.0000003 0.0000004)))
     (it "computes sums of large numbers"
       (= 7000000.0 (+ 3000000.0 4000000.0)))))
+
+(describe "The do-it macro"
+  (do-it "allows arbitrary code"
+	 (println "Hello, do-it!")
+	 (println "This test will succeed because it doesn't throw.")))


Added markdown formatter

Added markdown formatter

--- src/clj/salava/extra/application/db.clj
+++ src/clj/salava/extra/application/db.clj
@@ -106,8 +106,7 @@

 (defn get-badge-advert [ctx id user_id]
   (let [badge-advert (select-badge-advert {:id id :user_id user_id} (into {:result-set-fn first} (u/get-db ctx)))]
-    ;add markdown parser for :info
-    badge-advert))
+    (update badge-advert :info u/md->html)))

 (defn user-country
   "Return user's country id"