More comments on macros.

More comments on macros.

--- src/cbfg/act.clj
+++ src/cbfg/act.clj
@@ -1,6 +1,6 @@
-;; Wrappers around core.async that track parent-child relationships
-;; and provide events.  Useful for building things like visualizations
-;; and simulations.
+;; These "act" wrappers around ago provide parent-child tracking and
+;; event hooks.  Useful for building things like visualizations and
+;; simulations.  (ago ehances core.async with snapshots/rollback.)

 (ns cbfg.act
   (:require [cljs.core.async.macros :refer [go]]
@@ -10,12 +10,12 @@
   `(first ~actx))

 (defmacro actx-agw [actx]
-  `((:get-agw (actx-top ~actx))))
+  `((:get-agw (actx-top ~actx)))) ; The 'agw' means 'ago world'.

 (defmacro actx-event [actx event]
   `(cljs.core.async/>! (:event-ch (actx-top ~actx)) [~actx ~event]))

-(defmacro act [child-actx-binding-name actx & body]
+(defmacro act [child-actx-binding-name actx & body] ; Use 'act' instead of 'go'.
   `(let [act-ch# (achan-buf ~actx 1)
          act-id# ((:gen-id (actx-top ~actx)))
          ~child-actx-binding-name (conj ~actx
@@ -31,6 +31,7 @@
      act-ch#))

 (defmacro act-loop [child-actx-binding-name actx bindings & body]
+  ; Use 'act-loop' instead of 'go-loop'.
   (let [m (->> bindings
                (partition 2)
                (map first)
@@ -41,7 +42,7 @@
                         [:act-loop :loop-state (sorted-map ~@m)])
             ~@body))))

-(defmacro achan [actx]
+(defmacro achan [actx] ; Use 'achan' instead of 'chan'.
   `(achan-buf ~actx nil))

 (defmacro achan-buf [actx buf-or-size]


cleanup

cleanup

--- src/babel/francais/morphology.cljc
+++ src/babel/francais/morphology.cljc
@@ -18,7 +18,6 @@
 (declare analyze)
 (declare get-string)
 (declare suffix-of)
-

 (defn analyze [surface-form lexicon]
   "Analyze a single surface form into a set of lexical forms."


Removed debug println

Removed debug println

--- src/cljs/salava/badge/ui/modal.cljs
+++ src/cljs/salava/badge/ui/modal.cljs
@@ -35,7 +35,6 @@
     {:handler (fn [] (swap! state assoc :congratulated? true))}))

 (defn badge-endorsement-modal-link [badge-id endorsement-count]
-  (println badge-id)
   (when (pos? endorsement-count)
     [:div.row
      [:div.col.xs-12


Fix tweeting, fix animation check

Fix tweeting, fix animation check

--- src/cljs/surprise_kittens/core.cljs
+++ src/cljs/surprise_kittens/core.cljs
@@ -24,23 +24,21 @@
     (str (subs url 0 dot-index) "m" (subs url dot-index))))

 (defn image [kitten]
-  (if-let [webm (:webm kitten)]
+  (if (:animated kitten)
     (dom/video #js {:autoPlay "autoplay"
                     :className "clickable rounded shadowed"
                     :height (:height kitten)
                     :loop "loop"
                     :muted "muted"}
-      (dom/source #js {:src webm})
+      (dom/source #js {:src (:webm kitten)})
       (dom/source #js {:src (:mp4 kitten)}))
     (dom/img #js {:className "clickable rounded shadowed"
                   :src (medium-image-url (:link kitten))})))

 (defn tweet-url [link]
-  (str "https://twitter.com/intent/tweet?text="
+  (str "https://twitter.com/intent/tweet?via=srprisekittens&text="
     (js/encodeURIComponent "Surprise! Kittens! ")
-    (js/encodeURIComponent link)
-    (js/encodeURIComponent " from http://surprisekittens.com")
-    "&via=sprisekittens"))
+    (js/encodeURIComponent link)))

 (defn tweet-button [link]
   (dom/a #js {:className "twitter-share-button"


Some more macros for conexp.contrib.exec

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

--- src/conexp/contrib/exec.clj
+++ src/conexp/contrib/exec.clj
@@ -9,18 +9,31 @@
 (ns conexp.contrib.exec
   (:use conexp.main
         [conexp.io.util :only (tmpfile)])
-  (:use clojure.contrib.shell-out))
+  (:use clojure.contrib.shell-out
+        [clojure.contrib.io :only (with-out-writer)]))

 (ns-doc "Executing external programs with a common interface.")

 ;;;

 (defn run-in-shell
-  "Runs given commandline in an external shell process."
+  "Runs given commandline in an external shell process. Returns the
+  output on stdout as result."
   [& cmdln]
-  (apply sh
-         :return-map true
-         cmdln))
+  (let [result (apply sh
+                      :return-map true
+                      cmdln)]
+    (when-not (zero? (:exit result))
+      (illegal-state "External program " (first cmdln) " returned with non-zero status: " (:err result)))
+    (:out result)))
+
+(defn- context-to-file
+  "Writes context to a file using format and returns the name of the
+  file."
+  [context format]
+  (let [^java.io.File file (tmpfile)]
+    (write-context format context file)
+    (.getAbsolutePath file)))

 (defmacro define-external-program
   "Defines program-name to be a function calling an external
@@ -55,20 +68,24 @@
                                        (dissoc (zipmap arguments arg-names) :context))
                                 cmdln)))))

-;;;
+(defmacro with-context-from-output
+  "Runs body, expecting to get a string containing a formal
+  context. Writes this string to a file and reads it in
+  with read-context, returning the result."
+  [& body]
+  `(let [result# (do ~@body),
+         file#   (tmpfile)]
+     (with-out-writer file#
+       (print result#))
+     (read-context file#)))

-(defn- context-to-file
-  "Writes context to a file using format and returns the name of the
-  file."
-  [context format]
-  (let [^java.io.File file (tmpfile)]
-    (write-context format context file)
-    (.getAbsolutePath file)))
-
-(defn- context-from-file
-  "Returns the context from file."
-  [file]
-  (read-context file))
+(defmacro with-context-from-tmpfile
+  "Creates a new temporary file, executes body and returns the result
+  from calling read-context on file."
+  [file & body]
+  `(let [~file (tmpfile),
+         result# (do ~@body)]
+     (read-context ~file)))

 ;;;


add more pg operators

add more pg operators

--- src/clj_pg/honey.clj
+++ src/clj_pg/honey.clj
@@ -91,6 +91,10 @@

 (defmethod sqlf/fn-handler "ilike" [_ col qstr]
   (str (sqlf/to-sql col) " ilike " (sqlf/to-sql qstr)))
+
+(doseq [op ["@@" "@>" "<@" "||" "&&" "->" "->>" "#>>" "#>" "?" "?|" "?&" "#-"]]
+  (defmethod sqlf/fn-handler op [_ col qstr]
+    (str (sqlf/to-sql col) " " op " " (sqlf/to-sql qstr))))

 (defmethod sqlf/fn-handler "not-ilike" [_ col qstr]
   (str (sqlf/to-sql col) " not ilike " (sqlf/to-sql qstr)))


Fix a comment of docstring

Fix a comment of docstring

--- src/cljam/io/wig.clj
+++ src/cljam/io/wig.clj
@@ -122,7 +122,7 @@
                    (update current-track :values conj v))))))))

 (defn- serialize-wig
-  "Serialize WIG line into vector of strings."
+  "Serialize WIG fields into string."
   [wig]
   {:pre [;; There are two options for formatting wiggle data.
          (or (= (:format wig) :fixed-step) (= (:format wig) :variable-step))


svg/axis template should unify against ticks and scale so that tick marks are properly redrawn when axis scale changes.

--- src/cljx/c2/svg.cljx
+++ src/cljx/c2/svg.cljx
@@ -114,8 +114,9 @@
     [:g {:class (str "axis " (name orientation))}
      [:line.rule (apply hash-map (interleave [y1 y2] (:range scale)))]
      [:g.ticks
-      (unify ticks
-             (fn [d]
+      ;;Need to weave scale into tick stream so that unify updates nodes when the scale changes.
+      (unify (map vector ticks (repeat scale))
+             (fn [[d scale]]
                [:g.tick.major-tick {:transform (translate {x 0 y (scale d)})}
                 [:text {x (* parity text-margin)} (formatter d)]
                 [:line {x1 0 x2 (* parity major-tick-width)}]]))]


CMR-3773: Adding more comments and checking to tests.

--- orbits-lib/test/cmr/orbits/ruby_specs.clj
+++ orbits-lib/test/cmr/orbits/ruby_specs.clj
@@ -28,12 +28,17 @@
             ;; results for each spec.
             :let [jruby (create-jruby-runtime)]]
       (testing spec-name
-       (eval-jruby
-        jruby
-        (format "load 'spec/%s'" spec-name))
-       ;; RSPec returns 0 when tests pass and 1 when they fail.
-       (is (= 0 (eval-jruby jruby "require 'rspec/core'; RSpec::Core::Runner.run([])"))
-           (str "RSPec returned failure status for " spec-name))))))
+        (try
+          (eval-jruby
+           jruby
+           (format "load 'spec/%s'" spec-name))
+          (catch Exception e
+            (println "The spec failed to load. You may need to install the gems in orbits lib to continue."
+                     "Run lein install-gems in orbits-lib and restart your REPL.")
+            (throw e)))
+        ;; RSPec returns 0 when tests pass and 1 when they fail.
+        (is (= 0 (eval-jruby jruby "require 'rspec/core'; RSpec::Core::Runner.run([])"))
+            (str "RSPec returned failure status for " spec-name))))))


prepare event handler for reitit #377

prepare event handler for reitit
#377

--- src/clj/swarmpit/event/handler.clj
+++ src/clj/swarmpit/event/handler.clj
@@ -1,15 +1,17 @@
 (ns swarmpit.event.handler
   (:require [org.httpkit.server :refer [with-channel on-close send!]]
             [clojure.walk :refer [keywordize-keys]]
-            [swarmpit.handler :refer [dispatch resp-accepted resp-error resp-unauthorized]]
+            [swarmpit.handler :refer [resp-accepted resp-error resp-unauthorized]]
             [swarmpit.event.channel :as channel]
             [swarmpit.event.processor :as processor]
             [swarmpit.event.rules.predicate :refer [stats?]]
+            [clojure.tools.logging :as log]
+
             [swarmpit.slt :as slt]))

 (defn events
-  [{{:keys [query]} :parameters}]
-  (let [slt (:slt query)]
+  [{:keys [parameters] :as request}]
+  (let [slt (get-in parameters [:query :slt])]
     (if (slt/valid? slt)
       (with-channel request channel
                     (send! channel {:status  200


Fix badge schema: issuer name and url are not required values

--- src/cljc/salava/badge/schemas.cljc
+++ src/cljc/salava/badge/schemas.cljc
@@ -41,7 +41,7 @@
                            :image_file                           (s/maybe s/Str)
                            :issued_on                            (s/maybe s/Int)
                            :expires_on                           (s/maybe s/Int)
-                           :revoked (s/maybe s/Bool)
+                           :revoked                              (s/maybe s/Bool)
                            :visibility                           (s/maybe (s/enum "private" "internal" "public"))
                            :status                               (s/maybe (s/enum "pending" "accepted" "declined"))
                            :mtime                                s/Int
@@ -52,9 +52,9 @@
                            :issued_by_obf                        s/Bool
                            :verified_by_obf                      s/Bool
                            :issuer_verified                      (s/maybe s/Bool)
-                           (s/optional-key :issuer_content_name) s/Str
-                           (s/optional-key :issuer_content_url)  s/Str
-                           (s/optional-key :email)               s/Str
+                           (s/optional-key :issuer_content_name) (s/maybe s/Str)
+                           (s/optional-key :issuer_content_url)  (s/maybe s/Str)
+                           (s/optional-key :email)               (s/maybe s/Str)
                            (s/optional-key :assertion_url)       (s/maybe s/Str)
                            (s/optional-key :tags)                (s/maybe [s/Str])})


Sort files correctly

Sort files correctly

--- src/clojure/nightcode/projects.clj
+++ src/clojure/nightcode/projects.clj
@@ -73,22 +73,24 @@

 (defn get-node
   [file]
-  {:name (if (is-project-path? file)
+  {:html (when (is-project-path? file)
            (str ""
                 (.getName file)
-                "")
-           (.getName file))
+                ""))
+   :name (.getName file)
    :file file})

 (defn get-nodes
   [node children]
   (->> (for [child children]
          (get-node child))
+       (sort-by #(:name %))
        (cons (when (and (:file node)
                         (-> (.getCanonicalPath (:file node))
                             lein/is-android-project?))
-               {:name "LogCat"
-                :file (java.io/file "*LogCat*")}))
+               {:html "LogCat"
+                :name "LogCat"
+                :file (java.io/file (:file node) "*LogCat*")}))
        (remove nil?)
        vec))

@@ -105,7 +107,7 @@
       (getChildCount [] (count @children))
       (isLeaf [] (or (nil? (:file node))
                      (not (.isDirectory (:file node)))))
-      (toString [] (:name node)))))
+      (toString [] (or (:html node) (:name node))))))

 (defn root-node
   [project-vec]


fix index bug--ES takes time to insert before read

--- src/clojure/zensols/dataset/db.clj
+++ src/clojure/zensols/dataset/db.clj
@@ -459,8 +459,7 @@
                        (count train) (count test))
             (reset! ids-inst {:train-test {:train (lazy-seq train)
                                            :test (lazy-seq test)}})
-            (persist-id-state @ids-inst))))
-      (stats))))
+            (persist-id-state @ids-inst)))))))

 (defn write-dataset-to-excel
   "Write the data set to an excel file.


:nail_care:

--- src/com/wsscode/pathom/map_db.cljc
+++ src/com/wsscode/pathom/map_db.cljc
@@ -62,9 +62,6 @@
 (defn db->tree [query data refs]
   (parser {::p/entity data ::refs refs} (p/remove-query-wildcard query)))

-(s/def ::db-tree-args
-  (s/cat :query ::spec.query/query :data map? :refs (s/nilable map?)))
-
 (s/fdef db->tree
-  :args ::db-tree-args
+  :args (s/cat :query ::spec.query/query :data map? :refs (s/nilable map?))
   :ret map?)


Beautify load-config-handler

Beautify load-config-handler

--- src/discuss/communication/main.cljs
+++ src/discuss/communication/main.cljs
@@ -85,14 +85,15 @@
   "Handler for valid request, when a configuration file was found. Parse edn file
   and store the values in the app-state."
   [response]
-  (let [{dbas :dbas/api
-         eden :eden/api
-         slug :discussion/slug} (cljs.reader/read-string response)
-        to-be-called-fns [[slug lib/set-slug!] [dbas lib/host-dbas!] [eden lib/host-eden!]]]
-    (log/info "Found a valid service configuration file. Setting hosts to dbas: %s, eden: %s, slug: %s" dbas eden slug)
-    (doseq [[value f] to-be-called-fns]
-      (when (not-empty value)
-        (f value)))
+  (let [mappings {:discussion/slug lib/set-slug!
+                  :dbas/api lib/host-dbas!
+                  :eden/api lib/host-eden!}
+        response' (cljs.reader/read-string response)]
+    (log/debug "Found a configuration file: %s" (str response'))
+    (doseq [[k v] response'
+            :let [f (get mappings k)]
+            :when (not-empty v)]
+      (f v))
     (after-loading-config)))

 (defn- config-not-found [_response]
@@ -104,7 +105,7 @@
   "Function to query remote configuration file and call the appropriate handlers."
   ([url handler error-handler]
    (when (and (string? url) (seq url))
-     (log/info "Querying service information from %s" url)
+     (log/debug "Querying service information from %s" url)
      (GET url
           {:handler handler
            :error-handler error-handler})))


Use current slug to post positions

Use current slug to post positions

--- src/discuss/communication/main.cljs
+++ src/discuss/communication/main.cljs
@@ -54,15 +54,13 @@
   "Add new position, its reason and an optional reference to post it to the
   backend."
   [{:keys [position reason reference search/selected]}]
-  (if (seq (lib/get-last-api))
-    (let [url (lib/get-last-api)
-          headers (merge {"Content-Type" "application/json"} (comlib/token-header))
-          body {:position position
-                :reason (if (nil? selected) reason (:text selected))
-                :reference reference
-                :origin (build-origin-body selected)}]
-      (post-json url body process-url-handler headers))
-    (log/error ":api/last-call is empty, cannot post statement to empty URL.")))
+  (let [url (lib/get-current-slug)
+        headers (merge {"Content-Type" "application/json"} (comlib/token-header))
+        body {:position position
+              :reason (if (nil? selected) reason (:text selected))
+              :reference reference
+              :origin (build-origin-body selected)}]
+    (post-json url body process-url-handler headers)))

 ;;;; Get things started!


fix bug in recording stats for auto-acked tuples when there are no ackers

--- src/clj/backtype/storm/daemon/executor.clj
+++ src/clj/backtype/storm/daemon/executor.clj
@@ -275,6 +275,7 @@
         last-active (atom false)
         component-id (:component-id executor-data)
         max-spout-pending (executor-max-spout-pending storm-conf (count task-datas))
+        ^Integer max-spout-pending (if max-spout-pending (int max-spout-pending))
         event-queue (disruptor/non-blocking-disruptor-queue (storm-conf TOPOLOGY-SPOUT-EVENT-BUFFER-SIZE))
         event-handler (disruptor/handler [event _ _] (event))
         worker-context (:worker-context executor-data)
@@ -338,7 +339,10 @@
                                                                ACKER-INIT-STREAM-ID
                                                                [root-id (bit-xor-vals out-ids) task-id]))
                                        (when message-id
-                                         (disruptor/publish event-queue #(ack-spout-msg executor-data task-data message-id {:stream out-stream-id :values values} 0))))
+                                         (disruptor/publish event-queue
+                                            #(ack-spout-msg executor-data task-data message-id
+                                                            {:stream out-stream-id :values values}
+                                                            (if (sampler) 0)))))
                                      (or out-tasks [])
                                      ))]]
       (.open spout-obj


Implemented cleaning of the namespace when composing the specification.

--- src/clj_formal_specifications_app/core.clj
+++ src/clj_formal_specifications_app/core.clj
@@ -73,7 +73,8 @@

 (defn compose
   [spec]
-  {:body (do (load-string spec) (get-ns-name spec))})
+  (let [ns (get-ns-name spec)]
+  {:body (do (remove-ns (symbol ns)) (load-string spec) ns)}))

 (defn execute-with-ns
   [ns command]


whitespace

whitespace

--- src/cljs/infinitelives/pixi/resources.cljs
+++ src/cljs/infinitelives/pixi/resources.cljs
@@ -67,13 +67,11 @@

     (.generateTexture box false)))

-
 (defn add-prog-bar [stage options]
   (let [s (sprite/make-sprite (progress-texture 0 options))]
     (set! (.-alpha s) 0)
     (.addChild stage s)
     s))
-

 (defn get-texture [key scale]
   (scale (get @!textures key)))


cleanup edit list

cleanup edit list

--- src/cljs/material/component/list/edit.cljs
+++ src/cljs/material/component/list/edit.cljs
@@ -4,6 +4,44 @@
             [material.component.list.util :refer [render-keys]]
             [swarmpit.utils :refer [select-keys*]]
             [sablono.core :refer-macros [html]]))
+
+(defn list-item-normal [render-metadata index item delete-handler-fn]
+  (cmp/list-item
+    {:key            (str "Swarmpit-list-item-" index)
+     :className      "Swarmpit-list-item-edit"
+     :disableGutters true}
+    (->> (select-keys* item (render-keys render-metadata))
+         (map-indexed
+           (fn [coll-index coll]
+             (let [render-fn (:render-fn (nth render-metadata coll-index))
+                   value (val coll)]
+               (render-fn value item index)))))
+    (cmp/list-item-secondary-action
+      {:key (str "Swarmpit-list-status-" index)}
+      (cmp/tooltip
+        {:title     "Delete"
+         :placement "top-start"}
+        (cmp/icon-button
+          {:color   "secondary"
+           :onClick #(delete-handler-fn index)}
+          (cmp/svg icon/trash))))))
+
+(defn list-item-small [render-metadata index item delete-handler-fn]
+  (cmp/list-item
+    {:key            (str "Swarmpit-list-item-" index)
+     :className      "Swarmpit-list-item-edit-small"
+     :disableGutters true}
+    (html
+      [:div
+       (->> (select-keys* item (render-keys render-metadata))
+            (map-indexed
+              (fn [coll-index coll]
+                (let [render-fn (:render-fn (nth render-metadata coll-index))
+                      value (val coll)]
+                  (render-fn value item index)))))
+       (cmp/button {:size    "small"
+                    :onClick #(delete-handler-fn index)
+                    :color   "primary"} "Delete")])))

 (defn list-item
   [render-metadata index item delete-handler-fn]
@@ -12,43 +50,11 @@
      (cmp/hidden
        {:only           ["xs" "sm" "md"]
         :implementation "js"}
-       (cmp/list-item
-         {:key            (str "Swarmpit-list-item-" index)
-          :className      "Swarmpit-list-item-edit"
-          :disableGutters true}
-         (->> (select-keys* item (render-keys render-metadata))
-              (map-indexed
-                (fn [coll-index coll]
-                  (let [render-fn (:render-fn (nth render-metadata coll-index))
-                        value (val coll)]
-                    (render-fn value item index)))))
-         (cmp/list-item-secondary-action
-           {:key (str "Swarmpit-list-status-" index)}
-           (cmp/tooltip
-             {:title     "Delete"
-              :placement "top-start"}
-             (cmp/icon-button
-               {:color   "secondary"
-                :onClick #(delete-handler-fn index)}
-               (cmp/svg icon/trash))))))
+       (list-item-normal render-metadata index item delete-handler-fn))
      (cmp/hidden
        {:only           ["lg" "xl"]
         :implementation "js"}
-       (cmp/list-item
-         {:key            (str "Swarmpit-list-item-" index)
-          :className      "Swarmpit-list-item-edit-small"
-          :disableGutters true}
-         (html
-           [:div
-            (->> (select-keys* item (render-keys render-metadata))
-                 (map-indexed
-                   (fn [coll-index coll]
-                     (let [render-fn (:render-fn (nth render-metadata coll-index))
-                           value (val coll)]
-                       (render-fn value item index)))))
-            (cmp/button {:size    "small"
-                         :onClick #(delete-handler-fn index)
-                         :color   "primary"} "Delete")])))]))
+       (list-item-small render-metadata index item delete-handler-fn))]))

 (defn list
   [render-metadata items delete-handler-fn]


Fix the key-triad extraction problem

Fix the key-triad extraction problem

Debugging this has been the focus of the past few commits.

Root cause was that I was building the shared secred from an array of
zeros just before I copied the client's public long-term key into that
array.

--- src/clojure/frereth_cp/server/initiate.clj
+++ src/clojure/frereth_cp/server/initiate.clj
@@ -315,46 +315,48 @@
 "
   [state supplied-client-short-key client-message-box]
   (let [client-long-buffer (::K/long-term-public-key client-message-box)
-        client-long-key (byte-array K/key-length)
-        my-long-secret (.getSecretKey (get-in state [::shared/my-keys ::shared/long-pair]))
-        shared-secret (crypto/box-prepare client-long-key
-                                          my-long-secret)]
+        client-long-key (byte-array K/key-length)]
     (.getBytes client-long-buffer 0 client-long-key)
-    (log/info (str "Getting ready to decrypt the inner-most hidden public key\n"
-                   "Supplied client long-term key:\n"
-                   ;; This next should match:
-                   #_[0x26 0x9f 0x81 0x8d
-                    0x4a 0xfc 0x55 0x04
-                    0xad 0x01 0x34 0xfd
-                    0xb0 0xa4 0xf4 0x12
-                    0xe3 0x64 0x96 0xae
-                    0x8c 0xe7 0x14 0xb5
-                    0x70 0x76 0x62 0xb2
-                    0x64 0xb8 0x3f 0x19]
-                   (b-t/->string client-long-key)
-                   "My long-term secret key:\n"
-                   (b-t/->string my-long-secret)
-                   "My long-term public key:\n"
-                   (b-t/->string (.getPublicKey (get-in state [::shared/my-keys ::shared/long-pair])))
-                   "Shared:\n"
-                   ;; Client's version:
-                   #_[0xc5 0x91 0x62 0xcd
-                    0xfe 0xc1 0x33 0x89
-                    0xa3 0xff 0x82 0x3d
-                    0x26 0x2d 0x09 0x03
-                    0x09 0xbc 0x9e 0xdd
-                    0x35 0x87 0x1b 0x1c
-                    0x81 0xb5 0xff 0x2a
-                    0xa9 0xe1 0x6b 0x58]
-                   (b-t/->string shared-secret)))
-    ;; Failing here.
-    ;; The shared secret doesn't match what the client used to encrypt the box.
-    (when-let [inner-pk (crypto/open-crypto-box
-                         K/vouch-nonce-prefix
-                         (::K/inner-i-nonce client-message-box)
-                         (::K/hidden-client-short-pk client-message-box)
-                         shared-secret)]
-      (b-t/bytes= supplied-client-short-key inner-pk))))
+    (let [my-long-secret (.getSecretKey (get-in state [::shared/my-keys ::shared/long-pair]))
+          shared-secret (crypto/box-prepare client-long-key
+                                            my-long-secret)]
+      (log/info (str "Getting ready to decrypt the inner-most hidden public key\n"
+                     "Supplied client long-term key:\n"
+                     ;; This next should match:
+                     #_[0x26 0x9f 0x81 0x8d
+                        0x4a 0xfc 0x55 0x04
+                        0xad 0x01 0x34 0xfd
+                        0xb0 0xa4 0xf4 0x12
+                        0xe3 0x64 0x96 0xae
+                        0x8c 0xe7 0x14 0xb5
+                        0x70 0x76 0x62 0xb2
+                        0x64 0xb8 0x3f 0x19]
+                     (b-t/->string client-long-key)
+                     "which arrived in: "
+                     client-long-buffer
+                     "\nMy long-term secret key:\n"
+                     (b-t/->string my-long-secret)
+                     "My long-term public key:\n"
+                     (b-t/->string (.getPublicKey (get-in state [::shared/my-keys ::shared/long-pair])))
+                     "Shared:\n"
+                     ;; Client's version:
+                     #_[0xc5 0x91 0x62 0xcd
+                        0xfe 0xc1 0x33 0x89
+                        0xa3 0xff 0x82 0x3d
+                        0x26 0x2d 0x09 0x03
+                        0x09 0xbc 0x9e 0xdd
+                        0x35 0x87 0x1b 0x1c
+                        0x81 0xb5 0xff 0x2a
+                        0xa9 0xe1 0x6b 0x58]
+                     (b-t/->string shared-secret)))
+      ;; Failing here.
+      ;; The shared secret doesn't match what the client used to encrypt the box.
+      (when-let [inner-pk (crypto/open-crypto-box
+                           K/vouch-nonce-prefix
+                           (::K/inner-i-nonce client-message-box)
+                           (::K/hidden-client-short-pk client-message-box)
+                           shared-secret)]
+        (b-t/bytes= supplied-client-short-key inner-pk)))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Public


Improve entry actions popup

Improve entry actions popup

--- src/elfeed_cljsrn/android/core.cljs
+++ src/elfeed_cljsrn/android/core.cljs
@@ -350,7 +350,12 @@
         actions [{:label "Open in browser"
                   :action (fn [] (dispatch [:open-entry-in-browser]))}]]
     (fn []
-      [rn/view
+      [rn/view {:style {:flex 1
+                        :flex-direction "row"}}
+       ;; this empty view is a hack for showPopupmenu
+       ;; it adds the popup next to the tag, so we need an element before the
+       ;; icon.
+       [rn/view [rn/text {:ref (fn [ref] (reset! ref-icon ref))} ""]]
        [rn/touchable {:on-press (fn [e]
                                   (.showPopupMenu rn/ui-manager (.findNodeHandle rn/ReactNative @ref-icon)
                                                   (clj->js (map :label actions))
@@ -359,10 +364,7 @@
                                                     (when i
                                                       ((:action (nth actions i)))))))}
         [rn/view {:style (:button styles)}
-         [icon {:style (:icon styles)
-                :name "more-vert"
-                :size 24
-                :ref (fn [ref] (reset! ref-icon ref))}]]]])))
+         [icon {:style (:icon styles) :name "more-vert" :size 24}]]]])))

 (defmulti scene #(keyword (aget % "scene" "route" "key")))


tweak error wording

tweak error wording

--- src/github_contributions/github.clj
+++ src/github_contributions/github.clj
@@ -9,7 +9,7 @@
   []
   (if-let [auth (System/getenv "GITHUB_AUTH")]
     (if (.contains auth ":") {:auth auth} {:oauth-token auth})
-    (or (throw (ex-info "Set $GITHUB_AUTH to basic auth in order to use github api." {})))))
+    (or (throw (ex-info "Set $GITHUB_AUTH to an oauth token or basic auth in order to use Github's api." {})))))

 (defn get-in!
   "Fail fast if no truish value for get-in"


fix typo

fix typo

--- frontend/components/project/common.cljs
+++ frontend/components/project/common.cljs
@@ -1,5 +1,5 @@
 (ns frontend.components.project.common
-  (:require [cljs.core.async :as async :refer [>! <! alts! checan sliding-buffer close!]]
+  (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
             [frontend.async :refer [put!]]
             [frontend.components.forms :as forms]
             [frontend.datetime :as time-utils]


Avoid acegi issues at the REPL

Avoid acegi issues at the REPL

--- src/main/clojure/alfresco/nodes.clj
+++ src/main/clojure/alfresco/nodes.clj
@@ -111,7 +111,8 @@
    [node & aspect-defs]
    {:pre [(even? (count aspect-defs))]}
    (for [[aspect props] (partition 2 aspect-defs)]
-     (.addAspect *node-service* (c/c2j node) (m/qname aspect) props)))
+     (.addAspect *node-service* (c/c2j node) (m/qname aspect) props))
+   true)

   (del-aspect!
    [node aspect]


refactor last commit to produce a more informative error as well as cover all invalid arity cases for keywords

--- src/main/clojure/cljs/analyzer.cljc
+++ src/main/clojure/cljs/analyzer.cljc
@@ -2185,19 +2185,19 @@

 (defn parse-invoke*
   [env [f & args :as form]]
-  (let [enve (assoc env :context :expr)
-        fexpr (analyze enve f)
-        argc (count args)
-        ^boolean fn-var? (-> fexpr :info :fn-var)
-        kw? (= 'cljs.core/Keyword (:tag fexpr))]
-    (when (or fn-var? kw?)
+  (let [enve    (assoc env :context :expr)
+        fexpr   (analyze enve f)
+        argc    (count args)
+        fn-var? (-> fexpr :info :fn-var)
+        kw?     (= 'cljs.core/Keyword (:tag fexpr))]
+    (when ^boolean fn-var?
       (let [{:keys [^boolean variadic max-fixed-arity method-params name]} (:info fexpr)]
-        (when (or (and kw? (zero? argc))
-                  (and (not kw?)
-                       (not (valid-arity? argc method-params))
-                       (or (not variadic)
-                           (and variadic (< argc max-fixed-arity)))))
+        (when (and (not (valid-arity? argc method-params))
+                   (or (not variadic)
+                       (and variadic (< argc max-fixed-arity))))
           (warning :fn-arity env {:name name :argc argc}))))
+    (when (and kw? (not (or (== 1 argc) (== 2 argc))))
+      (warning :fn-arity env {:name (first form) :argc argc}))
     (let [deprecated? (-> fexpr :info :deprecated)
           no-warn? (-> form meta :deprecation-nowarn)]
       (when (and (boolean deprecated?)


Remove extraneous and in tag logic

Remove extraneous and in tag logic

--- src/docker_clojure/util.clj
+++ src/docker_clojure/util.clj
@@ -41,8 +41,8 @@
                                             (= build-tool cfg/default-build-tool))
                                      nil
                                      build-tool)
-          build-tool-version-label (if (and (or omit-all? omit-build-tool?
-                                                omit-build-tool-version?))
+          build-tool-version-label (if (or omit-all? omit-build-tool?
+                                           omit-build-tool-version?)
                                      nil
                                      build-tool-version)]
       (str/join "-" (remove nil? [jdk build-tool-label


pmd resourceLocation --> inFolder

pmd resourceLocation --> inFolder

--- src/grafter/rdf/ontologies/pmd.clj
+++ src/grafter/rdf/ontologies/pmd.clj
@@ -18,5 +18,5 @@
 (def folder:hasTree      (folder "hasTree"))
 (def folder:defaultTree  (folder "defaultTree"))
 (def folder:parentFolder (folder "parentFolder"))
-(def folder:resourceLocation (folder "resourceLocation"))
+(def folder:inFolder     (folder "inFolder"))
 (def folder:inTree       (folder "inTree"))


fix: accept xml prolog in gml, filter it in as-gml output

--- src/main/clojure/pdok/featured/feature.clj
+++ src/main/clojure/pdok/featured/feature.clj
@@ -65,7 +65,7 @@
   (.write wkt-writer jts))

 (defmulti as-gml (fn [obj] lower-case (get obj "type")))
-(defmethod as-gml "gml" [obj] (get obj "gml"))
+(defmethod as-gml "gml" [obj] (str/replace (get obj "gml") #"<\?[^\?]*\?>" ""))
 (defmethod as-gml :default [obj] nil)

 (defmulti as-jts (fn [obj] lower-case (get obj "type")))
@@ -77,7 +77,7 @@
   (get obj "jts"))

 (defmulti as-simple-gml (fn [obj] lower-case (get obj "type")))
-(defmethod as-simple-gml "gml" [obj]
+(defmethod as-simple-gml "gml" [obj]
   (when-let [gml (get obj "gml")]
     (.transform simple-gml-transfomer gml)))
 (defmethod as-simple-gml :default [obj] nil)
@@ -116,8 +116,8 @@
   #{"Curve" "CompositeCurve" "Arc" "ArcString" "Circle" "LineString"})

 (defmethod geometry-group "gml" [obj]
-  (let [re-result (re-find #"^<(gml:)?([^\s]+)" (get obj "gml"))
-        type (when re-result (nth re-result 2))]
+  (let [re-result (re-find #"^(<\?[^\?]*\?>)?<([a-zA-Z0-9]+:)?([^\s]+)" (get obj "gml"))
+        type (when re-result (nth re-result 3))]
     (geometry-group* gml-point-types gml-line-types type)))

 (def jts-point-types


adde get-count

adde get-count

--- src/extras/mongowrapper.clj
+++ src/extras/mongowrapper.clj
@@ -21,15 +21,20 @@
            [com.mongodb DB WriteConcern]
            (org.bson.types ObjectId)))

-(defn add-entry [doc dbname entry]
+(defn add-entry [dbname doc entry]
   (let [conn (mg/connect)
-        db (mg/get-db conn (str "iyye-" dbname))]
+        db (mg/get-db conn dbname)]
     (mc/insert db doc entry)))

-(defn get-entry [doc dbname key]
+(defn get-entry [dbname doc key]
   (let [conn (mg/connect)
-        db (mg/get-db conn (str "iyye-" dbname))]
+        db (mg/get-db conn dbname)]
     (mc/find-maps db doc key)))
+
+(defn get-count [dbname doc key]
+  (let [conn (mg/connect)
+        db (mg/get-db conn dbname)]
+    (mc/count db doc key)))

 ; drop all
 ;var dbs = db.getMongo().getDBNames()
@@ -38,3 +43,4 @@
 ; print           ("dropping db " + db.getName ())           ;
 ; db.dropDatabase ()                                         ;
 ; }
+


fix: shutdown agents on shutdown, name cleanup

--- src/featured_gml/runner.clj
+++ src/featured_gml/runner.clj
@@ -25,7 +25,7 @@
        (pmap member->map)
        (filter #(not= unknown %))))

-(defn process-file [in out dataset-name]
+(defn process [in out dataset-name]
   (let [first? (ref true)]
     (with-open [reader (clojure.java.io/reader in)
                 writer (clojure.java.io/writer out)]
@@ -35,4 +35,5 @@
           (.write writer ",\n")
           (dosync (ref-set first? false)))
         (.write writer (json/generate-string f)))
-      (.write writer "]}"))))
+      (.write writer "]}")))
+  (shutdown-agents))


got rid of frequency guessing stuff

got rid of frequency guessing stuff

--- src/hangman/core.clj
+++ src/hangman/core.clj
@@ -68,16 +68,6 @@
   { :pre  [ (integer? row-idx) ]
     :post [] }
   (nth word-array row-idx) )
-
-(defn to-freqs-by-col
-  "For each column of a 2D array (seq of seqs), computes an element frequency map. Returns
-  as a vector indexed by column."
-  [word-array]
-  { :pre  [ (< 0 (num-rows word-array) )
-            (< 0 (num-cols word-array) ) ]
-    :post [] }
-  (vec (for [idx (range 0 (num-cols word-array)) ]
-         (frequencies (get-array-col word-array idx)) )))

 (defn filter-with-idx
   "Returns values from data-seq where corresponding pred-seq elements are truthy.
@@ -171,17 +161,6 @@
         best-char     (apply max-key char-bits avail-chars) ]
     best-char ) )

-(defn make-guess-freq
-  "Generate the next guess letter, based on letter frequencies in the surviving words. "
-  [keep-words used-chars]
-  (let [
-    col-char-freqs  (to-freqs-by-col keep-words)
-    all-char-freqs    (apply merge-with + col-char-freqs)
-    avail-chars       (set/difference (set(keys all-char-freqs)) used-chars)
-      ; _ (println "avail-chars" avail-chars )
-    max-avail-char    (apply max-key all-char-freqs avail-chars )
-  ] max-avail-char ) )
-
 (defn make-clue
   "Generate a clue given the target word and a vec of guessed letters."
   [target-vec guesses-set]
@@ -251,16 +230,6 @@
     (assert (= (get-array-col tstArr 2) [:c  3 \c] ))
   )

-  ; Use of (frequencies...) and (merge-with...)
-  (assert (= (frequencies "abbccc")
-             {\a 1, \b 2, \c 3} ))
-  (assert (= (frequencies ["abc" "bc" "c"])
-             {"abc" 1 "bc" 1 "c" 1} ))
-  (assert (= (map frequencies ["abc" "bc" "c"])
-             [ {\a 1, \b 1, \c 1} {\b 1, \c 1} {\c 1} ] ))
-  (assert (= (apply merge-with + (map frequencies ["abc" "bc" "c"]) )
-             {\a 1 \b 2 \c 3} ))
-
   ; Match guesses
   (assert (guess-matches? "abcd" "abcd") )
   (assert (guess-matches? "abcd" [\a \b \c \d]) )
@@ -278,13 +247,6 @@
     word-array          (to-word-array  curr-words)
       _ (assert (= word-array
                    [[\a \b \c \d] [\x \b \c \d] [\x \x \c \d] [\x \x \x \d]] ))
-
-    col-char-freqs      (to-freqs-by-col word-array)
-      _ (assert (= col-char-freqs [{\a 1, \x 3} {\b 2, \x 2} {\c 3, \x 1} {\d 4}] ))
-    all-char-freqs      (apply merge-with + col-char-freqs)
-      _ (assert (= all-char-freqs { \a 1, \b 2, \c 3, \d 4, \x 6} ))
-    max-freq-val        (apply max-key all-char-freqs (keys all-char-freqs) )
-      _ (assert (= max-freq-val \x ))

     tgt-word            [ \x  \b  \c  \d  ]
     clue                [ nil \b  nil nil ]
@@ -294,12 +256,6 @@
       _ (assert (= keep-words ["abcd" "xbcd"] ))
     guessed-chars       #{ \b }
       _ (assert (= guessed-chars #{\b} ))
-    new-guess           (make-guess-freq word-array guessed-chars)
-      _ (assert (= new-guess \x ))
-    guessed-chars       (conj guessed-chars new-guess)
-      _ (assert (= guessed-chars #{\b \x} ))
-    new-clue            (make-clue tgt-word guessed-chars)
-      _ (assert (= new-clue [\x \b nil nil] ))
   ] )
 )


debugger: render newest signals at the bottom

--- examples/_common/middleware/devtools.cljs
+++ examples/_common/middleware/devtools.cljs
@@ -267,13 +267,13 @@
                    [:initial-model :persist? :visible? :toggle-visibility-shortcut :signal-events :action-events]))

 ;;;;;;;;;;;;;;;;;;;;;;;; View
-(def -menu-button-style {:font-size     "inherit"
+(def -menu-button-style {:margin        "5px 3px"
+                         :padding       4
+                         :font-size     "inherit"
                          :font-family   "inherit"
                          :font-weight   "bold"
                          :color         "white"
                          :cursor        "pointer"
-                         :margin        "5px 3px"
-                         :padding       4
                          :border-radius "3px"
                          :border        0
                          :background    "none"})
@@ -305,10 +305,7 @@

 (defn -menu
   [persist? toggle-visibility-shortcut dispatch]
-  [:div {:style {:text-align          "center"
-                 :border-bottom-width 1
-                 :border-bottom-style "solid"
-                 :border-color        "#4F5A65"}}
+  [:div {:style {:text-align "center"}}
    [-menu-button {} "Clear" #(dispatch ::on-clear) "Clears debugger history"]
    [-menu-button {} "Vacuum" #(dispatch ::on-vacuum) "Removes disabled actions and signals with no actions from history"]
    [-menu-button {} "Reset" #(dispatch ::on-reset) "Removes all actions and signals resetting the model to initial state"]
@@ -321,7 +318,7 @@
   [signal-events action-events dispatch]
   [:div
    (doall
-     (for [[signal-id signal] (reverse signal-events)]
+     (for [[signal-id signal] signal-events]
        ^{:key signal-id}
        [:div {:title "Signal"}
         [:div {:style    {:padding-left     4
@@ -362,7 +359,6 @@
 (defn -initial-model-view
   [initial-model]
   [:div
-   [:hr]
    [:strong "Initial model:"]
    [:div (pr-str initial-model)]])

@@ -374,6 +370,17 @@
                    :component-did-mount (fn [this] (.resizable (js/$ (r/dom-node this))
                                                                (clj->js {:grid    25
                                                                          :handles "n, e, s, w, ne, se, sw, nw"})))}))
+
+(defn -autoscrollable-div
+  "Will scroll to bottom on any update."
+  [_attrs & _body]
+  (letfn [(scroll [this]
+            (set! (.-scrollTop (r/dom-node this))
+                  (.-scrollHeight (r/dom-node this))))]
+    (r/create-class {:reagent-render       (fn [attrs & body]
+                                             (into [:div attrs] body))
+                     :component-did-mount  scroll
+                     :component-did-update scroll})))

 (defn -overlay
   [& body]
@@ -389,22 +396,31 @@
 (defn -view
   [{:keys [visible? toggle-visibility-shortcut persist? initial-model signal-events action-events] :as _view-model} dispatch]
   [-overlay
-   [-resizable-div {:style {:display        (if @visible? "block" "none") ; using CSS instead of React in order to persist resized frame on toggling visibility
-                            :left           "70%"
-                            :width          "30%"
-                            :height         "100%"
-                            :pointer-events "all"}}
-    [:div {:style {:height           "100%"
-                   :overflow         "auto"
-                   :background-color "#2A2F3A"
-                   :color            "white"
-                   :font-size        14
-                   :font-family      "sans-serif"
-                   :line-height      "1.4em"
-                   :font-weight      "300"}}
-     [-menu @persist? @toggle-visibility-shortcut dispatch]
-     [-signals-view @signal-events @action-events dispatch]
-     [-initial-model-view @initial-model]]]])
+   [-resizable-div {:style {:display          (if @visible? "block" "none") ; using CSS instead of React in order to persist resized frame on toggling visibility
+                            :left             "70%"
+                            :width            "30%"
+                            :height           "100%"
+                            :pointer-events   "all"
+
+                            :background-color "#2A2F3A"
+                            :color            "white"
+                            :font-size        14
+                            :font-family      "sans-serif"
+                            :line-height      "1.4em"
+                            :font-weight      "300"}}
+    [-menu @persist? @toggle-visibility-shortcut dispatch]
+
+    [-autoscrollable-div
+     {:style {:position "absolute"
+              :top      "2.5em"
+              :bottom   0
+              :left     0
+              :right    0
+              :overflow "auto"}}
+     [:hr]
+     [-initial-model-view @initial-model]
+     [:hr]
+     [-signals-view @signal-events @action-events dispatch]]]])

 ;;;;;;;;;;;;;;;;;;;;;;;; Middleware
 (defn -wrap-load-from-storage


Add `static` task for rendering non-dynamic content

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -575,6 +575,25 @@
                 paths))]
       (render-pre-wrap render-paths options :io.perun/render))))

+(def ^:private +static-defaults+
+  {:out-dir "public"
+   :page "index.html"
+   :meta {}})
+
+(deftask static
+  [o out-dir  OUTDIR   str "the output directory"
+   r renderer RENDERER sym "page renderer (fully qualified symbol resolving to a function)"
+   p page     PAGE     str "static result page path"
+   m meta     META     edn "metadata to set on the static entry"]
+  (let [options (merge +static-defaults+ *opts*)
+        path (make-path (:out-dir options) nil (:page options))
+        static-path (fn [fileset options]
+                      (perun/report-info "static" "rendered %s" path)
+                      {path {:render-data {:meta (perun/get-global-meta fileset)
+                                           :entry (:meta options)}
+                             :entry (:meta options)}})]
+    (render-pre-wrap static-path options :io.perun/static)))
+
 (defn- grouped-paths
   "Produces path maps of the shape required by `render-to-paths`, based
   on the provided `fileset` and `options`."


Set `:content\` key for `\ttr\` and \`word-count\` tasks

--- src/io/perun.clj
+++ src/io/perun.clj
@@ -209,6 +209,15 @@
          (perun/report-info "global-metadata" "read global metadata from %s" meta-file)
          (pm/set-global-meta fileset global-meta))))

+(defn- set-content-from-meta
+  [fileset meta]
+  (let [content (->> meta
+                     :path
+                     (boot/tmp-get fileset)
+                     boot/tmp-file
+                     slurp)]
+    (assoc meta :content content)))
+
 (def ^:private ttr-deps
   '[[time-to-read "0.1.0"]])

@@ -221,7 +230,10 @@
   (let [pod     (create-pod ttr-deps)
         options (merge +ttr-defaults+ *opts*)]
     (boot/with-pre-wrap fileset
-      (let [files         (filter (:filterer options) (pm/get-meta fileset))
+      (let [files (->> fileset
+                       pm/get-meta
+                       (filter (:filterer options))
+                       (map #(set-content-from-meta fileset %)))
             updated-files (trace :io.perun/ttr
                                  (pod/with-call-in @pod
                                    (io.perun.ttr/calculate-ttr ~files)))]
@@ -237,7 +249,10 @@
   (let [pod (create-pod ttr-deps)
         options (merge +word-count-defaults+ *opts*)]
     (boot/with-pre-wrap fileset
-      (let [files         (filter (:filterer options) (pm/get-meta fileset))
+      (let [files (->> fileset
+                       pm/get-meta
+                       (filter (:filterer options))
+                       (map #(set-content-from-meta fileset %)))
             updated-files (trace :io.perun/word-count
                                  (pod/with-call-in @pod
                                    (io.perun.word-count/count-words ~files)))]


Removed uneeded clj file

Removed uneeded clj file

--- src/java/owl/algorithm/Between.clj
+++ src/java/owl/algorithm/Between.clj
@@ -1,8 +0,0 @@
-(ns owl.algorithm.Between)
-
-(defn get-val
-  [map key default]
-  (if (contains? map key) (key map) default))
-
-(defn calculate
-  [graph-map])


read 10.3 - agents

read 10.3 - agents

--- src/joy/ch10.clj
+++ src/joy/ch10.clj
@@ -108,3 +108,62 @@
       (Thread/sleep 10)
       (dosync (alter r inc)))
     :done))
+
+;; 10.3 - agents
+
+(def joy (agent []))
+(send joy conj "first edition")
+(defn slow-conj [coll item]
+  (Thread/sleep 1000)
+  (conj coll item))
+
+(send joy slow-conj "Second edition")
+
+(def log-agent (agent 0))
+
+(defn do-log [msg-id message]
+  (println msg-id ":" message)
+  (inc msg-id))
+
+(defn do-step [channel message]
+  (Thread/sleep 1)
+  (send-off log-agent do-log (str channel message)))
+
+(defn three-step [channel]
+  (do-step channel " ready to begin (step 0)")
+  (do-step channel " warming up (step 1)")
+  (do-step channel " really getting going now (step 2)")
+  (do-step channel " done (step 3)"))
+
+(defn all-together-now []
+  (dothreads! #(three-step "alpha"))
+  (dothreads! #(three-step "beta"))
+  (dothreads! #(three-step "gamma")))
+
+(defn exercise-agents [send-fn]
+  (let [agents (map #(agent %) (range 10))]
+    (doseq [a agents]
+      (send-fn a (fn [_] (Thread/sleep 1000))))
+    (doseq [a agents]
+      (await a))))
+
+(time (exercise-agents send-off))
+(time (exercise-agents send))
+
+(send log-agent (fn [] 2000))
+
+@log-agent
+
+(agent-error log-agent)
+(send log-agent (fn [_] 3000))
+
+(restart-agent log-agent 2500 :clear-actions true)
+
+(send-off log-agent do-log "The agent lives")
+
+(defn handle-log-error [the-agent the-err]
+  (println "an action sent to the log-agent threw" the-err))
+
+(set-error-handler! log-agent handle-log-error)
+
+(set-error-mode! log-agent :continue)


Snapshot version

Snapshot version

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


Remove recorder

Remove recorder

--- src/main/audio_utils/recorder.cljs
+++ src/main/audio_utils/recorder.cljs
@@ -1,41 +0,0 @@
-(ns audio-utils.recorder
-  (:require [om.next :as om :refer-macros [defui]]
-            [om.dom :as dom]
-            [audio-utils.util :refer [audio-context get-user-media]]
-            [audio-utils.gate :as g]))
-
-(defui Recorder
-  Object
-  (start [this]
-    (let [audio-ctx (audio-context)
-          gate      (g/gate {:audio-ctx audio-ctx})]
-      (om/update-state! this assoc
-                        :audio-ctx audio-ctx
-                        :gate gate)
-      (get-user-media {:audio true}
-                      #(.connect-audio-nodes this %)
-                      js/console.warn)))
-
-  (connect-audio-nodes [this stream]
-    (let [{:keys [audio-ctx gate]} (om/get-state this)
-          source                   (.createMediaStreamSource audio-ctx
-                                                             stream)]
-      (.connect source gate)
-      (.connect gate (.-destination audio-ctx))))
-
-  (stop [this]
-    (let [audio-ctx (:audio-ctx (om/get-state this))]
-      (.close audio-ctx)
-      (om/update-state! this dissoc :audio-ctx)))
-
-  (componentWillReceiveProps [this new-props]
-    (when (not= (:record? (om/props this))
-                (:record? new-props))
-      (if (:record? new-props)
-        (.start this)
-        (.stop this))))
-
-  (render [this]
-    (dom/div nil)))
-
-(def recorder (om/factory Recorder))


Remove unused function overload

Remove unused function overload

--- src/main/clojure/pdok/postgres.clj
+++ src/main/clojure/pdok/postgres.clj
@@ -171,19 +171,16 @@
   (with-open [connection (j/get-connection tx)]
     (.commit connection)))

-(defn execute-batch-query
-  ([tx ^String query]
-   (execute-batch-query tx query []))
-  ([tx ^String query batch]
-   (with-open [stmt (let [^Connection c (:connection tx)] (.prepareStatement c query))]
-     (doseq [values batch]
-       (doseq [value (map-indexed vector values)]
-         (j/set-parameter
-           (second value)
-           ^PreparedStatement stmt
-           ^Integer (-> value first inc)))
-       (.addBatch ^PreparedStatement stmt))
-     (.executeBatch ^PreparedStatement stmt))))
+(defn execute-batch-query [tx ^String query batch]
+  (with-open [stmt (let [^Connection c (:connection tx)] (.prepareStatement c query))]
+    (doseq [values batch]
+      (doseq [value (map-indexed vector values)]
+        (j/set-parameter
+          (second value)
+          ^PreparedStatement stmt
+          ^Integer (-> value first inc)))
+      (.addBatch ^PreparedStatement stmt))
+    (.executeBatch ^PreparedStatement stmt)))

 (defn batch-insert [tx qualified-table columns batch]
   (let [query (str "INSERT INTO " qualified-table


Added use of name function

Added use of name function


Update tools-deps to 1.11.1.1129

Update tools-deps to 1.11.1.1129


bust favicon cache

bust favicon cache

--- src-cljs/frontend/favicon.cljs
+++ src-cljs/frontend/favicon.cljs
@@ -5,10 +5,12 @@
   (:require-macros [dommy.macros :refer [sel sel1]]))

 (def favicon-query "link[rel='icon']")
+;; increment version to break Chrome's aggressive caching
+(def version "1")

 (defn set-favicon! [path]
   (utils/swallow-errors
-   (attrs/set-attr! (sel1 favicon-query) :href path)))
+   (attrs/set-attr! (sel1 favicon-query) :href (str path "?v=" version))))

 (defn set-unread! []
   (set-favicon! "/favicon-notification.ico"))


run (optionally) without specifying args (the plans dir)

--- src/kbilling/calc/main.cljs
+++ src/kbilling/calc/main.cljs
@@ -25,12 +25,14 @@
 (defn do-post [plans-dir]
   (fn [req res] (.format res (clj->js {"application/transit+json" (process-transit (p/mk-load-plan plans-dir))}))))

-(defn -main [plans-dir & args]
-  (.use app (.text body-parser (clj->js {:type "application/*"})))
-  (.get app "/" say-hi)
-  (.post app "/" (do-post plans-dir))
-  (.use app (serve-static plans-dir))
-  (.listen app port #(.log js/console "Listening on port" port)))
+(defn -main
+  ([] (-main "."))
+  ([plans-dir]
+    (.use app (.text body-parser (clj->js {:type "application/*"})))
+    (.get app "/" say-hi)
+    (.post app "/" (do-post plans-dir))
+    (.use app (serve-static plans-dir))
+    (.listen app port #(.log js/console "Listening on port" port))))

 ;(node/enable-util-print!)


draw pixels

draw pixels

--- src/labs_4_cource/core.cljs
+++ src/labs_4_cource/core.cljs
@@ -3,6 +3,8 @@
    [reagent.core :as reagent]))

 (def window-width (reagent/atom nil))
+
+(defonce points (->> 100 range (map (fn [x] [x x])) doall atom))

 (defn on-window-resize [evt]
   (reset! window-width (.-innerWidth js/window)))
@@ -11,25 +13,18 @@
   (println value)
   value)

-(defn draw-pixel [node [x y]]
-  (let [ctx (-> node
-                .-children
-                (aget 0)
-                (.getContext "2d"))
-        ]
+(defn draw-pixel [ctx [x y]]
       (-> ctx
-          (.fillRect x y 1 1))))
+          (.fillRect x y 1 1)))
+
+(defn draw-pixels [ctx col]
+    (doall (map (fn [p] (draw-pixel ctx p)) col)))

 (defn draw-canvas-contents [canvas]
   (let [ctx (.getContext canvas "2d")
         w (.-clientWidth canvas)
         h (.-clientHeight canvas)]
-    (.beginPath ctx)
-    (.moveTo ctx 0 0)
-    (.lineTo ctx w h)
-    (.moveTo ctx w 0)
-    (.lineTo ctx 0 h)
-    (.stroke ctx)))
+    (draw-pixels ctx @points)))

 (defonce dom-node (reagent/atom nil))

@@ -61,3 +56,5 @@
   (reagent/render [home]
                   (.getElementById js/document "app"))
   (.addEventListener js/window "resize" on-window-resize))
+
+(init! )


add truthy/falsey

add truthy/falsey

--- src/matcha.clj
+++ src/matcha.clj
@@ -581,6 +581,26 @@

 (def
   ^{:doc
+    "passes if the value is truthy
+
+    (matcha/run-match matcha/truthy? #{}) ; => passes
+    (matcha/run-match matcha/truthy? nil) ; => fails"}
+  truthy?
+  {:match identity
+   :description "a set"})
+
+(def
+  ^{:doc
+    "passes if the value is falsey
+
+    (matcha/run-match matcha/falsey? #{}) ; => passes
+    (matcha/run-match matcha/falsey? nil) ; => fails"}
+  falsey?
+  {:match not
+   :description "a set"})
+
+(def
+  ^{:doc
     "passes if the value is a function

     (matcha/run-match matcha/fn? #()) ; => passes


typo - will will

typo - will will

--- frontend/components/project_settings.cljs
+++ frontend/components/project_settings.cljs
@@ -375,7 +375,7 @@
                            :title "Project fork pull requests"
                            :blurb '([:p
                                      "CircleCI will automatically update the commit status shown on GitHub's "
-                                     "pull request page. Builds will will be run using the parent repository's plan "
+                                     "pull request page. Builds will be run using the parent repository's plan "
                                      "and will be able to access the parent project's environment settings."]
                                     [:p
                                      "If you have SSH keys or AWS credentials stored in your project settings and "


add explicit conn + socket timeouts

add explicit conn + socket timeouts

--- src/link_checker/github.clj
+++ src/link_checker/github.clj
@@ -61,13 +61,18 @@
            (count links)
            (count (remove #(= 200 (:status %)) links)))))

+(def default-clj-http-options
+  {:max-redirects 5
+   :throw-exceptions false
+   :conn-timeout 100
+   :socket-timeout 1000})
+
 (defn- fetch-link [url]
   (log/info :msg (format "Fetching link %s" url))
-  (let [resp (try (let [opts {:max-redirects 5 :throw-exceptions false}
-                        head (client/head url opts)]
+  (let [resp (try (let [head (client/head url default-clj-http-options)]
                     (if (> 400 (:status head) 199)
                       head
-                      (client/get url opts)))
+                      (client/get url default-clj-http-options)))
                     (catch Exception err {:error err}))]
     {:url url
      :status (or (:error resp) (:status resp))


improve help message for -f/--format option

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -221,7 +221,7 @@

 (def cliopts
   [["-c" "--create"     "Create new namelist"                                                              ]
-   ["-f" "--format fmt" "Output in the specified format (see below)"   :assoc-fn assoc-f :parse-fn parse-f ]
+   ["-f" "--format fmt" "Output in format 'fmt' (default: namelist)"   :assoc-fn assoc-f :parse-fn parse-f ]
    ["-g" "--get n:k"    "Get value of key 'k' in namelist 'n'"         :assoc-fn assoc-g :parse-fn parse-g ]
    ["-h" "--help"       "Show usage information"                                                           ]
    ["-i" "--in file"    "Input file (default: stdin)"                  :assoc-fn assoc-i                   ]


Add site

Add site

--- server/src/receipts_server/service.clj
+++ server/src/receipts_server/service.clj
@@ -39,7 +39,7 @@
    ;; ::http/interceptors []

    ;; CORS allowed origins
-   ::http/allowed-origins ["http://localhost:3449" "http://lightsail-1.degel.com"]
+   ::http/allowed-origins ["http://localhost:3449" "http://lightsail-1.degel.com" "http://receipts.goldfarb-family.com"]

    ::route-set routes
    ::vase/api-root "/api"


Defined g-major in terms of translate, and moved translate before it's first used.

--- src/overtunes/songs/variatio-12.clj
+++ src/overtunes/songs/variatio-12.clj
@@ -10,11 +10,12 @@
        (-> % - downward-scale))
      (sum-n (cycle intervals) %)))

+(defn translate [f x y] #(-> % (+ x) f (+ y)))
 (def major (scale [2 2 1 2 2 2 1]))
-(def g-major #(-> % major (+ 67)))
+(defn modulate [scale mode] (translate scale mode (- (scale mode))))
+(def g-major (translate major 0 67))

 (defn bpm [per-minute] #(-> % (/ per-minute) (* 60) (* 1000)))
-(defn translate [f x y] #(-> % (+ x) f (+ y)))
 (defn syncopate [timing durations] #(->> % (sum-n durations) timing))
 (defn run [a b]
   (if (<= a b)
@@ -30,7 +31,7 @@
     (dorun (map-indexed note# notes))))

 (defn play# []
-  (let [timing (-> (bpm 120) (translate 0 (now)))
+  (let [timing (-> (bpm 90) (translate 0 (now)))
         rhythm-from #(syncopate (translate timing % 0) durations)
         leader pitches
         follower (->> leader (map -) (map #(- % 4)))]


Port all java.io calls to the fs lib

Port all java.io calls to the fs lib

--- src/markiki/core.clj
+++ src/markiki/core.clj
@@ -10,7 +10,6 @@
             [cljs.build.api :as cljs])
   (:gen-class))

-;; TODO: port all java.io calls to fs lib

 (def invalid-path-error
   "[ERROR] Make sure you provided a valid path as an argument")
@@ -32,11 +31,13 @@
         "Please refer to the repo for more information: https://github.com/ff-/markiki"]
        (string/join \newline)))

+
 (defn exit
   "Exits with status leaving a message"
   [status msg]
   (println msg)
   (System/exit status))
+

 (defn split-title
   "Separates the main title from a Markdown text - returns a vector [title text]"
@@ -51,6 +52,7 @@
                      [title (str text "\n" line)])))
                ["" ""])))

+
 (defn pathize
   "Takes a string, returns a trimmed down string only w/ alphabet and hyphens"
   [title]
@@ -59,32 +61,35 @@
       (string/replace #"[^a-zA-Z-]" "")
       string/lower-case))

+
 (defn parse-tree
   "Given a path scan for md files, and return a list. If folder, recur."
   [path category]
   (let [json (atom [])]
-    (doseq [f (.listFiles (io/file path))]
+    (doseq [f (fs/list-dir path)]
       ;; This is ugly. Here to avoid mapping the static folder
-      (when-not (some #{(.getName f)} ["static"])
+      (when-not (some #{(fs/name f)} ["static"])
         (swap! json
                conj
-               (if (.isDirectory f)
-                 (let [cat-name (.getName f)
+               (if (fs/directory? f)
+                 (let [cat-name (fs/name f)
                        [new-cat new-path] (map #(str %1 "/" cat-name)
                                                [category path])]
                    (parse-tree new-path new-cat))
-                 (let [[title content] (split-title (slurp (.getPath f)))]
+                 (let [[title content] (split-title (slurp f))]
                    {:title title
-                    :last-modified (.lastModified f)
+                    :last-modified (fs/mod-time f)
                     :path (str category "/" (pathize title))
                     :text content})))))
     @json))
+

 (defn generate-wiki
   "Given a OS path it will explore the folder tree and write a json in path/out/"
   [path]
   (spit (str path "/out/markiki.json")
         (generate-string (flatten (parse-tree (str path "/src") "")) {:pretty true})))
+

 (defn generate-index
   "Writes the index.html in out/"
@@ -127,6 +132,7 @@
                 (include-js "js/markiki.js")
                 [:script "window.onload = function(){markiki.core.main();}"]])))

+
 (defn build-cljs
   "Builds the Clojurescript files in the out/ folder"
   [path]
@@ -139,6 +145,7 @@
               :verbose true})
     (println "[OK] Clojurescript done. Elapsed"
              (/ (- (System/nanoTime) start) 1e9) "seconds")))
+

 (defn -main [& args]
   (let [[options arguments summary] (cli args
@@ -156,14 +163,14 @@
     (cond
      (:help options) (exit 0 (usage summary))
      (not path) (exit 1 (usage summary))
-     (not (.isDirectory (io/file src-path))) (exit 1 invalid-path-error))
+     (not (fs/directory? src-path)) (exit 1 invalid-path-error))
     ;; Start generating!
     (fs/delete-dir out-path)
     (fs/mkdir out-path)
     (generate-index out-path)
-    (doseq [p ["css" "fonts" "js"]] (fs/copy-dir (->> p io/resource io/file) out-path))
+    (generate-wiki path)
+    (doseq [p ["css" "fonts" "js"]] (fs/copy-dir (-> p io/resource io/file) out-path))
     (build-cljs out-path)
-    (generate-wiki path)
     (when (:watch options)
       (start-watch [{:path src-path
                      :event-types [:create :modify :delete]


Remove an unneeded require

Remove an unneeded require

--- src/mdr2/dtb/xml.clj
+++ src/mdr2/dtb/xml.clj
@@ -4,7 +4,6 @@
             [mdr2.data.xml :as xml-new]
             [clojure.walk :as w]
             [clojure.zip :as zip]
-            [clojure.data.zip.xml :as zx]
             [mdr2.production.path :as path]))

 (def ^:private manifest-doctype


cleanup

cleanup

--- src/polismath/math/conversation.clj
+++ src/polismath/math/conversation.clj
@@ -507,8 +507,8 @@
       ;; This is a little different from the group version above;
       ;; For each group, we take the subgroup clustering the best silhouette, and keep it.
       ;; To each of the clusters in this clustering, we assoc the :parent-id of that cluster.
-      ;; We end up with a map that looks like {:parent-id clusters}, where clusters looks as it does for `:group-clusters`,
-      ;; excepting the each cluster has a `:parent-id` attr.
+      ;; We end up with a map that looks like {<parent-id> clusters}, where clusters looks as it does for `:group-clusters`,
+      ;; excepting the each cluster has a `:parent-id <parent-id>` attr/value pair.
       :subgroup-clusters
       (plmb/fnk [subgroup-clusterings subgroup-k-smoother]
         (into
@@ -689,8 +689,8 @@
    (conv-update conv votes {}))
   ;; TODO Need to pass through these options from all the various places where we call this function...
   ;; XXX Also need to set the max globally and by conversation for plan throttling
-  ([conv votes {:keys [med-cutoff large-cutoff]
-                :or {med-cutoff 100 large-cutoff 10000}
+  ([conv votes {:keys [large-cutoff]
+                :or {large-cutoff 10000}
                 :as opts}]
    (let [zid     (or (:zid conv) (:zid (first votes)))
          ptpts   (nm/rownames (:raw-rating-mat conv))


Don't lower case on regexp matches

Don't lower case on regexp matches

--- src/marcgrep/predicates.clj
+++ src/marcgrep/predicates.clj
@@ -68,7 +68,7 @@

 (defn matches? [record fieldspec value]
   (some (fn [^String fv] (.matches (.matcher (re-pattern value)
-                                             (.toLowerCase fv))))
+                                             fv)))
         (field-values record fieldspec)))

@@ -76,7 +76,7 @@
   (when-let [fields (field-values record fieldspec)]
     (not-any? (fn [^String fv]
                 (.matches (.matcher (re-pattern value)
-                                    (.toLowerCase fv))))
+                                    fv)))
               fields)))


Cleaned up the if chain by cond

Cleaned up the if chain by cond

--- clojure/day1.clj
+++ clojure/day1.clj
@@ -9,9 +9,11 @@
     (contains? super tpe)))

 (defn collection-type [col]
-  (if (subinstance? col clojure.lang.IPersistentList) :list
-    (if (subinstance? col clojure.lang.IPersistentMap) :map
-      (if (subinstance? col clojure.lang.IPersistentVector) :vector nil))))
+  (cond
+    (subinstance? col clojure.lang.IPersistentList) :list
+    (subinstance? col clojure.lang.IPersistentMap) :map
+    (subinstance? col clojure.lang.IPersistentVector) :vector
+    :else nil))

 (println (collection-type '()))
 (println (collection-type {}))


WIP convert to poll()-based backend

WIP convert to poll()-based backend

--- src/merlion/core.clj
+++ src/merlion/core.clj
@@ -5,10 +5,19 @@
             Selector SelectionKey])
   (:require [merlion.etcd :as etcd]
             [clojure.string :as str]
+            [clojure.test :as test :refer [deftest testing is]]
             [clojure.java.io :as io]
             [clojure.pprint :refer [pprint]]
+            [clojure.set :as set]
             [clojure.core.async :as async
              :refer [<! <!! go chan >! close! alts!]]))
+
+(defn s->millepoch-time [s]
+  (.getTimeInMillis (clojure.instant/read-instant-calendar s)))
+
+(defn millepoch-time-now []
+  (.getTime (java.util.Date.)))
+

 (defn server-socket
   "Opens a ServerSocketChannel listening on the specified TCP `port` then
@@ -33,43 +42,202 @@
       (.clear buffer)
       true)))

-(defn relay-to-backend [socketchannel host port]
-  (.configureBlocking socketchannel false)
-  (let [sbuffer (ByteBuffer/allocate 8192)
-        obuffer (ByteBuffer/allocate 8192)
-        bo (Selector/open)
-        skey (.register socketchannel bo SelectionKey/OP_READ)
-        outchannel (doto (SocketChannel/open)
-                     (.connect (InetSocketAddress. host port))
-                     (.configureBlocking false))
-        skey2 (.register outchannel bo SelectionKey/OP_READ)]
-    (loop []
-      (let [ready (.select bo)
-            keys (.selectedKeys bo)
-            key (first (seq keys))]
-        (when key
-          (.remove keys key)
-          (condp = (.channel key)
-            socketchannel
-            (when (copy-channel socketchannel outchannel sbuffer) (recur))
-            outchannel
-            (when (copy-channel outchannel socketchannel obuffer) (recur))))))
-    (.close outchannel)
-    (.close bo)
-    ))
+
+(defn write-pending-buffer [w]
+  (let [ch (:to-channel w)
+        b (:buffer w)]
+    (.write ch b)
+    (if (.hasRemaining b) w nil)))
+
+(defn read-pending-buffer [from-channel to-channel]
+  (let [b (ByteBuffer/allocate 8192)
+        c (.read from-channel b)]
+    (cond
+      (zero? c) nil
+      (< c 0) {:eof? true
+               :from-channel from-channel
+               :to-channel to-channel}
+      :else {:to-channel to-channel :buffer (.flip b)})))
+
+(defn poll-ops-mask [ops]
+  (reduce + (map {:read SelectionKey/OP_READ
+                  :write SelectionKey/OP_WRITE
+                  :accept SelectionKey/OP_ACCEPT}
+                 ops)))
+
+(defn poll-op? [actual wanted]
+  (not (zero? (bit-and actual (poll-ops-mask wanted)))))
+
+
+(defn ready-for? [ops channel wanted]
+  (first (filter (fn [s]
+                   (and (= (:channel s) channel) (poll-op? (:ops s) [wanted])))
+                 ops)))
+
+(deftest poll-ops-test
+  (let [rw (+ SelectionKey/OP_READ SelectionKey/OP_WRITE)]
+    (is (= (poll-ops-mask [:read :write]) rw))
+    (is (thrown? Exception (poll-ops-mask [:read :wrong])))
+
+    (is (ready-for?
+         [{:channel :c1 :ops rw}
+          {:channel :c2 :ops (+ SelectionKey/OP_READ)}]
+         :c1
+         :write))
+    (is (ready-for?
+         [{:channel :c1 :ops rw}
+          {:channel :c2 :ops (+ SelectionKey/OP_READ)}]
+         :c2
+         :read))
+    (is (not (ready-for?
+              [{:channel :c1 :ops rw}
+               {:channel :c2 :ops (+ SelectionKey/OP_READ)}]
+              :c2
+              :write)))))
+
+
+(defn poll-channels [poll-set timeout]
+  (with-open [bo (reduce (fn [s [channel & ops]]
+                           (.register channel s (poll-ops-mask ops))
+                           s)
+                         (Selector/open)
+                         poll-set)]
+    (if-not (zero? (.select bo timeout))
+      (let [ready (.selectedKeys bo)]
+        (doall ; have to force evaluation of this before closing selector
+         (map (fn [k]
+                {:channel (.channel k)
+                 :ops (.readyOps k)})
+              ready))))))
+
+(deftest poll-test
+  (testing "timeout"
+    (let [before (millepoch-time-now)]
+      (poll-channels [] 1000)
+      (is (> (- (millepoch-time-now) before) 990))))
+
+  (testing "accept"
+    (let [ss (doto (ServerSocketChannel/open)
+               (.configureBlocking false)
+               (.bind (InetSocketAddress. 0)))
+          c (doto (SocketChannel/open)
+              (.connect
+               (InetSocketAddress. "127.0.0.1" (.getLocalPort (.socket ss))))
+              (.configureBlocking false))]
+      (let [ready (poll-channels [[ss :accept]] 1000)]
+        (is (ready-for? ready ss :accept)))))
+
+  (testing "read and write"
+    (with-open [ssh (doto (SocketChannel/open)
+                      (.connect (InetSocketAddress. "127.0.0.1" 22))
+                      (.configureBlocking false))]
+      (let [ready (poll-channels [[ssh :write ]] 1000)]
+        (is (ready-for? ready ssh :write)))
+      (let [msg (ByteBuffer/wrap (.getBytes "hello world\n"))]
+        (.write ssh msg)
+        (is (ready-for? (poll-channels [[ssh :read]] 1000) ssh :read))))))
+
+(defn backend [serversocket host port finished-ch]
+  (loop [pending-write false
+         downstreams-for-upstreams {}]
+    ;; BACKPRESSURE - we do things in a very specific order.  This is
+    ;; to ensure that we do not look at any avenues for accepting new
+    ;; work (data
+    ;; available on client connections, or new client connections) until
+    ;; we have dealt with current work, and thus that if the downstream
+    ;; is slow to accept our writes or slow to read from, we become
+    ;; slower as a result instead of spraying it with even more work it
+    ;; can't cope with.
+    (let [downstreams (set (vals downstreams-for-upstreams))
+          upstreams (set (keys downstreams-for-upstreams))
+          upstreams-for-downstreams
+          (set/map-invert downstreams-for-upstreams)
+          poll-set
+          (if pending-write
+            [[(:to-channel pending-write) :write]]
+            (concat (map #(vector % :read ) downstreams)
+                    (map #(vector % :read ) upstreams)
+                    [[serversocket :accept]]))]
+      (let [ready (poll-channels poll-set 1000)
+            ready-channels (set (map :channel ready))
+            readable-ds
+            (first (filter (fn [s]
+                             (and (poll-op? (:ops s) [:read])
+                                  (get downstreams (:channel s))))
+                           ready))
+            readable-us
+            (first (filter (fn [s]
+                             (and (poll-op? (:ops s) [:read])
+                                  (get upstreams (:channel s))))
+                           ready))
+            ]
+        (cond
+          ;; Quit when we get a finished message
+          (async/poll! finished-ch)
+          nil
+
+          ;; Zeroth, close the corresponding down/upstream for any up/downstream
+          ;; we received eof while reading
+          (and pending-write (:eof? pending-write))
+          (let [fch (:from-channel pending-write)
+                tch (:to-channel pending-write)]
+            (.close fch)
+            (.close tch)
+            (recur nil (dissoc downstreams-for-upstreams fch tch)))
+
+          ;; First deal with any unwritten buffer to/from the downstream.  We do not
+          ;; get past this point until the in-flight buffer is disposed of
+
+          pending-write
+          (let [r (ready-for? ready (:to-channel pending-write) :write)]
+            (if r
+              (recur (write-pending-buffer pending-write)
+                     downstreams-for-upstreams)
+              (recur pending-write
+                     downstreams-for-upstreams)))
+
+          ;; Next deal with readable downstreams
+          readable-ds
+          (do
+            (let [c (:channel readable-ds)]
+              (recur (read-pending-buffer c (upstreams-for-downstreams c))
+                     downstreams-for-upstreams)))
+
+          ;; Next look at new work from existing upstream requests
+          readable-us
+          (do
+            (let [c (:channel readable-us)]
+              (recur (read-pending-buffer c
+                                          (downstreams-for-upstreams c))
+                     downstreams-for-upstreams)))
+
+          ;; We can pick up a new upstream request if nothing else to do.
+          ;; Note this may block in connect(), I haven't decided if that's
+          ;; bad or not
+          (get ready-channels serversocket)
+          (let [sock (doto (.accept serversocket)
+                       (.configureBlocking false))]
+            (recur nil
+                   (assoc downstreams-for-upstreams
+                          sock
+                          (doto (SocketChannel/open)
+                            (.connect (InetSocketAddress. host port))
+                            (.configureBlocking false)))))
+          :default
+          (do
+            (println "timeout")
+            (recur pending-write downstreams-for-upstreams))
+
+
+          )))))
+

 (defn backend-chan
-  "a channel that repeatedly receives a nio ServerSocketChannel, accepts a new socket from it and relays the data being sent from/to it onto a new connection to host:port"
-  [host port]
+  [host port listener]
+  (println ["backend chan for " host port])
   (let [ch (chan)]
     (future
-      (loop []
-        (let [ssc (<!! ch)]
-          (when ssc
-            (let [socketchannel (.accept ssc)]
-              (relay-to-backend socketchannel host port)
-              (.close socketchannel))
-            (recur))))
+      (backend listener host port ch)
       (println ["backend thread quit" host port]))
     ch))

@@ -77,25 +245,21 @@
   (let [[address port] (str/split a #":")]
     {:address address :port (Integer/parseInt port)}))

-(defn s->millepoch-time [s]
-  (.getTimeInMillis (clojure.instant/read-instant-calendar s)))
-
-(defn millepoch-time-now []
-  (.getTime (java.util.Date.)))
-
-(defn update-backends [backends config]
+(defn update-backends [backends config listener]
   (let [existing (keys backends)
         wanted (keys (:backends config))
-        unwanted (clojure.set/difference (set existing) (set wanted))]
+        unwanted (set/difference (set existing) (set wanted))]
+    (println ["unwanted " unwanted])
     (run! close! (map #(:chan (get backends %)) unwanted))
     (reduce (fn [m [n v]]
               (let [a (parse-address (:listen-address v))]
                 (assoc m
                        n
-                       (or ;(get backends n)
+                       (or (get backends n)
                            (assoc v
                                   :name n
-                                  :chan (backend-chan (:address a) (:port a))
+                                  :chan
+                                  (backend-chan (:address a) (:port a) listener)
                                   :last-seen-at-ms
                                   (if-let [ls (:last-seen-at v)]
                                     (s->millepoch-time ls)
@@ -116,7 +280,9 @@
         listener
         (let [new-l (ServerSocketChannel/open)]
           (and listener (.close listener))
-          (doto new-l (.bind (InetSocketAddress. req-port))))))
+          (doto new-l
+            (.configureBlocking false)
+            (.bind (InetSocketAddress. req-port))))))
     nil))

 (defn combined-config-watcher [prefix]
@@ -148,24 +314,20 @@
     h))

 (defn run-server [prefix]
-  (let [config-ch (merlion.core/combined-config-watcher prefix)
+  (let [config-ch (combined-config-watcher prefix)
         shutdown (chan)]
     (go
       (loop [backends {}
              listener nil
              config {}]
-        (let [timestamp (- (millepoch-time-now) (* 10 1000))
+        (let [timestamp (- (millepoch-time-now) (* 3600 1000))
               healthy (healthy-backends timestamp backends)
-              [val ch] (alts!
-                        (conj
-                         (map #(vector (:chan %) listener)
-                              healthy)
-                         config-ch
-                         shutdown))]
+              [val ch] (alts! [config-ch shutdown])]
           (cond (= ch config-ch)
-                (recur (update-backends backends val)
-                       (update-listener listener val)
-                       val)
+                (let [l (update-listener listener val)]
+                  (recur (update-backends backends val l)
+                         l
+                         val))

                 (= ch shutdown)
                 (do (println "quit") (.close listener))


implement linear regression

implement linear regression

--- statspop/src/statspop/math/regression.cljs
+++ statspop/src/statspop/math/regression.cljs
@@ -15,19 +15,28 @@
 (defn linear-regression
   "estimate OLS parameters.

-  vector, nested numeric vectors --> vector"
+  nested numeric vectors, nested numeric vectors --> vector
+
+  expects rowwise input, e.g. labels are [[lab-row-1] [lab-row-2]] and
+  features are [[feat-1-row-1 feat-2-row-1] [feat-1-row-2] [feat-2-row-2]]
+
+  to transform column-wise data in native clj datastructures, use local helper function
+  cols->rows below."
   [labels features]
   (let [x (matrix/matrixify (add-intercept features))
-        y (matrix/matrixify [labels])
+        y (matrix/matrixify labels)
         x-transpose (matrix/transpose x)
         xtx-1 (matrix/invert (matrix/multiply x-transpose x))
         xty (matrix/multiply x-transpose y)]
     (matrix/m-to-cljs (matrix/multiply xtx-1 xty))))

+(defn cols->rows
+  "assumes you have a single vector of labels [l1 l2 l3]
+  and nested vectors of features [[f1-row1 f1-row2 f1-row3] [f2-row1 f2-row2 f2-row3]]

-(def test-data
-  {:labels [9.95 24.45 31.75 35.00 25.02 16.86 14.38 9.60 24.35 27.50 17.08 37.00 41.95 11.66
-            21.65 17.89 69.00 10.30 34.93 46.59 44.88 54.12 56.63 22.13 21.15]
-   :features [[2 8 11 10 8 4 2 2 9 8 4 11 12 2 4 4 20 1 10 15 15 16 17 6 5]
-              [50 110 120 550 295 200 375 52 100 300 412 400 500 360 205 400 600
-               585 540 250 290 510 590 100 400]]})
+  Just nests the labels in another vector and then transposes them both. "
+  [labels features]
+  {:labels (apply mapv vector [labels])
+   :features (apply mapv vector features)})
+
+


Fix some markup issues, indenting, spaces, etc.

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -135,30 +135,30 @@
               :on-click #(create-token! new-user-token)}
              "Create New Token")]

-          [:div.api-item
-           (when (seq tokens)
-             (om/build table/table
-                       {:rows tokens
-                        :key-fn :token
-                        :columns [{:header "Label"
-                                   :cell-fn :label}
-
-                                  {:header "Token"
-                                   :type :shrink
-                                   :cell-fn :token}
-
-                                  {:header "Created"
-                                   :type :shrink
-                                   :cell-fn (comp datetime/medium-datetime js/Date.parse :time)}
-
-                                  {:header "Remove"
-                                   :type #{:shrink :right}
-                                   :cell-fn
-                                   (fn [token]
-                                     (table/action-button
-                                      "Remove"
-                                      (icon/delete)
-                                      #(raise! owner [:api-token-revocation-attempted {:token token}])))}]}))]]])))))
+           [:div.api-item
+            (when (seq tokens)
+              (om/build table/table
+                        {:rows tokens
+                         :key-fn :token
+                         :columns [{:header "Label"
+                                    :cell-fn :label}
+
+                                   {:header "Token"
+                                    :type :shrink
+                                    :cell-fn :token}
+
+                                   {:header "Created"
+                                    :type :shrink
+                                    :cell-fn (comp datetime/medium-datetime js/Date.parse :time)}
+
+                                   {:header "Remove"
+                                    :type #{:shrink :right}
+                                    :cell-fn
+                                    (fn [token]
+                                      (table/action-button
+                                       "Remove"
+                                       (icon/delete)
+                                       #(raise! owner [:api-token-revocation-attempted {:token token}])))}]}))]]])))))

 (def available-betas
@@ -248,7 +248,7 @@
                        [:p "Thanks for being part of the beta program.
                             We'll let you know when we release updates
                             so you'll be the first to see new
-                            features!" ]
+                            features!"]
                        [:p "We'd love to know what you think - " [:a {:href "mailto:beta@circleci.com"} "send us your feedback"] "!"]
                        (button/button
                         {:on-click #(do


Solve part two of day 1 puzzle

Solve part two of day 1 puzzle

--- day-01/src/solver/core.clj
+++ day-01/src/solver/core.clj
@@ -1,16 +1,26 @@
 (ns solver.core
   (:gen-class))

+(defn- to-direction [index direction] { :index index :direction direction })
+
 (defn determine-floor [xs]
-  (let [to-direction (fn [index direction] {:index index :direction direction})
+  (let [
         determine-floor (fn [floor data] (+ floor  (case (data :direction)
                                              "(" +1
                                              ")" -1)))]
     (reduce determine-floor 0  (map-indexed to-direction xs))))

+(defn first-basement [directions]
+  (let [to-floor (fn [direction] (assoc direction
+                                        :floor (determine-floor
+                                                (take (direction :index) directions))))
+        hit-basement (fn [data] (= (data :floor) -1))]
+    (first (filter hit-basement (map to-floor (map-indexed to-direction directions))))))
+
 (defn -main
   "I don't do a whole lot ... yet."
   [& args]
   (let [directions (clojure.string/split (slurp "input") #"")]
-    (println (determine-floor directions))))
+    (println (determine-floor directions))
+    (println (first-basement directions))))


comments, better examples

comments, better examples

--- src/main/cljc/clojure_club/macros/mbastian.cljc
+++ src/main/cljc/clojure_club/macros/mbastian.cljc
@@ -1,5 +1,6 @@
 (ns clojure-club.macros.mbastian
-  (:require [taoensso.tufte :as tufte :refer (defnp p profiled profile)]))
+  (:require [taoensso.tufte :as tufte :refer (defnp p profiled profile)]
+            [clojure.pprint :as pp]))

 ;Techniques for manual polynomial creation
 (defn canonical-fn [t]
@@ -38,27 +39,41 @@

 ;Macros that allow for definition of complex polynomials with the convenience
 ;of a coefficients vector and the performance of manual expansion.
-(defmacro defpoly-canonical [n terms]
+(defmacro canonical-expand [terms]
   (let [t# (eval terms)]
-    `(defn ~n [~'t]
+    `(fn [~'t]
        (+ ~@(for [i (range (count t#)) :let [c (t# i)]]
               `(* ~c ~@(repeat i 't)))))))

-(defmacro defpoly-horner [n terms]
+(defmacro horner-expand [terms]
   (let [t# (rseq (eval terms))]
-    `(defn ~n [~'t]
+    `(fn [~'t]
      ~(reduce (fn [b a] `(+ ~a (* ~b ~'t))) t#))))

 ;Macroexpand to see what happend
-(macroexpand
-  '(defpoly-canonical canonical-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5]))
+(pp/pprint
+  (macroexpand
+  '(canonical-expand [134.96340251 477198.8675605 0.0088553 1.4343E-5])))

-(macroexpand
-  '(defpoly-horner horner-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5]))
+(pp/pprint
+  (macroexpand
+  '(horner-expand [134.96340251 477198.8675605 0.0088553 1.4343E-5])))
+
+;Create a macro to easily create functions along the lines of defn
+(defmacro defpoly [n terms]
+  `(def n (horner-expand ~terms)))
+
+(def c [1 2 3 4])
+(defpoly p c)
+(macroexpand '(defpoly p c))
+(pp/pprint (clojure.walk/macroexpand-all '(defpoly p c)))

 ;Define the functions
-(defpoly-canonical canonical-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5])
-(defpoly-horner horner-poly-macro [134.96340251 477198.8675605 0.0088553 1.4343E-5])
+(def canonical-poly-macro
+  (canonical-expand [134.96340251 477198.8675605 0.0088553 1.4343E-5]))
+
+(def horner-poly-macro
+  (horner-expand [134.96340251 477198.8675605 0.0088553 1.4343E-5]))

 (canonical-poly-macro 0.0426236319)
 (horner-poly-macro 0.0426236319)
@@ -81,11 +96,13 @@
 (def coefficients
   (vec (repeatedly 100 (comp dec #(* 2 %) rand))))

-(macroexpand
-  '(defpoly-canonical canonical-poly-macro coefficients))
+(macroexpand '(canonical-expand coefficients))

-(defpoly-canonical big-canonical coefficients)
-(defpoly-horner big-horner coefficients)
+(def big-canonical
+  (canonical-expand coefficients))
+
+(def big-horner
+  (horner-expand coefficients))

 (profile
   {:dynamic? true}


:bug: Set proper shape ordering on layers sidebar.

--- frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs
+++ frontend/src/uxbox/main/ui/workspace/sidebar/layers.cljs
@@ -177,7 +177,7 @@
          i/arrow-slide])]
      (when (and (:shapes item) (not collapsed?))
        [:ul.element-children
-        (for [[index id] (d/enumerate (:shapes item))]
+        (for [[index id] (reverse (d/enumerate (:shapes item)))]
           (when-let [item (get objects id)]
             [:& layer-item
              {:item item
@@ -194,7 +194,7 @@
         objects (:objects data)
         root (get objects uuid/zero)]
     [:ul.element-list
-     (for [[index id] (d/enumerate (reverse (:shapes root)))]
+     (for [[index id] (reverse (d/enumerate (:shapes root)))]
        (let [item (get objects id)]
          [:& layer-item
           {:item item


Rename build-definition-screen to build-definition-monitor

--- src/build_mon/core.clj
+++ src/build_mon/core.clj
@@ -142,7 +142,7 @@
          :headers {"Content-Type" "text/html; charset=utf-8"}
          :body (generate-build-monitor-html build-info-maps refresh-info)}))))

-(defn build-definition-screen [account project token request]
+(defn build-definition-monitor [account project token request]
   (let [build-definition-id (-> request :route-params :build-definition-id Integer.)]
     (build-monitor-for-build-definition-ids account project token request [build-definition-id])))

@@ -152,7 +152,7 @@
     (build-monitor-for-build-definition-ids account project token request build-definition-ids)))

 (def routes ["/" {"" :build-monitor
-                  ["build-definitions/" [#"\d+" :build-definition-id]] :build-definition
+                  ["build-definitions/" [#"\d+" :build-definition-id]] :build-definition-monitor
                   ["ajax/build-definitions/" [#"\d+" :build-definition-id]] :build-info}])

 (defn wrap-routes [handlers]
@@ -164,8 +164,8 @@
 (defn handlers [account project token]
   {:build-monitor
    (partial build-monitor account project token)
-   :build-definition
-   (partial build-definition-screen account project token)
+   :build-definition-monitor
+   (partial build-definition-monitor account project token)
    :build-info
    (partial build-info account project token)})


Removed old references.

Removed old references.

--- dev-resources/src/user.clj
+++ dev-resources/src/user.clj
@@ -11,10 +11,6 @@
    [clojure.java.io :as io]
    [clojure.pprint :refer [pprint]]
    [clojure.tools.namespace.repl :as repl]
-   [clojurewerkz.neocons.rest.cypher :as ncy]
-   [clojurewerkz.neocons.rest.nodes :as nn]
-   [clojurewerkz.neocons.rest.paths :as np]
-   [clojurewerkz.neocons.rest.relationships :as nrl]
    [cmr.opendap.dev :as dev]))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Peer parent can also be a coordinator id.

--- src/onyx/schema.cljc
+++ src/onyx/schema.cljc
@@ -823,11 +823,7 @@
    :completed-jobs [JobId]
    :killed-jobs [JobId]
    :task-slot-ids {JobId {TaskId {PeerId SlotId}}}
-   :message-short-ids s/Any #_{[[(s/one s/Keyword "PeerType")
-                         (s/one PeerId "PeerId")]
-                        (s/one JobId "JobId")
-                        (s/one TaskId "TaskId")
-                        (s/one SlotId "SlotId")] s/Int}
+   :message-short-ids s/Any
    :in->out {JobId {TaskId #{TaskId}}}
    :required-tags {JobId {TaskId [s/Keyword]}}
    :peer-tags {PeerId [s/Keyword]}
@@ -843,7 +839,7 @@
    :args {s/Any s/Any}
    (s/optional-key :message-id) s/Int
    (s/optional-key :created-at) s/Int
-   (s/optional-key :peer-parent) s/Uuid
+   (s/optional-key :peer-parent) s/Any
    (s/optional-key :entry-parent) s/Int})

 (s/defschema Reactions