arrange customers by logo type

arrange customers by logo type

--- frontend/components/landing_b.cljs
+++ frontend/components/landing_b.cljs
@@ -143,6 +143,22 @@
               :tools #{:rails :ruby}
               ;; TODO get position from index rather than specifying manually
               :position 0}
+    :intercom {:name "Intercom"
+               :logo ""
+               :quote "Sed dolor dolor, accumsan et lacinia bibendum, molestie eget est. Ut et aliquet quam, a molestie felis. Donec dignissim mi eget nibh iaculis convallis."
+               :cite "Tony Stark"
+               :cite-title "Engineer"
+               :cite-avatar "/img/outer/stories/john.jpg"
+               :tools #{:node :javascript}
+               :position 1}
+    :spotify {:name "Spotify"
+              :logo ""
+              :quote "Donec molestie scelerisque libero sed pellentesque. Integer cursus sem arcu, nec sagittis orci fermentum facilisis. Donec sit amet felis non leo interdum placerat."
+              :cite "Bruce Banner"
+              :cite-title "Brute Force Hacker"
+              :cite-avatar "/img/outer/stories/john.jpg"
+              :tools #{:php}
+              :position 2}
     :kickstarter {:name "Kickstarter"
                   :logo ""
                   :quote "CircleCI was super simple to set up and we started reaping the benefits immediately. It lets us ship code quickly and confidently."
@@ -150,15 +166,7 @@
                   :cite-title "Operations Engineer"
                   :cite-avatar "/img/outer/home/aaron-suggs.jpg"
                   :tools #{:django :python}
-                  :position 1}
-    :intercom {:name "Intercom"
-               :logo ""
-               :quote "Sed dolor dolor, accumsan et lacinia bibendum, molestie eget est. Ut et aliquet quam, a molestie felis. Donec dignissim mi eget nibh iaculis convallis."
-               :cite "Tony Stark"
-               :cite-title "Engineer"
-               :cite-avatar "/img/outer/stories/john.jpg"
-               :tools #{:node :javascript}
-               :position 2}
+                  :position 3}
     :gocardless {:name "GoCardless"
                  :logo ""
                  :quote "CircleCI lets us develop and ship better code, faster. Its awesome parallelisation feature allows us to test more thoroughly and deploy with confidence."
@@ -166,15 +174,7 @@
                  :cite-title "Engineer"
                  :cite-avatar "/img/outer/stories/arthur.jpg"
                  :tools #{:ruby :rails :postgres :javascript :node}
-                 :position 3}
-    :spotify {:name "Spotify"
-              :logo ""
-              :quote "Donec molestie scelerisque libero sed pellentesque. Integer cursus sem arcu, nec sagittis orci fermentum facilisis. Donec sit amet felis non leo interdum placerat."
-              :cite "Bruce Banner"
-              :cite-title "Brute Force Hacker"
-              :cite-avatar "/img/outer/stories/john.jpg"
-              :tools #{:php}
-              :position 4}))
+                 :position 4}))

 (defn home [app owner]
   (reify


[#3158] Fix test

[#3158] Fix test

--- backend/test/akvo/lumen/lib/data_group_test.clj
+++ backend/test/akvo/lumen/lib/data_group_test.clj
@@ -1,5 +1,6 @@
 (ns akvo.lumen.lib.data-group-test
   (:require [akvo.lumen.lib.data-group :as data-group]
+            [clojure.string :as str]
             [clojure.test :refer [deftest is]]))

 (def test-data-groups [{:columns [{:columnName "instance_id"}
@@ -44,4 +45,4 @@

 (deftest ^:unit data-groups-view
   (let [expected "CREATE TEMP VIEW foo AS SELECT * FROM bar"]
-    (is (= expected (data-group/data-groups-view "foo" true false "SELECT * FROM bar ")))))
+    (is (= expected (str/trim (data-group/data-groups-view "foo" true false "SELECT * FROM bar"))))))


remove silly function

remove silly function

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10856 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -63,9 +63,6 @@
 ;; globals

 (def ^:dynamic state (atom {:stop false}))
-
-(defn state-assoc! [& args]
-  (apply swap! state assoc args))

 (def attached-runnables (atom (vec nil)))

@@ -516,7 +513,7 @@

 (defn interruptible-sleep [time-ms]
   (let [sleepy (CountDownLatch. 1)]
-    (state-assoc! :sleepy sleepy :next-wake-time (+ (jvm-time-ms) time-ms))
+    (swap! state assoc :sleepy sleepy :next-wake-time (+ (jvm-time-ms) time-ms))
     (.await sleepy time-ms TimeUnit/MILLISECONDS)))

 (defn acq-sleep [interval-ms]
@@ -538,7 +535,7 @@
       (.enableLiveMode gui false))
     (let [now (jvm-time-ms)
           wake-time (if (> now (+ target-time 10)) now target-time)]
-      (state-assoc! :last-wake-time wake-time))))
+      (swap! state assoc :last-wake-time wake-time))))

 ;; higher level

@@ -603,7 +600,7 @@
     (when-not (empty? z-drive)
       (when (z-stage-needs-adjustment z-drive)
         (let [z (get-z-stage-position z-drive)]
-          (state-assoc! :reference-z z))))))
+          (swap! state assoc :reference-z z))))))

 ;; startup and shutdown

@@ -644,7 +641,7 @@
   (try
     (attempt-all
       (log "cleanup")
-      (state-assoc! :finished true :display nil)
+      (swap! state assoc :finished true :display nil)
       (when (core isSequenceRunning)
         (core stopSequenceAcquisition))
       (stop-trigger)


Style fix

Style fix

--- src/caesium/byte_bufs.clj
+++ src/caesium/byte_bufs.clj
@@ -31,7 +31,9 @@

 (extend-protocol BufLen
   (Class/forName "[B")
-  (buflen [this] (long (alength ^bytes this)))
+  (buflen [this]
+    (long (alength ^bytes this)))

   ByteBuffer
-  (buflen [this] (long (.remaining ^ByteBuffer this))))
+  (buflen [this]
+    (long (.remaining ^ByteBuffer this))))


Handle Enters in form fields if :on-submit set for a `form`. Generate an invisible submit button iff :on-submit option is used.

--- src/reforms/core.cljs
+++ src/reforms/core.cljs
@@ -87,10 +87,14 @@
        (form {:style {:background-color \"red\"}} [:div \"Contents go here\"])"
   [& args]
   (let [[attrs & elems] (impl/resolve-args [:form]
-                                      {:on-submit #(.preventDefault %)
-                                       :class     (when (impl/form-horizontal?) "form-horizontal")}
-                                      args)]
-    [:form attrs elems]))
+                                           {:on-submit #(.preventDefault %)
+                                            :class     (when (impl/form-horizontal?) "form-horizontal")}
+                                           args)]
+    [:form attrs
+     elems
+     (when (:on-submit (first args))                        ;; TODO: Kinda hackish.
+       [:button {:type  "submit"
+                 :style {:display "none"}}])]))

 (defn group-title
   "A title for a logical group of controls.


[#1381] Update backend pie test

[#1381] Update backend pie test

--- backend/test/akvo/lumen/lib/pie_test.clj
+++ backend/test/akvo/lumen/lib/pie_test.clj
@@ -17,14 +17,8 @@
     (testing "Simple queries"
       (let [[tag query-result] (query {"bucketColumn" "c1"})]
         (is (= tag ::lib/ok))
-        (is (= query-result {"metadata" {"bucketColumnTitle" "A"
-                                         "bucketColumnType" "text"},
-                             "data" [{"bucketValue" "a1", "bucketCount" 4}
-                                     {"bucketValue" "a2", "bucketCount" 4}]})))
+        (is (= query-result {"series" [{"key" "A" "label" "A" "data" [{"value" 4} {"value" 4}]}] "common" {"data" [{"key" "a1" "label" "a1"} {"key" "a2" "label" "a2"}] "metadata" {"type" "text"}}})))

       (let [[tag query-result] (query {"bucketColumn" "c2"})]
         (is (= tag ::lib/ok))
-        (is (= query-result {"metadata" {"bucketColumnTitle" "B"
-                                         "bucketColumnType" "text"},
-                             "data" [{"bucketValue" "b1", "bucketCount" 5}
-                                     {"bucketValue" "b2", "bucketCount" 3}]}))))))
+        (is (= query-result {"series" [{"key" "B" "label" "B" "data" [{"value" 5} {"value" 3}]}] "common" {"data" [{"key" "b1" "label" "b1"} {"key" "b2" "label" "b2"}] "metadata" {"type" "text"}}}))))))


src/riemann/xymon.clj: counting next-message, not next

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -138,7 +138,7 @@
    (if (empty? events)
      '(message)
      (let [next-message (formatter (first events))
-           next-length (count next)
+           next-length (count next-message)
            length (+ len next-length 2)
            events (rest events)]
        (cond


Extend utils/fs

Extend utils/fs

--- src/cider_ci/utils/fs.clj
+++ src/cider_ci/utils/fs.clj
@@ -9,6 +9,10 @@
     [clj-uuid]
     [clojure.string :as string]
     [clojure.tools.logging :as logging]
+    )
+  (:import
+    [java.io File]
+    [org.apache.commons.lang3 SystemUtils]
     ))

 (defn directory? [path]
@@ -35,7 +39,10 @@
        (clj-uuid/v5 clj-uuid/+null+ (str x))))

 (defn system-path [& args]
+  "Returns a path (segment) by joining the arguments
+  with the system specific file separator."
   (clojure.string/join (File/separator) args))

 (defn system-path-abs [& args]
-  (str (File/separator) (apply system-path args)))
+  (when-not SystemUtils/IS_OS_WINDOWS
+    (str (File/separator) (apply system-path args))))


fix var resolution bug pointed out by Brandon Bloom

Need to check the current namespace before checking that a var is a
core var.

--- src/clj/cljs/analyzer.clj
+++ src/clj/cljs/analyzer.clj
@@ -385,9 +385,11 @@
            (recur env (get-in @env/*compiler* [::namespaces (-> env :ns :name) :imports sym]) confirm)

            :else
-           (let [full-ns (if (core-name? env sym)
-                           'cljs.core
-                           (-> env :ns :name))]
+           (let [cur-ns (-> env :ns :name)
+                 full-ns (cond
+                           (get-in @env/*compiler* [::namespaces cur-ns :defs sym]) cur-ns
+                           (core-name? env sym) 'cljs.core
+                           :else cur-ns)]
              (when confirm
                (confirm env full-ns sym))
              (merge (get-in @env/*compiler* [::namespaces full-ns :defs sym])


* src/clj/cljs/compiler.clj: include line # in redef warn

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -798,7 +798,7 @@
                       (println (str "WARNING: " sym " already refers to: " (symbol (str (:ns ev)) (str sym))
                                     " being replaced by: " (symbol (str ns-name) (str sym))
                                     (when (:line env)
-                                      (str " at line " (:line env)))))))
+                                      (str " at line " (:line env) " " *cljs-file*))))))
                   (swap! namespaces update-in [ns-name :excludes] conj sym)
                   (update-in env [:ns :excludes] conj sym))
                 env)


putting conditionals around `goog.require` and `goog.provides` doesn't make sense, remove

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -823,11 +823,7 @@

 (defmethod emit* :ns
   [{:keys [name requires uses require-macros env]}]
-  (when (= (:optimizations *build-options*) :none)
-    (emitln "if(!goog.isProvided_('" (munge name) "')) {"))
   (emitln "goog.provide('" (munge name) "');")
-  (when (= (:optimizations *build-options*) :none)
-    (emitln "}"))
   (when-not (= name 'cljs.core)
     (emitln "goog.require('cljs.core');"))
   (load-libs requires)


tweak, only load analysis caches in compile-file if we're optimizing constants, this is what we need it for

--- src/clj/cljs/compiler.clj
+++ src/clj/cljs/compiler.clj
@@ -1113,9 +1113,9 @@
                     ret))
                 (do
                   ;; populate compilation environment with analysis information
-                  ;; while it would seem this isn't necessary avoiding to do so damages
-                  ;; composition of smaller compilation units like expressions (i.e. REPLs)
-                  (when (not (contains? (::ana/namespaces @env/*compiler*) ns))
+                  ;; when constants are optimized
+                  (when (and (true? (:optimize-constants opts))
+                             (not (contains? (::ana/namespaces @env/*compiler*) ns)))
                     (with-core-cljs opts (fn [] (ana/analyze-file src-file opts))))
                   ns-info)))
             (catch Exception e


Callback methods

Callback methods

--- src/clojure/yaw/world.clj
+++ src/clojure/yaw/world.clj
@@ -20,6 +20,22 @@
         thread (future world)]
     (.start (Thread. world))
     (atom {:world world :thread thread})))
+
+;;CALLBACKS---------------------------------------------------------------
+(defn callmap "Retrieve the `world` callback map"
+  [world] (.getCallback world))
+
+(defn register-callback! "Add a callback to the `world` callmap"
+  [world name f]
+  (.registerCallback (callmap world) name f))
+
+(defn clear-callback! "Remove the named callback from the `world` callmap"
+  [world name]
+  (.clearCallback (callmap world) name))
+
+(defn clear-keystroke! "Remove the specified function from the callback corresponding to the specified key"
+  [world key f]
+  (.clearFunctionOfKey (callmap world) key f))

 ;;Since we completely destroy the old architecture we will migrate the basic method to this module
 ;;README ONLY USE WORLD IT is A FACADE, no DIRECT USE OF MANAGEMENT/BUILDER TOOLS


[#2296] Improve error messages with detailed instructions to follow

--- backend/src/akvo/lumen/admin/add_tenant/db.clj
+++ backend/src/akvo/lumen/admin/add_tenant/db.clj
@@ -2,13 +2,20 @@
   (:require [akvo.lumen.admin.util :as util]
             [clojure.tools.logging :as log]
             [clojure.java.jdbc :as jdbc]
+            [clojure.string :as str]
             [ragtime.jdbc :as r.jdbc]
             [akvo.lumen.lib.aes :as aes]
             [akvo.lumen.migrate :as migrate]))

 (defn drop-tenant-db [root-db-uri tenant]
-  (util/exec-no-transact! root-db-uri "DROP DATABASE IF EXISTS \"%s\" " tenant)
+  (try
+    (util/exec-no-transact! root-db-uri "DROP DATABASE IF EXISTS \"%s\" " tenant)
+    (catch Exception e (let [message (.getMessage e)]
+                         (log/error e)
+                         (if (str/includes? message "is being accessed by other users")
+                           (throw (ex-info (format "Right now it's not possible to drop the database %s, there are still active connections to this db, don't hit the web application related, wait for a few minutes, then try again" tenant) {:tenant tenant} e))
+                           (throw e)))))
   (util/exec-no-transact! root-db-uri "DROP ROLE IF EXISTS \"%s\" " tenant))

 (defn create-tenant-db [root-db-uri tenant tenant-password drop-if-exists?]


Add tests for IDeref to identity.

Add tests for IDeref to identity.

--- spec/cats/monad/identity_spec.cljx
+++ spec/cats/monad/identity_spec.cljx
@@ -13,6 +13,9 @@
             [cats.core :as m]))

 (s/describe "identity-monad"
+  (s/it "Test IDeref"
+    (s/should= 1 @(id/identity 1)))
+
   (s/it "Test fmap"
     (s/should= (id/identity 2)
                (m/fmap inc (id/identity 1))))


Add 'all-git-trees function to find all tree objects in a repo.


sort autocomplete of same score by label


bumped version for new figwheel and devcards

--- src/leiningen/new/devcards/project.clj
+++ src/leiningen/new/devcards/project.clj
@@ -7,9 +7,9 @@
   :dependencies [[org.clojure/clojure "1.6.0"]
                  [org.clojure/clojurescript "0.0-2202"]]

-  :profiles { :dev {:dependencies [[devcards "0.1.1-SNAPSHOT"]]
+  :profiles { :dev {:dependencies [[devcards "0.1.2-SNAPSHOT"]]
                     :plugins [[lein-cljsbuild "1.0.3"]
-                              [lein-figwheel "0.1.3-SNAPSHOT"]] }}
+                              [lein-figwheel "0.1.4-SNAPSHOT"]] }}

   :source-paths ["src"]


with-component docs

with-component docs

--- src/main/clojure/trellis/component.clj
+++ src/main/clojure/trellis/component.clj
@@ -4,6 +4,8 @@
   (:use [mikera.cljutils.error]))

 (defmacro with-component
+  "Performs the operations specified by body after starting the given component and binding it to a symbol. Stops
+   the component once complete (in a finally clause)."
   [[sym comp :as v] & body]
   (when-not (and (vector? v) (== 2 (count v))) (error "with-component requires a 2-element binding vector"))
   (when-not (symbol? sym) (error "with-component requires a symbol to bind"))


lein-release plugin: preparing 0.3.29 release

--- re_view/project.clj
+++ re_view/project.clj
@@ -1,4 +1,4 @@
-(defproject re-view "0.3.29-SNAPSHOT"
+(defproject re-view "0.3.29"
   :description "Tiny React wrapper"
   :url "https://www.github.com/braintripping/re-view/tree/master/re_view"
   :license {:name "Eclipse Public License"


Got toggle working again for root world.

--- src/cbfg/vis.cljs
+++ src/cbfg/vis.cljs
@@ -273,26 +273,27 @@
 ;; ------------------------------------------------

 (defn vis-init [world-init-cb el-prefix on-render-cb]
-  (let [event-delay (atom 0)
+  (let [step-ch (chan (dropping-buffer 1))
         event-ch (chan)
-        step-ch (chan (dropping-buffer 1))
+        event-delay (atom 0)
+        render-ch (chan)
         last-id (atom 0)
         gen-id #(swap! last-id inc)
         w [{:gen-id gen-id
             :event-ch event-ch}]
-        vis (atom {:actxs {} ; {actx -> {:children {child-actx -> true},
-                             ;           :wait-chs {ch -> [:ghost|take|:put optional-ch-name])},
-                             ;           :loop-state last-loop-bindings
-                             ;           :closed bool}}.
-                   :chs {}   ; {ch -> {:id (gen-id),
-                             ;         :msgs {msg -> true}
-                             ;         :first-taker-actx actx-or-nil}}.
+        world (conj w "world-1")  ; No ago for world actx init to avoid recursion.
+        vis (atom {:actxs {world {:children {} ; child-actx -> true,
+                                  :wait-chs {} ; ch -> [:ghost|:take|:put optional-ch-name],
+                                  ; :loop-state last-loop-bindings,
+                                  ; :closed bool.
+                                  }}
+                   :chs {} ; {ch -> {:id (gen-id),
+                           ;         :msgs {msg -> true}
+                           ;         :first-taker-actx actx-or-nil}}.
                    :gen-id gen-id})
-        render-ch (chan)
         el-event (str el-prefix "-event")
         el-html (str el-prefix "-html")
-        el-svg (str el-prefix "-svg")
-        world (conj w 'world-1)] ; No ago for world actx init to avoid recursion.
+        el-svg (str el-prefix "-svg")]
     (world-init-cb world)
     (go-loop [num-events 0]      ; Process events from world / simulation.
       (let [[actx [verb step & args]] (<! event-ch)


whitespace for clarity

whitespace for clarity

--- src/babel/italiano/morphology.cljc
+++ src/babel/italiano/morphology.cljc
@@ -124,6 +124,7 @@
       (get-string
        (get-in word '(:a))
        (get-in word '(:b)))
+
       (= :verb (get-in word [:cat]))
       (let [conjugated (verbs/conjugate word)]
         (if (or (nil? conjugated) (empty? conjugated))
@@ -132,6 +133,7 @@
                             (dag_unify.core/strip-refs word)))
             "..")
           conjugated))
+
       ;; TODO: this rule is pre-empting all of the following rules
       ;; that look in :a and :b. Either remove those following rules
       ;; if they are redundant and not needed, or move this general rule
@@ -140,6 +142,7 @@
            (not (= :none (get-in word '(:b) :none))))
       (get-string (get-in word '(:a))
                   (get-in word '(:b)))
+
       (and
        (string? (get-in word '(:a :italiano)))
        (string? (get-in word '(:b :italiano)))


Add text to login-flow buttons

Add text to login-flow buttons

--- src/braid/client/mobile/views.cljs
+++ src/braid/client/mobile/views.cljs
@@ -84,7 +84,7 @@
                             :auto-focus true
                             :on-change (fn [e]
                                          (reset! email (.. e -target -value)))}]]
-            [:button.next {:type "submit"}]]
+            [:button.next {:type "submit"} "Next"]]

            :password
            [:form.content.login.password
@@ -103,7 +103,7 @@
                                :auto-focus true
                                :on-change (fn [e]
                                             (reset! password (.. e -target -value)))}]]
-            [:button.next {:type "submit"}]])
+            [:button.next {:type "submit"} "Next"]])

          :register
          (if-not @email


Improve/add generichash docstrings

Improve/add generichash docstrings

--- src/caesium/crypto/generichash.clj
+++ src/caesium/crypto/generichash.clj
@@ -33,7 +33,7 @@
    buf))

 (defn hash
-  "A friendlier API for generichash.
+  "Hashes a message with optional key using libsodium's generichash primitive.

   This is higher-level than [[hash-to-buf!]] because you don't have to
   allocate your own output buffer."
@@ -46,6 +46,11 @@
      (hash-to-buf! buf msg opts))))

 (defn blake2b-to-buf!
+  "Hashes a message using BLAKE2b into the given buffer. Optionally
+  takes key, salt and personal.
+
+  You only want this to manage the output byte array yourself. Otherwise, you
+  want [[blake2b]]."
   ([buf msg]
    (blake2b-to-buf! buf msg {}))
   ([buf msg {:keys [key salt personal]
@@ -64,6 +69,10 @@
    buf))

 (defn blake2b
+  "Hashes a message using BLAKE2b. Optionally takes key, salt and personal.
+
+  This is higher-level than [[blake2b-to-buf!]] because you don't have to
+  allocate your own output buffer."
   ([msg]
    (blake2b msg {}))
   ([msg {:keys [size] :or {size blake2b-bytes} :as opts}]


fix code blocks ending with a trailing comma

--- src/chat/client/views/helpers.cljs
+++ src/chat/client/views/helpers.cljs
@@ -93,6 +93,14 @@
                (vreset! in-code [])
                (xf result (result-fn (string/join " " code))))

+             (and (= @state ::in-code) (not= -1 (.indexOf input delimiter)))
+             (let [idx (.indexOf input delimiter)
+                   code (conj @in-code (.slice input 0 idx))
+                   after (.slice input (inc idx) (.-length input))]
+               (vreset! state ::start)
+               (vreset! in-code [])
+               (reduce xf result [(result-fn (string/join " " code)) after]))
+
              (= @state ::in-code) (do (vswap! in-code conj input) result)

              :else (xf result input))


fix task naming

fix task naming

--- src/clj/swarmpit/docker/domain.clj
+++ src/clj/swarmpit/docker/domain.clj
@@ -172,10 +172,15 @@
         service (filter/by-id services (:ServiceID task))
         service-name (:serviceName service)
         node (filter/by-id nodes (:NodeID task))
-        node-name (:name node)]
-    (array-map
-      :id (get task :ID)
-      :name (str service-name "." (get task :Slot))
+        node-name (:name node)
+        slot (get task :Slot)
+        id (get task :ID)
+        name (if (= "replicated" (:mode service))
+               (str service-name "." slot "." id)
+               (str service-name "." id))]
+    (sorted-map
+      :id id
+      :name name
       :version (get-in task [:Version :Index])
       :createdAt (get task :CreatedAt)
       :updatedAt (get task :UpdatedAt)


Allow custom schemas passed as symbols (rather than qualified keywords only)

--- src/cljc/mikron/compiler/spec.cljc
+++ src/cljc/mikron/compiler/spec.cljc
@@ -19,7 +19,7 @@
   (cond
     (simple-keyword? schema)    schema
     (vector? schema)            (first schema)
-    (qualified-keyword? schema) :custom))
+    :else                       :custom))

 (defmulti schema-spec
   "Returns a spec for a schema definition."


circle size and link distance depend on width and height

--- src/cljs/ceres_analytics/core.cljs
+++ src/cljs/ceres_analytics/core.cljs
@@ -30,8 +30,8 @@
 (strokes/bootstrap)

 (def graph-state (atom {:svg nil
-                        :width 800
-                        :height 800
+                        :width 2048
+                        :height 2048
                         :frame "#graph-container"
                         :color nil
                         :force nil
@@ -57,15 +57,15 @@
                :y 0
                :width width
                :height height})
-        (style {:stroke "#000000"
+        (style {:stroke "#777777"
                 :fill "none"
-                :stroke-width 5}))))
+                :stroke-width 3}))))

 (defn update-graph
   "Updates nodes and links in graph"
   [state]
-  (let [{:keys [svg width height data force color]} @state
+  (let [{:keys [svg width height data force color circle-size link-dist]} @state
         link (.. svg
                  (selectAll ".link")
                  (data (:links data)))
@@ -84,7 +84,7 @@
                          (call (.-drag force)))]
       (.. node-enter
           (append "svg:circle")
-          (attr {:class "node-stroke" :r 4})
+          (attr {:class "node-stroke" :r circle-size})
           (style {:fill (fn [d] (color (dec (:group d))))
                   :stroke "#fff"}))
       (.. node-enter (append "title") (text (fn [d] (:value d)))))
@@ -105,7 +105,7 @@
     (.. force
         (charge -550)
         (gravity 0.5)
-        (linkDistance 10)
+        (linkDistance link-dist)
         (friction 0.1)
         (size [width height])
         (nodes (:nodes data))
@@ -142,6 +142,8 @@
                                              :id "graph-svg"
                                              :height height})))
     (swap! state assoc-in [:force] force)
+    (swap! state assoc-in [:circle-size] (/ height 256))
+    (swap! state assoc-in [:link-dist] (/ height 128))
     (swap! state assoc-in [:color] ["purple" "steelblue" "orange" "green" "red" ])
     (update-graph state)))


refactoring

refactoring

--- src/cljs/om_next_leaflet/core.cljs
+++ src/cljs/om_next_leaflet/core.cljs
@@ -78,34 +78,21 @@
   [this]
   (-> (om/react-ref this :leaflet) om/get-state :mapobj))

-(defn map-state-change
+(defn change-mapstate
   [this e leaflet-map]
-  (let [center (-> leaflet-map .getCenter leaflet/latlng->clj)
+  (let [event-type (-> e .-type keyword) ;; for debug
+        center (-> leaflet-map .getCenter leaflet/latlng->clj)
         mapstate (map->MapState {:lat (:lat center)
                                  :lng (:lng center)
                                  :zoom (-> leaflet-map .getZoom)
                                  :bounds (-> leaflet-map .getBounds leaflet/bounds->clj)})]
-    (.log js/console (str "[" (-> e .-type) "]"))
+    (.log js/console (str "[" event-type "]"))
     (om/transact! this `[(app/update-mapstate {:new-mapstate ~mapstate})])))
-
-(defn map-callback-dispatch [this e leaflet-map] (-> e .-type keyword))
-
-(defmulti map-callback-fn* map-callback-dispatch)
-(defmethod map-callback-fn* :movestart        [this e leaflet-map] (map-state-change this e leaflet-map))
-(defmethod map-callback-fn* :move             [this e leaflet-map] (map-state-change this e leaflet-map))
-(defmethod map-callback-fn* :moveend          [this e leaflet-map] (map-state-change this e leaflet-map))
-(defmethod map-callback-fn* :zoomlevelschange [this e leaflet-map] (map-state-change this e leaflet-map))
-(defmethod map-callback-fn* :viewreset        [this e leaflet-map] (map-state-change this e leaflet-map))
-(defmethod map-callback-fn* :load             [this e leaflet-map] (map-state-change this e leaflet-map))
-
-(defn map-callback-fn
-  [this e leaflet-map]
-  (map-callback-fn* this e leaflet-map))

 (def init-center [34.6964898 135.4930235])
 (def init-zoom 15)

-(def leaflet-map (om/factory leaflet/Leaflet))
+(def leaflet-map-fn (om/factory leaflet/Leaflet))

 (defn jump-to
   [this lat lng]
@@ -161,36 +148,30 @@
                                           (let [line-id (-> (om/react-ref this "sel1") .-value js/parseInt)]
                                             (om/set-query! this {:params {:line-id line-id}})))}]
                            (map (fn [[id line-name]] [:option {:value (str id)} line-name]) lines)))
-          ;; [:div.row
-          ;;  [:button {:on-click (fn [e] (leaflet/set-center (get-mapobj this)
-          ;;                                (first init-center)
-          ;;                                (second init-center)))} "center"]]
-          ;; [:p "zoom: " (:zoom mapstate)]
           [:div.list-group {:style {:overflow-y "scroll", :height "400px"}}
            (mapv (fn [{:keys [id station-name geometry]}]
-                   (let [[lng lat] geometry
-                         id-str (str id "/" lat "/" lng)]
+                   (let [[lng lat] geometry]
                      [:a.list-group-item.list-group-item-action
                       {:href "#" :key id :on-click (fn [e] (jump-to this lat lng))} station-name]))
                  stations)]]
          [:div.col-xs-9
-          (leaflet-map {:mapid "map"
-                        :ref :leaflet
-                        :center init-center
-                        :zoom init-zoom
-                        :base-layer (leaflet/create-tilelayer "OpenStreetMap"
-                                      "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
-                                      "Map data © OpenStreetMap"
-                                      :maxZoom 18)
-                        :optional-layer (leaflet/create-tilelayer "地理院地図"
-                                          "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"
-                                          "国土地理院")
-                        :event-handlers {:movestart        (partial map-callback-fn this)
-                                         :move             (partial map-callback-fn this)
-                                         :moveend          (partial map-callback-fn this)
-                                         :zoomlevelschange (partial map-callback-fn this)
-                                         :viewreset        (partial map-callback-fn this)
-                                         :load             (partial map-callback-fn this)}})]]]))))
+          (leaflet-map-fn {:mapid "map"
+                           :ref :leaflet ;; referenced from get-mapobj function
+                           :center init-center
+                           :zoom init-zoom
+                           :base-layer (leaflet/create-tilelayer "OpenStreetMap"
+                                         "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
+                                         "Map data © OpenStreetMap"
+                                         :maxZoom 18)
+                           :optional-layer (leaflet/create-tilelayer "地理院地図"
+                                             "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"
+                                             "国土地理院")
+                           :event-handlers {:movestart        (partial change-mapstate this)
+                                            :move             (partial change-mapstate this)
+                                            :moveend          (partial change-mapstate this)
+                                            :zoomlevelschange (partial change-mapstate this)
+                                            :viewreset        (partial change-mapstate this)
+                                            :load             (partial change-mapstate this)}})]]]))))

 (def parser (om/parser {:read read :mutate mutate}))


Memoize enrich text function.

Memoize enrich text function.

--- src/cljs/openslack/views/text.cljs
+++ src/cljs/openslack/views/text.cljs
@@ -29,6 +29,8 @@
                                  (f v)
                                  [v])) %)))
     (filter (complement empty?) @result)))
+
+(def enrich-text (memoize enrich-text))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; String manipulation (maybe for cuerdas?)


Fix logged in page is social/stream

Fix logged in page is social/stream

--- src/cljs/salava/user/ui/login.cljs
+++ src/cljs/salava/user/ui/login.cljs
@@ -14,10 +14,11 @@
   (let [referrer js/document.referrer
         site-url (str (session/get :site-url) (base-path))
         path (if (and referrer site-url) (string/replace referrer site-url ""))]
-    (if (or (empty? path) (= referrer path) (= path (path-for "/user/login")))
-      (if (social-plugin?) "/social/stream" "/badge/mybadges")
-
-      path)))
+    (if (social-plugin?) "/social/stream" "/badge/mybadges")
+    ;(if (or (empty? path) (= referrer path) (= path (path-for "/user/login")))
+     ;"badge/mybadges"
+   ; path)
+  ))

 (defn login [state]
   (let [{:keys [email password]} @state]


Use Java terminology

Use Java terminology

--- src/clojure/nightcode/projects.clj
+++ src/clojure/nightcode/projects.clj
@@ -150,7 +150,7 @@
                (not (.exists (io/file dir "project.clj")))
                (dialogs/show-project-clj-dialog))
       (->> {:app-name (.getName dir)
-            :namespace "put.your.main.namespace.here"}
+            :namespace "put.your.main.class.here"}
            (lein/create-file-from-template dir
                                            "project.clj"
                                            (if (lein/is-android-project? dir)


kw->fn is now found in onyx.static.util

kw->fn is now found in onyx.static.util

--- src/onyx/lifecycle/metrics/metrics.clj
+++ src/onyx/lifecycle/metrics/metrics.clj
@@ -2,7 +2,7 @@
   (:require [clojure.core.async :refer [chan >!! <!! dropping-buffer]]
             [taoensso.timbre :refer [info warn fatal]]
             [clojure.set :refer [rename-keys]]
-            [onyx.peer.operation :refer [kw->fn]]
+            [onyx.static.util :refer [kw->fn]]
             [interval-metrics.core :as im]))

 (def historical-throughput-max-count 1000)


Implement deleting of contacts.

Implement deleting of contacts.

Write the code from the "Intercomponent communication" section of the
tutorial. This code implements the feature that deletes contacts from
our list.

--- basic/om-tut/src/om_tut/core.cljs
+++ basic/om-tut/src/om_tut/core.cljs
@@ -1,6 +1,8 @@
-(ns om-tut.core
+(ns ^:figwheel-always om-tut.core
+  (:require-macros [cljs.core.async.macros :refer [go]])
   (:require [om.core :as om :include-macros true]
-            [om.dom :as dom :include-macros true]))
+            [om.dom :as dom :include-macros true]
+            [cljs.core.async :refer [put! chan <!]]))

 (enable-console-print!)

@@ -26,19 +28,32 @@
   (str last ", " first (middle-name contact)))

 (defn contact-view [contact owner]
-  (reify om/IRender
-    (render [this]
+  (reify om/IRenderState
+    (render-state [this {:keys [delete]}]
       (dom/li nil
               (dom/span nil (display-name contact))
-              (dom/button nil "Delete")))))
+              (dom/button #js {:onClick (fn [e] (put! delete @contact))} "Delete")))))

 (defn contacts-view [data owner]
-  (reify om/IRender
-    (render [this]
+  (reify
+    om/IInitState
+    (init-state [_] {:delete (chan)})
+    om/IWillMount
+    (will-mount [_]
+      (let [delete (om/get-state owner :delete)]
+        (go (loop []
+              (let [contact (<! delete)]
+                (om/transact! data :contacts
+                              (fn [xs]
+                                (vec (remove #(= contact %) xs))))
+                (recur))))))
+    om/IRenderState
+    (render-state [this {:keys [delete]}]
       (dom/div nil
-               (dom/h2 nil "Contact list")
+               (dom/h2 nil "Contact List")
                (apply dom/ul nil
-                      (om/build-all contact-view (:contacts data)))))))
+                      (om/build-all contact-view (:contacts data)
+                                    {:init-state {:delete delete}}))))))

 (om/root contacts-view app-state
          {:target (. js/document (getElementById "contacts"))})
@@ -47,4 +62,4 @@
   ;; optionally touch your app-state to force rerendering depending on
   ;; your application
   ;; (swap! app-state update-in [:__figwheel_counter] inc)
-)
+  )


Stop rendering bar based history view

Stop rendering bar based history view

--- src-cljs/cljs_workspace/om_test.cljs
+++ src-cljs/cljs_workspace/om_test.cljs
@@ -131,11 +131,11 @@
                 (history/save-state (:new-state tx-data)) ; to enable the timeline
                 (put! tx-chan [tx-data root-cursor]))}))}))

-(om/root
-  (fn [app owner]
-    (om/component
-      (dom/div {}
-        (om/build morphic/morph app)
-        history/history-slider)))
-  history/history-view
-  {:target (. js/document (getElementById "inspector"))})+; (om/root
+;   (fn [app owner]
+;     (om/component
+;       (dom/div {}
+;         (om/build morphic/morph app)
+;         history/history-slider)))
+;   history/history-view
+;   {:target (. js/document (getElementById "inspector"))})


Don't feed output with stripped escape codes into terminal colorizer

--- src-cljs/frontend/models/action.cljs
+++ src-cljs/frontend/models/action.cljs
@@ -37,22 +37,29 @@
         starting-state (clj->js (get-in action [:converters-state type]))]
     (js/CI.terminal.ansiToHtmlConverter default-color "brblack" starting-state)))

-(defn maybe-strip-console-codes
+(defn strip-console-codes
   "Strips console codes if output is over 2mb (assuming 2 bytes per char)"
   [message]
-  (if (< (* 1024 1024) (count message))
-    (string/replace message #"\u001B\[[^A-Za-z]*[A-Za-z]" "")
-    message))
+  (string/replace message #"\u001B\[[^A-Za-z]*[A-Za-z]" ""))

 (defn format-output [action output-index]
   (let [output (get-in action [:output output-index])
-        escaped-message (maybe-strip-console-codes (gstring/htmlEscape (:message output)))
-        converter (new-converter action (keyword (:type output)))]
+        html-escaped-message (gstring/htmlEscape (:message output))
+        should-strip? (< (* 1024 1024) (count html-escaped-message))
+        converter (new-converter action (keyword (:type output)))
+        message (if should-strip?
+                  (strip-console-codes html-escaped-message)
+                  (.append converter html-escaped-message))]
     (-> action
-        (assoc-in [:output output-index :converted-message] (.append converter escaped-message))
+        (assoc-in [:output output-index :converted-message] message)
         (assoc-in [:output output-index :react-key] (utils/uuid))
-        (assoc-in [:converters-state (keyword (:type output))] (merge (utils/js->clj-kw (.currentState converter))
-                                                                      {:converted-output (.get_trailing converter)})))))
+        (assoc-in [:converters-state (keyword (:type output))] (if should-strip?
+                                                                 {:color "white"
+                                                                  :italic false
+                                                                  :bold false
+                                                                  :converted-output message}
+                                                                 (merge (utils/js->clj-kw (.currentState converter))
+                                                                        {:converted-output (.get_trailing converter)}))))))

 (defn format-latest-output [action]
   (if-let [output (seq (:output action))]


Fix request message style

Fix request message style

Former-commit-id: b13cb241164699054ae608deaa871e75cf6f64de

--- src/status_im/chat/styles/message.cljs
+++ src/status_im/chat/styles/message.cljs
@@ -131,6 +131,7 @@
 (def command-request-message-view
   {:borderRadius    14
    :padding         12
+   :paddingRight    28
    :backgroundColor color-white})

 (def command-request-from-text


Message queue: simplify scripts

Message queue: simplify scripts

--- src/taoensso/carmine/message_queue.clj
+++ src/taoensso/carmine/message_queue.clj
@@ -78,13 +78,13 @@
     if redis.call('hexists', _:qk-msgs, _:mid) ~= 1 then
       if (now < backoff_exp) then return 'done-with-backoff' end
       return nil
-    else
+    else -- Necessary for `enqueue`
       if redis.call('sismember', _:qk-gc, _:mid) == 1 then
         if (now < backoff_exp) then return 'done-with-backoff' end
         return 'done-awaiting-gc'
-      else
-        if     (now < lock_exp)    then return 'locked'
-        elseif (now < backoff_exp) then return 'retry-backoff' end
+      else -- Necessary for `enqueue`
+        if (now < lock_exp)    then return 'locked'        end
+        if (now < backoff_exp) then return 'retry-backoff' end
         return 'queued'
       end
     end"
@@ -118,23 +118,23 @@
         if (now < backoff_exp) then return 'done-with-backoff' end
         -- return 'done-awaiting-gc'
       else
-        if     (now < lock_exp)    then return 'locked'
-        elseif (now < backoff_exp) then return 'retry-backoff' end
+        if (now < lock_exp)    then return 'locked'        end
+        if (now < backoff_exp) then return 'retry-backoff' end
         return 'queued'
       end
     end
-    ---------------------------------------------------------------------------
+    ---

     redis.call('hset', _:qk-msgs, _:mid, _:mcontent)

     -- lpushnx end-of-circle marker to ensure an initialized mid-circle
-    if redis.call('exists', _:qk-mid-circle) == 0 then
+    if redis.call('exists', _:qk-mid-circle) ~= 1 then
       redis.call('lpush', _:qk-mid-circle, 'end-of-circle')
     end

     redis.call('lpush', _:qk-mid-circle, _:mid)
     return {_:mid} -- Wrap to distinguish from error replies
-    "
+" ; Necessary for Lua script-end weirdness
     {:qk-msgs       (qkey qname :msgs)
      :qk-locks      (qkey qname :locks)
      :qk-backoffs   (qkey qname :backoffs)
@@ -158,49 +158,43 @@
              :or   {lock-ms (* 1000 60 60)
                     eoq-backoff-ms 2000}}]]
   (car/lua
-   "if redis.call('exists', _:qk-eoq-backoff) == 1 then
+   "if redis.call('exists', _:qk-eoq-backoff) == 1 then return 'eoq-backoff' end
+
+    -- TODO Waiting for Lua brpoplpush support to get us long polling
+    local mid = redis.call('rpoplpush', _:qk-mid-circle, _:qk-mid-circle)
+
+    if (not mid) or (mid == 'end-of-circle') then
+      -- Set queue-wide polling backoff flag
+      redis.call('psetex', _:qk-eoq-backoff, _:eoq-backoff-ms, 'true')
+      redis.call('incr',   _:qk-ndry-runs)
       return 'eoq-backoff'
-    else
-      -- TODO Waiting for Lua brpoplpush support to get us long polling
-      local mid = redis.call('rpoplpush', _:qk-mid-circle, _:qk-mid-circle)
-
-      if (not mid) or (mid == 'end-of-circle') then
-        -- Set queue-wide polling backoff flag
-        redis.call('psetex', _:qk-eoq-backoff, _:eoq-backoff-ms, 'true')
-        redis.call('incr', _:qk-ndry-runs)
-        return 'eoq-backoff'
-      end
-
-      if redis.call('sismember', _:qk-gc, mid) == 1 then -- GC
-        redis.call('lrem', _:qk-mid-circle, 1, mid) -- Efficient here
-        redis.call('srem', _:qk-gc,            mid)
-        redis.call('hdel', _:qk-msgs,          mid)
-        redis.call('hdel', _:qk-locks,         mid)
-        redis.call('hdel', _:qk-nattempts,     mid)
-        -- NB do NOT prune :qk_backoffs now, will be used post-handler as a
-        -- dedupe backoff
-        redis.call('set', _:qk-ndry-runs, 0) -- Did work on this run
-        return nil
-      end
-
-      local now         = tonumber(_:now)
-      local lock_exp    = tonumber(redis.call('hget', _:qk-locks,    mid) or 0)
-      local backoff_exp = tonumber(redis.call('hget', _:qk-backoffs, mid) or 0)
-
-      if (now < lock_exp) then return nil -- Active lock
-      else
-        redis.call('hset', _:qk-locks, mid, now + tonumber(_:lock-ms)) -- (Re)acq lock
-      end
-      if (now < backoff_exp) then return nil -- Active backoff
-      else
-        redis.call('hdel', _:qk-backoffs, mid)
-      end
-
-      redis.call('set', _:qk-ndry-runs, 0) -- Did work on this run
-      local mcontent  = redis.call('hget', _:qk-msgs, mid)
-      local nattempts = redis.call('hincrby', _:qk-nattempts, mid, 1)
-      return {mid, mcontent, nattempts}
-    end"
+    end
+
+    if redis.call('sismember', _:qk-gc, mid) == 1 then -- GC
+      redis.call('lrem', _:qk-mid-circle, 1, mid) -- Efficient here
+      redis.call('srem', _:qk-gc,            mid)
+      redis.call('hdel', _:qk-msgs,          mid)
+      redis.call('hdel', _:qk-locks,         mid)
+      --redis.call('hdel', _:qk-backoffs,    mid) -- No! Will use as dedupe backoff
+      redis.call('hdel', _:qk-nattempts,     mid)
+      redis.call('set',  _:qk-ndry-runs, 0) -- Did work
+      return nil
+    end
+
+    local now         = tonumber(_:now)
+    local lock_exp    = tonumber(redis.call('hget', _:qk-locks,    mid) or 0)
+    local backoff_exp = tonumber(redis.call('hget', _:qk-backoffs, mid) or 0)
+
+    -- Active lock/backoff
+    if (now < lock_exp) or (now < backoff_exp) then return nil end
+
+    redis.call('hset', _:qk-locks,    mid, now + tonumber(_:lock-ms)) -- Acquire
+    redis.call('hdel', _:qk-backoffs, mid) -- Expired, so prune
+    redis.call('set',  _:qk-ndry-runs, 0) -- Did work
+
+    local mcontent  = redis.call('hget',    _:qk-msgs,      mid)
+    local nattempts = redis.call('hincrby', _:qk-nattempts, mid, 1)
+    return {mid, mcontent, nattempts}"
    {:qk-msgs        (qkey qname :msgs)
     :qk-locks       (qkey qname :locks)
     :qk-backoffs    (qkey qname :backoffs)


Added credentials and status patterns to config

--- src/strange_coop/components/config.clj
+++ src/strange_coop/components/config.clj
@@ -16,16 +16,20 @@

 (def defaults
   {:nrepl-port 9999
-   :satellite {:url "http://localhost:3000/"}
+   :satellite {:url "http://localhost:3000/"
+               :credentials {:username "fuckshit" :password "stack"}}
    :channels {:buffer-size 100}
    :day-state-machine {:day-threshold   0.13
                        :night-threshold 0.03}
    :pins  {:motor-hb     {:pins   [16 17 18]
-                          :header :P8}}
+                          :header :P8}
            :light-sensor [:P9 33]
            :temp-sensor  [:P9 35]
            :floor-button [:P8 11 :normally-off]
-           :roof-button  [:P8 12 :normally-on]})
+           :roof-button  [:P8 12 :normally-on]}
+   :status-led {:status-patterns {:running  [1500 3000]
+                                  :warnings [1000 1000]
+                                  :errors   [100 50 100 750]}}})

 (defn ->long [x]
   (Long/parseLong x))


Fix scrolling bug in inbox

Fix scrolling bug in inbox

--- src/trustroots/shared/pages/inbox.cljs
+++ src/trustroots/shared/pages/inbox.cljs
@@ -34,10 +34,16 @@
         relative-time (to-now (:updated row))
         ]

-
-    [view {:flex 1 :flex-direction "column"}
-     [ui/card-with-gravatar
-      { :message excerpt
+    ^{:key (:_id row)}
+     [view {
+            ;           :flex 1
+            :flex -1
+            ;           :flex-direction "row"
+            :flex-direction "column"
+            :background-color :yellow
+            :margin 1}
+      [ui/card-with-gravatar
+       { :message excerpt
         :name partner-name
         :time relative-time
         :background-colpropsor bg-color
@@ -51,7 +57,8 @@
   (let [messages (subscribe [:inbox/get])]
     (fn []
       [view {:style { :flex-direction "column"
-                      :margin 20
+                     :margin 20
+                     :flex 1
                      :align-items "stretch"}}
        [list-view-with-subscription messages list-view-item "Messages"]
        [ui/button { :text "Refresh"


Improve CLI Options Handling

Improve CLI Options Handling

--- src/lens/core.clj
+++ src/lens/core.clj
@@ -1,30 +1,61 @@
 (ns lens.core
-  (:require [clojure.tools.cli :as cli]
+  (:require [clojure.string :as str]
+            [clojure.tools.cli :as cli]
             [org.httpkit.server :refer [run-server]]
             [lens.app :refer [app]]
             [lens.util :refer [parse-int]]))

-(defn cli [args]
-  (cli/cli args
-    ["-p" "--port" "Listen on this port" :default 8080 :parse-fn parse-int]
-    ["-i" "--ip" "The IP to bind" :default "0.0.0.0"]
-    ["-t" "--thread" "Number of worker threads" :default 4 :parse-fn parse-int]
-    ["-d" "--database-uri" "The Datomic database URI to use"]
-    ["--token-introspection-uri" "The OAuth2 token inspection URI to use"]
-    ["-c" "--context-path" "An optional context path under which the workbook service runs. Has to start and end with a slash." :default "/"]))
+(def cli-options
+  [["-p" "--port PORT" "Listen on this port" :default 8080 :parse-fn parse-int
+    :validate [#(< 0 % 0x10000) "Must be a number between 0 and 65536"]]
+   ["-i" "--ip IP" "The IP to bind" :default "0.0.0.0"]
+   ["-t" "--thread NUM" "Number of worker threads" :default 4 :parse-fn parse-int
+    :validate [#(< 0 % 64) "Must be a number between 0 and 64"]]
+   ["-d" "--database-uri URI" "The Datomic database URI to use"
+    :validate [#(.startsWith % "datomic")
+               "Database URI has to start with datomic."]]
+   [nil "--token-introspection-uri URI" "The OAuth2 token inspection URI to use"]
+   ["-c" "--context-path PATH" (str "An optional context path under which the "
+                                    "workbook service runs. Has to start and end "
+                                    "with a slash.") :default "/"]
+   ["-h" "--help" "Show this help"]])
+
+(defn usage [options-summary]
+  (->> ["Usage: lens-workbook [options]"
+        ""
+        "Options:"
+        options-summary
+        ""]
+       (str/join "\n")))
+
+(defn error-msg [errors]
+  (str/join "\n" errors))
+
+(defn exit [status msg]
+  (println msg)
+  (System/exit status))

 (defn -main [& args]
-  (let [[options _ banner] (cli args)]
-    (if (and (:database-uri options) (:token-introspection-uri options))
-      (do
-        (run-server (app (:database-uri options)
-                         (:token-introspection-uri options)
-                         (:context-path options))
-                    (merge {:worker-name-prefix "http-kit-worker-"} options))
-        (println "Datomic:" (:database-uri options))
-        (println "OAuth2:" (:token-introspection-uri options))
-        (println "Context Path:" (:context-path options))
-        (println "Server started")
-        (println "Listen at" (str (:ip options) ":" (:port options)))
-        (println "Using" (:thread options) "worker threads"))
-      (println banner))))
+  (let [{:keys [options errors summary]} (cli/parse-opts args cli-options)]
+    (cond
+      (:help options)
+      (exit 0 (usage summary))
+
+      errors
+      (exit 1 (error-msg errors))
+
+      (nil? (:database-uri options))
+      (exit 1 "Missing database URI.")
+
+      (nil? (:token-introspection-uri options))
+      (exit 1 "Missing OAuth2 token inspection URI."))
+
+    (let [{:keys [database-uri token-introspection-uri context-path]} options]
+      (run-server (app database-uri token-introspection-uri context-path)
+                  (merge {:worker-name-prefix "http-kit-worker-"} options))
+      (println "Datomic:" database-uri)
+      (println "OAuth2:" token-introspection-uri)
+      (println "Context Path:" context-path)
+      (println "Server started")
+      (println "Listen at" (str (:ip options) ":" (:port options)))
+      (println "Using" (:thread options) "worker threads"))))


correct solution

correct solution

--- src/hackerrank/time_conversion.clj
+++ src/hackerrank/time_conversion.clj
@@ -43,8 +43,8 @@
 (defn pm-am-time [time]
   (let [hours (hour time)
         time24 (cond
-          (and (pm? time) (not (= hours 12))) (hour-time (+ hours 12) time)
-          (and (am? time) (= hours 12)) (hour-time 0 time)
+          (and (pm? time) (not= hours 12)) (hour-time (+ hours 12) time)
+          (and (am? time) (= hours 12)) (hour-time "00" time)
           :else time)]
     (remove-am-pm time24)))


Use cam abbrev string if unrecognized

Use cam abbrev string if unrecognized

--- src/mars_ogler/scrape.clj
+++ src/mars_ogler/scrape.clj
@@ -1,5 +1,6 @@
 (ns mars-ogler.scrape
-  (:require [clojure.string :as str]
+  (:require [clojure.set :as set]
+            [clojure.string :as str]
             [clj-time.core :as time]
             [clj-time.coerce :as cvt-time]
             [clj-time.format :as fmt-time]
@@ -13,8 +14,7 @@
 ;;

 (def image-attributes
-  #{:w :h :id :url
-    :cam :delay :released :sol :taken-martian :taken-utc :thumbnail :type})
+  (set/union #{:w :h :id :url :cam :delay :sol :thumbnail :type} times/types))

 (defn classify-size
   [{:keys [w h type] :as image}]
@@ -42,8 +42,8 @@
 (defmethod cell->map :camera
   [_ cell]
   (let [abbrev (-> (html/text cell) str/trim)]
-    {:cam (cams/cams-by-abbrev abbrev)
-     :cam-name (cams/cam-names-by-abbrev abbrev)}))
+    {:cam (get cams/cams-by-abbrev abbrev abbrev)
+     :cam-name (get cams/cam-names-by-abbrev abbrev abbrev)}))

 (defmethod cell->map :delay
   [_ cell]


removed comments

removed comments

--- test/examples/mad.clj
+++ test/examples/mad.clj
@@ -105,11 +105,7 @@
 ;(stop)

 ; Now for a Bach challenge:
-; How do we do this:
 ; http://www.sheetmusic1.com/new.great.music/bach.minuet.gmajor/bach.1.demo.gif
-;
-; These are the notes for the right hand in bars (I think), but it's tough to
-; get the timing right.
 (def g-minuet-right-hand [[D5 D5 D5]
                          [B4 [A4 B4] G4]
                          [A4 D5 C5]


Change to defpartial api - for use with mpc/mpd

--- src/moodseer_clj/core.clj
+++ src/moodseer_clj/core.clj
@@ -34,21 +34,40 @@
     [:div#wrapper
     content]]))

+;; (defpartial api [params & [content]]
+;;   (let [params (into {} params)
+;;         cmd (:cmd params)
+;;         resp
+;;         (cond
+;;           (= "play" cmd) (moodseer-clj.process/start-player "-shuffle -playlist /home/gregj/work/all.m3u")
+;;           (= "pause" cmd) (moodseer-clj.process/pause-player)
+;;           (= "stop" cmd) (moodseer-clj.process/pause-player)
+;;           (= "next" cmd) (moodseer-clj.process/next-player)
+;;           (= "prev" cmd) (moodseer-clj.process/prev-player)
+;;           (= "quit" cmd) (moodseer-clj.process/quit-player)
+;;           (= "nowplaying" cmd) (moodseer-clj.process/mplayer-pairs->map (moodseer-clj.process/get-player-track-info)))]
+;;     (if (= "nowplaying" cmd)
+;;       (cheshire.core/generate-string {:status true :message "Hello" :nowplaying resp})
+;;       (cheshire.core/generate-string {:testresponse {:message "WTF honey" :muted false :command  cmd}}))))
+
 (defpartial api [params & [content]]
   (let [params (into {} params)
         cmd (:cmd params)
         resp
         (cond
-          (= "play" cmd) (moodseer-clj.process/start-player "-shuffle -playlist /home/gregj/work/all.m3u")
+          (= "play" cmd) (moodseer-clj.process/play-player)
           (= "pause" cmd) (moodseer-clj.process/pause-player)
           (= "stop" cmd) (moodseer-clj.process/pause-player)
           (= "next" cmd) (moodseer-clj.process/next-player)
           (= "prev" cmd) (moodseer-clj.process/prev-player)
-          (= "quit" cmd) (moodseer-clj.process/quit-player)
-          (= "nowplaying" cmd) (moodseer-clj.process/mplayer-pairs->map (moodseer-clj.process/get-player-track-info)))]
-    (if (= "nowplaying" cmd)
-      (cheshire.core/generate-string {:status true :message "Hello" :nowplaying resp})
-      (cheshire.core/generate-string {:testresponse {:message "WTF honey" :muted false :command  cmd}}))))
+          (= "quit" cmd) nil
+          (= "nowplaying" cmd) (moodseer-clj.process/player-nowplaying)
+          (= "upcoming"   cmd) (moodseer-clj.process/get-player-upcoming))
+        ]
+    (cond
+      (= "nowplaying" cmd) (cheshire.core/generate-string {:status true :message "Hello" :nowplaying resp})
+      (= "upcoming" cmd) (cheshire.core/generate-string {:status true :message "Hello" :upcoming {:songlist resp}})
+      true      (cheshire.core/generate-string {:testresponse {:message "WTF honey" :muted false :command  cmd}}))))

 (defpage "/api:cmd" {:as params}
   (api params))


Added space between employees first name and last name

--- dashboard/src/cljs/dashboard/core.cljs
+++ dashboard/src/cljs/dashboard/core.cljs
@@ -23,7 +23,7 @@
 (defn employee-info [{:keys [lastname firstname]}]
   (om/component
   (dom/li nil
-          (apply dom/span #js {:classname "employee-name"} (str firstname lastname)))))
+          (apply dom/span #js {:classname "employee-name"} (str firstname " " lastname)))))

 (defn department-name [{:keys [department employees]} owner opts]
   (om/component


Joe: Update the test now we've dropped the conversion lib

--- test/build_monitor_clj/parser_test.clj
+++ test/build_monitor_clj/parser_test.clj
@@ -3,12 +3,12 @@
             [midje.sweet :refer :all]))

 (fact "Will split project names with hyphens and underscores in them"
-      (subject/sentanceize "first_second-third-fourthCamel") => "first second third fourth camel")
+      (subject/sentanceize "first_second-third-fourth") => "first second third fourth")

 (fact "will split project name to seperate attributes in map"
       (subject/extract-name "name1 :: test :: deploy")
-      => {:name "name 1" :stage "test" :job "deploy"})
+      => {:name "name1" :stage "test" :job "deploy"})

 (tabular "will say if the build is healthy"
          (fact (subject/extract-health {:lastBuildStatus ?status :activity ?activity}) => {:prognosis ?healthy})


Fix sentry-env var name.

Fix sentry-env var name.

--- src/oc/storage/config.clj
+++ src/oc/storage/config.clj
@@ -19,7 +19,7 @@

 (defonce dsn (or (env :open-company-sentry-storage) false))
 (defonce sentry-release (or (env :sentry-release) ""))
-(defonce sentry-env (or (env :env-name) "local"))
+(defonce sentry-env (or (env :sentry-env) "local"))

 ;; ----- Logging (see https://github.com/ptaoussanis/timbre) -----


renamed 'locals' to 'scratch' for DSL

renamed 'locals' to 'scratch' for DSL

--- test/push/design_spikes/dsl_macros.clj
+++ test/push/design_spikes/dsl_macros.clj
@@ -48,11 +48,11 @@
 ;    store item in `stackname` at position `where` under key `local`
 ;    raise an Exception if it's empty or undefined

-; - `remember-stack [stackname :as local]`
+; + `remember-stack [stackname :as local]`
 ;    save the entire stack to the `local`
 ;    raise an Exception if it's undefined

-; - `place [stackname args kwd]`
+; + `place [stackname args kwd]`
 ;    push the local `kwd` on the named stack
 ;    raise an Exception if it's undefined

@@ -65,40 +65,40 @@
 (def six-ints (make-interpreter :stacks {:integer '(6 5 4 3 2 1)}))

-(defn store-local
-  "stores a local kv pair"
-  [[interpreter locals] k v]
-  (vector interpreter (assoc locals k v)))
-
-
-
-(fact "store-local saves thing to the locals hashmap"
-  (second (store-local [(make-interpreter) {}] :foo 8)) => {:foo 8}
-  (let [foo (store-local [(make-interpreter) {}] :foo 8)]
-    (second (store-local foo :bar 9)) => {:foo 8, :bar 9}))
-
-
-(fact "store-local can overwrite an existing :locals value"
-  (let [foo (store-local [(make-interpreter) {}] :foo 8)]
-    (second (store-local foo :foo 999)) => {:foo 999}))
+
+(defn store-scratch
+  "stores a scratch kv pair; convenience function for DSL"
+  [[interpreter scratch] k v]
+  (vector interpreter (assoc scratch k v)))
+
+
+(fact "store-scratch saves thing to the scratch hashmap"
+  (second (store-scratch [(make-interpreter) {}] :foo 8)) => {:foo 8}
+  (let [foo (store-scratch [(make-interpreter) {}] :foo 8)]
+    (second (store-scratch foo :bar 9)) => {:foo 8, :bar 9}))
+
+
+(fact "store-scratch can overwrite an existing :scratch value"
+  (let [foo (store-scratch [(make-interpreter) {}] :foo 8)]
+    (second (store-scratch foo :foo 999)) => {:foo 999}))

 (defn consume
-  [[interpreter locals] stack & {:keys [as]}]
+  [[interpreter scratch] stack & {:keys [as]}]
   (let [old-stack (get-stack interpreter stack)]
     (cond (empty? old-stack)
             (throw (Exception. (str "Push DSL Error: " stack " is empty")))
           (nil? as)
-            [(set-stack interpreter stack (pop old-stack)) locals]
+            [(set-stack interpreter stack (pop old-stack)) scratch]
           :else
-            (store-local
-              [(set-stack interpreter stack (pop old-stack)) locals]
+            (store-scratch
+              [(set-stack interpreter stack (pop old-stack)) scratch]
               as
               (first old-stack)))))

 (defn get-stack-from-dslblob ;; convenience for testing only
-  [[interpreter locals] stackname]
+  [[interpreter scratch] stackname]
   (get-stack interpreter stackname))

@@ -131,14 +131,14 @@

 (defn place
-  "pushes a named local onto a given stack"
-  [[interpreter locals] stack kwd]
-  (let [item (kwd locals)
+  "pushes a named scratch value onto a given stack"
+  [[interpreter scratch] stack kwd]
+  (let [item (kwd scratch)
         updated (push-item interpreter stack item)]
-  (into [] (list updated locals))))
-
-
-(fact "`place` will push the saved local value to the indicated stack in the interpreter"
+  (vector updated scratch)))
+
+
+(fact "`place` will push the saved scratch value to the indicated stack in the interpreter"
   (let [integer-added (-> [six-ints {}]
                           (consume :integer :as :int1)
                           (consume :integer :as :int2)
@@ -147,14 +147,14 @@

 (defn remember-calc
-  [[interpreter locals] args function & {:keys [as]}]
-  (if (nil? as)
-    (vector interpreter locals)
-    (let [result (apply function (map locals args))]
-      (vector interpreter (assoc locals as result)))))
-
-
-(fact "remember-calc stores the result of a calculation in a named local"
+  [[interpreter scratch] args function & {:keys [as]}]
+  (if (nil? as)
+    (vector interpreter scratch)
+    (let [result (apply function (map scratch args))]
+      (vector interpreter (assoc scratch as result)))))
+
+
+(fact "remember-calc stores the result of a calculation in a named scratch"
   (let [integer-added (-> [six-ints {}]
                           (consume :integer :as :int1)
                           (consume :integer :as :int2)
@@ -171,11 +171,11 @@

 (defn remember-top
-  [[interpreter locals] stackname & {:keys [as]}]
-  (if (nil? as)
-    (vector interpreter locals)
+  [[interpreter scratch] stackname & {:keys [as]}]
+  (if (nil? as)
+    (vector interpreter scratch)
     (let [result (first (get-stack interpreter stackname))]
-      (into [] (list interpreter (assoc locals as result))))))
+      (vector interpreter (assoc scratch as result)))))

 (fact "remember-top stores the top item of a named stack"
@@ -195,13 +195,13 @@

 (defn remember-nth
-  [[interpreter locals] stackname & {:keys [as at]}]
-  (if (nil? as)
-    (vector interpreter locals)
+  [[interpreter scratch] stackname & {:keys [as at]}]
+  (if (nil? as)
+    (vector interpreter scratch)
     (let [stack (get-stack interpreter stackname)
           which (mod (or at 0) (count stack))
           result (nth stack which)]
-      (into [] (list interpreter (assoc locals as result))))))
+      (vector interpreter (assoc scratch as result)))))

 (fact "remember-nth stores the nth item of a named stack"
@@ -229,11 +229,11 @@

 (defn remember-stack
-  [[interpreter locals] stackname & {:keys [as at]}]
-  (if (nil? as)
-    (vector interpreter locals)
+  [[interpreter scratch] stackname & {:keys [as at]}]
+  (if (nil? as)
+    (vector interpreter scratch)
     (let [stack (get-stack interpreter stackname)]
-      (into [] (list interpreter (assoc locals as stack))))))
+      (vector interpreter (assoc scratch as stack)))))

 (fact "remember-stack stores the stack specified in the :as variable"
   (let [integer-munged (-> [six-ints {}]


fix merge skew

fix merge skew

Signed-off-by: Eric Baur <a1c9c5f8609c68027db0779b39e5f932d4cb0053@robeybaur.org>

--- src/obcc/core.clj
+++ src/obcc/core.clj
@@ -48,11 +48,11 @@
           (:help options)
           (exit 0 (usage summary))

+          (not= errors nil)
+          (exit -1 "Error: " (string/join errors))
+
           (:version options)
           (exit 0 (version))
-
-          (not= errors nil)
-          (exit -1 "Error: " (string/join errors))

           (= (count arguments) 0)
           (exit 0 (usage summary))


Reflow docstring

Reflow docstring

--- src/caesium/magicnonce/secretbox.clj
+++ src/caesium/magicnonce/secretbox.clj
@@ -103,9 +103,9 @@
   messages will not repeat or you can't rely on encryption-time
   randomness, consider [[secrebox-nmr]].

-  To decrypt, use [[decrypt]] or [[open]], depending on which argument order
-  you prefer."
   [msg key])
+  To decrypt, use [[decrypt]] or [[open]], depending on which argument
+  order you prefer."
 (defn ^:private xor!
   "Populates `out` with the XOR of matching elements in `a`, `b`.


CW | 22 | add denying app test

CW | 22 | add denying app test

--- test/stonecutter_journey_test/test.clj
+++ test/stonecutter_journey_test/test.clj
@@ -50,6 +50,9 @@
 (def stonecutter-register-create-profile-button ".func--create-profile__button")
 (def stonecutter-profile-created-page-body ".func--profile-created-page")
 (def stonecutter-authorise-page-body ".func--authorise-page")
+(def stonecutter-authorise-failure-body ".func--authorise-failure-page")
+(def stonecutter-authorise-cancel-link ".func--authorise-cancel__link")
+(def stonecutter-authorise-return-to-client-link ".func--redirect-to-client-home__link")
 (def stonecutter-authorise-share-profile-button ".func--authorise-share-profile__button")
 (def stonecutter-delete-account-page-body ".func--delete-account-page")
 (def stonecutter-delete-account-button ".func--delete-account__button")
@@ -145,7 +148,18 @@
           (screenshot "stonecutter_authorisation_form")
           (wd/current-url) => (contains "stonecutter.herokuapp.com/authorisation"))

+    (fact "denying app redirects to home page"
+          (wd/click stonecutter-authorise-cancel-link)
+          (wait-for-selector stonecutter-authorise-failure-body)
+          (screenshot "sstonecutter_authorise_failure")
+          (wd/click stonecutter-authorise-return-to-client-link)
+          (wait-for-selector client-home-page-body)
+          (wd/current-url) => (contains "stonecutter-client.herokuapp.com/voting")
+          (wd/page-source) =not=> (contains "stonecutter-journey-test@tw.com"))
+
     (fact "authorising app redirects to voting page"
+          (wd/click "button")
+          (wait-for-selector stonecutter-authorise-page-body)
           (wd/click stonecutter-authorise-share-profile-button)
           (wait-for-selector client-poll-page-body)
           (screenshot "client_voting_page")


Some cosmetic changes to pepa.web.handlers

--- src/pepa/web/handlers.clj
+++ src/pepa/web/handlers.clj
@@ -320,14 +320,6 @@
   :handle-created (fn [{documents ::documents}]
                     (zipmap (map :id documents) documents)))

-(defn wrap-component [handler {:keys [config db bus] :as web}]
-  (fn [req]
-    (handler (assoc req
-                    :pepa/web web
-                    :pepa/config config
-                    :pepa/db db
-                    :pepa/bus bus))))
-
 (def handlers
   (routes (GET "/" [] (html/root))
           (ANY "/inbox" [] inbox)
@@ -379,16 +371,24 @@
              :body "Malformed request."})))
       (handler req))))

-(defn wrap-logging [handler]
+(defn wrap-request-logging [handler]
   (fn [req]
     (when (get-in req [:pepa/config :web :log-requests?])
       (pprint req))
     (handler req)))
+
+(defn wrap-component [handler {:keys [config db bus] :as web}]
+  (fn [req]
+    (handler (assoc req
+                    :pepa/web web
+                    :pepa/config config
+                    :pepa/db db
+                    :pepa/bus bus))))

 (defn make-handlers [web-component]
   (-> #'handlers
       ;; NOTE: *first* transit, then JSON
       (wrap-transit-body)
       (wrap-params)
-      (wrap-logging)
+      (wrap-request-logging)
       (wrap-component web-component)))


Fix bug

Fix bug

--- src/checkin_halake/models/ticket.clj
+++ src/checkin_halake/models/ticket.clj
@@ -10,10 +10,10 @@

 (defn add-ticket-to-user [user ticket-type count]
   (let [ticket-key (str "tickets." ticket-type)]
-    (mc/update db "users" {:_id (:id user)} {mo/$inc {ticket-key count}})))
+    (mc/update db "users" {:_id (:_id user)} {mo/$inc {ticket-key count}})))

 (defn use-ticket [user ticket-type]
   (let [ticket-key (str "tickets." ticket-type)]
-    (mc/update db "users" {:_id (:id user) mo/$gt {ticket-type 0}} {mo/$inc {ticket-key -1}})))
+    (mc/update db "users" {:_id (:_id user) ticket-key {mo/$gt 0}} {mo/$inc {ticket-key -1}})))


hack for making centering work.

hack for making centering work.

--- src/play_clj/entities.clj
+++ src/play_clj/entities.clj
@@ -21,10 +21,10 @@

 (defrecord TextureEntity [object] Entity
   (draw! [{:keys [^TextureRegion object x y width height
-                  scale-x scale-y angle origin-x origin-y]}
-          _
-          batch]
-    (let [x (float (or x 0))
+                         scale-x scale-y angle origin-x origin-y]}
+                 _
+                 batch]
+    (let [x (- (float (or x 0)) (* (float (or origin-x 0.0)) (float (or scale-x 1.0))))
           y (float (or y 0))
           width (float (or width (.getRegionWidth object)))
           height (float (or height (.getRegionHeight object)))]


Fixed typo in resource.

Fixed typo in resource.

--- src/cljc/cmr/client/search/impl.cljc
+++ src/cljc/cmr/client/search/impl.cljc
@@ -57,12 +57,12 @@
   ([this concept-id http-options]
    (-> this
        :http-client
-       (http/get (base/get-url this (str "/concept/" concept-id))
+       (http/get (base/get-url this (str "/concepts/" concept-id))
                  http-options)))
   ([this concept-id revision-id http-options]
    (-> this
        :http-client
-       (http/get (base/get-url this (str "/concept/"
+       (http/get (base/get-url this (str "/concepts/"
                                          concept-id
                                          "/"
                                          revision-id))


fix indenting on phone-sub

fix indenting on phone-sub

--- src/cljs/phonecat_re_frame/core.cljs
+++ src/cljs/phonecat_re_frame/core.cljs
@@ -14,9 +14,9 @@
 ;; Re-frame data

 (re-frame/register-sub        ;; a new subscription handler
-   :phones             ;; usage (subscribe [:phones])
-   (fn [db]
-     (reaction (:phones @db))))  ;; pulls out :phones
+ :phones             ;; usage (subscribe [:phones])
+ (fn [db]
+   (reaction (:phones @db))))  ;; pulls out :phones

 (re-frame/register-sub
  :search-input


Switch from perspective to ortho view matrix

--- src/cljs/robinson/webglterminal.cljs
+++ src/cljs/robinson/webglterminal.cljs
@@ -116,13 +116,15 @@
         vertex-shader (shaders/get-shader gl "shader-vs")]
   (shaders/create-program gl fragment-shader vertex-shader)))

-(defn get-perspective-matrix [gl]
+(defn get-ortho-matrix [gl]
   (let [viewport-width (context/get-drawing-buffer-width gl)
         viewport-height (context/get-drawing-buffer-height gl)]
-    (mat4/perspective
+    (mat4/ortho
       (mat4/create)
-      45
-      (/ viewport-width viewport-height)
+      0
+      viewport-width
+      viewport-height
+      0
       0.1
       100.0)))

@@ -162,19 +164,19 @@
       shader-prog         (init-shaders gl)
       square-vertex-buffer
         (buffers/create-buffer gl
-          (ta/float32 [1.2, 1.6, 0.0,
-                       0.0, 1.6, 0.0,
-                       1.2, 0.0, 0.0,
-                       0.0, 0.0, 0.0])
+          (ta/float32 [12.0, 16.0, 0.0,
+                       0.0,  16.0, 0.0,
+                       12.0, 0.0,  0.0,
+                       0.0,  0.0,  0.0])
           buffer-object/array-buffer
           buffer-object/static-draw
           3)
       square-texture-buffer
         (buffers/create-buffer gl
-          (ta/float32 [u1 v0
-                       u0 v0
-                       u1 v1
-                       u0 v1])
+          (ta/float32 [u1 v1
+                       u0 v1
+                       u1 v0
+                       u0 v0])
           buffer-object/array-buffer
           buffer-object/static-draw
           2)
@@ -189,8 +191,8 @@
       :count (.-numItems square-vertex-buffer)
       :attributes [{:buffer square-vertex-buffer :location vertex-position-attribute}
                    {:buffer square-texture-buffer :location texture-coord-attribute}]
-      :uniforms [{:name "uPMatrix" :type :mat4 :values (get-perspective-matrix gl)}
-                 {:name "uMVMatrix" :type :mat4 :values (get-position-matrix [1.5 0.0 -5.0])}]
+      :uniforms [{:name "uPMatrix" :type :mat4 :values (get-ortho-matrix gl)}
+                 {:name "uMVMatrix" :type :mat4 :values (get-position-matrix [12.0 16.0 -1.0])}]
       :textures [{:name "uSampler" :texture characters-texture}]))))

 ;; Normally this would be a record, but until http://dev.clojure.org/jira/browse/CLJ-1224 is fixed


Temporary work-around for data readers issue.

--- src/clojure/parkour/remote/basic.clj
+++ src/clojure/parkour/remote/basic.clj
@@ -2,7 +2,7 @@
   {:private true}
   (:require [clojure.string :as str]
             [clojure.edn :as edn]
-            [parkour (conf :as conf)]
+            [parkour (conf :as conf) (fs :as fs)]
             [parkour.util :refer [doto-let]]))

 (defn ^:private step-f-args


working on attempt-each

working on attempt-each

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@8841 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

--- acqEngine/src/org/micromanager/mm.clj
+++ acqEngine/src/org/micromanager/mm.clj
@@ -142,13 +142,19 @@
     `(if (and ~@args_)
       (~f ~@args_))))

-(defn try-each [fns]
+(defn attempt-each-fn [fns]
   "Attempt to run each fn in fns, and if they fail,
    then report at end."
   (let [errs (atom nil)]
     (doseq [fun fns]
       (try (fun)
-           (catch Throwable t (swap! errs conj t))))))
+           (catch Throwable t (swap! errs conj t))))
+    (when-let [first-err (first @errs)]
+      (throw first-err))))
+
+(defmacro attempt-each
+  [& body]
+  `(map #(fn [] %) '~body))

 (defn get-default-devices
   "Get the list of default (core) devices."


scroll functions added

scroll functions added

--- src/etaoin/api.clj
+++ src/etaoin/api.clj
@@ -1069,8 +1069,28 @@
     (:value resp)))

 ;;
-;; execute js
-;;
+;; Javascript
+;;
+
+(defn el-to-js
+  "Turns machinery-wise element ID into an object
+  that Javascript use to reference existing DOM element.
+
+  The magic constant below is taken from the standard:
+  https://www.w3.org/TR/webdriver/#elements
+
+  Passing such an object to `js-execute` automatically expands into a
+  DOM node. For example:
+
+  ;; returns long UUID
+  (def el (query driver :button-ok))
+
+  ;; the first argument will the an Element instance.
+  (js-execute driver \"arguments[0].scrollIntoView()\", (el-to-js el))
+  "
+  [el]
+  {:ELEMENT el
+   :element-6066-11e4-a52e-4f735466cecf el})

 (defmulti js-execute
   "Executes Javascript code in browser synchronously.
@@ -1134,6 +1154,59 @@
              "s.src = arguments[0];"
              "document.head.appendChild(s);")]
     (js-execute driver script url)))
+
+;;
+;; scrolling
+;;
+
+(defn scroll
+  "Scrolls the window into absolute position (jumps to exact place)."
+  ([driver x y]
+   (js-execute driver "window.scroll(arguments[0], arguments[1]);" x y))
+  ([driver {:keys [x y]}]
+   (scroll driver x y)))
+
+(defn scroll-by
+  "Scrolls the window by offset (relatively the current position)."
+  ([driver x y]
+   (js-execute driver "window.scrollBy(arguments[0], arguments[1]);" x y))
+  ([driver {:keys [x y]}]
+   (scroll-by driver x y)))
+
+(defn scroll-query
+  "Scrolls to the first element found with a query.
+
+  Invokes element's `.scrollIntoView()` method. Accepts extra `param`
+  argument that might be either boolean or object for more control.
+
+  See this page for details:
+  https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
+  "
+  ([driver q]
+   (let [el (query driver q)]
+     (js-execute driver "arguments[0].scrollIntoView();" (el-to-js el))))
+  ([driver q param]
+   (let [el (query driver q)]
+     (js-execute driver "arguments[0].scrollIntoView(arguments[1]);" (el-to-js el) param))))
+
+(defn get-scroll
+  "Returns the current scroll position as a map
+  with `:x` and `:y` keys and integer values."
+  [driver]
+  (js-execute driver "return {x: window.scrollX, y: window.scrollY};"))
+
+(defn scroll-top
+  "Scrolls to top of the page keeping current horizontal position."
+  [driver]
+  (let [{:keys [x y]} (get-scroll driver)]
+    (scroll driver x 0)))
+
+(defn scroll-bottom
+  "Scrolls to bottom of the page keeping current horizontal position."
+  [driver]
+  (let [y-max (js-execute driver "return document.body.scrollHeight;")
+        {:keys [x y]} (get-scroll driver)]
+    (scroll driver x y-max)))

 ;;
 ;; get/set hash


update example to 0.2.3

update example to 0.2.3

--- example/project.clj
+++ example/project.clj
@@ -8,19 +8,22 @@
                  [sablono "0.2.16"]
                  [crate "0.2.4"]
                  [jayq "2.4.0"]
-                 [figwheel "0.2.2-SNAPSHOT"]]
+                 [figwheel "0.2.3-SNAPSHOT"]
+                 ;; for development
+                 [figwheel-sidecar "0.2.3-SNAPSHOT"]]

   :plugins [[lein-ring "0.8.13"]
             [lein-cljsbuild "1.0.4"]
-            [lein-figwheel "0.2.2-SNAPSHOT"]]
+            [lein-figwheel "0.2.3-SNAPSHOT"]]

   ;; this is used for testing an external server
   :ring { :handler example.server/static-server }

   :source-paths ["src"]

-  ;; :clean-targets ["resources/public/js/compiled"]
-
+  :clean-targets ^{:protect false} ["resources/public/js/compiled/out"
+                                    "resources/public/js/compiled/example.js"]
+
   :resource-paths ["resources" "other_resources"]

   :cljsbuild {


fix cache issue when using :minimize-require true

--- src/main/shadow/build/compiler.clj
+++ src/main/shadow/build/compiler.clj
@@ -1042,7 +1042,7 @@
   "populates :cache-key of the resource with the resolved symbols of its deps
    to ensure recompilation when their names change"
   [state resource-id]
-  (let [rc (data/get-source-by-id state resource-id)
+  (let [{:keys [require-id] :as rc} (data/get-source-by-id state resource-id)
         deps-syms (data/deps->syms state rc)

         require-ids
@@ -1053,9 +1053,16 @@

     (update-in state [:sources resource-id :cache-key]
       (fn [key]
-        (->> (into key (concat deps-syms require-ids))
-             (distinct)
-             (into []))))))
+        ;; FIXME: this still isn't clean but nothing should be allowed to modify
+        ;; cache-key beyond this point
+        ;; must make sure we don't keep appending the same data in watch
+        (-> (take-while #(not= ::resolve %) key)
+            (vec)
+            (conj
+              ::resolve
+              {:require-id require-id
+               :deps-ids require-ids
+               :deps-syms deps-syms}))))))

 (defn throw-js-errors-now! [state]
   (doseq [{:keys [file js-errors source] :as src} (data/get-build-sources state)
@@ -1101,7 +1108,7 @@
           ;;
           ;; wonder if there is something that is gzip-friendly but also cache-friendly

-          (let [alias idx #_ (subs (util/md5hex (str ns)) 0 6)]
+          (let [alias idx #_(subs (util/md5hex (str ns)) 0 6)]
             (-> state
                 (update-in [:sources src-id] assoc :require-id alias)
                 (assoc-in [:require-id->sym alias] ns)


shopping-cart: more asserts

shopping-cart: more asserts

--- examples/shopping-cart/src/app/controller.cljs
+++ examples/shopping-cart/src/app/controller.cljs
@@ -7,7 +7,7 @@
   [shop]
   {:pre [(satisfies? api/ShopAPIProtocol shop)]}
   (fn control
-    [_model signal dispatch]
+    [model signal dispatch]
     (println "signal" signal)
     (match signal
            :on-get-all-products
@@ -16,10 +16,13 @@
                              #(dispatch :receive-products-error))

            [:on-add-to-cart id]
-           (dispatch [:add-to-cart id])
+           (do
+             (assert (not (:checking-out? model)))
+             (dispatch [:add-to-cart id]))

            :on-checkout
            (do
+             (assert (not (:checking-out? model)))
              (dispatch :checkout-request)
              (api/buy-products shop
                                "<orders data from model>"


Bind non-namespaced parameter vars to namespaced keys as a fallback

This allows to bind [?foo ?bar] to e.g. {:x/foo {:y/bar <val>}}
and makes the notation for parameterizing against deeply nested
parameter maps even more compact than it already is.

--- src/main/workflo/macros/query.cljc
+++ src/main/workflo/macros/query.cljc
@@ -172,12 +172,22 @@
           (path? [x]
             (and (vector? x)
                  (every? var? x)))
+          (denamespace-keys [m]
+            (if (map? m)
+              (zipmap (map (comp keyword name) (keys m))
+                      (vals m))
+              m))
+          (resolve-var [vname params]
+            (let [kw (keyword vname)]
+              (or (get params kw)
+                  (when (nil? (namespace kw))
+                    (get (denamespace-keys params) kw)))))
           (bind-path [path params]
             (loop [path path params params]
               (let [[var & remainder] path
                     vname (when (var? var)
                             (subs (str var) 1))]
-                (let [val (get params (keyword vname))]
+                (let [val (resolve-var vname params)]
                   (if (empty? remainder)
                     val
                     (recur remainder val))))))


Fix email retrieve.

Fix email retrieve.

--- src/oc/email/async/ses_monitor.clj
+++ src/oc/email/async/ses_monitor.clj
@@ -70,7 +70,7 @@
   (timbre/debug "About to flag for hard bounce:" recipients)
   (doseq [recipient recipients]
     (timbre/debugf "Lookup user with email %s" recipient)
-    (let [email-rec (bounced-email/retrieve-email recipient)
+    (let [email-rec (bounced-email/retrieve-email c/dynamodb-opts recipient)
           msg (bounce-msg recipient email-rec)]
       (when (bounced-email/store-hard-bounce! recipient)
         (if (repeated-bounce? email-rec)


Parse out commas from search terms

Parse out commas from search terms

--- src/kevin/core.clj
+++ src/kevin/core.clj
@@ -44,7 +44,7 @@
   This maps to Lucene's QueryParser.parse
   See http://lucene.apache.org/core/3_6_1/api/core/org/apache/lucene/queryParser/QueryParser.html"
   [query]
-  (->> (split query #"\s")
+  (->> (split query #",?\s+")
        (remove str/blank?)
        (map #(str "+" % "*"))
        (join " ")))


Added  function and removed old crufty parsing functions from cljsv

--- src/semantic_csv/core.clj
+++ src/semantic_csv/core.clj
@@ -217,23 +217,27 @@
 ;;         (parse-and-process in-file)))

-
-(defn read-csv-file
-  "Read csv in from a filename or file handle. For details see the docstring for read-csv-rows"
-  [file-or-filename & opts]
-  (if (string? file-or-filename)
-    (with-open [f (io/reader file-or-filename)]
+;; ## slurp-and-process
+
+(defn slurp-and-process
+  "This convenience function let's you `parse-and-process` csv data given a csv filename."
+  [csv-filename & {:as opts}]
+  (let [rest-options (dissoc opts :parser-opts)]
+    (with-open [in-file (io/reader csv-filename)]
       (doall
-        ;; Trying out internal doc
-        (impl/apply-kwargs read-csv-file f opts)))
-    (impl/apply-kwargs read-csv-rows (line-seq file-or-filename) opts)))
-
-
-(defn read-csv-str
-  "Read csv in from a csv string. For details see the docstring for read-csv-rows"
-  [csv-str & opts]
-  (impl/apply-kwargs read-csv-rows (clojure.string/split-lines csv-str) opts))
-
+        (impl/apply-kwargs parse-and-process in-file opts)))))
+
+;; And now, for the ultimate in programmer laziness at the sacrifice of _program_ laziness:
+;;
+;;     (slurp-and-process "test/test.csv")
+
+
+;; ## Caveat Emptor...
+;;
+;; But before you go, we encourage you to use the less heavy handed of these methods.
+;; Magick can be nice sometimes, but is best when used in moderation.
+;; And Clojure is all about composability and modularity, so consider this libraries emphasis to be on the
+;; individual, single goal processing functions.

 ;; # Some parsing functions for your convenience


1.1.3  Evaluating Combinations

1.1.3  Evaluating Combinations

--- src/sicp/chapter1/1_3.clj
+++ src/sicp/chapter1/1_3.clj
@@ -3,3 +3,6 @@
 ;;;; 1.1  The Elements of Programming

 ;;; 1.1.3  Evaluating Combinations
+
+(* (+ 2 (* 4 6))
+   (+ 3 5 7))


Group by artist, album, title

Group by artist, album, title

--- src/single_track/core.clj
+++ src/single_track/core.clj
@@ -22,10 +22,19 @@
                {:trackLength :track-length :bitRateAsNumber :bit-rate}))

 (defn convert-longs [m & ks]
-  (apply assoc m (mapcat #(vector % (try (Long/parseLong (m %)) (catch Exception e nil))) ks)))
+  (apply assoc m (mapcat
+                   (fn [k] (vector k (try (Long/parseLong (m k))
+                                          (catch Exception e nil))))
+                   ks)))

 (def tags
-  [FieldKey/ALBUM FieldKey/ARTIST FieldKey/TITLE FieldKey/TRACK FieldKey/ALBUM_ARTIST FieldKey/GENRE FieldKey/YEAR])
+  [FieldKey/ALBUM
+   FieldKey/ARTIST
+   FieldKey/TITLE
+   FieldKey/TRACK
+   FieldKey/ALBUM_ARTIST
+   FieldKey/GENRE
+   FieldKey/YEAR])

 (defn tag-val [tag tagname]
   [(->kebab-case-keyword (.name tagname)) (.getFirst tag tagname)])
@@ -68,11 +77,33 @@

 (defn all? [& fns] (fn [x] (every? #(% x) fns)))

+(defn filtered [dir]
+  (filter (all? file? audio?) (visible-file-seq (io/file dir))))
+
+(defn put
+  ([m k v]
+   (if-let [cv (get m k)]
+     (if (vector? cv)
+       (assoc m k (conj cv v))
+       (assoc m k (vector cv v)))
+     (assoc m k v)))
+  ([m [k v]]
+   (put m k v)))
+
+(defn put-af
+  [m {:keys [:artist :album :title] :as v}]
+  (put m [artist album title] v))
+
+(defn af-key [{:keys [:artist :album :title] :as v}]
+  [artist album title])
+
+(defn entry [v]
+  (vector (af-key v) v))
+
 (defn -main
   ([] (-main "."))
   ([dir]
    (set-logger-level! "org.jaudiotagger" Level/OFF)
-   (doseq [^File f (filter (all? file? audio?) (visible-file-seq (io/file dir)))]
-     (pprint (metadata f)))))
+   (reduce put {} (map entry (filtered dir)))))

 #_(-main)


Corrected string in an assertion.

Corrected string in an assertion.

In the function concept-robustness, the assertion that 'sorted?' is a boolean had a wrong output-string.

--- src/main/clojure/conexp/fca/more.clj
+++ src/main/clojure/conexp/fca/more.clj
@@ -297,7 +297,7 @@
    This function uses the function concept-robustness-polynomial."
   ([concept concepts alpha sorted?]
    (assert (<= 0 alpha 1) "Third argument must be between 0 and 1!")
-   (assert (or (true? sorted?) (false? sorted?)) "Fourth argument must be between 0 and 1!")
+   (assert (or (true? sorted?) (false? sorted?)) "Fourth argument must be a boolean value!")
    (eval-polynomial (concept-robustness-polynomial concept concepts sorted?) (- 1 alpha)))
   ([concept concepts alpha]
    (concept-robustness concept concepts alpha false)))


Fix error message for missing query server

--- src/onyx/query.clj
+++ src/onyx/query.clj
@@ -10,15 +10,16 @@
   (stop [this]
     (assoc this :replica nil)))

-(defmulti query-server (fn [peer-config]
-                         (boolean (:onyx.query/server? peer-config))))
+(defmulti query-server
+  (fn [peer-config]
+    (boolean (:onyx.query/server? peer-config))))

 (defmethod query-server false [_]
   (map->DummyQueryServer {}))

 (defmethod query-server :default [peer-config]
   (throw (ex-info (str "No http query server implementation found. "
-                       "Did you include org.onyxplatform/onyx-node-query in your dependencies "
+                       "Did you include org.onyxplatform/onyx-peer-http-query in your dependencies "
                        "and require onyx.http-query in your peer bootup namespace?")
                   {:peer-config peer-config})))


Drop get-spec.

Drop get-spec.

--- src/onyx/spec.cljc
+++ src/onyx/spec.cljc
@@ -149,22 +149,26 @@

 (s/def :flow/from
   (s/or :task-name keyword?
-        :special-task (s/get-spec :flow/special-tasks)))
+        :special-task :flow/special-tasks))

 (s/def :flow/to
   (s/or :task-name keyword?
         :task-names (s/coll-of keyword? :kind vector?)
-        :special-task (s/get-spec :flow/special-tasks)))
+        :special-task :flow/special-tasks))

 (s/def :flow/predicate
-  (s/or :keyword keyword?
-        :coll (s/coll-of any? :kind vector?)))
+  (s/or :and (s/cat :op #{:and} :exprs (s/+ :flow/predicate))
+        :or (s/cat :op #{:or} :exprs (s/+ :flow/predicate))
+        :not (s/cat :op #{:not} :exprs (s/cat :pred :flow/predicate))
+        :fn keyword?
+        :fn-and-args (s/cat :fn (fn [x]
+                                  (and (keyword? x)
+                                       (not (some #{x} #{:and :or :not}))))
+                            :args (s/* keyword?))))

 (s/def :flow/post-transform namespaced-keyword?)

 (s/def :flow/thrown-exception? boolean?)
-
-(s/def :flow/action (s/get-spec :flow/action))

 (s/def :flow/short-circuit? boolean?)

@@ -183,7 +187,7 @@
                 :flow/short-circuit]))

 (s/def :job/flow-conditions
-  (s/coll-of (s/get-spec :flow/condition)
+  (s/coll-of :flow/condition
              :kind vector?))

 (s/def :job.lifecycles/lifecycle
@@ -326,7 +330,7 @@
 (s/def :job/trigger (s/multi-spec trigger-on :trigger/on))

 (s/def :job/triggers
-  (s/coll-of (s/get-spec :job/trigger) :kind vector?))
+  (s/coll-of :job/trigger :kind vector?))

 (s/def :jvm/function
   (s/or :fn fn? :var var?))
@@ -403,24 +407,21 @@

 (s/def :onyx.core/serialized-task any?)

-(s/def :onyx.core/workflow (s/get-spec :job/workflow))
-
-(s/def :onyx.core/task-map
-  (s/multi-spec onyx-type :onyx/type))
+(s/def :onyx.core/workflow :job/workflow)
+
+(s/def :onyx.core/task-map (s/multi-spec onyx-type :onyx/type))

 (s/def :onyx.core/catalog
-  (s/coll-of (s/multi-spec onyx-type :onyx/type)
-             :kind vector?))
-
-(s/def :onyx.core/flow-conditions
-  (s/get-spec :job/flow-conditions))
-
-(s/def :onyx.core/windows (s/get-spec :job/windows))
-
-(s/def :onyx.core/triggers (s/get-spec :job/triggers))
+  (s/coll-of (s/multi-spec onyx-type :onyx/type) :kind vector?))
+
+(s/def :onyx.core/flow-conditions :job/flow-conditions)
+
+(s/def :onyx.core/windows :job/windows)
+
+(s/def :onyx.core/triggers :job/triggers)

 (s/def :onyx.core/lifecycles
-  (s/coll-of (s/get-spec :job.lifecycles/lifecycle) :kind vector?))
+  (s/coll-of :job.lifecycles/lifecycle :kind vector?))

 (s/def :onyx.messaging/peer-port integer?)

@@ -462,11 +463,9 @@
 (s/def :aeron/idle-strategy
   #{:busy-spin :low-restart-latency :high-restart-latency})

-(s/def :onyx.messaging.aeron/poll-idle-strategy
-  (s/get-spec :aeron/idle-strategy))
-
-(s/def :onyx.messaging.aeron/offer-idle-strategy
-  (s/get-spec :aeron/idle-strategy))
+(s/def :onyx.messaging.aeron/poll-idle-strategy :aeron/idle-strategy)
+
+(s/def :onyx.messaging.aeron/offer-idle-strategy :aeron/idle-strategy)

 (s/def :onyx.bookkeeper/client-timeout pos-int?)

@@ -568,7 +567,7 @@

 (s/def :onyx/messaging #{:aeron :dummy-messenger})

-(s/def :onyx.messaging/impl (s/get-spec :onyx/messaging))
+(s/def :onyx.messaging/impl :onyx/messaging)

 (s/def :onyx/peer-config
   (s/keys :req [:onyx/tenancy-id
@@ -641,8 +640,7 @@
                 :onyx.zookeeper/backoff-max-retries
                 :onyx.zookeeper/prepare-failure-detection-interval]))

-(s/def :onyx.core/peer-opts
-  (s/get-spec :onyx/peer-config))
+(s/def :onyx.core/peer-opts :onyx/peer-config)

 (s/def :onyx.core/event-map
   (s/keys :req [:onyx.core/id
@@ -691,8 +689,7 @@

 (s/def :onyx.state-event/event-type keyword?)

-(s/def :onyx.state-event/task-event
-  (s/get-spec :onyx.core/event-map))
+(s/def :onyx.state-event/task-event :onyx.core/event-map)

 (s/def :onyx.state-event/segment any?)


remove IEquiv and IComparable from js/Date, it comes with core already. Add those for OffsetTime

--- src/tick/core.cljc
+++ src/tick/core.cljc
@@ -529,12 +529,12 @@
      (-compare [x y] (.compareTo x y))
      LocalDateTime
      (-compare [x y] (.compareTo x y))
-     Date
-     (-compare [x y] (.compareTo x y))
      LocalDate
      (-compare [x y] (.compareTo x y))
      LocalTime
      (-compare [x y] (.compareTo x y))
+     OffsetTime
+     (-compare [x y] (.compareTo x y))
      LocalDateTime
      (-compare [x y] (.compareTo x y))
      OffsetDateTime
@@ -552,11 +552,11 @@
      (-equiv [x y] (.equals x y))
      LocalDateTime
      (-equiv [x y] (.equals x y))
-     Date
-     (-equiv [x y] (= (.getTime x) (.getTime y)))
      LocalDate
      (-equiv [x y] (.equals x y))
      LocalTime
+     (-equiv [x y] (.equals x y))
+     OffsetTime
      (-equiv [x y] (.equals x y))
      LocalDateTime
      (-equiv [x y] (.equals x y))