send ping message to server

send ping message to server

--- src-cljs/tranjlator/slash_commands.cljs
+++ src-cljs/tranjlator/slash_commands.cljs
@@ -1,7 +1,7 @@
 (ns tranjlator.slash-commands)

-(def slash-command #"[@/]([^\s]+)")
-(def slash-body #"[@/][^\s]+\s+(.*?)\s*$")
+(def slash-command #"^[@/]([^\s]+)")
+(def slash-body #"^[@/][^\s]+\s+(.*?)\s*$")

 (defn command-word
   [text]
@@ -20,6 +20,12 @@
    :text text
    :body (command-body text)})

+(defmethod command :ping
+  [text]
+  {:topic :ping
+   :text text
+   :user-name (command-body text)})
+
 (defmethod command :default
   [text]
   {:topic :original


Change taw.net to TAW.net

Change taw.net to TAW.net

--- src/matchmaker/core.cljs
+++ src/matchmaker/core.cljs
@@ -122,9 +122,9 @@

 (defn root []
   [:section.root
-   [:h1.title "TAW CS:GO team builder"]
+   [:h1.title "TAW.net CS:GO team builder"]
    [:p.introduction
-    "This tool helps the " [:a {:href "http://taw.net/"} "taw.net"]
+    "This tool helps the " [:a {:href "http://taw.net/"} "TAW.net"]
     " CS:GO division to build (fairly) balanced teams for our regular training games. It's written in "
     [:a {:href "http://clojurescript.org/"} "ClojureScript"] ", you can find the source on "
     [:a {:href "https://github.com/TAW-CSGO/matchmaker"} "GitHub"] ". "


Add test for writing out assigned value.

--- test/isla/test/interpreter.clj
+++ test/isla/test/interpreter.clj
@@ -25,3 +25,7 @@
     ;; run test
     (let [result (interpret (parse "write 2\nage is 1"))]
     (is (nil? (:ret result))))))
+
+(deftest test-write-assigned-value
+  (let [result (interpret (parse "name is 'mary'\nwrite name"))]
+    (is (= (:ret result) "mary"))))


Bugikorjaus

Bugikorjaus

--- mtg-pairings-wer/src/mtg_pairings/core.clj
+++ mtg-pairings-wer/src/mtg_pairings/core.clj
@@ -144,3 +144,4 @@
                     :pairings pairings-handler
                     :results results-handler
                     :seatings seatings-handler)))
+


improve variable name

improve variable name

--- src/clj/backtype/storm/scheduler/IsolationScheduler.clj
+++ src/clj/backtype/storm/scheduler/IsolationScheduler.clj
@@ -192,17 +192,17 @@
             (.blacklistHost cluster host))
           )))

-    (let [non-iso-topologies (->> topology-worker-specs
+    (let [failed-iso-topologies (->> topology-worker-specs
                                   (mapcat (fn [[top-id worker-specs]]
                                     (if-not (empty? worker-specs) [top-id])
                                     )))]
-      (if (empty? non-iso-topologies)
+      (if (empty? failed-iso-topologies)
         ;; run default scheduler on non-isolated topologies
         (-<> topology-worker-specs
              allocated-topologies
              (leftover-topologies topologies <>)
              (DefaultScheduler/default-schedule <> cluster))
-        (log-warn "Unstable to isolate topologies " (pr-str non-iso-topologies) ". Will wait for enough resources for isolated topologies before allocating any other resources.")
+        (log-warn "Unstable to isolate topologies " (pr-str failed-iso-topologies) ". Will wait for enough resources for isolated topologies before allocating any other resources.")
         ))
     (.setBlacklistedHosts cluster orig-blacklist)
     ))


service resources 0.x -> 3.x

service resources 0.x -> 3.x

--- src/cljs/swarmpit/component/service/form_resources.cljs
+++ src/cljs/swarmpit/component/service/form_resources.cljs
@@ -1,10 +1,10 @@
 (ns swarmpit.component.service.form-resources
-  (:require [material.icon :as icon]
-            [material.component :as comp]
+  (:require [material.component :as comp]
             [material.component.form :as form]
             [swarmpit.component.parser :refer [parse-int parse-float]]
             [swarmpit.component.state :as state]
             [sablono.core :refer-macros [html]]
+            [clojure.walk :refer [keywordize-keys]]
             [rum.core :as rum]))

 (enable-console-print!)
@@ -20,69 +20,77 @@
     value))

 (defn- form-cpu-reservation [value]
-  (form/comp
-    (str "CPU  " "(" (cpu-value value) ")")
-    (comp/slider {:min          0
-                  :max          2
-                  :step         0.10
-                  :defaultValue 0
-                  :value        value
-                  :onChange     (fn [_ v]
-                                  (state/update-value [:reservation :cpu] (parse-float v) form-value-cursor))
-                  :sliderStyle  {:marginTop "14px"}})))
+  (html
+    [:div
+     [:div (str "CPU  " "(" (cpu-value value) ")")]
+     [:div
+      (comp/rc-slider
+        {:min          0
+         :max          2
+         :step         0.10
+         :defaultValue 0
+         :value        value
+         :onChange     #(state/update-value [:reservation :cpu] (parse-float %) form-value-cursor)})]]))

 (defn- form-memory-reservation [value]
-  (form/comp
-    "MEMORY (MB)"
-    (comp/vtext-field
-      {:name            "memory-reservation"
-       :key             "memory-reservation"
-       :type            "number"
-       :min             4
-       :validations     "isValidMemoryValue"
-       :validationError "Please use minimum of 4 MB or leave blank for unlimited"
-       :value           value
-       :onChange        (fn [_ v]
-                          (state/update-value [:reservation :memory] (parse-int v) form-value-cursor))})))
+  (comp/text-field
+    {:label           "Memory"
+     :key             "memory-reservation"
+     :type            "number"
+     :variant         "outlined"
+     :helperText      "Use minimum of 4 MB or leave blank for unlimited"
+     :min             4
+     :fullWidth       true
+     :required        true
+     :value           value
+     :InputLabelProps {:shrink true}
+     :onChange        #(state/update-value [:reservation :memory] (parse-int (-> % .-target .-value)) form-value-cursor)}))

 (defn- form-cpu-limit [value]
-  (form/comp
-    (str "CPU  " "(" (cpu-value value) ")")
-    (comp/slider {:min          0
-                  :max          2
-                  :step         0.10
-                  :defaultValue 0
-                  :value        value
-                  :onChange     (fn [_ v]
-                                  (state/update-value [:limit :cpu] (parse-float v) form-value-cursor))
-                  :sliderStyle  {:marginTop "14px"}})))
+  (html
+    [:div
+     [:div (str "CPU  " "(" (cpu-value value) ")")]
+     [:div
+      (comp/rc-slider
+        {:min          0
+         :max          2
+         :step         0.10
+         :defaultValue 0
+         :value        value
+         :onChange     #(state/update-value [:limit :cpu] (parse-float %) form-value-cursor)})]]))

 (defn- form-memory-limit [value]
-  (form/comp
-    "MEMORY (MB)"
-    (comp/vtext-field
-      {:name            "memory-limit"
-       :key             "memory-limit"
-       :type            "number"
-       :min             4
-       :validations     "isValidMemoryValue"
-       :validationError "Please use minimum of 4 MB or leave blank for unlimited"
-       :value           value
-       :onChange        (fn [_ v]
-                          (state/update-value [:limit :memory] (parse-int v) form-value-cursor))})))
+  (comp/text-field
+    {:label           "Memory"
+     :key             "memory-limit"
+     :type            "number"
+     :variant         "outlined"
+     :helperText      "Use minimum of 4 MB or leave blank for unlimited"
+     :min             4
+     :fullWidth       true
+     :required        true
+     :value           value
+     :InputLabelProps {:shrink true}
+     :onChange        #(state/update-value [:limit :memory] (parse-int (-> % .-target .-value)) form-value-cursor)}))

 (rum/defc form < rum/reactive []
   (let [{:keys [reservation limit]} (state/react form-value-cursor)]
-    [:div.form-edit
-     (form/form
-       {:onValid   #(state/update-value [:valid?] true form-state-cursor)
-        :onInvalid #(state/update-value [:valid?] false form-state-cursor)}
-       (html (form/subsection "Reservation"))
-       (html (form/icon-value icon/info [:span "Minimal resource availability to run a task. Empty for unlimited."]))
-       (form-cpu-reservation (:cpu reservation))
-       (form-memory-reservation (:memory reservation))
-       (html (form/subsection "Limit"))
-       (html (form/icon-value icon/info [:span "Maximal resource usage per task. Empty for unlimited."]))
-       (form-cpu-limit (:cpu limit))
-       (form-memory-limit (:memory limit))
-       (html [:div {:style {:height "20px"}}]))]))
+    (comp/grid
+      {:container true
+       :spacing   40}
+      (comp/grid
+        {:item true
+         :xs   12
+         :sm   6}
+        (form/subsection "Reservation")
+        (html [:div "Minimal resource availability to run a task. Empty for unlimited."])
+        (form-cpu-reservation (:cpu reservation))
+        (form-memory-reservation (:memory reservation)))
+      (comp/grid
+        {:item true
+         :xs   12
+         :sm   6}
+        (form/subsection "Limit")
+        (html [:div "Maximal resource usage per task. Empty for unlimited."])
+        (form-cpu-limit (:cpu limit))
+        (form-memory-limit (:memory limit))))))


fix resource reservation section info typo

--- src/cljs/swarmpit/component/service/form_resources.cljs
+++ src/cljs/swarmpit/component/service/form_resources.cljs
@@ -78,7 +78,7 @@
        {:onValid   #(reset! isValid true)
         :onInvalid #(reset! isValid false)}
        (html (form/subsection "Reservation"))
-       (html (form/icon-value icon/info [:span "Minimal resource availablility to run a task. Empty for unlimited."]))
+       (html (form/icon-value icon/info [:span "Minimal resource availability to run a task. Empty for unlimited."]))
        (form-cpu-reservation (:cpu reservation))
        (form-memory-reservation (:memory reservation))
        (html (form/subsection "Limit"))


Parse lyrics of kriti from hstore to clojure map.

--- src/kosha/db/kriti.clj
+++ src/kosha/db/kriti.clj
@@ -1,5 +1,33 @@
 (ns kosha.db.kriti
-  (:require [kosha.db.util :as db-util]))
+  (:require [clojure.set :as set]
+            [clojure.string :as str]
+            [kosha.db.util :as db-util]
+            [pg-hstore.core :as hs]))
+
+(defn to-kebab-case
+  "Takes a keyword with spaces and converts it to a kebab-cased keyword."
+  [key-with-spaces]
+  (let [key-string         (name key-with-spaces)
+        kebab-cased-string (str/replace key-string #" " "-")]
+    (keyword kebab-cased-string)))
+
+(defn rename-stanza-keys
+  "Renames keys of stanzas to replace spaces in them, if the lyrics has named stanzas."
+  [{:keys [content has-named-stanzas] :as lyrics}]
+  (let [lyrics-map   (hs/from-hstore content)
+        stanza-keys  (keys lyrics-map)
+        new-names    (into {} (map (juxt identity to-kebab-case) stanza-keys))]
+    (if has-named-stanzas
+      (assoc lyrics :content (set/rename-keys (hs/from-hstore content) new-names))
+      lyrics)))
+
+(defn parse-lyrics
+  "Parses lyrics of a kriti into a clojure map if it has named stanzas."
+  [lyrics]
+  (-> lyrics
+      (hs/from-hstore)
+      (update :has-named-stanzas (partial = "true"))
+      (rename-stanza-keys)))

 (defn kriti
   "Retrieve details of a kriti given it's kriti_id."
@@ -9,7 +37,8 @@
             JOIN ragams r
             ON k.kriti_id = ? AND r.ragam_id = k.ragam_id; "
            kriti-id]]
-    (first (db-util/run-query q))))
+    (-> (first (db-util/run-query q))
+        (update :lyrics parse-lyrics))))

 (defn renditions-of-kriti
   "Retrieve all renditions of a kriti."


print an error message instead of a stack trace when no project.clj is found

--- src/leiningen/core.clj
+++ src/leiningen/core.clj
@@ -40,8 +40,12 @@

 ;; TODO: prompt to run "new" if no project file is found
 (defn read-project
-  ([file] (load-file file)
-     project)
+  ([file]
+     (try
+      (load-file file)
+      project
+      (catch java.io.FileNotFoundException _
+        (exit-with-error "No project.clj found in this directory."))))
   ([] (read-project "project.clj")))

 (def aliases {"--help" "help" "-h" "help" "-?" "help"


Add 'q macro for easier relational db querying.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -8,6 +8,7 @@
             [clojure.data.fressian :as fress]
             [clojure.core.logic.pldb :as pldb]
             [clojure.core.logic :as l]
+            [clojure.walk :as walk]
             [leiningen.core.project :as project]
             [leiningen.core.main :as lmain]
             [leiningen.voom.long-sha :as sha :only [mk]]
@@ -1141,6 +1142,24 @@
   [_]
   (time (p-repos (fn [p] (updated-git-db p)))))

+(defmacro q
+  [db & args]
+  (let [[count [rfresh & body]] (if (-> args first number?)
+                                  ((juxt first rest) args)
+                                  [nil args])
+        run-mode (if count
+                   '[l/run count]
+                   '[l/run*])
+        body (walk/postwalk #(if (= % '_)
+                               '(l/lvar)
+                               %)
+                            body)]
+    `(pldb/with-db ~db
+       (~@run-mode ~rfresh
+                   ~@body))))
+
+;; ===== relational queries =====
+
 #_
 (def obj-patho
   (l/tabled [tree-sha so-far fname ftype fsha tree-path]
@@ -1185,6 +1204,13 @@
                         (obj-patho p-tree-sha nil fname :blob p-obj-sha tree-path)
                         (obj-patho tree-sha nil fname :blob obj-sha tree-path)
                         (l/!= obj-sha p-obj-sha)))))))
+
+  ;; find merges involving projects
+  (time
+   (into #{}
+    (q db2 [s q]
+       (r-commit s _ 2 _)
+       (r-proj s _ q _ _ _ _ _ _))))

   (time
    (let [c (sha/mk "612e0705de7ff991aa65b910ed0820adabd1d921") ; for large test repo


Decomplect 'adj-path creating 'adj-dir and 'to-file.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -634,17 +634,28 @@
         :when (.contains ^String proj dep)]
     proj))

-(defn adj-path
-  ([f path] (adj-path false f path))
-  ([dir-flag f path]
-     (->
-      ;; TODO Should this be made an isDirectory check?
-      (if (and = dir-flag (.isFile ^File f))
-        (.getParentFile ^File f)
-        ^File f)
-      (.getCanonicalPath)
-      ^String (str "/" path)
-      (File.))))
+(defn ^File to-file
+  [p]
+  (if (= File (type p))
+    p
+    (File. ^String p)))
+
+(defn ^File adj-path
+  [^File f & path]
+  (-> f
+      to-file
+      .getCanonicalPath
+      (str "/" (s/join "/" path))
+      File.))
+
+(defn ^File adj-dir
+  [p & path]
+  ;; TODO Should this be made an isDirectory check?
+  (let [^File f (to-file p)
+        d (if (.isFile f)
+            (.getParentFile f)
+            f)]
+    (apply adj-path d path)))

 (defn ^File find-box
   "Locates voom-box root starting from current working directory."


Minor code cleanup.

Minor code cleanup.

--- src/oc/email/content.clj
+++ src/oc/email/content.clj
@@ -416,8 +416,7 @@
         from-avatar? (not (s/blank? from-avatar))
         show-note? (and note? from-avatar?)
         secure-uuid (:secure-uuid entry)
-        origin-url config/web-url
-        entry-url (s/join "/" [origin-url org-slug "post" secure-uuid])]
+        entry-url (s/join "/" [config/web-url org-slug "post" secure-uuid])]
     [:td {:class "small-12 large-12 columns" :valign "middle" :align "center"}
       (spacer 40)
       (when logo? (org-logo entry))
@@ -575,8 +574,7 @@
         headline? (not (s/blank? headline))
         org-slug (:org-slug entry)
         secure-uuid (:secure-uuid entry)
-        origin-url config/web-url
-        update-url (s/join "/" [origin-url org-slug "post" secure-uuid])]
+        update-url (s/join "/" [config/web-url org-slug "post" secure-uuid])]
     (str (when note? (str note "\n\n"))
          "Check out the latest" (when org-name? (str " from " org-name)) ":"
          "\n\n" (when headline? (str headline "- ")) update-url)))


golang.core/build to golang.core/build-interfaces

Signed-off-by: Gregory Haskins <640d9fe47775e6723f0355b7315e38f7d98d3539@gmail.com>

--- src/chaintool/platforms/golang/core.clj
+++ src/chaintool/platforms/golang/core.clj
@@ -105,7 +105,7 @@
         queries (build-functions (:queries interface))]
     (vector name (->Interface name (package-name name) (package-camel name) (package-path base name) transactions queries))))

-(defn- build [base interfaces]
+(defn- build-interfaces [base interfaces]
   (into {} (map (fn [[name interface]] (build-interface base name interface)) interfaces)))

 (defn- build-cci [ipath name]
@@ -150,7 +150,7 @@
 ;;-----------------------------------------------------------------
 (defn- render-primary-stub [base package config interfaces]
   (let [functions (algo/fmap intf/getallfunctions interfaces)
-        provides (build base (select-keys functions (intf/getprovides config)))]
+        provides (build-interfaces base (select-keys functions (intf/getprovides config)))]

     (render-golang "primary" [["base" base]
                               ["system" package]


rename old MessageRouter

rename old MessageRouter

--- src/clj/ow/starbuck/message_routerx.clj
+++ src/clj/ow/starbuck/message_routerx.clj
@@ -135,10 +135,10 @@
              (query @(ns-resolve rns 'get-routed-messages))
              ))))

-(defcomponentrecord MessageRouter)
+(defcomponentrecord MessageRouterX)

 (defn new-comp [ch-in ch-out rulens]
-  (map->MessageRouter {:processfn process
+  (map->MessageRouterX {:processfn process
                        :ch-in ch-in
                        :ch-out ch-out
                        :rulens rulens}))


add text back

add text back

--- src/cljs/just_married/home/find_us.cljs
+++ src/cljs/just_married/home/find_us.cljs
@@ -2,8 +2,10 @@
   (:require [just-married.home.language :refer [translate]]))

 (def ^:private find-us-dict
-  {:en {:find-us "Find Us"}
-   :it {:find-us "Come Trovarci"}})
+  {:en {:find-us "Find Us"
+        :find-us-text "The wedding will be celebrated in the beautiful Abruzzo region, between the cities Chieti and Pescara."}
+   :it {:find-us "Come Trovarci"
+        :find-us-text "Il matrimonio verrà celebrato nella bellissima regione Abruzzo, tra Chieti e Pescara."}})

 (def ^:private tr
   (partial translate find-us-dict))
@@ -12,4 +14,5 @@
   []
   [:div.find-us {:id "find-us"}
    [:h3 (tr :find-us)]
+   [:div.find-us-text (tr :find-us-text)]
    [:div.google-map {:id "map"}]])


Improve log message for `store report` command

This just changes the log message for the `store report` command
to log the puppet version and the certname, rather than logging
the (useless) report id.

--- src/com/puppetlabs/puppetdb/command.clj
+++ src/com/puppetlabs/puppetdb/command.clj
@@ -356,12 +356,8 @@
     (with-transacted-connection db
       (scf-storage/maybe-activate-node! name timestamp)
       (scf-storage/add-report! report timestamp))
-    ;; TODO: replace this ":report-id" bit in the log message with something better;
-    ;;  the real report ids are likely to be completely useless for this purpose,
-    ;;  but we can't necessarily use something like a certname because there is
-    ;;  no guarantee that all of the events in a group will be from the same
-    ;;  node?  need like a 'group desc' or something.
-    (log/info (format "[%s] [store report] %s" id (:id report)))))
+    (log/info (format "[%s] [store report] puppet v%s - %s"
+                id (:puppet-version report) (:certname report)))))

 ;; ## MQ I/O
 ;;


clean up connect fn

clean up connect fn

--- src/overtone/sc/core.clj
+++ src/overtone/sc/core.clj
@@ -166,11 +166,10 @@

 ; TODO: setup an error-handler in the case that we can't connect to the server
 (defn connect
-  "Connect to an external SC audio server on the specified host and port."
-  [& [host port]]
-   (if (and host port)
-     (.run (Thread. #(connect-external host port)))
-     (connect-internal)))
+  "Connect to an running SC audio server. Either an external server if host and port are passed or an internal server
+   in the case of no args."
+  ([] (connect-internal))
+  ([host port] (.run (Thread. #(connect-external host port)))))

 (defn server-log
   "Print the server log."


midi renamed again

midi renamed again

--- src/lights/my_show.clj
+++ src/lights/my_show.clj
@@ -179,7 +179,7 @@
 (show/add-effect! :dimmers (global-dimmer-effect 255))

 ; 2DO rewrite to connect multiple devices
-(defn midi
+(defn midi-help
   "Bind MIDI devices"
   [interface]

@@ -256,13 +256,13 @@
       (afterglow.midi/sync-to-midi-clock "USB Uno MIDI Interface"))
     )

-  (if (= interface "identify")
-    (afterglow.midi/midi-mapping))
-
-)
-
-
-;(midi "automap")
+  (if (or (= interface "identify") (= interface "id"))
+    (afterglow.midi/identify-mapping))
+
+)
+
+
+;(midi-help "automap")

 (defn set-hue
   "Set main hue"
@@ -371,8 +371,8 @@
 (defn london-init
   "Init of London show"
   []
-  (midi "automap")
-  (midi "audio6")
+  (midi-help "automap")
+  (midi-help "audio6")
   (shutter-open)
   )


Added testing for flush

Added testing for flush

--- test/tree/core_test.clj
+++ test/tree/core_test.clj
@@ -164,3 +164,19 @@

 (comment
   (time (tc/quick-check 1 (mixed-op-seq 0.5 100 1000))))
+
+(deftest testing-flush-works
+  (:tree (flush-tree (apply b-tree (range 30))))
+  )
+
+(defspec test-flush
+  1000
+  (prop/for-all [v (gen/vector gen/int)]
+                (let [sorted-set-order (into (sorted-set) v)
+                      b-tree (reduce insert (b-tree) v)
+                      b-tree-order (lookup-fwd-iter b-tree Integer/MIN_VALUE)
+                      flushed-tree (:tree (flush-tree b-tree))
+                      flushed-tree-order (lookup-fwd-iter flushed-tree Integer/MIN_VALUE)]
+                  (= (seq sorted-set-order)
+                     b-tree-order
+                     flushed-tree-order))))


[#2212] Use protocol function instead of component ns function

--- backend/src/akvo/lumen/auth.clj
+++ backend/src/akvo/lumen/auth.clj
@@ -2,6 +2,7 @@
   (:require [akvo.commons.jwt :as jwt]
             [akvo.lumen.component.auth0 :as auth0]
             [akvo.lumen.component.keycloak :as keycloak]
+            [akvo.lumen.protocols :as p]
             [cheshire.core :as json]
             [clj-http.client :as client]
             [clojure.set :as set]
@@ -130,7 +131,7 @@
       (if (api-authz? jwt-claims)
         (try
           (let [email (get jwt-claims "email")
-                allowed-paths (delay (keycloak/allowed-paths keycloak email))]
+                allowed-paths (delay (p/allowed-paths keycloak email))]
             (cond
               (nil? jwt-claims) not-authenticated
               (admin-path? request) (if (api-tenant-admin? tenant @allowed-paths)


Update repl code references.

Update repl code references.

--- dev/user.clj
+++ dev/user.clj
@@ -6,8 +6,8 @@
       [core :as block]
       [data :as data])
     (blocks.store
-      [memory :refer [memory-store]]
-      [file :refer [file-store]]
+      [memory :refer [memory-block-store]]
+      [file :refer [file-block-store]]
       [tests :as tests])
     [clojure.java.io :as io]
     [clojure.repl :refer :all]
@@ -32,4 +32,4 @@

 (def tbs
   "Temporary block store in target."
-  (file-store "target/blocks"))
+  (file-block-store "target/blocks"))


remove dead code

remove dead code

--- dev/user.clj
+++ dev/user.clj
@@ -6,11 +6,7 @@
 (import '(com.google.appengine.tools.development.testing
           LocalServiceTestHelper
           LocalServiceTestConfig
-          LocalMemcacheServiceTestConfig
-          LocalMemcacheServiceTestConfig$SizeUnit
-          LocalMailServiceTestConfig
-          LocalDatastoreServiceTestConfig
-          LocalUserServiceTestConfig))
+          LocalDatastoreServiceTestConfig))

 (require '(migae [datastore :as ds]))


Add «order-by»

Add «order-by»

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

--- src/conexp/fca/many_valued_contexts.clj
+++ src/conexp/fca/many_valued_contexts.clj
@@ -192,6 +192,16 @@
   ([values others]
      (make-context values others =)))

+(defn order-by
+  "Returns a function on two arguments a and b that returns true if and only if a occurs
+  not after b in the given sequence."
+  [sequence]
+  (let [pos (zipmap sequence (range))]
+    (fn [a b]
+      (and (contains? pos a)
+           (contains? pos b)
+           (<= (pos a) (pos b))))))
+
 (defn ordinal-scale
   "Returns the ordinal scale on the set values, optionally given an
   order relation <=."


Reflect changes in the index page to the site layout

--- src/pict_source/site.clj
+++ src/pict_source/site.clj
@@ -18,10 +18,11 @@
         [:h1 title]]
        [:div {:class "six columns"}
         [:nav
-         [:a {:href "#"} "ru"]
-         [:a {:href "#"} "en"]]]]
+         [:a {:href "/lang/"} "ru"]
+         [:a {:href "/lang/"} "en"]]]]
       content
       [:footer {:class "row"}
        [:p
         "© 2015 "
-        [:a {:href "http://shvetsovdm.github.io"} "Дмитрий Швецов (shvetsovdm)"]]]]]))
+        [:a {:href "http://shvetsovdm.github.io"}
+         "Дмитрий Швецов/Dmitry Shvetsov (shvetsovdm)"]]]]]))


Fixing loop to actually recur, and shortening function.

--- src/noamb/foe/auth.clj
+++ src/noamb/foe/auth.clj
@@ -3,7 +3,11 @@
     :doc "Functions for updating the session with the authentication state."}
   (:require [noamb.foe.user :refer [authenticate-from-storage]]))

-(def ^{:dynamic true} *authentication-methods* [authenticate-from-storage])
+(defn authenticate-from-cookie
+  [db identifiers]
+  nil)
+
+(def ^{:dynamic true} *authentication-methods* [authenticate-from-cookie authenticate-from-storage])

 (defn logged-in?
   "Takes a session map and inspects it for the required keys to be logged in.
@@ -16,8 +20,8 @@
   [db identifiers]
   (loop [methods *authentication-methods*]
     (when (seq methods)
-      (let [user ((first methods) db identifiers)]
-        user))))
+      (or ((first methods) db identifiers)
+          (recur (rest methods))))))

 (defn login
   "Sets user-id in session (effectively logs in the user)."


send darwin email notifications through pol.is node server

--- src/polismath/server.clj
+++ src/polismath/server.clj
@@ -21,7 +21,8 @@
             [clojure.tools.logging :as log]
             [clj-time.core :as time]
             [bidi.bidi :as bidi]
-            [bidi.ring]))
+            [bidi.ring]
+            [clj-http.client :as client]))

 ;; First we'll just set up some basic helpers and settings/variables we'll need.
@@ -105,8 +106,8 @@
       ;; Don't really need this if we have params instead of query params, but whateves
       (let [k (keyword k)]
         (if (allowed-params k)
-                      (assoc m k ((or (parsers k) identity) v))
-                      m)))
+            (assoc m k ((or (parsers k) identity) v))
+            m)))
     {}
     params))

@@ -216,7 +217,24 @@
      [:p "Thanks for using " polis-link "!"]
      [:p "Christopher Small" [:br] "Chief Data Scientist"]]))

-(defn send-email-notification!
+
+;(defn send-email!
+;  ([{:keys [from to subject text html] :as params}]
+;   (log/info "Sending email to:" to)
+;   (log/debug "  have mailgun key?" (boolean *mailgun-key*))
+;   (try
+;     (client/post *mailgun-url*
+;                  {:basic-auth ["api" *mailgun-key*]
+;                   :headers {"host" "pol.is"}
+;                   :query-params params})
+;     (catch Exception e (.printStackTrace e))))
+;  ([from to subject text html] (send-email! {:from from :to to :subject subject :text text :html html}))
+;  ([from to subject text] (send-email! {:from from :to to :subject subject :text text})))
+
+
+(defn send-email-notification-via-mailgun!
+  "This is the old implementation of the send method, which directly sends an email using the mailgun AP.
+  It will likely be removed soon but is being left here for posterity, for the moment."
   [filename params]
   (let [zinvite (:zinvite params)
         download-url (public-datadump-url filename zinvite)
@@ -228,12 +246,29 @@
       (hiccup-to-plain-text email-hiccup)
       (hiccup/html email-hiccup))))

+; curl -X POST -s "https://pol.is/api/v3/sendEmailExportReady"
+;   -d "conversation_id=9isb32"
+;   -d "filename=polis-export-9isb32-1472680904264.zip"
+;   -d "webserver_username=$WEBSERVER_USERNAME"
+;   -d "webserver_pass=$WEBSERVER_PASS"
+;   -d "uid=125"
+
+(defn send-email-notification-via-polis-api!
+  [filename {:keys [zinvite email]}]
+  (client/post "https://pol.is/api/v3/sendEmailExportReady"
+               {:query-params {:webserver_username (:webserver-username env/env)
+                               :webserver_pass (:webserver-pass env/env)
+                               :email email
+                               :filename filename
+                               :conversation_id zinvite}}))
+
 (defn handle-completion!
   [aws-cred filename params]
   (log/info "Completed export computation for filename" filename "params:" (with-out-str (str params)))
   (upload-to-aws aws-cred filename)
   (notify-mongo filename "complete" params)
-  (when (:email params) (send-email-notification! filename params)))
+  (when (:email params) (send-email-notification-via-polis-api! filename params)))
+  ;(when (:email params) (send-email-notification-via-mailgun! filename params)))

 (defn handle-timedout-datadump!
   [aws-cred filename compute-chan params]
@@ -457,10 +492,10 @@
    (-> handler
        ring.keyword-params/wrap-keyword-params
        ring.params/wrap-params
-       (auth/wrap-basic-authentication authenticated?)
+       (auth/wrap-basic-authentication authenticated?))})
        ;redirect-http-to-https-if-required
        ;restrict-remote-access
-       )})
+

 (defn get-port
   [default]
@@ -478,8 +513,8 @@
   {:app app
    :port (get-port 3000)
    ;; Not sure exactly what this is doing; maybe leave out XXX
-   :client-auth :need
-   })
+   :client-auth :need})
+

 (defonce http-server
@@ -528,8 +563,8 @@

   (-> (client/post "http://localhost:3000/ping" {:form-params {:q "foo, bar"}})
       (dissoc :body)
-      clojure.pprint/pprint)
-  )
+      clojure.pprint/pprint))
+

 ;; TODO / Thoughts


create logs metadata dir when running securely

--- storm-core/src/clj/backtype/storm/daemon/supervisor.clj
+++ storm-core/src/clj/backtype/storm/daemon/supervisor.clj
@@ -596,9 +596,11 @@
   (let [file (get-log-metadata-file storm-id port)]
     ;;run worker as user needs the directory to have special permissions
     ;; or it is insecure
-    (when (and (not (conf SUPERVISOR-RUN-WORKER-AS-USER))
-               (not (.exists (.getParentFile file))))
-      (.mkdirs (.getParentFile file)))
+    (when (not (.exists (.getParentFile file)))
+      (if (conf SUPERVISOR-RUN-WORKER-AS-USER)
+        (do (FileUtils/forceMkdir (.getParentFile file))
+            (setup-storm-code-dir conf (read-supervisor-storm-conf conf storm-id) (.getCanonicalPath (.getParentFile file))))
+        (.mkdirs (.getParentFile file))))
     (let [writer (java.io.FileWriter. file)
         yaml (Yaml.)]
       (try


re throwing

re throwing

--- src/proxmox/provider.clj
+++ src/proxmox/provider.clj
@@ -147,7 +147,7 @@
               (->Container node ct* extended network*)
               (catch [:status 500] e
                 (warn "Container already exists" e) (throw e))
-              (catch Throwable e (release-ip ip :proxmox)))))
+              (catch Throwable e (release-ip ip :proxmox) (throw e)))))

   (delete [this]
      (try


Fix registered-parser-factories to work with RDF4j api change.

Make it work with the Java optionals we now receive

--- src/grafter/rdf/repository/registry.clj
+++ src/grafter/rdf/repository/registry.clj
@@ -38,7 +38,10 @@
   These factories define the parsers used for content negotiation
   inside sesame."
   []
-  (let [setify-factories (fn [r] (set (map #(class (.get r %)) (.getKeys r))))]
+  (let [setify-factories (fn [r] (->> r
+                                     .getKeys
+                                     (map #(class (.orElse (.get r %) nil)))
+                                     set))]
     (apply merge
            (for [[q-type reg] (parser-registries)]
              {q-type (setify-factories reg)}))))


In macros-test, line up the `x`s.

In macros-test, line up the `x`s.

--- test/com/nomistech/clojure_the_language/macros_test.clj
+++ test/com/nomistech/clojure_the_language/macros_test.clj
@@ -2,10 +2,10 @@
   (:require [midje.sweet :refer :all]))

 (defmacro do-things-with-symbols [x]
-  `(list x
-         'x
+  `(list   x
+          'x
          ~'x
-         ~x
+          ~x
          '~x))

 (fact


Rudimentary iteration over lines in FASTA file in Clojure version

--- clojure/biotool/src/biotool/core.clj
+++ clojure/biotool/src/biotool/core.clj
@@ -5,6 +5,6 @@
 (defn -main
   "Prints the first sequence from a fasta file"
   [file]
-  (with-open [r (bs/bs-reader (bs/init-fasta-file file :iupacAminoAcids))]
-    (println
-     (bs/bioseq->string (first (bs/biosequence-seq r))))))
+  (with-open [reader (bs/bs-reader (bs/init-fasta-file file :iupacAminoAcids))]
+    (doseq [row (bs/biosequence-seq reader)]
+      (println (count (:sequence row))))))


Using 'subedit->' in Upgrade.

Using 'subedit->' in Upgrade.

--- src/leiningen/ancient/tasks/upgrade.clj
+++ src/leiningen/ancient/tasks/upgrade.clj
@@ -46,7 +46,7 @@
               (when (prompt! group-id artifact-id latest version)
                 (println "Upgrade to" (artifact-string group-id artifact-id latest)
                          "from" (yellow (version-string version)))
-                (z/edit-> zloc z/down z/right (z/replace (first latest)))))))))
+                (z/subedit-> zloc z/down z/right (z/replace (first latest)))))))))
     zloc))

 (defn- upgrade-dependencies!


include boot-cljs release with important fixes

--- resources/leiningen/new/tenzing/build.boot
+++ resources/leiningen/new/tenzing/build.boot
@@ -1,7 +1,7 @@
 (set-env!
  :source-paths    {{{source-paths}}}
  :resource-paths  #{"resources"}
- :dependencies '[[adzerk/boot-cljs      "0.0-2814-0" :scope "test"]
+ :dependencies '[[adzerk/boot-cljs      "0.0-2814-4" :scope "test"]
                  [adzerk/boot-cljs-repl "0.1.9"      :scope "test"]
                  [adzerk/boot-reload    "0.2.4"      :scope "test"]
                  [pandeiro/boot-http    "0.6.1"      :scope "test"]{{{deps}}}])


use log instead of println for this test


Update profiles.clj

Update profiles.clj

--- extra/profiles.clj
+++ extra/profiles.clj
@@ -1,5 +1,5 @@
 {:user
- {:plugins [[cider/cider-nrepl "0.16.0-snapshot"]
+ {:plugins [[cider/cider-nrepl "0.17.0-snapshot"]
             [lein-pprint "1.1.1"]
             [refactor-nrepl "2.4.0-SNAPSHOT"]
             [venantius/ultra "0.4.1"]]


CMR-6221 removed unnecessary sorting param, values with identical scores still sorted alphabetically in case of tie

--- search-app/src/cmr/search/models/query.clj
+++ search-app/src/cmr/search/models/query.clj
@@ -179,8 +179,6 @@
 (defmethod common-qm/default-sort-keys :autocomplete
   [_]
   [{:field :_score :order :desc}
-   ;; TODO: remove sorting by type field after relevancy works, will be unneeccsary
-   {:field :type :order :asc}
    {:field :value :order :asc}])

 (defmethod common-qm/concept-type->default-query-attribs :granule


enable multiline for-all bodies

enable multiline for-all bodies


use $AVCONV if set (for nixos and other weirdos)

--- src/sledge/transcode.clj
+++ src/sledge/transcode.clj
@@ -6,14 +6,15 @@

 (defn avconv [filename format]
   (let [rt (Runtime/getRuntime)
+        bin (or (System/getenv "AVCONV") "/usr/bin/avconv")
         codec (get {"ogg" "libvorbis"
                     "mp3" "libmp3lame"}
                    format)
         p (.exec rt
                  (into-array
-                  ["/usr/bin/avconv",
-                   "-i",
-                   filename,
+                  [bin
+                   "-i"
+                   filename
                    "-f"
                    format
                    "-c"


USER and NICK should be allowed from non-authenticated clients, other commands should not

--- src/subrosa/commands.clj
+++ src/subrosa/commands.clj
@@ -10,15 +10,25 @@
     (dispatch-command cmd socket (or args ""))))

 (defn fix-args
-  [fn-tail]
+  [require-auth? fn-tail]
   (let [[f & r] fn-tail]
-    (if (vector? f)
-      (list* (vec (cons '_ f)) r)
-      (map fix-args fn-tail))))
+    `(~(vec (cons '_ f))
+      ~(if require-auth?
+         `(when (authenticated? ~(first f))
+            ~@r)
+         `(do ~@r)))))

-(defmacro defcommand [cmd & fn-tail]
+(defmacro defcommand*
+  "Define a command which can be called by unauthenticated users."
+  [cmd & fn-tail]
   `(.addMethod dispatch-command ~cmd
-               (fn ~@(fix-args fn-tail))))
+               (fn ~@(fix-args false fn-tail))))
+
+(defmacro defcommand
+  "Define a command which requires its user to be authenticated."
+  [cmd & fn-tail]
+  `(.addMethod dispatch-command ~cmd
+               (fn ~@(fix-args true fn-tail))))

 (defmethod dispatch-command :default [cmd channel args]
   (when (authenticated? channel)
@@ -29,7 +39,7 @@
 (defn valid-nick? [nick]
   (not (re-find #"[^a-zA-Z0-9\-\[\]\'`^{}_]" nick)))

-(defcommand "NICK" [channel nick]
+(defcommand* "NICK" [channel nick]
   (if (not (.isEmpty nick))
     (if (valid-nick? nick)
       (if (not (user-for-nick nick))
@@ -53,7 +63,7 @@
             :code 431
             :msg ":No nickname given"})))

-(defcommand "USER" [channel parts]
+(defcommand* "USER" [channel parts]
   (dosync
    (update-user-for-nick! (nick-for-channel channel) parts)
    (maybe-add-authentication-step! channel "USER")


Add `lua-script` helper

Add `lua-script` helper

This is a further abstraction over `eval*` to allow conveniently named arguments in scripts.

--- src/taoensso/carmine.clj
+++ src/taoensso/carmine.clj
@@ -94,6 +94,56 @@
             (do (apply eval script numkeys key args)
                 (protocol/get-one-reply!))
             (throw e))))))
+
+(def ^:private interpolate-script
+  "Substitutes indexed KEYS[]s and ARGV[]s for named variables in Lua script.
+
+  (interpolate-script \"return redis.call('set', _:my-key, _:my-val)\"
+                      {:my-key \"foo\"} {:my-val \"bar\"})
+  => {:script \"return redis.call('set', KEYS[1], ARGV[1])\"
+      :eval-args [\"1\" \"foo\" \"bar\"]}"
+  (memoize
+   (fn [script key-vars-map arg-vars-map]
+     (let [key-vars-map (into (sorted-map) key-vars-map)
+           arg-vars-map (into (sorted-map) arg-vars-map)
+
+           ;; {match replacement} e.g. {"_:my-var" "ARRAY-NAME[1]"}
+           subst-map (fn [vars array-name]
+                       (zipmap (map #(str "_" %) vars)
+                               (map #(str array-name "[" % "]")
+                                    (map inc (range)))))]
+
+       {:script
+        (reduce (fn [s [match replacement]] (str/replace s match replacement))
+                (str script)
+                (merge (subst-map (clojure.core/keys key-vars-map) "KEYS")
+                       (subst-map (clojure.core/keys arg-vars-map) "ARGV")))
+
+        :eval-args (-> [(str (count key-vars-map))]
+                       (into (vals key-vars-map))
+                       (into (vals arg-vars-map)))}))))
+
+(comment
+  (interpolate-script "return redis.call('set', _:my-key, _:my-val)"
+                      {:my-key "foo"} {:my-val "bar"})
+
+  (interpolate-script "Hello _:k1 _:k1 _:k2 _:k3 _:a1 _:a2 _:a3"
+                      {:k3 "k3" :k1 "k1" :k2 "k2"}
+                      {:a3 "a3" :a1 "a1" :a2 "a2"}))
+
+(defn lua-script
+  "All singing, all dancing Lua script helper. Like `eval*` but allows script
+  to use \"_:my-var\"-style named keys and args."
+  [script key-vars-map arg-vars-map]
+  (let [{:keys [script eval-args]}
+        (interpolate-script script key-vars-map arg-vars-map)]
+    (apply eval* script eval-args)))
+
+(comment
+  (wc (lua-script "redis.call('set', _:my-key, _:my-val)
+                   return redis.call('get', 'foo')"
+                  {:my-key "foo"}
+                  {:my-val "bar"})))

 (defn hgetall*
   "Like `hgetall` but automatically coerces reply into a hash-map."
@@ -248,11 +298,12 @@
 ;;;; Dev/tests

 (comment
-  (do (def pool (make-conn-pool))
-      (def spec (make-conn-spec)))
+  (do (def conn (conns/get-conn pool spec))
+      (def pool (make-conn-pool))
+      (def spec (make-conn-spec))
+      (defmacro wc [& body] `(with-conn pool spec ~@body)))

   ;;; Basic connections
-  (def conn (conns/get-conn pool spec))
   (conns/conn-alive? conn)
   (conns/release-conn pool conn) ; Return connection to pool (don't close)
   (conns/close-conn conn)        ; Actually close connection


Commenting out query functions from Collection protocol for now.

--- src/org/libraryweasel/ligature/core.clj
+++ src/org/libraryweasel/ligature/core.clj
@@ -29,11 +29,11 @@
   (compute [this f]
     "Accepts a closure that is passed a ReadTx, executes in a read-only transaction, and returns a value.")
   (write [this f]
-    "Accepts a closure that is passed a WriteTx, executes in a read/write transaction, and returns a value.")
-  (sparql-query [this query]
-    "")
-  (wander-query [this query]
-    ""))
+    "Accepts a closure that is passed a WriteTx, executes in a read/write transaction, and returns a value."))
+;  (sparql-query [this query]
+;    "")
+;  (wander-query [this query]
+;    ""))

 (defprotocol ReadTx
   (all-statements [this]


add weasel repl

add weasel repl

--- frontend/core.cljs
+++ frontend/core.cljs
@@ -2,6 +2,7 @@
   (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
             [frontend.async :refer [put!]]
             [cljs-time.core :as time]
+            [weasel.repl :as ws-repl]
             [clojure.browser.repl :as repl]
             [clojure.string :as string]
             [dommy.core :as dommy]
@@ -201,7 +202,10 @@
                            :messages [:refresh]}]))

 (defn setup-browser-repl [repl-url]
-  (repl/connect repl-url)
+  (when repl-url
+    (repl/connect repl-url))
+  ;; this is harmless if it fails
+  (ws-repl/connect "ws://localhost:9001" :verbose true)
   ;; the repl tries to take over *out*, workaround for
   ;; https://github.com/cemerick/austin/issues/49
   (js/setInterval #(enable-console-print!) 1000))
@@ -244,8 +248,7 @@
     (when-let [user (:current-user @state)]
       (subscribe-to-user-channel user (get-in @state [:comms :ws])))
     (when (env/development?)
-      (when-let [repl-url (get-in @state [:render-context :browser_connected_repl_url])]
-        (try
-          (setup-browser-repl repl-url)
-          (catch js/error e
-            (merror e)))))))
+      (try
+        (setup-browser-repl (get-in @state [:render-context :browser_connected_repl_url]))
+        (catch js/error e
+          (merror e))))))


(PDB-4931) maint-mode-service: guard against incomplete init/start

Since stop can be called before either init or start are
called (i.e. if a dependency's start or init throws), check the state
before acting.

--- src/puppetlabs/puppetdb/pdb_routing.clj
+++ src/puppetlabs/puppetdb/pdb_routing.clj
@@ -87,11 +87,8 @@

   (enable-maint-mode
    [this]
-   (if-let [context (tksvc/service-context this)]
-     (update context ::maint-mode? reset! true)
-     (if (get-shutdown-reason)
-       true
-       (throw (IllegalStateException. (trs "Service has not started"))))))
+   (when-let [mode (::maint-mode? (tksvc/service-context this))]
+     (reset! mode true)))

   (disable-maint-mode
    [this]
@@ -180,4 +177,7 @@
     "PuppetDB routing service start" (get-shutdown-reason) context
     #(start-pdb-routing context (get-config) disable-maint-mode)))

-  (stop [this context] (enable-maint-mode)))
+  (stop
+   [this context]
+   (enable-maint-mode)
+   context))


Optimize floating graph.

Optimize floating graph.

--- src/cljs/main/quil_site/examples/floating_graph.cljs
+++ src/cljs/main/quil_site/examples/floating_graph.cljs
@@ -31,55 +31,53 @@
    :dfs '()})

 ;;;
+;;; util
+;;;
+
+(defn rand-bi-dir
+  "get a random value between -n and n"
+  [n]
+  (q/random (- n) n))
+
+(defn map-value
+  "iterates through map and applies fn to values returning new map"
+  [fn m]
+  (into {} (for [[key value] m] [key (fn value)])))
+
+;;;
 ;;; graph elements and operations
 ;;;

-(defn node
-  "Construct a node record"
-  [label ; used for referencing the node in the graph's map
-   pos ; {:x __ :y __}
-   color-key ; color key used by the x-first-search and as the key for physically coloring the node
-   size ; float
-   vel ; velocity {:x __ :y __ :s __} where s is size-change velocity
-   siblings] ; set of labels of directly connected nodes
-
-  {:label label :pos pos :color-key color-key :size size :vel vel :siblings siblings})
+(defn create-random-node
+  "Construct a random node record
+   label used for referencing the node in the graph's map"
+  [label]
+  {:label label
+   :pos {:x (rand-int (q/width))
+         :y (rand-int (q/height))}
+   ; color key used by the x-first-search and as the key for physically coloring the node
+   :color-key :untouched
+   :size (+ size-min (rand-int (- size-max size-min)))
+   :vel {:x (rand-bi-dir directional-speed-max)
+         :y (rand-bi-dir directional-speed-max)
+         :s (rand-bi-dir size-acceleration)}
+   :siblings '()})

 (defn add-edge
   "add an edge (set with two elements - the label of each node) to a node-map (map node-label->node)."
   [nodes edge]
-  (let [edge (into '() edge) ; cannot index/peek set, so use list
-        n1-key (peek edge)
-        n2-key (peek (pop edge))
-        ;; each node has the other node as a sibling
-        nodes (update-in nodes [n1-key :siblings] (fn [s] (conj s n2-key)))
-        nodes (update-in nodes [n2-key :siblings] (fn [s] (conj s n1-key)))]
-    nodes))
+  (let [[n1-label n2-label] edge]
+    (-> nodes
+        (update-in [n1-label :siblings] conj n2-label)
+        (update-in [n2-label :siblings] conj n1-label))))

 (defn extract-edges
   "get a set of edges given a node-map"
   [nodes]
-  ;; reduce edge sets from each node into a single set
-  (reduce
-    (fn [edges n]
-      (sets/union edges
-                  ;; create set of edges from a given node
-                  (reduce
-                    (fn [edges k]
-                      (conj edges #{(:label n) k}))
-                    #{}
-                    (:siblings n))))
-    #{}
-    nodes))
-
-;;;
-;;; util
-;;;
-
-(defn rand-bi-dir
-  "get a random value between -n and n"
-  [n]
-  (- (rand (* 2 n)) n))
+  (set (for [node nodes
+             sibling-label (:siblings node)]
+         #{(:label node) sibling-label})))
+

 ;;;
 ;;; quil state manipulation and drawing
@@ -94,7 +92,7 @@
 (defn adjust-directional-vel-to-bounds
   "adjust velocity if it is too fast or goes outside of view area"
   [vel pos max-speed min-pos max-pos bounce-vel size]
-  (cond
+  (cond
     (> (+ pos vel (/ size 2)) max-pos)
     (- 0 bounce-vel)

@@ -119,110 +117,80 @@
                     :search-type search-type
                     :collection (into (search-type collections-init-by-search-type) [starting-node-key])}})) ; use the appropriate collection type for the search type

-(defn setup
+(defn setup
   "quil setup step"
-  []
-  ;; don't change :dfs/:bfs color names as they are equivalent to search-states's search-type keywords
-  (def colors {:dfs(q/color 220 255 255)
-               :bfs(q/color 225 150 225)
-               :visiting (q/color 0)
-               :edge (q/color 240 150)
-               :untouched (q/color 240 150)})
-
+  []
   (q/frame-rate frame-rate)

   (q/color-mode :rgb)

-  ;; create initial nodes and edges ~randomly
-  (let [nodes (loop [nodes {} amt-to-add node-count]
-                (let [label (keyword (str "n" amt-to-add))
-                      node (node label
-                                 {:x (rand-int (q/width))
-                                  :y (rand-int (q/height))}
-                                 :untouched
-                                 (+ size-min (rand-int (- size-max size-min)))
-                                 {:x (rand-bi-dir directional-speed-max)
-                                  :y (rand-bi-dir directional-speed-max)
-                                  :s (rand-bi-dir size-acceleration)}
-                                 '())
-                      nodes (assoc nodes label node)]
-                  (if (> amt-to-add 0)
-                    (recur nodes (dec amt-to-add))
-                    nodes)))
-        nodes (loop [nodes nodes amt-to-add edge-count]
-                (let [ks (keys nodes)
-                      k1 (rand-nth ks)
-                      ks (into [] (disj (into #{} ks) k1))
-                      k2 (rand-nth ks)
-                      nodes (add-edge nodes #{k1 k2})] ; edge might already exist, but whatever
-                  (if (> amt-to-add 0)
-                    (recur nodes (dec amt-to-add))
-                    nodes)))]
-    (infer-new-search-state :dfs nodes)))
+  ;; create initial nodes and edges ~randomly
+  (let [labels (map #(keyword (str "n" %))
+                    (range node-count))
+        nodes (into {} (for [label labels]
+                         [label (create-random-node label)]))
+        create-random-edge #(take 2 (shuffle labels))
+        edges (repeatedly edge-count create-random-edge)
+        nodes (reduce add-edge nodes edges)
+        state (infer-new-search-state :dfs nodes)]
+    (assoc state
+           ;; don't change :dfs/:bfs color names as they are equivalent
+           ;; to search-states's search-type keywords
+           :colors {:dfs (q/color 220 255 255)
+                    :bfs (q/color 225 150 225)
+                    :visiting (q/color 0)
+                    :edge (q/color 240 150)
+                    :untouched (q/color 240 150)})))

 (defn update-movement
   "apply changes to velocity, position, and size"
   [state]
-  (assoc state
-         :nodes (loop [moved-nodes {} nodes (:nodes state)]
-                  (let [k (first (keys nodes))
-                        n (k nodes)
-                        nodes (dissoc nodes k)
-                        n (assoc n
-                                 :vel {:x (adjust-directional-vel-to-bounds
-                                            (+ (:x (:vel n)) (rand-bi-dir directional-axis-acceleration))
-                                            (:x (:pos n))
-                                            directional-speed-max
-                                            0
-                                            (q/width)
-                                            directional-bounce-velocity
-                                            (:size n))
-
-                                       :y (adjust-directional-vel-to-bounds
-                                            (+ (:y (:vel n)) (rand-bi-dir directional-axis-acceleration))
-                                            (:y (:pos n))
-                                            directional-speed-max
-                                            0
-                                            (q/height)
-                                            directional-bounce-velocity
-                                            (:size n))
-
-                                       :s (let
-                                            [new-vel (+ (:s (:vel n)) (rand-bi-dir size-acceleration))]
-                                            (if (> (+ (:size n) new-vel) size-max)
-                                              (- 0 size-bounce-velocity)
-                                              (if (< (+ (:size n) new-vel) size-min)
-                                                size-bounce-velocity
-                                                new-vel)))}
-
-                                 :size (+ (:size n) (:s (:vel n)))
-
-                                 :pos {:x (+ (:x (:pos n)) (:x (:vel n)))
-                                       :y (+ (:y (:pos n)) (:y (:vel n)))})
-                        moved-nodes (assoc moved-nodes k n)]
-                    (if (empty? nodes)
-                      moved-nodes
-                      (recur moved-nodes nodes))))))
+  (letfn [(new-velocity-coord [node coordinate max]
+            (adjust-directional-vel-to-bounds
+             (+ (get-in node [:vel coordinate]) (rand-bi-dir directional-axis-acceleration))
+             (get-in node [:pos coordinate])
+             directional-speed-max
+             0
+             max
+             directional-bounce-velocity
+             (:size node)))
+
+          (new-velocity [node]
+            {:x (new-velocity-coord node :x (q/width))
+             :y (new-velocity-coord node :y (q/height))
+             :s (let [new-vel (+ (:s (:vel node)) (rand-bi-dir size-acceleration))]
+                  (cond (> (+ (:size node) new-vel) size-max) (- 0 size-bounce-velocity)
+                        (< (+ (:size node) new-vel) size-min) size-bounce-velocity
+                        :else new-vel))})
+
+          (update-node [node]
+            (assoc node
+                   :vel (new-velocity node)
+                   :size (+ (:size node) (:s (:vel node)))
+                   :pos {:x (+ (:x (:pos node)) (:x (:vel node)))
+                         :y (+ (:y (:pos node)) (:y (:vel node)))}))]
+    (update-in state [:nodes] #(map-value update-node %))) )

 (defn x-first-search
   "Colors nodes based on the progression of a search algorithm, determined by the search-type and collection type.
   Generic for breadth first search and depth first search because they just use different collection types (queue vs stack)."
   [state]
-  (let [search-type (get-in state [:search-state :search-type]) ; search-type key for coloring / checking if visited
-        nodes (:nodes state)
-        collection (get-in state [:search-state :collection]) ; is a stack if dfs, queue if bfs
-        n ((peek collection) nodes) ; for both list and queue, the first element
-        next-n-key (first
-                     ;; filter is lazy so we aren't necessarily searching through entire list.
-                     (filter (fn [node-key]
-                               (not= search-type (:color-key (node-key nodes))))
-                             (:siblings n)))
-        collection (if (nil? next-n-key)
+  (let [{:keys [nodes search-state]} state
+        ; search-type key for coloring / checking if visited
+        ; collection is  a stack if dfs, queue if bfs. Contains node labels.
+        {:keys [search-type collection]} search-state
+        n (nodes (peek collection)) ; for both list and queue, the first element
+        next-n-label (first
+                      ;; filter is lazy so we aren't necessarily searching through entire list.
+                      (filter (fn [node-label]
+                                (not= search-type (:color-key (nodes node-label))))
+                              (:siblings n)))
+        collection (if (nil? next-n-label)
                      (pop collection) ; for both list and queue, remove the first element
-                     (conj collection next-n-key)) ; for list, add to front, for queue add to end - the defining difference between nfs and bfs
-        nodes (if (nil? next-n-key)
+                     (conj collection next-n-label)) ; for list, add to front, for queue add to end - the defining difference between nfs and bfs
+        nodes (if (nil? next-n-label)
                 nodes
-                (set-color nodes next-n-key search-type))]
+                (set-color nodes next-n-label search-type))]
     (-> state
         (assoc :nodes nodes)
         (assoc-in [:search-state :collection] collection))))
@@ -234,33 +202,26 @@
         state (if (= (:frames-to-wait search-state) 1)
                 (x-first-search (assoc-in state [:search-state :frames-to-wait] frames-between-visits))
                 (update-in state [:search-state :frames-to-wait] dec))
-        collection (get-in state [:search-state :collection])
-        state (if (empty? collection)
+        collection (get-in state [:search-state :collection])
+        state (if (empty? collection)
                 ;; when x-first-search returns empty collection, search finished, so start fresh with the other search alg
-                (infer-new-search-state (if (= :bfs (get-in state [:search-state :search-type])) :dfs :bfs) (:nodes state))
+                (merge state
+                       (infer-new-search-state (if (= :bfs (get-in state [:search-state :search-type])) :dfs :bfs) (:nodes state)))
                 state)]
     state))

 (defn update-state
   "quil update-state step"
   [state]
-  (update-colors
-    (update-movement state)))
-
-(defn draw-state
-  "quil draw-state step"
-  [state]
-  (q/background 0 0 0 0)
-  (q/no-stroke)
-  (let [nodes (:nodes state)
-        edges (extract-edges (vals nodes))
-        visiting (peek (get-in state [:search-state :collection]))]
+  (-> state update-movement update-colors))
+
+(defn draw-edges [state]
+  (let [{:keys [nodes colors]} state
+        edges (extract-edges (vals nodes))]
     (q/fill (:edge colors)) ; set fill as edge color
     ;; draw each edge as a quad. Determine points using some mathematical math.
-    (doseq [ks edges]
-      (let [ks (into [] ks)
-            n1 ((nth ks 0) nodes)
-            n2 ((nth ks 1) nodes)
+    (doseq [edge edges]
+      (let [[n1 n2] (map nodes edge)
             n1-pos (:pos n1)
             n2-pos (:pos n2)
             x1 (:x n1-pos)
@@ -275,7 +236,7 @@
             y-delta (- y2 y1)
             theta (q/atan2 x-delta y-delta)
             theta-2 (- (q/radians 90) theta)
-            x-delta-2 (q/sin theta-2)
+            x-delta-2 (q/sin theta-2)
             y-delta-2 (q/cos theta-2)
             x1-a (+ x1 (* size1-adj x-delta-2))
             x1-b (- x1 (* size1-adj x-delta-2))
@@ -285,18 +246,26 @@
             x2-b (- x2 (* size2-adj x-delta-2))
             y2-a (- y2 (* size2-adj y-delta-2))
             y2-b (+ y2 (* size2-adj y-delta-2))]
-        (q/with-translation [0 0]
-          (q/quad x1-a y1-a x1-b y1-b x2-b y2-b x2-a y2-a))))
-
+        (q/quad x1-a y1-a x1-b y1-b x2-b y2-b x2-a y2-a)))))
+
+(defn draw-nodes [state]
+  (let [{:keys [nodes colors search-state]} state
+        visiting (peek (:collection search-state))]
     ;; draw each node
     (doseq [n (vals nodes)]
       (q/fill ((:color-key n) colors))
       (if (= visiting (:label n)) ; use a stroke for the node at the front of the stack/queue
         (q/stroke (:visiting colors))
         (q/no-stroke))
-      (q/with-translation [0 0]
-        (q/ellipse (:x (:pos n)) (:y (:pos n)) (:size n) (:size n))))
-    state))
+      (q/ellipse (:x (:pos n)) (:y (:pos n)) (:size n) (:size n)))))
+
+(defn draw-state
+  "quil draw-state step"
+  [state]
+  (q/background 255)
+  (q/no-stroke)
+  (draw-edges state)
+  (draw-nodes state))

 (defn run-sketch [host size] ;DELETE
   (q/sketch


increase minor version due to new feature

--- backend/project.clj
+++ backend/project.clj
@@ -1,4 +1,4 @@
-(defproject lambdaui "1.0.1-SNAPSHOT"
+(defproject lambdaui "1.1.0-SNAPSHOT"
   :description "LambdaCD-Plugin that provides a modern UI for your pipeline."
   :url "https://github.com/sroidl/lambda-ui"
   :license {:name "Apache License 2.0"


test2junit plugin

test2junit plugin

--- resources/leiningen/new/closp/project.clj
+++ resources/leiningen/new/closp/project.clj
@@ -144,6 +144,8 @@
                    :integration :integration
                    :all (constantly true)}

+  :test2junit-output-dir "test-results"
+
   :main {{ns}}.core

   :uberjar-name "{{name}}.jar"


add constants replacements

add constants replacements

--- sass-dsl/test/sass_dsl/transform_test.clj
+++ sass-dsl/test/sass_dsl/transform_test.clj
@@ -49,4 +49,32 @@
   (transform/strip-constant-declarations
    sass-constants-nested-tree))

+(deftest remove-constants-test
+  (testing "Ensure we stripped the constant declarations."
+    (is (=
+         sass-constants-stripped-nested-tree
+         [".content-navigation" ["border-color: $blue"
+                                 "color: darken($blue, 9%)"]
+          ".border" ["padding: $margin / 2"
+                     "margin: $margin / 2"
+                     "border-color: $blue"]]))))
+
+(deftest remove-constants
+  (testing "Ensure stripped the constant declarations."
+    (is (=
+         (transform/replace-const-references "border-color: $blue" {"$blue" "#3bbfce" "$margin" "16px"})
+         "border-color: #3bbfce"))))
+
+(deftest replaced-constants-structure
+  (testing "Ensure we replaced the constants structure."
+    (is (=
+         (transform/replaced-constants-structure-vec-zip
+          sass-constants-stripped-nested-tree
+          constant-map)
+         [".constant-navigation" ["bonrder-color: #3ddfce"
+                                  "color: darken(#3bbfce, 9%)"]
+          ".border" ["padding: 16px / 2"
+                     "margin: 16px / 2"
+                     "border-color: #3bbfce"]]))))
+


Fix tests.

Fix tests.

--- test/beicon/tests/core_tests.cljc
+++ test/beicon/tests/core_tests.cljc
@@ -236,13 +236,13 @@
      (t/async done
        (let [s1 (s/from-coll [1 2 3])
              s2 (s/from-coll [4 5 6])
-             cs (s/concat s2 s1)]
+             cs (s/concat s1 s2)]
          (drain! cs #(t/is (= % [1 2 3 4 5 6])))
          (s/on-end cs done)))
      :clj
      (let [s1 (s/from-coll [1 2 3])
            s2 (s/from-coll [4 5 6])
-           cs (s/concat s2 s1)]
+           cs (s/concat s1 s2)]
        (drain! cs #(t/is (= % [1 2 3 4 5 6]))))))

 (t/deftest observable-zip
@@ -404,14 +404,14 @@
      (t/async done
        (let [s1 (s/from-coll [0])
              s2 (s/from-coll [1 2 3])
-             s3 (s/with-latest-from s1 s2)]
+             s3 (s/with-latest vector s1 s2)]
          (t/is (s/observable? s3))
          (drain! s3 #(t/is (= % [[1 0] [2 0] [3 0]])))
          (s/on-end s3 done)))
      :clj
      (let [s1 (s/from-coll [0])
            s2 (s/from-coll [1 2 3])
-           s3 (s/with-latest-from s1 s2)]
+           s3 (s/with-latest vector s1 s2)]
        (t/is (s/observable? s3))
        (drain! s3 #(t/is (= % [[1 0] [2 0] [3 0]]))))))


Formatted generator_test.clj by zprint

Formatted generator_test.clj by zprint

--- test/clj_flotr/generator_test.clj
+++ test/clj_flotr/generator_test.clj
@@ -15,152 +15,152 @@
             [clj-flotr.generator :refer :all]))

 (deftest test-line-chart-existence
-    (testing "Test if line-chart function exists"
-        (is (function? line-chart))))
+  (testing "Test if line-chart function exists"
+           (is (function? line-chart))))

 (deftest test-pie-chart-existence
-    (testing "Test if pie-chart function exists"
-        (is (function? pie-chart))))
+  (testing "Test if pie-chart function exists"
+           (is (function? pie-chart))))

 (deftest test-stacked-bars-existence
-    (testing "Test if stacked-bars function exists"
-        (is (function? stacked-bars))))
+  (testing "Test if stacked-bars function exists"
+           (is (function? stacked-bars))))

 (deftest test-script-existence
-    (testing "Test if script function exists"
-        (is (function? script))))
+  (testing "Test if script function exists"
+           (is (function? script))))

 (deftest test-flotr-scripts-existence
-    (testing "Test if flotr-scripts function exists"
-        (is (function? flotr-scripts))))
+  (testing "Test if flotr-scripts function exists"
+           (is (function? flotr-scripts))))

 (deftest test-bool->string-existence
-    (testing "Test if bool->string function exists"
-        (is (function? bool->string))))
+  (testing "Test if bool->string function exists"
+           (is (function? bool->string))))

 (deftest test-data-series-for-pie-chart-existence
-    (testing "Test if data-series-for-pie-chart function exists"
-        (is (function? data-series-for-pie-chart))))
+  (testing "Test if data-series-for-pie-chart function exists"
+           (is (function? data-series-for-pie-chart))))

 (deftest test-vals->js-existence
-    (testing "Test if vals->js function exists"
-        (is (function? vals->js))))
+  (testing "Test if vals->js function exists"
+           (is (function? vals->js))))

 (deftest test-data-series-for-line-chart-existence
-    (testing "Test if data-series-for-line-chart function exists"
-        (is (function? data-series-for-line-chart))))
+  (testing "Test if data-series-for-line-chart function exists"
+           (is (function? data-series-for-line-chart))))

 (deftest test-data-series-for-stacked-bars-existence
-    (testing "Test if data-series-for-stacked-bars function exists"
-        (is (function? data-series-for-stacked-bars))))
+  (testing "Test if data-series-for-stacked-bars function exists"
+           (is (function? data-series-for-stacked-bars))))

 (deftest test-legend-part-existence
-    (testing "Test if legend-part function exists"
-        (is (function? legend-part))))
+  (testing "Test if legend-part function exists"
+           (is (function? legend-part))))

 (deftest test-grid-part-existence
-    (testing "Test if grid-part function exists"
-        (is (function? grid-part))))
+  (testing "Test if grid-part function exists"
+           (is (function? grid-part))))

 ;
 ; Unit tests
 ;

 (deftest test-bool->string-1
-    (testing "Test the function bool->string"
-        (are [x y] (= x y)
-            "false" (bool->string false)
-            "false" (bool->string nil))))
+  (testing "Test the function bool->string"
+           (are [x y] (= x y)
+                "false" (bool->string false)
+                "false" (bool->string nil))))

 (deftest test-bool->string-2
-    (testing "Test the function bool->string"
-        (are [x y] (= x y)
-            "true" (bool->string true)
-            "true" (bool->string 42)
-            "true" (bool->string "foobar")
-            "true" (bool->string '())
-            "true" (bool->string [])
-            "true" (bool->string {})
-            "true" (bool->string #{}))))
+  (testing "Test the function bool->string"
+           (are [x y] (= x y)
+                "true" (bool->string true)
+                "true" (bool->string 42)
+                "true" (bool->string "foobar")
+                "true" (bool->string '())
+                "true" (bool->string [])
+                "true" (bool->string {})
+                "true" (bool->string #{}))))

 (deftest test-script
-    (testing "Test the function script"
-        (are [x y] (= x y)
-            [:script {:type "text/javascript" :src ""}]       (script nil nil)
-            [:script {:type "text/javascript" :src ""}]       (script "" "")
-            [:script {:type "text/javascript" :src "aaa"}]    (script "aaa" "")
-            [:script {:type "text/javascript" :src "bbb"}]    (script "" "bbb")
-            [:script {:type "text/javascript" :src "aaa"}]    (script "aaa" nil)
-            [:script {:type "text/javascript" :src "bbb"}]    (script nil "bbb")
-            [:script {:type "text/javascript" :src "aaabbb"}] (script "aaa" "bbb"))))
+  (testing "Test the function script"
+           (are [x y] (= x y)
+                [:script {:type "text/javascript" :src ""}]       (script nil nil)
+                [:script {:type "text/javascript" :src ""}]       (script "" "")
+                [:script {:type "text/javascript" :src "aaa"}]    (script "aaa" "")
+                [:script {:type "text/javascript" :src "bbb"}]    (script "" "bbb")
+                [:script {:type "text/javascript" :src "aaa"}]    (script "aaa" nil)
+                [:script {:type "text/javascript" :src "bbb"}]    (script nil "bbb")
+                [:script {:type "text/javascript" :src "aaabbb"}] (script "aaa" "bbb"))))

 (deftest test-flotr-scripts-1
-    (testing "Test the function flotr-scripts"
-        (is (= (flotr-scripts nil "flotr/lib" false)
-               '([:script {:type "text/javascript", :src "flotr/lib/lib/prototype-1.6.0.2.js"}]
-                 [:script {:type "text/javascript", :src "flotr/lib/lib/canvas2image.js"}]
-                 [:script {:type "text/javascript", :src "flotr/lib/lib/canvastext.js"}]
-                 [:script {:type "text/javascript", :src "flotr/lib/flotr-0.2.0-alpha.js"}])))))
+  (testing "Test the function flotr-scripts"
+           (is (= (flotr-scripts nil "flotr/lib" false)
+                  '([:script {:type "text/javascript", :src "flotr/lib/lib/prototype-1.6.0.2.js"}]
+                    [:script {:type "text/javascript", :src "flotr/lib/lib/canvas2image.js"}]
+                    [:script {:type "text/javascript", :src "flotr/lib/lib/canvastext.js"}]
+                    [:script {:type "text/javascript", :src "flotr/lib/flotr-0.2.0-alpha.js"}])))))

 (deftest test-flotr-scripts-2
-    (testing "Test the function flotr-scripts"
-        (is (= (flotr-scripts "http://example.com" "flotr/lib" false)
-               '([:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/prototype-1.6.0.2.js"}]
-                 [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvas2image.js"}]
-                 [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvastext.js"}]
-                 [:script {:type "text/javascript", :src "http://example.com/flotr/lib/flotr-0.2.0-alpha.js"}])))))
+  (testing "Test the function flotr-scripts"
+           (is (= (flotr-scripts "http://example.com" "flotr/lib" false)
+                  '([:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/prototype-1.6.0.2.js"}]
+                    [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvas2image.js"}]
+                    [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvastext.js"}]
+                    [:script {:type "text/javascript", :src "http://example.com/flotr/lib/flotr-0.2.0-alpha.js"}])))))

 (deftest test-flotr-scripts-3
-    (testing "Test the function flotr-scripts"
-        (is (= (flotr-scripts nil "flotr/lib" true)
-               '([:script {:type "text/javascript", :src "flotr/lib/lib/prototype-1.6.0.2.js"}]
-                 [:script {:type "text/javascript", :src "flotr/lib/lib/canvas2image.js"}]
-                 [:script {:type "text/javascript", :src "flotr/lib/lib/canvastext.js"}]
-                 [:script {:type "text/javascript", :src "flotr/lib/flotr.debug-0.2.0-alpha.js"}])))))
+  (testing "Test the function flotr-scripts"
+           (is (= (flotr-scripts nil "flotr/lib" true)
+                  '([:script {:type "text/javascript", :src "flotr/lib/lib/prototype-1.6.0.2.js"}]
+                    [:script {:type "text/javascript", :src "flotr/lib/lib/canvas2image.js"}]
+                    [:script {:type "text/javascript", :src "flotr/lib/lib/canvastext.js"}]
+                    [:script {:type "text/javascript", :src "flotr/lib/flotr.debug-0.2.0-alpha.js"}])))))

 (deftest test-flotr-scripts-4
-    (testing "Test the function flotr-scripts"
-        (is (= (flotr-scripts "http://example.com" "flotr/lib" true)
-               '([:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/prototype-1.6.0.2.js"}]
-                 [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvas2image.js"}]
-                 [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvastext.js"}]
-                 [:script {:type "text/javascript", :src "http://example.com/flotr/lib/flotr.debug-0.2.0-alpha.js"}])))))
+  (testing "Test the function flotr-scripts"
+           (is (= (flotr-scripts "http://example.com" "flotr/lib" true)
+                  '([:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/prototype-1.6.0.2.js"}]
+                    [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvas2image.js"}]
+                    [:script {:type "text/javascript", :src "http://example.com/flotr/lib/lib/canvastext.js"}]
+                    [:script {:type "text/javascript", :src "http://example.com/flotr/lib/flotr.debug-0.2.0-alpha.js"}])))))

 (deftest test-data-series-for-pie-chart-1
-    (testing "Test the function data-series-for-pie-chart"
-        (are [x y] (= x y)
-            (data-series-for-pie-chart nil) '()
-            (data-series-for-pie-chart [])  '())))
+  (testing "Test the function data-series-for-pie-chart"
+           (are [x y] (= x y)
+                (data-series-for-pie-chart nil) '()
+                (data-series-for-pie-chart [])  '())))

 (deftest test-data-series-for-pie-chart-2
-    (testing "Test the function data-series-for-pie-chart"
-        (are [x y] (= x y)
-            (data-series-for-pie-chart [{:values :v1 :label :l1}])
-                                       ["{data:[[1,:v1]], label: ':l1'},\n"]
-            (data-series-for-pie-chart [{:values :v1 :label :l1}
-                                        {:values :v2 :label :l2}])
-                                       ["{data:[[1,:v1]], label: ':l1'},\n"
-                                        "{data:[[1,:v2]], label: ':l2'},\n"])))
+  (testing "Test the function data-series-for-pie-chart"
+           (are [x y] (= x y)
+                (data-series-for-pie-chart [{:values :v1 :label :l1}])
+                                           ["{data:[[1,:v1]], label: ':l1'},\n"]
+                (data-series-for-pie-chart [{:values :v1 :label :l1}
+                                            {:values :v2 :label :l2}])
+                                           ["{data:[[1,:v1]], label: ':l1'},\n"
+                                            "{data:[[1,:v2]], label: ':l2'},\n"])))

 (deftest test-data-series-for-pie-chart-3
-    (testing "Test the function data-series-for-pie-chart"
-        (are [x y] (= x y)
-            (data-series-for-pie-chart [{:values nil :label nil}])
-                                       ["{data:[[1,]], label: ''},\n"]
-            (data-series-for-pie-chart [{:values nil :label :l1}])
-                                       ["{data:[[1,]], label: ':l1'},\n"]
-            (data-series-for-pie-chart [{:values :v1 :label nil}])
-                                       ["{data:[[1,:v1]], label: ''},\n"])))
+  (testing "Test the function data-series-for-pie-chart"
+           (are [x y] (= x y)
+                (data-series-for-pie-chart [{:values nil :label nil}])
+                                           ["{data:[[1,]], label: ''},\n"]
+                (data-series-for-pie-chart [{:values nil :label :l1}])
+                                           ["{data:[[1,]], label: ':l1'},\n"]
+                (data-series-for-pie-chart [{:values :v1 :label nil}])
+                                           ["{data:[[1,:v1]], label: ''},\n"])))

 (deftest test-data-series-for-line-chart-1
-    (testing "Test the function data-series-for-line-chart"
-        (are [x y] (= x y)
-            (data-series-for-line-chart nil) '()
-            (data-series-for-line-chart [])  '())))
+  (testing "Test the function data-series-for-line-chart"
+           (are [x y] (= x y)
+                (data-series-for-line-chart nil) '()
+                (data-series-for-line-chart [])  '())))

 (deftest test-data-series-for-stacked-bars-1
-    (testing "Test the function data-series-for-stacked-bars"
-        (are [x y] (= x y)
-            (data-series-for-stacked-bars nil) '()
-            (data-series-for-stacked-bars [])  '())))
+  (testing "Test the function data-series-for-stacked-bars"
+           (are [x y] (= x y)
+                (data-series-for-stacked-bars nil) '()
+                (data-series-for-stacked-bars [])  '())))


fixed example (duplicate dictionary items)


Change all paths passed to Karma to absolute

--- library/src/doo/core.clj
+++ library/src/doo/core.clj
@@ -87,17 +87,29 @@
         (.deleteOnExit)
         (#(io/copy (slurp (io/resource full-path)) %))))))

+;; In Karma all paths (including config.files) are normalized to
+;; absolute paths using the base path, extracted from the
+;; karma.conf.js file passed (if it's relative the current directory
+;; becomes the basePath).
+;; To avoid this, we need to ensure the paths passed to Karma are
+;; already absolute.
+;; https://github.com/karma-runner/karma/blob/master/lib/config.js#L80
+
+(defn ->absolute [path]
+  (.getAbsolutePath (io/file path)))
+
 (defn karma-runner!
   "Creates a file for the given runner resource file in the users dir"
   [js-env compiler-opts]
   {:pre [(some? (:output-dir compiler-opts))]}
   (let [resource-path (str base-dir "karma.conf.js.tmpl")
-        tmpl-opts (assoc compiler-opts
-                    js-env true
-                    :none (= :none (:optimizations compiler-opts)))]
-    ;; TODO: get karma to work with an absolute path instead
-    (.getPath
-      (doto (io/file "doo_karma_runner.js")
+        tmpl-opts (-> compiler-opts
+                    (update :output-to ->absolute)
+                    (update :output-dir ->absolute)
+                    (assoc js-env true
+                      :none (= :none (:optimizations compiler-opts))))]
+    (.getAbsolutePath
+      (doto (File/createTempFile "doo_karma_runner" ".js")
         (.deleteOnExit)
         (#(io/copy (selmer/render-file resource-path tmpl-opts) %))))))


Update blocks-tests dependencies.

Update blocks-tests dependencies.

--- blocks-tests/project.clj
+++ blocks-tests/project.clj
@@ -8,8 +8,8 @@
   :pedantic? :abort

   :dependencies
-  [[org.clojure/clojure "1.10.0"]
+  [[org.clojure/clojure "1.10.1"]
    [org.clojure/test.check "0.9.0"]
    [mvxcvi/blocks "2.0.2-SNAPSHOT"]
    [mvxcvi/test.carly "0.4.1"]
-   [mvxcvi/puget "1.1.0"]])
+   [mvxcvi/puget "1.1.2"]])


[#2872] Fix more test

[#2872] Fix more test

--- backend/test/akvo/lumen/lib/aggregation/commons_test.clj
+++ backend/test/akvo/lumen/lib/aggregation/commons_test.clj
@@ -56,7 +56,9 @@
      "aggregationColumn" "c5"}
     ],
    "version" 1,
-   "baseLayer" "street"})
+   "baseLayer" "street"
+   "centreOfTheWorld" "greenwich"
+   })

 (deftest ^:unit spec-columns-test
   (let [data


Some refactoring, plus support for saving multiple entities.

--- src/appengine_magic/services/datastore.clj
+++ src/appengine_magic/services/datastore.clj
@@ -74,6 +74,8 @@
     "Returns nil if no tag is specified in the record definition, and no :key
      metadata exists. Otherwise returns a Key object. Specify optional entity
      group parent.")
+  (get-entity-object [this]
+    "Returns a datastore Entity object instance for the record.")
   (save! [this]
     "Writes the given entity to the data store."))

@@ -110,6 +112,10 @@
          (instance? clojure.lang.APersistentSet v) (to-java-hashset v) ; broken in GAE 1.3.7
          (extends? EntityProtocol (class v)) (get-key-object v)
          :else v)))
+
+
+(defn- coerce-to-key-seq [any-seq]
+  (map #(if (instance? Key %) % (get-key-object %)) any-seq))

 (defn get-key-object-helper [entity-record key-property kind &
@@ -137,7 +143,7 @@
                    "entity has no valid :key metadata, and has no fields marked :key")))))

-(defn save!-helper [entity-record kind]
+(defn get-entity-object-helper [entity-record kind]
   (let [key-object (get-key-object entity-record)
         entity (if key-object
                    (Entity. key-object)
@@ -145,7 +151,21 @@
     (doseq [[property-kw value] entity-record]
       (let [property-name (.substring (str property-kw) 1)]
         (.setProperty entity property-name (coerce-clojure-type value))))
-    (.put (get-datastore-service) entity)))
+    entity))
+
+
+(defn save!-helper [entity-record]
+  (.put (get-datastore-service) (get-entity-object entity-record)))
+
+
+(defn- save-many-helper! [entity-record-seq]
+  (let [entities (map get-entity-object entity-record-seq)]
+    (.put (get-datastore-service) entities)))
+
+
+(extend-type Iterable
+  EntityProtocol
+  (save! [this] (save-many-helper! this)))

 (defn retrieve [entity-record-type key-value &
@@ -175,9 +195,7 @@

 (defn delete! [target]
   (let [target (if (sequential? target) target [target])
-        key (if (every? #(instance? Key %) target)
-                target
-                (map get-key-object target))]
+        key (coerce-to-key-seq target)]
     (.delete (get-datastore-service) key)))

@@ -192,8 +210,10 @@
          (get-key-object-helper this# ~key-property ~kind))
        (get-key-object [this# parent#]
          (get-key-object-helper this# ~key-property ~kind :parent parent#))
+       (get-entity-object [this#]
+         (get-entity-object-helper this# ~kind))
        (save! [this#]
-         (save!-helper this# ~kind)))))
+         (save!-helper this#)))))

 (defmacro new* [entity-record-type property-values & {:keys [parent]}]


Render-front-page: different mode for blacklist

--- src/zg/html_renderer.clj
+++ src/zg/html_renderer.clj
@@ -108,16 +108,30 @@
             [:div {:class "container"}
                 (render-navigation-bar-section word user-name url-prefix zw-mode)

-                (form/form-to [:post (str url-prefix "add-words")]
-                        [:div {:class "label label-primary"} "New words"]
-                        " "
-                        [:div {:class "label label-warning"} "(please use spaces or commas as separators)"]
-                        [:br]
-                        (form/text-area {:cols "120" :rows "8"} "new-words")
-                        [:br]
-                        (form/submit-button {:class "btn btn-danger"} "Add new words")
-                        [:br]
+                (if zw-mode
+                    (form/form-to [:post (str url-prefix "add-word")]
+                            [:table {:style "border-collapse: separate; border-spacing: 10px;"}
+                                [:tr [:td [:div {:class "label label-primary"} "New word"]]
+                                     [:td " "]
+                                     [:td (form/text-field {:size "30"} "new-word")]]
+                                [:tr [:td [:div {:class "label label-default"} "Description (optional)"]]
+                                     [:td " "]
+                                     [:td (form/text-field {:size "60"} "description")]]
+                                [:tr [:td " "]
+                                     [:td " "]
+                                     [:td (form/submit-button {:class "btn btn-danger"} "Add new word")]]]
+                            [:br]
                     )
+                    (form/form-to [:post (str url-prefix "add-words")]
+                            [:div {:class "label label-primary"} "New words"]
+                            " "
+                            [:div {:class "label label-warning"} "(please use spaces or commas as separators)"]
+                            [:br]
+                            (form/text-area {:cols "120" :rows "8"} "new-words")
+                            [:br]
+                            (form/submit-button {:class "btn btn-danger"} "Add new words")
+                            [:br]
+                        ))

                         [:br]
                         [:br]


Refactored returning of actions and refs from backend to frontend for better performance (looping the namespace just once).

--- src/clj_formal_specifications_app/core.clj
+++ src/clj_formal_specifications_app/core.clj
@@ -36,19 +36,36 @@
   [s]
   (re-find #"(?<=\(ns\s)[a-zA-Z0-9\.-]+(?=[\s\(\)])" s))

-(defn ns-actions
-  [ns]
-  (map key (filter #(:action (meta (val %))) (ns-publics (symbol ns)))))
+(defn action-entry?
+  [map-entry]
+  (:action (meta (val map-entry))))

-(defn ns-spec-refs
-  [ns]
-  (map key (filter #(:spec-ref (meta (var-get (val %))))
-                   (ns-publics (symbol ns)))))
+(defn spec-ref-entry?
+  [map-entry]
+  (:spec-ref (meta (var-get (val map-entry)))))
+
+(defn assoc-action-to-specification
+  [specification action-entry]
+  (assoc-in specification [:actions (key action-entry)] {}))
+
+(defn assoc-spec-ref-to-specification
+  [specification spec-ref-entry]
+  (assoc-in specification [:spec-refs (key spec-ref-entry)] {}))
+
+(defn assoc-to-specification
+ [specification map-entry]
+  (cond
+   (action-entry? map-entry)
+   (assoc-action-to-specification specification map-entry)
+
+   (spec-ref-entry? map-entry)
+   (assoc-spec-ref-to-specification specification map-entry)
+
+   :else specification))

 (defn ns-specification
   [ns]
-  {:actions (ns-actions ns)
-   :spec-refs (ns-spec-refs ns)})
+  (reduce assoc-to-specification {} (ns-publics (symbol ns))))

 (defn compose
   [specification]


adds stars to rating | sg | #5

adds stars to rating | sg | #5

--- src/cljs/conference_rating/conference.cljs
+++ src/cljs/conference_rating/conference.cljs
@@ -53,6 +53,8 @@
    [:div {:class "form-group"}
     [:input {:type "text" :placeholder "author" :class "form-control" :field :text :id :author}]]
    [:div {:class "form-group"}
+    [:input {:type "number" :placeholder "stars" :class "form-control" :min 1 :max 5 :field :range :id :stars}]]
+   [:div {:class "form-group"}
     [:textarea {:placeholder "comment" :class "form-control" :rows "5" :field :textarea :id :comment}]]])

 (defn create-rating [form-data]
@@ -70,9 +72,11 @@
    [:div {:class "jumbotron"}
     [:h1(:conference-name conference)]
     [:p (:conference-description conference)]]
-   [:div
-    [forms/bind-fields add-rating-template doc]
-    [:button {:class "btn btn-primary" :on-click #(create-rating doc)} "add rating"]]
+   [:div {:class "panel panel-default"}
+    [:div {:class "panel-heading"} "rate this conference now!"]
+    [:div {:class "panel-body"}
+      [forms/bind-fields add-rating-template doc]
+      [:button {:class "btn btn-primary" :on-click #(create-rating doc)} "add rating"]]]
    [:div (display-ratings conference-ratings)]]))

 (defn conference-page []


Fix cnt problem.

Fix cnt problem.

--- src/wlmmap/handler.clj
+++ src/wlmmap/handler.clj
@@ -232,7 +232,9 @@
         rset (str cntry srlang)
         res (json/read-str (slurp req) :key-fn keyword)
         next (or (:srcontinue (:continue res)) "")]
-    (doseq [[m cnt] (map list (:monuments res) (range))]
+    (doseq [[m cnt] (map list
+                         (:monuments res)
+                         (range (inc (count (wcar* (car/hvals rset)))) 100000))]
       (when (and (not (nil? (:lat m)))
                  (not (nil? (:lon m)))
                  (not (or (nil? (:name m)) (= "" (:name m)))))
@@ -269,8 +271,8 @@
         [:h1 (format "Store monuments for country %s and lang %s into \"%s\""
                      (:country params) (:srlang params) rset)]
         [:form {:method "POST" :action "/process" :class "main"}
-         [:h2 "Continuated from"] (:cont params)
-         [:h2 "Done"] size
+         [:h2 (str "Continuated from " (:cont params))]
+         [:h2 (str "Done so far: " size)]
          [:h2 "Next"]
          [:input {:type "hidden" :name "country" :value (:country params)}]
          [:input {:type "hidden" :name "srlang" :value (:srlang params)}]


Added walk-3 with mapv-recurse

Added walk-3 with mapv-recurse

--- test/tst/tupelo/xxx.cljc
+++ test/tst/tupelo/xxx.cljc
@@ -86,5 +86,26 @@
   (println :walk-2)
   (pretty result))

+(newline)
+(println "-----------------------------------------------------------------------------")
+(defn walk-3 [node]
+; (newline)
+  (let [tag     (grab :tag node)
+      ; _       (spyx tag)
+        content (grab :content node)]
+    (if (empty? content)
+      (spyx [[tag]])
+      (spy :mapv-prepend
+        (mapv #(prepend tag %)
+          (spy :apply-concat
+            (apply concat
+              (spy :mapv-recurse
+                (mapv walk-3 content)))))))))
+
+(let [result (walk-3 data)]
+  (newline)
+  (println :walk-3)
+  (pretty result))

+


Fix compilation error

Fix compilation error

--- crawler/src/crawler/core.clj
+++ crawler/src/crawler/core.clj
@@ -14,8 +14,8 @@
       (doseq [doc (s/search-results geo-loc start-date end-date)]
         (try
           (m/insert-waterquality-data doc)
-          (catch e (println "Error inserting doc" e)))))))
-
+          (catch Exception e
+            (println "Error inserting doc" e)))))))

 (defn fake-data


Fix build-worker script.

Fix build-worker script.

--- scripts/build-worker.clj
+++ scripts/build-worker.clj
@@ -12,7 +12,7 @@
     :parallel-build false
     :optimizations :simple
     :static-fns true
-    :language-in  :ecmascript5
+    :language-in  :ecmascript6
     :language-out :ecmascript5
     :verbose true})
   (println "... done. Elapsed" (/ (- (System/nanoTime) start) 1e9) "seconds"))


I think this may fix [IMMUTANT-586]

I think this may fix [IMMUTANT-586]

Hey, I rhymed!

--- web/src/immutant/web.clj
+++ web/src/immutant/web.clj
@@ -35,9 +35,13 @@
      * :path          Maps the handler to a prefix of the url path [\"/\"]
      * :virtual-host  Virtual host name[s] (a String or a List of Strings) [nil]
      * :dispatch?     Invoke handlers in worker thread pool [true]
-     * :servlet-name  The name to register the servlet under (gets passed to
-                      ServletInfo, valid for servlets only) [the :path]

+  When `handler` is a Servlet, the following options are also supported:
+
+     * :servlet-name  The servlet's registered name [the :path]
+     * :filter-map    An ordered mapping, e.g. a LinkedHashMap, of names
+                      to Filter instances [nil]
+
    Note the web server only binds to the loopback interface, by
    default. To expose your handler to the network, set :host to an
    external IP address, or use \"0.0.0.0\" to bind it to all interfaces.


Supply samba drum clapping music.

Supply samba drum clapping music.

--- src/african_polyphony_and_polyrhythm/talk.clj
+++ src/african_polyphony_and_polyrhythm/talk.clj
@@ -42,13 +42,24 @@
          (canon #(->> % (take 64) (then (rhythm [1/8])) forever (all :part :clap2))))))

 (comment
-  (live/play (clapping-music)))
+  (->> (clapping-music)
+       live/play))
+
+(definst clap [freq 440 vol 0.5 pan 0]
+  (-> (* 2/3 (brown-noise))
+      (+ (* 1/2 (sin-osc (* 3 freq))))
+      (+ (* 1/5 (sin-osc (* 5 freq))))
+      (clip2 0.8)
+      (rlpf (line:kr freq (* 7 freq) 0.02))
+      (* (env-gen (adsr 0.02 0.4 0.15 0.2) (line:kr 1 0 0.1) :action FREE))
+      (pan2 pan)
+      (* vol)))

 (defmethod live/play-note :clap1 [_]
-  ((sample "samples/click2.wav")))
+  (clap 225 :pan 1))

 (defmethod live/play-note :clap2 [_]
-  ((sample "samples/select-click.wav")))
+  (clap 150 :pan -1))

 (defn vary [t f]
   (fn [notes]


straight jacket the FB analytics code

straight jacket the FB analytics code

It was somehow causing projects to fail to load when the callback
on the goog.net.jsloader fired

--- src-cljs/frontend/analytics/facebook.cljs
+++ src-cljs/frontend/analytics/facebook.cljs
@@ -3,7 +3,8 @@
             [goog.net.jsloader]))

 (defn track-conversion []
-  (.push js/window._fbq #js ["track" "6017370234581" {:value "0.01" :currency "USD"}]))
+  (utils/swallow-errors
+    (.push js/window._fbq #js ["track" "6017370234581" {:value "0.01" :currency "USD"}])))

 (defn track-signup []
   (utils/swallow-errors
@@ -11,4 +12,3 @@
       (track-conversion)
       (-> (goog.net.jsloader.load "//connect.facebook.net/en_US/fbds.js")
           (.addCallback track-conversion)))))
-


tweak background bot to avoid clipping shapes

--- src-cljs/frontend/components/drawing.cljs
+++ src-cljs/frontend/components/drawing.cljs
@@ -317,7 +317,7 @@
         box-width 540
         start-x (int (- (+ (:start-x browser) (/ width 2))
                         (/ box-width 2)))
-        box-height 50
+        box-height 40
         start-y (int (- (+ (:start-y browser) (/ height 2))
                         (* 2 box-height)))]
     {:doc-id (:db/id document) :tool :rect
@@ -358,7 +358,7 @@
         line-width 500
         start-x (int (- (+ (:start-x browser) (/ width 2))
                         (/ line-width 2)))
-        start-y (- (:end-y browser) 50)]
+        start-y (- (:end-y browser) 60)]
     {:doc-id (:db/id document) :tool :line
      :start-x start-x  :end-x (+ start-x line-width)
      :start-y start-y :end-y start-y
@@ -371,7 +371,7 @@
         line-width 400
         start-x (int (- (+ (:start-x browser) (/ width 2))
                         (/ line-width 2)))
-        start-y (- (:end-y browser) 37.5)]
+        start-y (- (:end-y browser) 40)]
     {:doc-id (:db/id document) :tool :line
      :start-x start-x  :end-x (+ start-x line-width)
      :start-y start-y :end-y start-y


make the public aspect less scary

make the public aspect less scary

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -268,7 +268,7 @@
            [:h2
             [:span "This document is "]
             [:span.privacy-public-word "public."]]
-           [:p.privacy-public-words "It's visible to everyone.
+           [:p.privacy-public-words "It's visible to everyone who can guess the URL.
                Email a friend to invite them to collaborate."]
            (if-not (:cust app)
              [:a.menu-button {:href (auth/auth-url)


A richer properties table.

A richer properties table.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -342,49 +342,35 @@
 (defmethod properties-table-html :error [properties owner]
   (error-row properties))

-(defn form-group-static [label text]
-  [:div.form-group
-   [:label.col-sm-2.control-label label]
-   [:div.col-sm-10
-    [:p.form-control-static text]]])
-
-(defn dl-horizontal [title item]
-  [:div [:dt title] [:dd item]])
-
-(defn property-detail [property-detail]
-  (let [property_data (:property_data property-detail)]
-    [:div.col-md-12
-     [:div.col-md-6
-      [:dl.dl-horizontal
-       (dl-horizontal "Property Type" (:property_type property_data))
-       (dl-horizontal "Property Code" (:property_code property_data))
-       (dl-horizontal "Address" [:address
-                                 (:address_street property_data) [:br]
-                                 (when-let [address-two (:address_street_two property_data)]
-                                   [:div address-two [:br]])
-                                 (:address_code property_data) [:br]
-                                 (:address_country property_data)])
-       (dl-horizontal "Region" (:address_region property_data))
-       (dl-horizontal "Ownership" (:ownership property_data))]]
-     [:div.col-md-2
-      (when-let [pic (:path (first (:photos property-detail)))]
-        [:img.img-thumbnail.tmg-responsive
-         {:src (str "https://s3-us-west-2.amazonaws.com/get-embed-data/" pic)}])]
-     [:div.col-md-4
-      (for [ti (:technology_icons property_data)]
-        [:img.tmg-responsive {:src ti :width 40 :height 40}])]]))
-
 (defmethod properties-table-html :has-data [properties owner]
   (let [table-id "properties-table"
         history  (om/get-shared owner :history)]
-    [:div.row
-     [:div.col-md-12
+    [:div.col-md-12
+     [:table {:className "table table-hover"}
+      [:thead
+       [:tr [:th "ID"] [:th "Type"] [:th "Address"] [:th "Region"] [:th "Ownership"] [:th "Technologies"] [:th "Monitoring Hierarchy"]]]
       (for [row (sort-by #(-> % :property_data :property_code) (:data properties))]
         (let [property_data (:property_data row)
-              slug (str "Property Code: " (:property_code property_data)
-                        " | Address: "
-                        (:address_code property_data))]
-          (bs/panel slug (property-detail row))))]]))
+              id            (:id row)]
+          [:tr
+           {:onClick (fn [_ _]
+                       (om/update! properties :selected id)
+                       (history/update-token-ids! history :properties id)
+                       (fixed-scroll-to-element "devices-div"))
+            :className (if (= id (:selected properties)) "success")
+            :id (str table-id "-selected")}
+           [:td (:property_code property_data)]
+           [:td (:property_type property_data)]
+           [:td (:address_street_two property_data)
+            (when-let [address_two (:address_street_two property_data)]
+              (str ", " address_two))
+            (str ", " (:address_city property_data))
+            (str ", " (:address_code property_data) ", " (:address_country property_data))]
+           [:td (:address_region property_data)]
+           [:td (:ownership property_data)]
+           [:td (for [ti (:technology_icons property_data)]
+                  [:img.tmg-responsive {:src ti :width 40 :height 40}])]
+           [:td (:monitoring_hierarchy property_data)]]))]]))

 (defmethod properties-table-html :default [properties owner]
   [:div.row [:div.col-md-12]])


[#1450]Set akvo.lumen.specs/sample default amount to 1

--- backend/specs/akvo/lumen/specs.clj
+++ backend/specs/akvo/lumen/specs.clj
@@ -9,8 +9,12 @@
 (defn sample-with-gen [s map-gen amount]
   (map first (s/exercise s amount map-gen)))

-(defn sample [s amount]
-  (map first (s/exercise s amount)))
+(defn sample
+  ([s]
+   (map first (s/exercise s 1)))
+  ([s amount]
+   (map first (s/exercise s amount))))
+
 (defn str-uuid? [v]
   (when (some? v)
     (uuid? (read-string (format "#uuid \"%s\"" v)))))


Read cljs.edn always instead of only once

--- src/adzerk/boot_cljs.clj
+++ src/adzerk/boot_cljs.clj
@@ -102,9 +102,7 @@
   (let [tmp-src (core/tmp-dir!)]
     {:pod         (new-pod! tmp-src)
      :initial-ctx {:tmp-src tmp-src
-                   :tmp-out (core/tmp-dir!)
-                   :main    (-> (read-cljs-edn cljs-edn)
-                                (assoc :ns-name (name (gensym "main"))))}}))
+                   :tmp-out (core/tmp-dir!)}}))

 (defn- compile-1
   [compilers task-opts macro-changes write-main? {:keys [path] :as cljs-edn}]
@@ -114,6 +112,8 @@
                        (assoc compilers path (make-compiler cljs-edn)))))
   (let [{:keys [pod initial-ctx]} (get @compilers path)
         ctx (-> initial-ctx
+                (assoc :main (-> (read-cljs-edn cljs-edn)
+                                 (assoc :ns-name (name (gensym "main")))))
                 (wrap/compiler-options task-opts)
                 (wrap/main write-main?)
                 wrap/source-map)


Add ln command function

Add ln command function

--- src/aerobio/pgmgraph.clj
+++ src/aerobio/pgmgraph.clj
@@ -69,6 +69,7 @@
             bowtie bowtie2 bowtie-build bowtie2-build
             featureCounts breseq
             Rscript python ruby perl
+            ln
             bp_load_genbank
             ))