Inc tests

Inc tests

--- test/onyx/coordinator/simulation_test.clj
+++ test/onyx/coordinator/simulation_test.clj
@@ -215,6 +215,7 @@
     (fn [coordinator sync log]
       (let [peer-node (extensions/create sync :peer)
             in-payload-node (extensions/create sync :payload)
+            inc-payload-node (extensions/create sync :payload)
             sync-spy (chan 1)
             ack-ch-spy (chan 1)
             offer-ch-spy (chan 1)
@@ -280,39 +281,52 @@
             (let [event (<!! ack-ch-spy)]
               (= (:path event) (:ack nodes)))))

-        (let [inc-payload-node (extensions/create sync :payload)]
-          (extensions/write-place sync peer-node inc-payload-node)
-          (extensions/on-change sync inc-payload-node #(>!! sync-spy %))
-
-          (testing "Touching the completion node triggers the callback"
-            (let [nodes (:nodes (extensions/read-place sync in-payload-node))]
-              (extensions/touch-place sync (:completion nodes))
-              (let [event (<!! completion-ch-spy)]
-                (= (:path event) (:completion nodes)))))
-
-          (testing "The offer channel receives the tx id of the completion"
-            (let [tx-id (<!! offer-ch-spy)
-                  db (d/as-of (d/db (:conn log)) tx-id)]
-
-              (testing "The peer's nodes have been stripped"
-                (let [query '[:find ?payload ?ack ?status ?completion :in $ ?peer-node :where
-                              [?p :node/peer ?peer-node]
-                              [?p :node/payload ?payload]
-                              [?p :node/ack ?ack]
-                              [?p :node/status ?status]
-                              [?p :node/completion ?completion]]
-                      result (d/q query db peer-node)]
-                  (is (empty? result))))))
-
-          (testing "The payload node is populated"
-            (let [event (<!! sync-spy)]
-              (is (= (:path event) inc-payload-node))))
-
-          (let [db (d/db (:conn log))]
-            (testing "It receives the :inc task"
-              (let [task (:task (extensions/read-place sync inc-payload-node))
-                    query '[:find ?task :where [?task :task/name :inc]]]
-                (is (= (:db/id task) (ffirst (d/q query db))))))))))
+        (extensions/write-place sync peer-node inc-payload-node)
+        (extensions/on-change sync inc-payload-node #(>!! sync-spy %))
+
+        (testing "Touching the completion node triggers the callback"
+          (let [nodes (:nodes (extensions/read-place sync in-payload-node))]
+            (extensions/touch-place sync (:completion nodes))
+            (let [event (<!! completion-ch-spy)]
+              (= (:path event) (:completion nodes)))))
+
+        (testing "The offer channel receives the tx id of the completion"
+          (let [tx-id (<!! offer-ch-spy)
+                db (d/as-of (d/db (:conn log)) tx-id)]
+
+            (testing "The peer's nodes have been stripped"
+              (let [query '[:find ?payload ?ack ?status ?completion :in $ ?peer-node :where
+                            [?p :peer/status :idle]
+                            [?p :node/peer ?peer-node]
+                            [?p :node/payload ?payload]
+                            [?p :node/ack ?ack]
+                            [?p :node/status ?status]
+                            [?p :node/completion ?completion]]
+                    result (d/q query db peer-node)]
+                (is (empty? result))))))
+
+        (testing "The payload node is populated"
+          (let [event (<!! sync-spy)]
+            (is (= (:path event) inc-payload-node))))
+
+        (let [db (d/db (:conn log))]
+          (testing "It receives the :inc task"
+            (let [task (:task (extensions/read-place sync inc-payload-node))
+                  query '[:find ?task :where [?task :task/name :inc]]]
+              (is (= (:db/id task) (ffirst (d/q query db))))))
+
+          (testing "The peer is marked as :acking the task"
+            (let [query '[:find ?task :where
+                          [?peer :peer/status :acking]
+                          [?peer :peer/task ?task]
+                          [?task :task/name :inc]]]
+              (is (= (count (d/q query db)) 1))))
+
+          (testing "The payload node contains the other node paths"
+            (let [nodes (:nodes (extensions/read-place sync inc-payload-node))]
+              (is (= (clojure.set/difference (into #{} (keys nodes))
+                                             #{:payload :ack :completion :status})
+                     #{})))))))
     {:eviction-delay 500000}))

 (run-tests 'onyx.coordinator.simulation-test)


`components/Lifecycle` implementors must give both `start` and `stop` implementations

--- src/whatsoup/food_kb.clj
+++ src/whatsoup/food_kb.clj
@@ -40,7 +40,9 @@
             (assoc this :food-compatibility-matrix food-compatibility-matrix)
             (assoc this :food-property-catalog (food-property-catalog food-catalog))
             (assoc this :property-weights (property-weights (:property-catalog this)))
-            (dissoc this :config)))))
+            (dissoc this :config))))
+
+  (stop [this] this))

 (defn expand-catalog [catalog]
   "{:a #{:b :c}} -> {:food/name :food/a


Use bulk byte copying

Use bulk byte copying

--- src/zaffre/imageutil.clj
+++ src/zaffre/imageutil.clj
@@ -94,8 +94,8 @@

 (defn copy-buffer-range! [dest src n]
-  (doseq [_ (range n)]
-    (.put dest (.get src))))
+  (let [slice (.limit (.slice src) n)]
+    (.put dest slice)))

 (defn copy-sub-image [{dwidth :width dheight :height dchannels :channels dbytes :byte-buffer :as dimg}
                       {swidth :width sheight :height schannels :channels sbytes :byte-buffer}


make function private

make function private

--- src/zombie_run/world.clj
+++ src/zombie_run/world.clj
@@ -21,7 +21,7 @@
         dist (Math/sqrt (+ x-dist y-dist))]
     (int dist)))

-(defn calc-position [[x y] action steps]
+(defn- calc-position [[x y] action steps]
   (case action
     :right [(+ x steps) y]
     :left [(- x steps) y]


make model a (def ^:dynamic) to avoid passing it around to every function

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -17,6 +17,8 @@
 (def ^:dynamic truncate? false)
 (def ^:dynamic println? false)
 (def ^:dynamic use-spec-cache? false)
+(def ^:dynamic model)
+
 (declare gen)
 (declare get-lexemes)
 (declare grow)
@@ -25,43 +27,27 @@

 (defn generate
   "Return one expression matching spec _spec_ given the model _model_."
-  [spec language-model]
-  ;;
-  ;; Return the tree of an expression, generated by the given model,
-  ;; that satisfies given spec:
-  ;;
-  ;; The tree will look like:
-  ;;
-  ;; Where H is the head of a certain node in the tree, and C
-  ;; is the complement. Terminal nodes are lexemes given by the model.
-  ;;
-  ;;       H
-  ;;      / \
-  ;;     H   C
-  ;;        / \
-  ;;       H   C
-  ;;
-  ;; A convenient wrapper around (defn gen) (below).
-
-  (log/debug (str "(generate) with model named: " (:name language-model) "; "
-                 "truncate? " truncate? "; "
-                 "use-spec-cache? " use-spec-cache?))
-  (first (gen spec language-model)))
+  ([spec model]
+   (log/debug (str "(generate) with model named: " (:name model)
+                   "; "truncate? " truncate? "; "))
+                   "use-spec-cache? " use-spec-cache?))
+   (binding [model model]
+     (first (gen spec)))))

 (defn gen
   "generate a potentially infinite (depending on given _spec_ and _model_)
    list of expressions that match the given _spec_."
-  [spec model]
-  (grow (parent-with-head spec model 0) model))
-
-(defn matching-rules [spec model]
+  [spec]
+  (grow (parent-with-head spec 0)))
+
+(defn matching-rules [spec]
   (->> (:grammar model)
        (map #(unify % spec))
        (filter #(not (= :fail %)))))

-(defn rules-for-spec [spec model]
+(defn rules-for-spec [spec]
   (if (not use-spec-cache?)
-    (matching-rules spec model)
+    (matching-rules spec)
     (let [plain-spec (strip-refs spec)
           looked-up
           (cond
@@ -74,26 +60,26 @@
             (get @(:rules-for-spec model) plain-spec ::none))]
       (if (not (= ::none looked-up))
         looked-up
-        (let [matching-rules (matching-rules spec model)]
+        (let [matching-rules (matching-rules spec)]
           (swap! (:rules-for-spec model) #(assoc % plain-spec matching-rules))
           matching-rules)))))

 (defn parent-with-head
   "Return every possible tree of depth 1 from the given spec and model."
-  [spec model depth]
+  [spec depth]
   ;; get all rules that match input _spec_:
   (if (nil? spec) (throw (Exception. (str "nope: spec was nil."))))
   (let [matching-rules
-        (shuffle (rules-for-spec spec model))]
+        (shuffle (rules-for-spec spec))]
     (->> matching-rules
          (map #(unify % spec))
          (filter #(not (= :fail %)))
          ;; 2. try to add heads to each matching rule:
-         (parent-with-head-1 spec model depth)
+         (parent-with-head-1 spec depth)
          (filter #(not (= % :fail)))
          (map #(u/assoc-in! % [::started?] true)))))

-(defn parent-with-head-1 [spec model depth parent-rules]
+(defn parent-with-head-1 [spec depth parent-rules]
   (if (not (empty? parent-rules))
     (let [parent-rule (first parent-rules)
           phrases-with-phrasal-head #(map (fn [child]
@@ -103,8 +89,7 @@
                                              (u/assoc-in parent-rule [:head] child))
                                            (get-lexemes (unify
                                                          (u/get-in spec [:head] :top)
-                                                         (u/get-in parent-rule [:head] :top))
-                                                        model))]
+                                                         (u/get-in parent-rule [:head] :top))))]
       (log/debug (str "pwh-1:" (:rule parent-rule)))
       (cond
         (branch? depth)
@@ -115,7 +100,7 @@
          (phrases-with-phrasal-head)
          ;; 2. lexemes that could be the head child:
          (phrases-with-lexical-heads)
-         (parent-with-head-1 spec model depth (rest parent-rules)))
+         (parent-with-head-1 spec depth (rest parent-rules)))

         true
         (lazy-cat
@@ -123,9 +108,9 @@
          (phrases-with-lexical-heads)
          ;; 2. phrases that could be the head child:
          (phrases-with-phrasal-head)
-         (parent-with-head-1 spec model depth (rest parent-rules)))))))
-
-(defn get-lexemes [spec model]
+         (parent-with-head-1 spec depth (rest parent-rules)))))))
+
+(defn get-lexemes [spec]
   "Get lexemes matching the spec. Use a model's index if available, where the index
    is a function that we call with _spec_ to get a set of indices.
    Otherwise use the model's entire lexeme."
@@ -162,7 +147,7 @@

     true []))

-(defn assoc-each-default [tree children f model]
+(defn assoc-each-default [tree children f]
   (if (not (empty? children))
     (lazy-cat
      (let [child (first children)
@@ -173,25 +158,25 @@
             true)
            (u/dissoc-paths (if truncate? [f] []))
            ((or (:default-fn model) (fn [x] [x])))))
-     (assoc-each-default tree (rest children) f model))))
-
-(defn assoc-children [tree children f model]
+     (assoc-each-default tree (rest children) f))))
+
+(defn assoc-children [tree children f]
   (if (not (empty? children))
     (let [child (first children)
           default-fn (or (:default-fn model)
                          (fn [x] [x]))]
       (lazy-cat
        (if (= true (u/get-in child [::done?]))
-         (assoc-each-default tree (default-fn child) f model)
+         (assoc-each-default tree (default-fn child) f)
          [(u/assoc-in tree f child)])
-       (assoc-children tree (rest children) f model)))))
+       (assoc-children tree (rest children) f)))))

 (defn grow
   "recursively generate trees given
    input trees and model. continue recursively
    until no futher expansion is
    possible."
-  [trees model]
+  [trees]
   (if (not (empty? trees))
     ;; for each tree,
     ;; find the next point of
@@ -201,8 +186,8 @@
           f (frontier tree)
           depth (count f)
           child-spec (u/get-in tree f)
-          child-lexemes #(get-lexemes child-spec model)
-          child-trees #(parent-with-head child-spec model depth)]
+          child-lexemes #(get-lexemes child-spec)
+          child-trees #(parent-with-head child-spec depth)]
       (when println? (println (str "grow at:" ((:morph-ps model) tree))))
       (log/debug (str "grow at:" ((:morph-ps model) tree)))
       (lazy-cat
@@ -224,8 +209,7 @@

                   true ;; generate children that are leaves before children that are trees.
                   (lazy-cat (child-lexemes) (child-trees)))]
-            (assoc-children tree children f model))
-          model)
+            (assoc-children tree children f)))
          [tree])
-       (grow (rest trees) model)))))
-
+       (grow (rest trees))))))
+


working on creating a function that operates on comp-paths: list<comp-path>

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -92,17 +92,19 @@
                                (rest comp-paths)
                                (rest bolts-at-paths)
                                depth max-depth top-bolt truncate? take-n)
-                   (let [path (first comp-paths)
-                         bolts-at (first bolts-at-paths)]
-                     (flatten
-                      (mapfn #(let [bolt (assoc-in bolt path %)]
-                                (if (= false (get-in % [:phrasal]))
-                                  [bolt]
-                                  (-> (add-bolt-at top-bolt bolt path % model depth max-depth truncate? take-n)
-                                      ((fn [with-added-complement]
-                                         (if truncate? (truncate with-added-complement [path] model)
-                                             with-added-complement))))))
-                             bolts-at)))))))))))
+                   ((fn [comp-paths]
+                      (let [path (first comp-paths)
+                            bolts-at (first bolts-at-paths)]
+                        (flatten
+                         (mapfn #(let [bolt (assoc-in bolt path %)]
+                                   (if (= false (get-in % [:phrasal]))
+                                     [bolt]
+                                     (-> (add-bolt-at top-bolt bolt path % model depth max-depth truncate? take-n)
+                                         ((fn [with-added-complement]
+                                            (if truncate? (truncate with-added-complement [path] model)
+                                                with-added-complement))))))
+                                bolts-at))))
+                    comp-paths)))))))))

 (defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth truncate? & [take-n]]
   (mapfn #(do-defaults % model)


Fix multi-prod.

Fix multi-prod.

--- src/onyx/peer/transform.clj
+++ src/onyx/peer/transform.clj
@@ -3,7 +3,7 @@
             [onyx.peer.pipeline-extensions :as p-ext]
             [onyx.extensions :as extensions]))

-(defn read-batch [{:keys [batch-size timeout] :as task} queue consumers]
+(defn read-batch [queue consumers batch-size timeout]
   (let [consumer-chs (take (count consumers) (repeatedly #(chan 1)))]
     (doseq [[c consumer-ch] (map vector consumers consumer-chs)]
       (go (loop []
@@ -28,14 +28,14 @@
 (defn compress-segment [segment]
   (pr-str segment))

-(defn write-batch [queue session producer msgs]
-  (doseq [msg msgs]
-    (extensions/produce-message queue producer msg)))
+(defn write-batch [queue session producers msgs]
+  (for [p producers msg msgs]
+    (extensions/produce-message queue p session msg)))

 (defmethod p-ext/read-batch :default
   [{:keys [task queue session ingress-queues batch-size timeout]}]
   (let [consumers (map (partial extensions/create-consumer queue session) ingress-queues)
-        batch (read-batch task queue consumers batch-size timeout)]
+        batch (read-batch queue consumers batch-size timeout)]
     {:batch batch :consumers consumers}))

 (defmethod p-ext/decompress-batch :default
@@ -55,8 +55,9 @@
     {:compressed compressed-msgs}))

 (defmethod p-ext/write-batch :default
-  [{:keys [queue queue-name session compressed]}]
-  (let [producer (extensions/create-producer queue session queue-name)
-        batch (write-batch queue session producer compressed)]
-    {:producer producer}))
+  [{:keys [queue egress-queues session compressed]}]
+  (prn "Transformer: Writing batch " compressed)
+  (let [producers (map (partial extensions/create-producer queue session) egress-queues)
+        batch (write-batch queue session producers compressed)]
+    {:producers producers}))


(if x y false) is equivalent to (and x y)

--- src/overcode/introvert.cljs
+++ src/overcode/introvert.cljs
@@ -123,19 +123,17 @@

 (defn deep-arr=
   ([val1 val2 visited]
-   (if (= (count val1) (count val2))
-     (every? identity (map #(deep= % %2 visited) val1 val2))
-     false)))
+   (and (= (count val1) (count val2))
+        (every? identity (map #(deep= % %2 visited) val1 val2)))))

 (defn deep-obj=
   ([val1 val2 visited]
-  (if (and (= (obj-size val1) (obj-size val2))
-           (deep-arr= (.keys js/Object val1)
-                      (.keys js/Object val2)
-                      visited))
-    (every? #(deep= (aget val1 %) (aget val2 %) visited)
-            (.keys js/Object val1))
-    false)))
+  (and (= (obj-size val1) (obj-size val2))
+       (deep-arr= (.keys js/Object val1)
+                  (.keys js/Object val2)
+                  visited)
+       (every? #(deep= (aget val1 %) (aget val2 %) visited)
+               (.keys js/Object val1)))))

 (defn deep=
   "Compares JS values for equality by value instead of by reference."


really add an admin graphs page

really add an admin graphs page

--- src/pc/http/admin/inner.clj
+++ src/pc/http/admin/inner.clj
@@ -22,8 +22,13 @@
                                 [:h2 "Early access"]
                                 (admin-content/early-access-users)
                                 [:h2 "User Growth"]
-                                [:p "Here's a cumulative graph of users. It needs some work."
-                                 (admin-content/users-graph)]])))
+                                (admin-content/users-graph)])))
+
+(defpage base "/graphs" [req]
+  (hiccup/html (content/layout {}
+                               [:div {:style "padding: 40px"}
+                                [:h2 "User Growth"]
+                                (admin-content/users-graph)])))

 (defpage grant-early-access [:post "/grant-early-access"] [req]
   (let [uuid (some-> req :params (get "cust-uuid") (UUID/fromString))]


refine tcp setup and handle basic messages

--- src/block_chain/net.clj
+++ src/block_chain/net.clj
@@ -1,6 +1,7 @@
 (ns block-chain.net
   (:require [clojure.java.io :as io]
-            [clojure.core.async :as async])
+            [clojure.core.async :as async]
+            [block-chain.utils :refer :all])
   (:import  [java.net ServerSocket]))

 (defn write-response
@@ -19,14 +20,11 @@
         (recur (conj lines next-line)
                (.readLine reader))))))

-(defn echo-handler [lines]
-  (println "handling lines: " lines)
-  (str (clojure.string/join "\n" lines) "\n"))
-
 (defn serve-loop [server-sock handler]
   (future
     (while true
       (with-open [socket (.accept server-sock)]
+        (println "received req")
         (write-response socket
                         (handler (read-lines socket)))))))

@@ -35,3 +33,39 @@
     (println "server waiting for will wait for next request")
     {:server server :run-loop (serve-loop server handler)}))

+(defn echo [msg]
+  (println "echoing msg: " msg)
+  msg)
+
+(defn pong [msg]
+  (println "ponging")
+  {:message_type "pong" :payload (:payload msg)})
+
+(defn get-peers [msg]
+  {:message_type "peers" :payload []})
+
+(def message-handlers
+  {"echo" echo
+   "ping" pong
+   "get_peers" get-peers})
+
+(defonce server (atom nil))
+(def default-port 8334)
+
+(defn handler [lines]
+  (let [msg (read-json (first lines))
+        type (:message-type msg)
+        handler (get message-handlers type echo)]
+    (str (write-json (handler msg)) "\n\n")))
+
+(defn start!
+  ([] (start! default-port))
+  ([port] (reset! server (start-server port handler))))
+
+(defn shutdown! []
+  (if (:server @server)
+    (.close (:server @server))))
+
+(defn restart! []
+  (shutdown!)
+  (start!))


Make the test pass

Make the test pass

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -232,11 +232,16 @@

 (defn ^:private c-name
   "Resolves the fn name in the current ns to the fn name in the equivalent
-  libsodium C pseudo-namespace."
+  libsodium C pseudo-namespace.
+
+  This understands problems like e.g. generichash in the generichash
+  namespace meaning crypto_generichash, not the (nonexistant)
+  crypto_generichash_generichash."
   [^clojure.lang.Namespace namespace ^clojure.lang.Symbol fn-name]
   (let [fn-name (-> (name fn-name) (s/replace "-" "_"))
+        fn-name-parts (set (str/split fn-name #"_"))
         prefix (-> namespace ns-name str (s/split #"\.") rest vec)
-        path (into prefix (when-not (= (last prefix) fn-name) [fn-name]))]
+        path (concat (remove fn-name-parts prefix) [fn-name])]
     (symbol (s/join "_" path))))

 (defn ^:private java-call-sym


fold autotest into test task

fold autotest into test task

--- src/cake/tasks/test.clj
+++ src/cake/tasks/test.clj
@@ -172,11 +172,9 @@
 (deftask test #{compile-java}
   "Run project tests."
   "Specify which tests to run as arguments like: namespace, namespace/function, or :tag"
-  (run-project-tests))
-
-(deftask autotest #{compile-java}
-  "Automatically run tests whenever your project code changes."
-  "Specify tests to run just like the test task. Specify the interval with --interval."
-  (run-project-tests)
-  (while true
-    (run-project-tests :autotest true)))
+  "Use --auto to automatically run tests whenever your project code changes."
+  (if (:auto *opts*)
+    (do (run-project-tests)
+        (while true
+          (run-project-tests :autotest true)))
+    (run-project-tests)))


Show finished (canceled) time even when never ran.

If you cancel while queued/scheduled, you get a `:stop_time` but no
`:start_time`.

--- src-cljs/frontend/components/build_head.cljs
+++ src-cljs/frontend/components/build_head.cljs
@@ -1363,11 +1363,9 @@
               {:opts {:formatter datetime/time-ago-abbreviated}})
     " ago"]])

-(defn build-finished-status [{start-time :start_time
-                              stop-time :stop_time
+(defn build-finished-status [{stop-time :stop_time
                               :as build}]
-  {:pre [(some? start-time)
-         (some? stop-time)]}
+  {:pre [(some? stop-time)]}
   [:div.summary-item
    [:span.summary-label "Finished: "]
    [:span.stop-time
@@ -1412,10 +1410,10 @@
             [:div.summary-items
              [:div.summary-item
               (builds-table/build-status-badge build)]
-             (when (:start_time build)
-               (if-not (:stop_time build)
-                 (build-running-status build)
-                 (build-finished-status build)))]
+             (if-not (:stop_time build)
+               (when (:start_time build)
+                 (build-running-status build))
+               (build-finished-status build))]
             [:div.summary-items
              (om/build previous-build-label build)
              [:div.summary-item


resolve conflict?

resolve conflict?

--- src-cljs/frontend/components/doc_viewer.cljs
+++ src-cljs/frontend/components/doc_viewer.cljs
@@ -1,16 +1,42 @@
 (ns frontend.components.doc-viewer
   (:require [clojure.set :as set]
             [clojure.string :as str]
+            [cljs-time.core :as time]
             [datascript :as d]
             [frontend.async :refer [put!]]
             [frontend.components.common :as common]
             [frontend.datascript :as ds]
             [frontend.state :as state]
             [frontend.utils :as utils :include-macros true]
+            [goog.date]
             [om.core :as om :include-macros true]
             [om.dom :as dom :include-macros true])
   (:require-macros [frontend.utils :refer [html]])
   (:import [goog.ui IdGenerator]))
+
+(def day-of-week
+  {1 "Monday"
+   2 "Tuesday"
+   3 "Wednesday"
+   4 "Thursday"
+   5 "Friday"
+   6 "Saturday"
+   7 "Sunday"})
+
+(defn date->bucket [date]
+  (let [time (goog.date.DateTime. date)
+        start-of-day (doto (goog.date.DateTime.)
+                       (.setHours 0)
+                       (.setMinutes 0)
+                       (.setSeconds 0)
+                       (.setMilliseconds 0))]
+    (cond
+     (time/after? time start-of-day) "today"
+     (time/after? time (time/minus start-of-day (time/days 1))) "yesterday"
+     (time/after? time (time/minus start-of-day (time/days 6))) (day-of-week (time/day-of-week time))
+     (time/after? time (time/minus start-of-day (time/days 14))) "last week"
+     :else "a while ago")))
+

 (defn doc-viewer [app owner]
   (reify
@@ -19,22 +45,29 @@
       (let [cast! (om/get-shared owner :cast!)
             touched-docs (get-in app [:cust :touched-docs])
             ;; Not showing created for now, since we haven't been storing that until recently
-            created-docs (get-in app [:cust :created-docs])]
+            created-docs (get-in app [:cust :created-docs])
+            docs (take 100 (reverse (sort-by :last-updated-instant (filter :last-updated-instant touched-docs))))]
         (html
          [:div.menu-prompt {:class (str "menu-prompt-" "doc-viewer")}
           [:div.menu-header
            [:a.menu-close {:on-click #(cast! :overlay-closed)
                            :role "button"}
             (common/icon :times)]]
-          [:div.menu-prompt-body {:style {:overflow "scroll"}}
+          [:div.menu-prompt-body
            [:h2 "Your Docs"]
            [:a {:on-click #(cast! :touched-fetched)
                 :role "button"}
             "Fetch docs"]
-           (for [doc (take 100 (reverse (sort-by :last-updated-instant touched-docs)))
-                 :when (:last-updated-instant doc)]
-             [:a {:href (str "/document/" (:db/id doc))}
-              [:img {:src (str "/document/" (:db/id doc) ".svg")
-                     :style {:border "1px solid black"}
-                     :width 300
-                     :height 300}]])]])))))
+
+           (for [[time-bucket bucket-docs] (reverse (sort-by #(:last-updated-instant (first (last %)))
+                                                             (group-by #(date->bucket (:last-updated-instant %)) docs)))]
+             (list*
+              [:div.time-bucket (str "Updated " time-bucket)]
+
+              (for [doc bucket-docs]
+                [:a {:href (str "/document/" (:db/id doc))}
+                 [:img {:src (str "/document/" (:db/id doc) ".svg")
+                        :style {:border "1px solid black"
+                                :margin-bottom 20}
+                        :width 300
+                        :height 300}]])))]])))))


Load team members correctly

Load team members correctly

--- src-cljs/frontend/components/pages/team.cljs
+++ src-cljs/frontend/components/pages/team.cljs
@@ -98,13 +98,10 @@
             selected-org (when selected-org-ident (get-in app selected-org-ident))]
         (when (not= (:selected-org-ident (om/get-render-state owner))
                     selected-org-ident)
-          (api/get-org-settings-normalized name vcs-type api-chan)
-          (api/get-org-members api-chan (:name selected-org)))
+          (api/get-org-settings-normalized name vcs-type api-chan))
         (when (and selected-org
                    invite-teammates?)
-          ;; TODO -ac here or up there? ^
-          ;; (api/get-org-members api-chan (:name selected-org)))
-          )))
+          (api/get-org-members api-chan (:name selected-org)))))

     om/IRenderState
     (render-state [_ {:keys [selected-org-ident invite-teammates?]}]


detecting command fail and supporting sudo

--- src/vsphere/guest.clj
+++ src/vsphere/guest.clj
@@ -17,12 +17,13 @@
   (:require
     [clj-http.client :as client])
   (:use
+    [slingshot.slingshot :only  [throw+]]
     [celestial.provider :only (wait-for)]
     [celestial.common :only (gen-uuid import-logging)]
     [clostache.parser :only (render-resource)]
     [clojure.core.strint :only (<<)]
     [clojure.java.io :only (copy file reader)]
-    [vsphere.vijava :only (with-service tools-installed? service find-vm)]))
+    [vsphere.vijava :only (with-service tools-installed? guest-status service find-vm)]))

 (import-logging)

@@ -57,20 +58,30 @@
     (let[{:keys [url]} (bean (.initiateFileTransferFromGuest (manager hostname :file) (npa auth) src))]
       (:body (client/get url {:as :stream :insecure? true})))))

+(defn exit-code
+   "returns a remote pid exit status"
+   [m pid auth]
+   (-> (.listProcessesInGuest m (npa auth) (long-array [pid])) first bean :exitCode))
+
+(defn prog-spec [cmd args* {:keys [sudo] :as auth}]
+  (if sudo
+     (doto (GuestProgramSpec.) (.setProgramPath "/usr/bin/sudo") (.setArguments (str cmd " " args*)))
+     (doto (GuestProgramSpec.) (.setProgramPath cmd) (.setArguments args*))))
+
 (defn guest-run
-  "Runs a remote command using out of band guest access,
+  "Runs a remote command using out of band using guest access,
     wait - how much to wait before logging output
     uuid - the log file uuid, if missing no logging will take place"
   [hostname cmd args auth uuid timeout]
-  {:pre [(tools-installed? hostname)]}
+  {:pre [(= (guest-status hostname) :running)]}
   (with-service
     (let [m (manager hostname :proc)
           args* (if uuid (<< "~{args} >> /tmp/run-~{uuid}.log") args)
-          spec (doto (GuestProgramSpec.) (.setProgramPath cmd) (.setArguments args*))
-          pid (.startProgramInGuest m (npa auth) spec)]
-         (wait-for {:timeout timeout :sleep [200 :ms]}
-           #(-> (.listProcessesInGuest m (npa auth) (long-array [pid])) first bean :exitCode nil? not)
-           {:type ::vsphere:guest-run-timeout :message (<< "Timed out on running ~{cmd} ~{args} in guest") :timeout timeout} ))))
+          pid (.startProgramInGuest m (npa auth) (prog-spec cmd args* auth))]
+         (wait-for {:timeout timeout :sleep [200 :ms]} #(-> (exit-code m pid auth) nil? not)
+           {:type ::vsphere:guest-run-timeout :message (<< "Timed out on running ~{cmd} ~{args} in guest") :timeout timeout})
+         (when-not (= (exit-code m pid auth) 0)
+           (throw+ {:type ::vsphere:guest-run-fail :message (<< "Failed running ~{cmd} ~{args} in guest") :timeout timeout})))))

 (defn fetch-log
    "fetched remote log file by uuid"
@@ -88,9 +99,9 @@
     (debug (fetch-log hostname uuid auth))))

 (comment
-  (set-ip "foo" {:user "root" :pass "foobar"}
+  (set-ip "red1" {:user "ronen" :pass "foobar" :sudo true}
      {:ip "192.168.5.91" :mask "255.255.255.0" :network "192.168.5.0" :gateway "192.168.5.1" :search "local" :names ["192.168.5.1"]})
   (download-file "/tmp/project.clj" "/tmp/project.clj" "foo" {:user "root" :pass "foobar"})
-  (upload-file "project.clj" "/tmp/project.clj" "foo" {:user "ronen" :pass "foobar"})
+  (upload-file "project.clj" "/tmp/project.clj" "red1" {:user "ronen" :pass "foobar"})
   (download-file "/tmp/project.clj" "/tmp/project.clj" "foo" {:user "ronen" :pass "foobar"})
   (tools-installed? "foo"))


Add size, strength, and toughness

Add size, strength, and toughness

--- src/robinson/monstergen.clj
+++ src/robinson/monstergen.clj
@@ -25,7 +25,7 @@
                :turtle :crocodile
                :crab :hermit-crab} race))

-(defrecord Monster [race name name-plural hp energy speed body-parts attacks movement-policy range-threshold status]
+(defrecord Monster [race name name-plural hp energy speed size strength toughness body-parts attacks movement-policy range-threshold status]
   Object
   (toString [this] (str "#Monster" (into {} this))))

@@ -33,41 +33,43 @@
   [
   ;;        race            name             name-plural       hp
   ;;                                                             energy
-  ;;                                                               speed
-  ;;                                                                   body-parts                                  attacks                       movement policy                       range-threshold
-  ;;                                                                                status
-  (Monster. :rat            "rat"            "rats"            5 0 1.1 #{:face :head :neck :body :leg :tail}       #{:bite :claw}                :hide-from-player-in-range-or-random  5 #{:hostile})
-  (Monster. :spider         "spider"         "spiders"         2 0 0.9 #{:face :leg :abdomen}                      #{:bite-venom}                :hide-from-player-in-range-or-random  5 #{:hostile})
-  (Monster. :scorpion       "scorpion"       "scorpions"       3 0 1.1 #{:head :claw :leg :abdomen :tail}          #{:bite :claw :sting-venom}   :hide-from-player-in-range-or-random  4 #{:hostile})
-  (Monster. :snake          "snake"          "snakes"          5 0 0.8 #{:head :body :tail}                        #{:bite :bite-venom}          :hide-from-player-in-range-or-random  5 #{:hostile})
-  (Monster. :bat            "bat"            "bats"            5 0 1.6 #{:head :body :wing :leg :face}             #{:bite}                      :hide-from-player-in-range-or-random  7 #{:hostile})
-  (Monster. :boar           "boar"           "boars"          18 0 1.2 #{:head :body :tail :snout :face :eye :leg} #{:bite :gore}                :hide-from-player-in-range-or-random  7 #{:hostile})
-  (Monster. :gecko          "gecko"          "geckos"          2 0 0.9 #{:head :face :body :tail :leg}             #{:bite}                      :hide-from-player-in-range-or-random  4 #{:hostile})
-  (Monster. :monkey         "monkey"         "monkies"        13 0 1.2 #{:head :neck :body :tail :leg :face :arm}  #{:bite :punch}               :hide-from-player-in-range-or-random 10 #{:hostile})
-  (Monster. :bird           "bird"           "birds"           4 0 2.1 #{:head :body :tail :leg :beak :wing}       #{:bite :claw}                :hide-from-player-in-range-or-random  8 #{:hostile})
-  (Monster. :centipede      "centipede"      "centipedes"      1 0 0.5 #{:head :body :leg}                         #{:bite}                      :hide-from-player-in-range-or-random  3 #{:hostile})
-  (Monster. :turtle         "turtle"         "turtles"         4 0 0.5 #{:head :neck :body :leg :face :shell}      #{:bite}                      :hide-from-player-in-range-or-random  5 #{:hostile})
-  (Monster. :frog           "frog"           "frogs"           2 0 0.9 #{:head :body :leg :face}                   #{:claw}                      :hide-from-player-in-range-or-random  4 #{:hostile})
-  (Monster. :parrot         "parrot"         "parrots"         5 0 2.1 #{:head :body :leg :face :wing :tail}       #{:claw :bite}                :hide-from-player-in-range-or-random 10 #{:hostile})
-  (Monster. :shark          "shark"          "sharks"         16 0 1.4 #{:head :body :fin :nose :tail}             #{:bite}                      :hide-from-player-in-range-or-random 10 #{:hostile})
-  (Monster. :fish           "fish"           "fish"            4 0 1.2 #{:head :body :fin :tail}                   #{:bite}                      :hide-from-player-in-range-or-random  4 #{:hostile})
-  (Monster. :octopus        "octopus"        "octopodes"       4 0 1.5 #{:head :body :tentacle}                    #{:bite :bite-venom :squeeze} :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :sea-snake      "sea snake"      "sea snakes"      4 0 1.5 #{:head :body}                              #{:bite :bite-venom}          :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :clam           "clam"           "clams"           2 0 0.1 #{:shell}                                   #{:clamp}                     :constant                             1 #{:hostile})
-  (Monster. :urchin         "urchin"         "urchins"         2 0 0.1 #{:body}                                    #{:spike}                     :constant                             1 #{:hostile})
-  (Monster. :squid          "squid"          "squids"          4 0 1.5 #{:head :body :tentacle}                    #{:bite :squeeze}             :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :crocodile      "crocodile"      "crocodiles"     10 0 0.8 #{:head :body :arm :leg :tail :snout}       #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :mosquito       "mosquito"       "mosquitoes"      1 0 1.4 #{:head :body :leg :wing}                   #{:bite}                      :hide-from-player-in-range-or-random  3 #{:hostile})
-  (Monster. :mongoose       "mongoose"       "mongeese"        4 0 1.4 #{:head :body :leg :tail}                   #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :tarantula      "tarantula"      "tarantulas"      2 0 1.4 #{:head :body :leg}                         #{:bite}                      :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :monitor-lizard "monitor lizard" "monitor lizards" 7 0 1.1 #{:head :body :leg :tail}                   #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :komodo-dragon  "komodo dragon"  "komodo dragons" 12 0 0.8 #{:head :body :leg :tail}                   #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :cobra          "cobra"          "cobras"          5 0 0.8 #{:head :body :tail}                        #{:bite :bite-venom}          :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :puffer-fish    "puffer fish"    "puffer fish"     3 0 1.1 #{:head :body :tail}                        #{:sting-venom}               :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :crab           "crab"           "crabs"           4 0 0.8 #{:head :body}                              #{:claw}                      :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :hermit-crab    "hermit crab"    "hermit crabs"    3 0 0.6 #{:head :shell :leg}                        #{:claw}                      :hide-from-player-in-range-or-random  1 #{:hostile})
-  (Monster. :electric-eel   "electric eel"   "electric eels"   5 0 0.6 #{:head :body}                              #{:bite}                      :hide-from-player-in-range-or-random  2 #{:hostile})
-  (Monster. :jellyfish      "jellyfish"      "jellyfish"       3 0 0.6 #{:body}                                    #{:sting-venom}               :hide-from-player-in-range-or-random  1 #{:hostile})])
+  ;;                                                               speed size (kg)
+  ;;                                                                           strength
+  ;;                                                                               toughness
+  ;;                                                                                body-parts                                  attacks                       movement policy                       range-threshold
+  ;;                                                                                status
+  (Monster. :rat            "rat"            "rats"            5 0 1.1   0.2   1    5 #{:face :head :neck :body :leg :tail}       #{:bite :claw}                :hide-from-player-in-range-or-random  5 #{:hostile})
+  (Monster. :spider         "spider"         "spiders"         2 0 0.9   0.01  0.1  1 #{:face :leg :abdomen}                      #{:bite-venom}                :hide-from-player-in-range-or-random  5 #{:hostile})
+  (Monster. :scorpion       "scorpion"       "scorpions"       3 0 1.1   0.01  0.1  1 #{:head :claw :leg :abdomen :tail}          #{:bite :claw :sting-venom}   :hide-from-player-in-range-or-random  4 #{:hostile})
+  (Monster. :snake          "snake"          "snakes"          5 0 0.8   1     1    8 #{:head :body :tail}                        #{:bite :bite-venom}          :hide-from-player-in-range-or-random  5 #{:hostile})
+  (Monster. :bat            "bat"            "bats"            5 0 1.6   1     0.5  4 #{:head :body :wing :leg :face}             #{:bite}                      :hide-from-player-in-range-or-random  7 #{:hostile})
+  (Monster. :boar           "boar"           "boars"          18 0 1.2  70    20    8 #{:head :body :tail :snout :face :eye :leg} #{:bite :gore}                :hide-from-player-in-range-or-random  7 #{:hostile})
+  (Monster. :gecko          "gecko"          "geckos"          2 0 0.9   0.1   0.5  5 #{:head :face :body :tail :leg}             #{:bite}                      :hide-from-player-in-range-or-random  4 #{:hostile})
+  (Monster. :monkey         "monkey"         "monkies"        13 0 1.2  50    10    5 #{:head :neck :body :tail :leg :face :arm}  #{:bite :punch}               :hide-from-player-in-range-or-random 10 #{:hostile})
+  (Monster. :bird           "bird"           "birds"           4 0 2.1   1     0.3  4 #{:head :body :tail :leg :beak :wing}       #{:bite :claw}                :hide-from-player-in-range-or-random  8 #{:hostile})
+  (Monster. :centipede      "centipede"      "centipedes"      1 0 0.5   0.1   0.1  1 #{:head :body :leg}                         #{:bite}                      :hide-from-player-in-range-or-random  3 #{:hostile})
+  (Monster. :turtle         "turtle"         "turtles"         4 0 0.5  10     1.5 20 #{:head :neck :body :leg :face :shell}      #{:bite}                      :hide-from-player-in-range-or-random  5 #{:hostile})
+  (Monster. :frog           "frog"           "frogs"           2 0 0.9   1     0.7  3 #{:head :body :leg :face}                   #{:claw}                      :hide-from-player-in-range-or-random  4 #{:hostile})
+  (Monster. :parrot         "parrot"         "parrots"         5 0 2.1   1     1    3 #{:head :body :leg :face :wing :tail}       #{:claw :bite}                :hide-from-player-in-range-or-random 10 #{:hostile})
+  (Monster. :shark          "shark"          "sharks"         16 0 1.4 800    30   15 #{:head :body :fin :nose :tail}             #{:bite}                      :hide-from-player-in-range-or-random 10 #{:hostile})
+  (Monster. :fish           "fish"           "fish"            4 0 1.2   4     1    8 #{:head :body :fin :tail}                   #{:bite}                      :hide-from-player-in-range-or-random  4 #{:hostile})
+  (Monster. :octopus        "octopus"        "octopodes"       4 0 1.5  15     5    4 #{:head :body :tentacle}                    #{:bite :bite-venom :squeeze} :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :sea-snake      "sea snake"      "sea snakes"      4 0 1.5   2     1    7 #{:head :body}                              #{:bite :bite-venom}          :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :clam           "clam"           "clams"           2 0 0.1   0.2   0.2 25 #{:shell}                                   #{:clamp}                     :constant                             1 #{:hostile})
+  (Monster. :urchin         "urchin"         "urchins"         2 0 0.1   0.1  10   10 #{:body}                                    #{:spike}                     :constant                             1 #{:hostile})
+  (Monster. :squid          "squid"          "squids"          4 0 1.5  10     6    4 #{:head :body :tentacle}                    #{:bite :squeeze}             :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :crocodile      "crocodile"      "crocodiles"     10 0 0.8 150    15    9 #{:head :body :arm :leg :tail :snout}       #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :mosquito       "mosquito"       "mosquitoes"      1 0 1.4   0.01  0.1  1 #{:head :body :leg :wing}                   #{:bite}                      :hide-from-player-in-range-or-random  3 #{:hostile})
+  (Monster. :mongoose       "mongoose"       "mongeese"        4 0 1.4   5     4    6 #{:head :body :leg :tail}                   #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :tarantula      "tarantula"      "tarantulas"      2 0 1.4   0.1   0.2  2 #{:head :body :leg}                         #{:bite}                      :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :monitor-lizard "monitor lizard" "monitor lizards" 7 0 1.1  10     5   10 #{:head :body :leg :tail}                   #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :komodo-dragon  "komodo dragon"  "komodo dragons" 12 0 0.8  60    10   14 #{:head :body :leg :tail}                   #{:bite :claw}                :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :cobra          "cobra"          "cobras"          5 0 0.8   6     3    7 #{:head :body :tail}                        #{:bite :bite-venom}          :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :puffer-fish    "puffer fish"    "puffer fish"     3 0 1.1   1     0.6  7 #{:head :body :tail}                        #{:sting-venom}               :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :crab           "crab"           "crabs"           4 0 0.8   2     1.5  9 #{:head :body}                              #{:claw}                      :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :hermit-crab    "hermit crab"    "hermit crabs"    3 0 0.6   1     1   15 #{:head :shell :leg}                        #{:claw}                      :hide-from-player-in-range-or-random  1 #{:hostile})
+  (Monster. :electric-eel   "electric eel"   "electric eels"   5 0 0.6  10     5    8 #{:head :body}                              #{:bite}                      :hide-from-player-in-range-or-random  2 #{:hostile})
+  (Monster. :jellyfish      "jellyfish"      "jellyfish"       3 0 0.6   1     0.1  4 #{:body}                                    #{:sting-venom}               :hide-from-player-in-range-or-random  1 #{:hostile})])

 (def ^:private race->monster-map
   (apply hash-map (mapcat (fn [[k v]] [k (first v)])


- Fix spark serialization issue

- Fix spark serialization issue

--- examples/sparkling.clj
+++ examples/sparkling.clj
@@ -32,6 +32,14 @@
 ;; @@

 ;; @@
+(require '[sparkling.destructuring :as s-de])
+;; @@
+
+;; @@
+(require '[sparkling.serialization :as requirered-to-have-serializer-class-read])
+;; @@
+
+;; @@
 (def c (-> (conf/spark-conf)
            (conf/master "local")
            (conf/app-name "sparkling-example")))
@@ -40,3 +48,11 @@
 ;; @@
 (def sc (spark/spark-context c))
 ;; @@
+
+;; @@
+(def data (spark/parallelize sc ["a" "b" "c" "d" "e"]))
+;; @@
+
+;; @@
+(spark/first data)
+;; @@


upgrade clojurescript

upgrade clojurescript

--- ext/chrome/project.clj
+++ ext/chrome/project.clj
@@ -2,15 +2,14 @@
   :description "Owl web front"
   :source-paths ["src/clj" "src/cljs" "src/brepl"]
   :dependencies [[org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "0.0-2816"
+                 [org.clojure/clojurescript "1.8.40"
                   :exclusions [org.apache.ant/ant]]
-                 [compojure "1.2.1"]
-                 [ring/ring-defaults "0.1.3"]
+                 [compojure "1.5.0"]
+                 [ring/ring-defaults "0.2.0"]
                  [hiccup "1.0.5"]
-                 [domina "1.0.3"]
-                 ]
-  :plugins [[lein-cljsbuild "1.0.4"]
-            [lein-ring "0.9.0" #_ ("0.8.13")
+                 [domina "1.0.3"]]
+  :plugins [[lein-cljsbuild "1.1.3"]
+            [lein-ring "0.9.7"
              :exclusions [org.clojure/clojure]]
             [lein-packer "0.1.0"]]
   :hooks [leiningen.cljsbuild]
@@ -32,10 +31,10 @@
                                  }]}
                    :pack {:mapping [{:source-paths ["manifest.json"
                                                     "resources/public"]
-                                     :target-path "target/packed"
+                                     :target-path "target/dev"
                                      :excludes [#"\w+\.\w+\~"]}]
                           :target {:type "crx"
-                                   :path "target/"}}}
+                                   :path "target/dev"}}}
              :pro {:cljsbuild {:builds
                                [{:source-paths ["src/cljs"]
                                  :compiler {:externs
@@ -47,7 +46,7 @@
                                             :warnings true}}]}
                    :pack {:mapping [{:source-paths ["manifest.json"
                                                     "resources/public"]
-                                     :target-path "target/packed"
+                                     :target-path "target/pro"
                                      :excludes [#"\w+\.\w+\~"]}]
                           :target {:type "crx"
-                                   :path "target/packed"}}}})
+                                   :path "target/pro"}}}})


UPdates for May

UPdates for May

--- scrape-n-mail/src/scrape_n_mail/core.cljs
+++ scrape-n-mail/src/scrape_n_mail/core.cljs
@@ -193,8 +193,8 @@
       [:br]
       [:p "Dear " (first-name (::submitter-name (first name-records))) ","]

-      [:p "Our general call for names for Wellbeing for March 2020 has gone out to the newDharma mailing list."
-          " Please let me know if you want to join me for a wellbeing sit - it would be great to see you! (details are in that general call)"]
+      [:p "Our general call for names for Wellbeing for May 2020 has gone out to the newDharma mailing list."
+          " Please let me (Dav) know if you want to join us for a wellbeing sit - it would be great to see you! (details are in that general call)"]

       [:p "Currently, the community is holding the following names on the altar "
           "in support of their wellbeing at your request. Click "


fix the scss component

fix the scss component

--- src/clj/tictag/scss.clj
+++ src/clj/tictag/scss.clj
@@ -19,11 +19,12 @@
   component/Lifecycle
   (start [component]
     (timbre/debugf "Starting SCSS builder? %s" run?)
-    (when run?
+    (if run?
       (assoc component
              :watcher
              (juxt.dirwatch/watch-dir (compile-scss in out)
-                                      (io/file "resources/scss")))))
+                                      (io/file "resources/scss")))
+      component))
   (stop [component]
     (when-let [watcher (:watcher component)]
       (juxt.dirwatch/close-watcher watcher))


decode quote entity references

decode quote entity references

--- src/cljs/app/jokes.cljs
+++ src/cljs/app/jokes.cljs
@@ -3,7 +3,8 @@
    [cljs.core.async.macros :refer [go go-loop alt!]])
   (:require
    [cljs.core.async :as async :refer [chan close! timeout put!]]
-   [app.json :as json :refer [fetch-json]]))
+   [app.json :as json :refer [fetch-json]]
+   [clojure.string :as string :refer [replace]]))

 (def endpoint {:url "http://api.icndb.com/jokes/random"
                :extract #(get-in % ["value" "joke"]) })
@@ -14,6 +15,7 @@
   ([n buf & {:keys [concur] :or {concur n}}]
    (let [out (chan buf (comp
                         (map (:extract endpoint))
+                        (map #(replace % #""" "\""))
                         (partition-all n)))]
      (async/pipeline-async concur out
                            (fn [url ch](fetch-json url #(put! ch % (partial close! ch))))


Use goog.object.clone instead of goog.cloneObject

cloneObject is deprecated, and was failing to clone some kinds of objects
correctly, such as Dates.  Refs #10

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -8,6 +8,7 @@

 (ns cljs.core)
 (goog.require "goog.string.StringBuffer")
+(goog.require "goog.object")

 (defprotocol ICounted
   (-count [coll] "constant time count"))
@@ -1094,7 +1095,7 @@
   IAssociative
   (-assoc [coll k v]
     (if (goog.isString k)
-      (let [new-strobj (goog.cloneObject strobj) ; should use goog.object.clone
+      (let [new-strobj (goog.object.clone strobj)
             overwrite? (.hasOwnProperty new-strobj k)]
         (aset new-strobj k v)
         (if overwrite?
@@ -1107,7 +1108,7 @@
             bucket (aget hashobj h)]
         (if bucket
           (let [new-bucket (array-clone bucket)
-                new-hashobj (goog.cloneObject hashobj)]
+                new-hashobj (goog.object.clone hashobj)]
             (aset new-hashobj h new-bucket)
             (if-let [i (scan-array 2 k new-bucket)]
               (do
@@ -1118,7 +1119,7 @@
                 (.push new-bucket k v)
                 (HashMap. meta new-keys strobj new-hashobj))))
           (let [new-keys (array-clone keys)
-                new-hashobj (goog.cloneObject hashobj)]
+                new-hashobj (goog.object.clone hashobj)]
             (.push new-keys k)
             (aset new-hashobj h (array k v))
             (HashMap. meta new-keys strobj new-hashobj))))))
@@ -1129,7 +1130,7 @@
       (if (not (.hasOwnProperty strobj k))
         coll ; key not found, return coll unchanged
         (let [new-keys (array-clone keys)
-              new-strobj (goog.cloneObject strobj)
+              new-strobj (goog.object.clone strobj)
               new-count (dec (.length keys))]
           (.splice new-keys (scan-array 1 k new-keys) 1)
           (js-delete new-strobj k)
@@ -1141,7 +1142,7 @@
         (if (not i)
           coll ; key not found, return coll unchanged
           (let [new-keys (array-clone keys)
-                new-hashobj (goog.cloneObject hashobj)]
+                new-hashobj (goog.object.clone hashobj)]
             (if (> 3 (.length bucket))
               (js-delete new-hashobj h)
               (let [new-bucket (array-clone bucket)]


fix escape-interaction hiding shapes

fix escape-interaction hiding shapes

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -90,6 +90,8 @@
 (defn cancel-drawing [state]
   (-> state
     (assoc :drawing {:layers []})
+    (assoc-in [:editing-eids :editing-eids] #{})
+    (assoc-in [:selected-eids :selected-eids] #{})
     (assoc-in [:mouse-down] false)))

 (defmethod control-event :cancel-drawing


shutdown workers with disallowed state when shutting down topology

--- src/clj/backtype/storm/daemon/supervisor.clj
+++ src/clj/backtype/storm/daemon/supervisor.clj
@@ -99,11 +99,11 @@
      {}
      (dofor [[id hb] id->heartbeat]
             (let [state (cond
+                         (not hb)
+                           :not-started
                          (or (not (contains? approved-ids id))
                              (not (matches-an-assignment? hb assigned-executors)))
                            :disallowed
-                         (not hb)
-                           :not-started
                          (> (- now (:time-secs hb))
                             (conf SUPERVISOR-WORKER-TIMEOUT-SECS))
                            :timed-out
@@ -263,10 +263,18 @@
        (map :storm-id)
        set))

-(defn try-shutdown-workers [supervisor]
-  (let [worker-root (worker-root (:conf supervisor))
-         ids (read-dir-contents worker-root)]
-    (doseq [id ids]
+(defn shutdown-disallowed-workers [supervisor]
+  (let [conf (:conf supervisor)
+        ^LocalState local-state (:local-state supervisor)
+        assigned-executors (defaulted (.get local-state LS-LOCAL-ASSIGNMENTS) {})
+        now (current-time-secs)
+        allocated (read-allocated-workers supervisor assigned-executors now)
+        disallowed (keys (filter-val
+                                  (fn [[state _]] (= state :disallowed))
+                                  allocated))]
+    (log-debug "Allocated workers " allocated)
+    (log-debug "Disallowed workers " disallowed)
+    (doseq [id disallowed]
       (shutdown-worker supervisor id))
     ))

@@ -325,12 +333,12 @@
       ;; important that this happens after setting the local assignment so that
       ;; synchronize-supervisor doesn't try to launch workers for which the
       ;; resources don't exist
+      (if on-windows? (shutdown-disallowed-workers supervisor))
       (doseq [storm-id downloaded-storm-ids]
         (when-not (assigned-storm-ids storm-id)
           (log-message "Removing code for storm id "
                        storm-id)
           (try
-            (if on-windows? (try-shutdown-workers supervisor))
             (rmr (supervisor-stormdist-root conf storm-id))
             (catch Exception e (log-message (.getMessage e))))
           ))


include as-of date in price query

include as-of date in price query

--- src/clj_money/models/storage/sql_storage.clj
+++ src/clj_money/models/storage/sql_storage.clj
@@ -333,7 +333,7 @@
                   (h/from :prices)
                   (h/where [:and
                             [:= :commodity-id commodity-id]
-                            [:< :trade-date as-of]])
+                            [:<= :trade-date as-of]])
                   (h/order-by [:trade-date :desc])
                   (append-where options)
                   (append-limit options)


(SERVER-2130) Update tests to reflect jit as default compile-mode for jruby 9k

--- test/unit/puppetlabs/services/jruby/jruby_puppet_core_test.clj
+++ test/unit/puppetlabs/services/jruby/jruby_puppet_core_test.clj
@@ -167,7 +167,10 @@
                                     nil)]

       (testing "jruby-config default values are used if not provided"
-        (is (= :off (:compile-mode initialized-jruby-config)))
+        ; jruby-utils defaults to jit when running 9k
+        (if jruby-schemas/using-jruby-9k?
+          (is (= :jit (:compile-mode initialized-jruby-config)))
+          (is (= :off (:compile-mode initialized-jruby-config))))
         (is (= jruby-core/default-borrow-timeout (:borrow-timeout initialized-jruby-config)))
         (is (= (jruby-core/default-pool-size (ks/num-cpus)) (:max-active-instances initialized-jruby-config)))
         (is (= 0 (:max-borrows-per-instance initialized-jruby-config))))


update basic.clj

update basic.clj


main.clj: Cleanup the forms.

main.clj: Cleanup the forms.

Use class btn for submit buttons and form-inline for the entry form.

--- src/statuses/views/main.clj
+++ src/statuses/views/main.clj
@@ -40,9 +40,9 @@

 (defn entry-form []
-  (form-to [:post base]
+  (form-to {:class "form-inline" } [:post base]
            (text-field {:class "input-xxlarge" :autofocus "autofocus" } "text")
-           (submit-button "Send update")))
+           (submit-button {:class "btn" } "Send update")))

 (defn reply-form [id author]
   (form-to [:post base]
@@ -50,7 +50,7 @@
                         :autofocus "autofocus"
                         :value (str "@" author) } "text")
            (hidden-field "reply-to" id)
-           (submit-button "Reply")))
+           (submit-button {:class "btn" } "Reply")))

 (defn list-page [items next request]
   (common/layout


~p118

--- src/study_4clojure/p118.clj
+++ src/study_4clojure/p118.clj
@@ -7,7 +7,10 @@
 ;; Use M-x 4clojure-check-answers when you're done!

 (= [3 4 5 6 7]
-   (__ inc [2 3 4 5 6]))
+   ((fn k [f col]
+      (if (empty? col)
+        col
+        (cons (f (first col)) (lazy-seq (k f (rest col)))))) inc [2 3 4 5 6]))

 (= (repeat 10 nil)
    (__ (fn [_] nil) (range 10)))
@@ -15,4 +18,34 @@
 (= [1000000 1000001]
    (->> (__ inc (range))
         (drop (dec 1000000))
-        (take 2)))+        (take 2)))
+
+(
+(fn k [f col]
+  (if (empty? col)
+    col
+    (cons (f (first col)) (lazy-seq (k f (rest col))))))
+  inc [2 3 4 5 6])
+
+;지금. 이전이랑 거의 똑같네.
+(fn k [f col]
+  (if (empty? col)
+    col
+    (cons (f (first col)) (lazy-seq (k f (rest col))))))
+
+;이전
+(fn _map [f col]
+  (if (empty? col)
+    []
+    (cons (f (first col)) (lazy-seq (_map f (rest col))))))
+
+;max. 여기서 배울 점 deconstructuring.
+(fn m [f [h & t :as v]]
+  (if (empty? v)
+    ()
+    (lazy-seq (cons (f h) (m f t)))))
+
+;chouser. 여기서 배울 점 if를 lazy-seq 안에서 쓸 수 있다는 점.
+(fn l [f [a & m]]
+  (lazy-seq
+    (cons (f a) (if m (l f m)))))


macro initiation

macro initiation

--- src/clj/algorithms_clj/macro_initiation.clj
+++ src/clj/algorithms_clj/macro_initiation.clj
@@ -497,14 +497,10 @@
     (-> log-config :log :enabled?)))

 (defmacro defn-log-3
-  [name bindings body]
+  [& args]
   (if (logger-enabled?)
-    `(defn-log-2 ~name
-       ~bindings
-       ~body)
-    `(defn ~name
-       ~bindings
-       ~body)))
+    `(defn-log-2 ~@args)
+    `(defn ~@args)))

 (defn-log-3 add-with-log-3
   [a b]


Renamed things to "digital-multiplier" instead of "multiple-output-multiplier"

--- src/clojush/examples/digital_multiplier.clj
+++ src/clojush/examples/digital_multiplier.clj
@@ -1,13 +1,13 @@
-;; multiple-output-multiplier.clj
+;; digital-multiplier.clj
 ;; an example problem for clojush, a Push/PushGP system written in Clojure
 ;; Tom Helmuth, thelmuth@cs.umass.edu
 ;;
-;; This is code for the multiple output multiplier problem, as defined in:
+;; This is code for the digital multiplier problem, as defined in:
 ;;    Walker, J.A.; Miller, J.F., "The Automatic Acquisition, Evolution and
 ;;    Reuse of Modules in Cartesian Genetic Programming," Evolutionary
 ;;    Computation, IEEE Transactions on , vol.12, no.4, pp.397,417, Aug. 2008
 ;;
-;; The n-bit multiple output multiplier takes 2 n-bit numbers and outputs their
+;; The n-bit digital multiplier takes 2 n-bit numbers and outputs their
 ;; product. So, this problem requires 2*n bits of input and 2*n bits of output.
 ;; The input is stored in a vector as the first item on the auxiliary stack, and
 ;; the output is stored in a vector as the second item on the auxiliary stack.
@@ -66,7 +66,7 @@
     (eval `(define-registered ~symb (out ~num)))))

 ;; Define atom generators for the problem
-(defn mom-atom-generators
+(defn dm-atom-generators
   [num-bits-n]
   (list
     (fn [] (lrand-nth (list 'boolean_and
@@ -81,7 +81,7 @@
     ))

 ;; Create test cases
-(defn mom-test-cases
+(defn dm-test-cases
   [num-bits-n]
   (for [num1 (range (expt 2 num-bits-n))
         num2 (range (expt 2 num-bits-n))]
@@ -92,7 +92,7 @@

 ;; Create error function; it is applied partially when defined, and takes
 ;; a program and returns its error vector.
-(defn mom-error-function
+(defn dm-error-function
   "Defines the error function of num-bits binary multiplier."
   [num-bits-n test-cases program]
   (doall
@@ -118,15 +118,15 @@
                       result-output))))))

 ;; Define argmap for pushgp
-(defn define-multiple-output-multiplier
+(defn define-digital-multiplier
   [num-bits-n]
   (define-ins (* 2 num-bits-n))
   (define-outs (* 2 num-bits-n))
   (def argmap
-    {:error-function (partial mom-error-function
+    {:error-function (partial dm-error-function
                               num-bits-n
-                              (mom-test-cases num-bits-n))
-     :atom-generators (mom-atom-generators num-bits-n)
+                              (dm-test-cases num-bits-n))
+     :atom-generators (dm-atom-generators num-bits-n)
      :population-size 1000
      :max-generations 500
      :max-points 400
@@ -140,4 +140,4 @@
   )

 ;; Create the argmap passing the number of bits for the problem
-(define-multiple-output-multiplier 2)
+(define-digital-multiplier 2)


Removed some testing code from linclosure implementation

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

--- src/conexp/contrib/algorithms/linclosure.clj
+++ src/conexp/contrib/algorithms/linclosure.clj
@@ -54,30 +54,6 @@
                         (get list a))]
           (recur counts update newdep))))))

-(defn stem-base-from-base
-  "For a given set of implications returns its stem-base."
-  [implications]
-  (loop [stem-base    #{},
-         implications (pmap #(make-implication (premise %)
-                                               (close-under-implications implications
-                                                                         (into (premise %) (conclusion %))))
-                            implications),
-         all          (vec implications)]
-    (if (empty? implications)
-      stem-base
-      (let [A->B         (first implications),
-            implications (rest implications),
-            all          (subvec all 1)
-            A*           (close-under-implications all (premise A->B)),
-            A*->B        (make-implication A* (conclusion A->B))]
-        (if (not-empty (conclusion A*->B))
-          (recur (conj stem-base A*->B)
-                 implications
-                 (conj all A*->B))
-          (recur stem-base
-                 implications
-                 all))))))
-
 ;;;

 (comment


Shape up user Heroku Settings a bit

Shape up user Heroku Settings a bit

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -3,15 +3,13 @@
   is migrating to frontend.components.pages.user-settings. Components will
   migrate there as they conform to Component-Oriented Style."
   (:require [frontend.async :refer [raise!]]
-            [frontend.components.common :as common]
-            [frontend.components.forms :as forms]
             [frontend.components.pieces.button :as button]
             [frontend.components.pieces.card :as card]
+            [frontend.components.pieces.form :as form]
             [frontend.components.pieces.icon :as icon]
             [frontend.components.pieces.modal :as modal]
             [frontend.components.pieces.table :as table]
             [frontend.components.project.common :as project]
-            [frontend.components.svg :refer [svg]]
             [frontend.datetime :as datetime]
             [frontend.models.organization :as org-model]
             [frontend.models.user :as user]
@@ -20,7 +18,6 @@
             [frontend.state :as state]
             [frontend.utils :as utils :include-macros true]
             [frontend.utils.github :as gh-utils]
-            [frontend.utils.seq :refer [select-in]]
             [om.core :as om :include-macros true])
   (:require-macros
    [frontend.utils :refer [component defrender element html]]))
@@ -74,36 +71,30 @@
         (html
          [:div.account-settings-subpage
           [:legend "Heroku Settings"]
-          [:div
-           [:p
-            "Add your " [:a {:href "https://dashboard.heroku.com/account"} "Heroku API Key"]
-            " to set up deployment with Heroku."
-            [:br]
-            ;; Don't tell them to go to the project page if they're already there
-            (when-not project-page?
-              "You'll also need to set yourself as the Heroku deploy user from your project's settings page.")]
-           [:form
-            (when heroku-api-key
-              [:div
-               [:input.disabled
-                {:required  true
-                 :type      "text",
-                 :value heroku-api-key}]
-               [:label {:placeholder "Current Heroku key"}]])
-            [:input
-             {:required  true
-              :auto-focus true
-              :type      "text"
-              :value     heroku-api-key-input
-              :on-change  #(utils/edit-input owner (conj state/user-path :heroku-api-key-input) %)}]
-            [:label {:placeholder "Add new key"}]
-            (button/managed-button
-             {:loading-text "Saving..."
-              :failed-text "Failed to save key"
-              :success-text "Saved"
-              :kind :primary
-              :on-click submit-form!}
-             "Save Heroku Key")]]])))))
+          (card/titled
+           {:title "Heroku API Key"}
+           [:div
+            [:p
+             "Add your " [:a {:href "https://dashboard.heroku.com/account"} "Heroku API Key"]
+             " to set up deployment with Heroku."
+             [:br]
+             ;; Don't tell them to go to the project page if they're already there
+             (when-not project-page?
+               "You'll also need to set yourself as the Heroku deploy user from your project's settings page.")]
+            [:p
+             "Your Heroku Key is currently " heroku-api-key]
+            (form/form
+             {}
+             (om/build form/text-field {:label "Heroku Key"
+                                        :value heroku-api-key-input
+                                        :on-change #(utils/edit-input owner (conj state/user-path :heroku-api-key-input) %)})
+             (button/managed-button
+              {:loading-text "Saving..."
+               :failed-text "Failed to save key"
+               :success-text "Saved"
+               :kind :primary
+               :on-click submit-form!}
+              "Save Heroku Key"))])])))))

 (defn api-tokens [app owner]
   (reify


rearrange shortcuts menu list

rearrange shortcuts menu list

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -397,37 +397,41 @@
            [:table.shortcuts-items
             [:tbody
              ;;
-             ;; keystrokes beginning with "option"
-             ;;
-             [:tr.make
-              [:td
-               [:div.shortcuts-keys
-                [:div.shortcuts-key  {:title "Option Key"} (common/icon :option)]
-                [:div.shortcuts-misc {:title "Left Click"} (common/icon :mouse)]]]
-              [:td [:div.shortcuts-result {:title "Hold option, drag shape(s)."} "Duplicate"]]]
-             [:tr.make
-              [:td
-               [:div.shortcuts-keys
-                [:div.shortcuts-key  {:title "Option Key"} (common/icon :option)]
-                [:div.shortcuts-misc {:title "Scroll Wheel"} (common/icon :scroll)]]]
-              [:td [:div.shortcuts-result {:title "Hold option, scroll."} "Zoom"]]]
-             ;;
-             ;; keystrokes beginning with "shift"
-             ;;
-             [:tr.make
-              [:td {:col-span "2"}]]
-             [:tr.make
-              [:td
-               [:div.shortcuts-keys
-                [:div.shortcuts-key {:title "Shift Key"} (common/icon :shift)]
-                [:div.shortcuts-misc {:title "Left Click"} (common/icon :mouse)]]]
-              [:td [:div.shortcuts-result {:title "Hold shift, click multiple shapes."} "Stack"]]]
-             [:tr.make
-              [:td
-               [:div.shortcuts-keys
-                [:div.shortcuts-key {:title "Shift Key"} (common/icon :shift)]
-                [:div.shortcuts-misc {:title "Scroll Wheel"} (common/icon :scroll)]]]
-              [:td [:div.shortcuts-result {:title "Hold shift, scroll."} "Pan"]]]
+             ;; single keystrokes
+             ;;
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "V Key"} "V"]]
+              [:td [:div.shortcuts-result {:title "Switch to Select Tool."} "Select"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "M Key"} "M"]]
+              [:td [:div.shortcuts-result {:title "Switch to Rectangle Tool."} "Rectangle"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "L Key"} "L"]]
+              [:td [:div.shortcuts-result {:title "Switch to Circle Tool."} "Circle"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "Backslash Key"} "\\"]]
+              [:td [:div.shortcuts-result {:title "Switch to Line Tool."} "Line"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "N Key"} "N"]]
+              [:td [:div.shortcuts-result {:title "Switch to Pen Tool."} "Pen"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "T Key"} "T"]]
+              [:td [:div.shortcuts-result {:title "Switch to Text Tool."} "Text"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "1 Key"} "1"]]
+              [:td [:div.shortcuts-result {:title "Initial view when entering doc."} "Origin"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "2 Key"} "2"]]
+              [:td [:div.shortcuts-result {:title "Return to previous view after jumping to origin."} "Return"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "? Key"} "?"]]
+              [:td [:div.shortcuts-result {:title "Hold shift, press \"/\"."} "Shortcuts"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "Delete Key"} (common/icon :delete)]]
+              [:td [:div.shortcuts-result {:title "Delete selected shape(s)."} "Delete"]]]
+             [:tr.make
+              [:td [:div.shortcuts-key {:title "Escape Key"} (common/icon :esc)]]
+              [:td [:div.shortcuts-result {:title "Cancel action or close menu."} "Cancel"]]]
              ;;
              ;; keystrokes beginning with "command"
              ;;
@@ -456,43 +460,39 @@
                 [:div.shortcuts-key {:title "Z Key"} "Z"]]]
               [:td [:div.shortcuts-result {:title "Hold command, press \"Z\"."} "Undo"]]]
              ;;
-             ;; single keystrokes
+             ;; keystrokes beginning with "option"
              ;;
              [:tr.make
               [:td {:col-span "2"}]]
              [:tr.make
-              [:td [:div.shortcuts-key {:title "V Key"} "V"]]
-              [:td [:div.shortcuts-result {:title "Switch to Select Tool."} "Select"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "M Key"} "M"]]
-              [:td [:div.shortcuts-result {:title "Switch to Rectangle Tool."} "Rectangle"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "L Key"} "L"]]
-              [:td [:div.shortcuts-result {:title "Switch to Circle Tool."} "Circle"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "Backslash Key"} "\\"]]
-              [:td [:div.shortcuts-result {:title "Switch to Line Tool."} "Line"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "N Key"} "N"]]
-              [:td [:div.shortcuts-result {:title "Switch to Pen Tool."} "Pen"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "T Key"} "T"]]
-              [:td [:div.shortcuts-result {:title "Switch to Text Tool."} "Text"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "1 Key"} "1"]]
-              [:td [:div.shortcuts-result {:title "Initial view when entering doc."} "Origin"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "2 Key"} "2"]]
-              [:td [:div.shortcuts-result {:title "Return to previous view after jumping to origin."} "Return"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "? Key"} "?"]]
-              [:td [:div.shortcuts-result {:title "Hold shift, press \"/\"."} "Shortcuts"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "Delete Key"} (common/icon :delete)]]
-              [:td [:div.shortcuts-result {:title "Delete selected shape(s)."} "Delete"]]]
-             [:tr.make
-              [:td [:div.shortcuts-key {:title "Escape Key"} (common/icon :esc)]]
-              [:td [:div.shortcuts-result {:title "Cancel action or close menu."} "Cancel"]]]
+              [:td
+               [:div.shortcuts-keys
+                [:div.shortcuts-key  {:title "Option Key"} (common/icon :option)]
+                [:div.shortcuts-misc {:title "Left Click"} (common/icon :mouse)]]]
+              [:td [:div.shortcuts-result {:title "Hold option, drag shape(s)."} "Duplicate"]]]
+             [:tr.make
+              [:td
+               [:div.shortcuts-keys
+                [:div.shortcuts-key  {:title "Option Key"} (common/icon :option)]
+                [:div.shortcuts-misc {:title "Scroll Wheel"} (common/icon :scroll)]]]
+              [:td [:div.shortcuts-result {:title "Hold option, scroll."} "Zoom"]]]
+             ;;
+             ;; keystrokes beginning with "shift"
+             ;;
+             [:tr.make
+              [:td {:col-span "2"}]]
+             [:tr.make
+              [:td
+               [:div.shortcuts-keys
+                [:div.shortcuts-key {:title "Shift Key"} (common/icon :shift)]
+                [:div.shortcuts-misc {:title "Left Click"} (common/icon :mouse)]]]
+              [:td [:div.shortcuts-result {:title "Hold shift, click multiple shapes."} "Stack"]]]
+             [:tr.make
+              [:td
+               [:div.shortcuts-keys
+                [:div.shortcuts-key {:title "Shift Key"} (common/icon :shift)]
+                [:div.shortcuts-misc {:title "Scroll Wheel"} (common/icon :scroll)]]]
+              [:td [:div.shortcuts-result {:title "Hold shift, scroll."} "Pan"]]]
              ]]]])))))

 (defn username [app owner]


Added ?gadm2 field to forma->cdm output

Added ?gadm2 field to forma->cdm output

--- src/clj/forma/hadoop/jobs/postprocess.clj
+++ src/clj/forma/hadoop/jobs/postprocess.clj
@@ -87,7 +87,7 @@
                 50)"
   [src nodata zoom tres tres-out start thresh]
   (let [epoch (date/datetime->period tres-out "2000-01-01")]
-    (<- [?x ?y ?z ?p ?iso ?lat ?lon]
+    (<- [?x ?y ?z ?p ?iso ?gadm2 ?lat ?lon]
         (src ?sres ?modh ?modv ?s ?l ?start-period ?prob-series ?gadm2)
         (gadm2->iso ?gadm2 :> ?iso)
         (o/clean-probs ?prob-series nodata :> ?clean-series)


Add missing function to handlers/postal that is previously removed from helpers.

--- src/clojure/catacumba/handlers/postal.clj
+++ src/clojure/catacumba/handlers/postal.clj
@@ -167,9 +167,20 @@
           (-encode content-type)
           (frame->http content-type)))))

-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Public Api
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defn- connect-chans
+  "Like core.async pipe but reacts on close
+  in both sides."
+  [from to]
+  (a/go-loop []
+    (let [v (a/<! from)]
+      (if (nil? v)
+        (a/close! to)
+        (if (a/>! to v)
+          (recur)
+          (a/close! from)))))
+  to)
+
+;; --- Public Api

 (defn frame
   "A convenience helper that allow easy create a frame compatible
@@ -242,8 +253,8 @@
                     in' (a/chan 1 in-xf)]

                 ;; Connect transformatons
-                (hp/connect-chans out' out)
-                (hp/connect-chans in in')
+                (connect-chans out' out)
+                (connect-chans in in')

                 ;; keep-alive loop
                 (a/go-loop [n 1]


reducing session timeout

reducing session timeout

--- src/clojure/src/leela/blackbox/config.clj
+++ src/clojure/src/leela/blackbox/config.clj
@@ -121,7 +121,7 @@
 (defn zk-connect [zkref]
   (let [watcher             (zk-make-watcher zk-watcher zk-connect zkref)
         [_ _ endpoint auth] @zkref]
-    (swap! zkref (fn [[_ & args] zk] (cons zk args)) (ZooKeeper. endpoint 30000 watcher))
+    (swap! zkref (fn [[_ & args] zk] (cons zk args)) (ZooKeeper. endpoint 5000 watcher))
     zkref))

 (defn zk-attach [node endpoint auth]


gain ~15% throughput by buffering the ack-process chan

--- src/com/farmlogs/conduit/subscription.clj
+++ src/com/farmlogs/conduit/subscription.clj
@@ -61,7 +61,7 @@
   (start [this]
     (log/infof "Starting subscription on queue '%s'" (:queue-name queue-config))
     (let [rmq-chan (or rmq-chan (make-channel (:conn rmq-connection) queue-config))
-          new-messages (a/chan)
+          new-messages (a/chan buffer-size)
           pending-messages (a/chan buffer-size)
           ack-process (->ack-process new-messages buffer-size rmq-chan)
           cancelled? (promise)


Useless expression removed. (if a b nil) is equivalent to (if a b)

--- KataTrigrams/src/kata_trigrams/helpers.clj
+++ KataTrigrams/src/kata_trigrams/helpers.clj
@@ -44,5 +44,4 @@
   [w1 w2 m] ; word1 word2 trigrams-map
   (let [wl (m (join-2-words w1 w2))] ; words list
     (if (seq wl)
-      (rand-nth wl)
-      nil)))
+      (rand-nth wl))))


Add a protected routes component

Add a protected routes component

This allows routes to be created and protected with a protection domain.

--- modules/entrance/src/modular/entrance.clj
+++ modules/entrance/src/modular/entrance.clj
@@ -284,13 +284,38 @@
   (routes [this] (routes (:login this)))
   (context [this] (context (:login this))))

-(def new-protection-domain-schema {(s/optional-key :session-timeout-in-seconds) s/Int})
-
-(defn new-protection-domain [cfg]
-  (s/validate new-protection-domain-schema cfg)
+(def new-default-protection-domain-schema {(s/optional-key :session-timeout-in-seconds) s/Int})
+
+(defn new-default-protection-domain [cfg]
+  (s/validate new-default-protection-domain-schema cfg)
   (map->ProtectionDomain
    {:login (new-login-form)
     :authorizer (new-map-backed-user-registry {"malcolm" "password"})
     :http-session-store (new-atom-backed-session-store
                          (or (:session-timeout-in-seconds cfg)
                              10))}))
+
+;; Now that we have a protection domain, we want the ability to create
+;; routes components that can be protected.
+
+(defrecord ProtectedRoutes [routes context]
+  component/Lifecycle
+  (start [this]
+    (let [pd (get-in this [:protection-domain :login])
+          routes (cond-> routes
+                         (fn? routes) (apply [this])
+                         pd ((partial protect-routes pd)))]
+
+      (println "Routes is" routes)
+      (assoc this :routes routes)))
+  (stop [this] this)
+
+  BidiRoutesContributor
+  (routes [this] (:routes this))
+  (context [this] context))
+
+(defn new-protected-routes
+  "Routes can a bidi route structure, or a function that takes the
+  component and returns a bidi route structure."
+  [routes context]
+  (component/using (->ProtectedRoutes routes context) [:protection-domain]))


Adjust for name change

Adjust for name change

--- desktop/src/nightmod/core/desktop_launcher.clj
+++ desktop/src/nightmod/core/desktop_launcher.clj
@@ -26,8 +26,8 @@
 (def ^:const window-height 768)
 (def ^:const editor-width 700)

-(def editor-controls [:save :undo :redo :font-dec :font-inc
-                      :doc :paredit :paredit-help])
+(def editor-widgets [:save :undo :redo :font-dec :font-inc
+                     :doc :paredit :paredit-help])

 (defn create-layered-pane
   "Returns the pane with the editors."
@@ -92,6 +92,6 @@
   (SubstanceLookAndFeel/setSkin (GraphiteSkin.))
   (s/invoke-later
     (s/show! (reset! ui/ui-root (create-window)))
-    (binding [editors/editor-controls editor-controls]
+    (binding [editors/editor-widgets editor-widgets]
       (comment editors/show-editor! "")))
   (Keyboard/enableRepeatEvents true))


fix change to init-state (no longer a function)

--- src/leiningen/new/lein_quick_om/main.cljs
+++ src/leiningen/new/lein_quick_om/main.cljs
@@ -29,11 +29,11 @@
 (def init-state
   {:example-data (mapv (fn [n] {:value n}) (range 1 5))})

-(defonce state (atom (init-state)))
+(defonce state (atom init-state))

 (def devbar-opts
-  {:buttons [[#(reset! state (init-state)) "reset state"]
+  {:buttons [[#(reset! state init-state) "reset state"]
              [#(db/toggle-dev dev-mode state) "toggle devmode"]
              [#(sv/toggle-state-view state-viewer state) "toggle state viewer"]]})


fix(backend): fix run-test function

fix(backend): fix run-test function

--- backend/src/user.clj
+++ backend/src/user.clj
@@ -41,7 +41,7 @@
       (mount/start)))

 (defn- run-test
-  ([] (test #"^uxbox.tests.*"))
+  ([] (run-test #"^uxbox.tests.*"))
   ([o]
    (repl/refresh)
    (cond


UUID tests, skipping identical? for now

UUID tests, skipping identical? for now


(TK-149) cleanup flow per feedback in crl handling

* per feedback remove thread-first macro and anonymous function, instead opting
  for shadowing a variable in the let context. overall increase readability.

Signed-off-by: Moses Mendoza <76c580f0e3e4c9061b71a0636aee421ebf678b6e@puppet.com>

--- src/clj/puppetlabs/services/ca/certificate_authority_service.clj
+++ src/clj/puppetlabs/services/ca/certificate_authority_service.clj
@@ -24,7 +24,8 @@
          puppet-version (get-in-config [:puppetserver :puppet-version])
          custom-oid-file (get-in-config [:puppetserver :trusted-oid-mapping-file])
          oid-mappings (ca/get-oid-mappings custom-oid-file)
-         auth-handler (fn [request] (wrap-with-authorization-check request {:oid-map oid-mappings}))]
+         auth-handler (fn [request] (wrap-with-authorization-check request {:oid-map oid-mappings}))
+         context' (assoc context :auth-handler auth-handler)]
      (ca/validate-settings! settings)
      (ca/initialize! settings)
      (log/info (i18n/trs "CA Service adding a ring handler"))
@@ -39,32 +40,29 @@
          auth-handler
          puppet-version)
        {:normalize-request-uri true})
-     (-> context
-         (assoc :auth-handler auth-handler)
-         ((fn [context]
-           (if-let [filesystem-watch-service
-                      (tk-services/maybe-get-service this :FilesystemWatchService)]
-              (let [ca-crl-file (.getCanonicalPath (fs/file
-                                                (get-in-config
-                                                  [:puppetserver :cacrl])))
-                    host-crl-file (.getCanonicalPath (fs/file
-                                                  (get-in-config
-                                                    [:puppetserver :hostcrl])))
-                    watcher (watch-protocol/create-watcher filesystem-watch-service)]
-                (when (not= ca-crl-file host-crl-file)
-                  (watch-protocol/add-watch-dir! watcher
-                                                  (fs/parent ca-crl-file)
-                                                  {:recursive true})
-                  (watch-protocol/add-callback!
-                    watcher
-                    (fn [events]
-                      (when (some #(and (:changed-path %)
-                                        (= (.getCanonicalPath (:changed-path %))
-                                          ca-crl-file))
-                                  events)
-                        (ca/retrieve-ca-crl! ca-crl-file host-crl-file)))))
-                (assoc context :watcher watcher))
-            context))))))
+       (if-let [filesystem-watch-service
+                 (tk-services/maybe-get-service this :FilesystemWatchService)]
+         (let [ca-crl-file (.getCanonicalPath (fs/file
+                                           (get-in-config
+                                             [:puppetserver :cacrl])))
+               host-crl-file (.getCanonicalPath (fs/file
+                                             (get-in-config
+                                               [:puppetserver :hostcrl])))
+               watcher (watch-protocol/create-watcher filesystem-watch-service)]
+           (when (not= ca-crl-file host-crl-file)
+             (watch-protocol/add-watch-dir! watcher
+                                             (fs/parent ca-crl-file)
+                                             {:recursive true})
+             (watch-protocol/add-callback!
+               watcher
+               (fn [events]
+                 (when (some #(and (:changed-path %)
+                                   (= (.getCanonicalPath (:changed-path %))
+                                     ca-crl-file))
+                             events)
+                   (ca/retrieve-ca-crl! ca-crl-file host-crl-file)))))
+           (assoc context' :watcher watcher))
+       context')))

   (initialize-master-ssl!
    [this master-settings certname]


Update sal petroprodukt

Update sal petroprodukt

--- src/clj_simple_chart/ssb/data/sal_av_petroleumsprodukt_11174.clj
+++ src/clj_simple_chart/ssb/data/sal_av_petroleumsprodukt_11174.clj
@@ -9,15 +9,13 @@
 ;
 ; https://www.ssb.no/statbank/table/11174?rxid=49a52ff4-5d3c-4264-aa49-95134312070d

-(def raw-data (ssb/fetch 11174 {"ContentsCode"  "Salg"
-                                "Region"        "Hele landet"
-                                "PetroleumProd" ["Autodiesel" "Bilbensin"]
-                                "Kjopegrupper"  "Alle kjøpegrupper"
-                                "Tid"           "*"}))
+(def raw-data (ssb/fetch 11174 {[:ContentsCode :as :salg]               "Salg"
+                                "Region"                                "Hele landet"
+                                [:PetroleumProd :as :petroleumsprodukt] ["Autodiesel" "Bilbensin"]
+                                [:Kjopegrupper :as :kjøpegruppe]        "Alle kjøpegrupper"
+                                [:Tid :as :dato]                        "*"}))

-(test/is (= [:kjøpegruppe :petroleumsprodukt :region :salg] (:columns raw-data)))
-
-(def data (->> (:data raw-data)
+(def data (->> raw-data
                (map #(dissoc % :kjøpegruppe))
                (map #(dissoc % :region))
                (csv/number-or-throw-columns [:salg])
@@ -25,4 +23,5 @@
                (contract-by-column :dato)
                (flat->12-mms)))

-(test/is (= "2010-12" (:dato (first data))))+(test/is (= "2010-12" (:dato (first data))))
+(test/is (= "2018-03" (:dato (last data))))


CMR-3676 PR comments

CMR-3676 PR comments

--- umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/iso19115_2.clj
+++ umm-spec-lib/src/cmr/umm_spec/xml_to_umm_mappings/iso19115_2.clj
@@ -172,8 +172,11 @@
 (defn- parse-online-resource
  "Parse online resource from the publication XML"
  [publication sanitize?]
- (when-let [party (first (select publication "gmd:citedResponsibleParty/gmd:CI_ResponsibleParty[gmd:role/gmd:CI_RoleCode/@codeListValue='resourceProvider']"))]
-  (when-let [online-resource (first (select party "gmd:contactInfo/gmd:CI_Contact/gmd:onlineResource/gmd:CI_OnlineResource"))]
+ (when-let [party
+            (first (select publication (str "gmd:citedResponsibleParty/gmd:CI_ResponsibleParty"
+                                            "[gmd:role/gmd:CI_RoleCode/@codeListValue='resourceProvider']")))]
+  (when-let [online-resource
+             (first (select party "gmd:contactInfo/gmd:CI_Contact/gmd:onlineResource/gmd:CI_OnlineResource"))]
     {:Linkage (url/format-url (value-of online-resource "gmd:linkage/gmd:URL") sanitize?)
      :Protocol (char-string-value online-resource "gmd:protocol")
      :ApplicationProtocol (char-string-value online-resource "gmd:applicationProfile")


Don't rely on ring internals.

Don't rely on ring internals.

This has the side effect of allowing us to work with ring 1.2.x.

--- web/src/immutant/web/internal/headers.clj
+++ web/src/immutant/web/internal/headers.clj
@@ -12,14 +12,15 @@
 ;; See the License for the specific language governing permissions and
 ;; limitations under the License.

-(ns ^{:no-doc true}
-  immutant.web.internal.headers
-  (:require [clojure.string :as str]
-            ring.util.request))
+(ns ^:no-doc ^:internal
+    immutant.web.internal.headers
+  (:require [clojure.string :as str]))

-(def charset-pattern (deref #'ring.util.request/charset-pattern))
+;; borrowed from ring.util.request/charset-pattern, which appeared in ring 1.3.0.
+(def ^:private charset-pattern
+  #";(?:.*\s)?(?i:charset)=([!#$%&'*\-+.0-9A-Z\^_`a-z\|~]+|\"(\\\"|[^\"])*\")\s*(?:;|$)")

-(def default-encoding "ISO-8859-1")
+(def ^:private default-encoding "ISO-8859-1")

 (defprotocol Headers
   (get-names [x])
@@ -28,13 +29,13 @@
   (set-header [x key value])
   (add-header [x key value]))

-(defn ^String get-character-encoding [headers]
+(defn ^:internal ^String get-character-encoding [headers]
   (or
     (when-let [type (get-value headers "content-type")]
       (second (re-find charset-pattern type)))
     default-encoding))

-(defn headers->map [headers]
+(defn ^:internal headers->map [headers]
   (persistent!
     (reduce
       (fn [accum ^String name]
@@ -46,7 +47,7 @@
       (transient {})
       (get-names headers))))

-(defn write-headers
+(defn ^:internal write-headers
   [output, headers]
   (doseq [[^String k, v] headers]
     (if (coll? v)


Save partial solution when ProblemActivity is stopped

--- src/clojure/org/bytopia/foreclojure/problem.clj
+++ src/clojure/org/bytopia/foreclojure/problem.clj
@@ -243,6 +243,13 @@
            (check-solution-on-server this solution)))))
     )

+  :on-stop
+  (fn [this]
+    (safe-for-ui
+     (let [code (str (.getText ^EditText (find-view this ::codebox)))]
+       (when-not (= code "")
+         (save-solution this code false)))))
+
   :on-create-options-menu
   (fn [this menu]
     (safe-for-ui
@@ -256,8 +263,5 @@
   (fn [this item]
     (safe-for-ui
      (if (= (.getItemId item) android.R$id/home)
-       (let [code (str (.getText ^EditText (find-view this ::codebox)))]
-         (when-not (= code "")
-           (save-solution this code false))
-         (.finish this))
+       (.finish this)
        (.superOnOptionsItemSelected this item)))))