project-root -> *project-root*

project-root -> *project-root*

--- src/cake/core.clj
+++ src/cake/core.clj
@@ -22,8 +22,8 @@
   (let [opts (into-map opts)
         [tasks task-opts] (split-with symbol? (:tasks opts))
         task-opts (into-map task-opts)]
-    `(do (alter-var-root #'*project*    (fn [_#] (project/create '~name ~version '~opts)))
-         (alter-var-root #'project-root (fn [_#] (project/create '~name ~version '~opts)))
+    `(do (alter-var-root #'*project*      (fn [_#] (project/create '~name ~version '~opts)))
+         (alter-var-root #'*project-root* (fn [_#] (project/create '~name ~version '~opts)))
          (require 'cake.tasks.default)
          (load-tasks '~tasks)
          (undeftask ~@(:exclude task-opts)))))


Start the world off as closed.

Start the world off as closed.

--- src/cbfg/vis.cljs
+++ src/cbfg/vis.cljs
@@ -317,11 +317,10 @@
         world (conj w "world-0")  ; No ago for world actx init to avoid recursion.
         vis (atom {:actxs {world {:children {} ; child-actx -> true,
                                   :wait-chs {} ; ch -> [:ghost|:take|:put optional-ch-name],
+                                  :closed true
                                   ; :loop-state last-loop-bindings,
-                                  ; :closed bool.
                                   }}
-                   :chs {} ; {ch -> {:id (gen-id),
-                           ;         :msgs {msg -> true}
+                   :chs {} ; {ch -> {:id (gen-id), :msgs {msg -> true},
                            ;         :first-taker-actx actx-or-nil}}.
                    :gen-id gen-id})
         el-event (str el-prefix "-event")


Added a pause atom that stops new rendering from happening

--- src/cljs/app.cljs
+++ src/cljs/app.cljs
@@ -29,9 +29,15 @@
   (doseq [child (.slice (.-children stage) 0)]
     (.removeChild stage child)))

+(def pause (atom false))
+
 (defn update-world [bunny]
-  (aset bunny "rotation" (+ 0.05 (aget bunny "rotation"))))
+  (when-not @pause
+    (aset bunny "rotation" (+ 0.05 (aget bunny "rotation")))))

+(def global (atom {}))
+
+;; TODO macro that takes a body and draws it repeatedly
 (defn animate
   "The main draw function called repeatedly"
   [renderer stage bunny]


require facebook

require facebook

--- frontend/analytics.cljs
+++ frontend/analytics.cljs
@@ -6,6 +6,7 @@
             [frontend.analytics.perfect-audience :as pa]
             [frontend.analytics.rollbar :as rollbar]
             [frontend.analytics.twitter :as twitter]
+            [frontend.analytics.facebook :as facebook]
             [frontend.models.build :as build-model]
             [frontend.utils :as utils :include-macros true]
             [frontend.utils.vcs-url :as vcs-url]


virtualbox-guest-x11 -> hwe, to make install on new vm easier

--- main/src/dda/pallet/dda_managed_vm/infra/basics.clj
+++ main/src/dda/pallet/dda_managed_vm/infra/basics.clj
@@ -39,7 +39,7 @@
   [facility]
   (actions/as-action
    (logging/info (str facility "-install system: virtualbox-guest")))
-  (actions/packages :aptitude ["virtualbox-guest-x11"]))
+  (actions/packages :aptitude ["virtualbox-guest-x11-hwe"]))

 (defn configure-virtualbox-guest-additions
   "configures virtual-box guest additions"


[lein] inject 'refresh & 'doc

[lein] inject 'refresh & 'doc

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -17,7 +17,23 @@

         :dependencies [; Code quality
                        [slamhound                    "1.5.5"]
-                       [walmartlabs/datascope        "0.1.1"]]
+                       [walmartlabs/datascope        "0.1.1"]
+
+                       [org.clojure/tools.namespace  "0.2.11"]
+
+                       ;; Inject symbols in the REPL's global ns
+                       ;; http://dev.solita.fi/2014/03/18/pimp-my-repl.html
+                       ;; http://docs.caudate.me/lucidity/lucid-core.html#core-inject
+                       [im.chit/lucid.core.inject    "1.3.9"]]

         :aliases {"slamhound" ["run" "-m" "slam.hound"]}
+
+        :injections [(require 'lucid.core.inject)
+                     (lucid.core.inject/in
+                       ;; help function
+                       [clojure.repl :refer [doc]]
+
+                       ;; Refresh namespaces without reloading the REPL
+                       [clojure.tools.namespace.repl :refer [refresh]])]
+
         :signing {:gpg-key "E5B26621"}}}


Add special form parsing

Add special form parsing

--- src/cas/language.cljs
+++ src/cas/language.cljs
@@ -1,33 +1,46 @@
-(ns cas.language)
+(ns cas.language
+  (:require [clojure.string :as string]))

 ;;
 ;; Defines the language that Robot programs are written in
 ;;

 ;; Tokenizes a splitted part of source, ie "124" or "KEYWORD"
-(defn tokenize-source-thing [obj]
+(defn- tokenize-source-thing [obj]
   (cond
     (re-matches #"[0-9]+" obj) ;; literal int
     (js/parseInt obj)

     ;; keywords
-    (= 0 (compare obj "FOR"))
+    (= obj "FOR")
     :for

-    (= 0 (compare obj "WHILE"))
+    (= obj "WHILE")
     :while

-    (= 0 (compare obj "INT"))
+    (= obj "INT")
     :int

-    (= 0 (compare obj "SUB"))
+    (= obj "SUB")
     :sub

-    (= 0 (compare obj "{"))
+    (= obj "DO")
+    :do
+
+    (= obj "DONE")
+    :done
+
+    (= obj "{")
     :open-curly

-    (= 0 (compare obj "}"))
+    (= obj "}")
     :close-curly
+
+    (= obj "(")
+    :open-paren
+
+    (= obj ")")
+    :close-paren

     ;; otherwise, it's a user defined string
     true
@@ -36,15 +49,118 @@
     )
   )

-(defn- tokenize [text]
-  (map tokenize-source-thing (split text #" ")))
+;;
+;; Anything of the form: DO expression_list... DONE
+;;
+(defn- parse-block [stream]
+  (assert (= (stream :eat) :do))

-(defn- parse-program [text])
+  [:block (loop [x []]
+            (if (= (stream :peek) :done)
+              x
+              (recur (concat x (parse-expression stream)))))]
+  )

-(defn- execuate-ast [ast state])
+;;
+;; FOR i = 0; i < 10; i += 1
+;; DO
+;;   SOME_FUNCTION (i)
+;; DONE
+;;
+(defn- parse-for [stream]
+  (assert (= (stream :eat) :for))

-(defn run [text state]
-  (let [ast (parse-program text)]
-    (execuate-ast ast state)
+  (let [init (parse-expression stream)
+        cond (parse-expression stream)
+        loop (parse-expression stream)
+        blck (parse-block stream)]
+    [:for init cond loop blck]
+    ))
+
+;;
+;; WHILE i < 2;
+;; DO
+;;   i += 1;
+;; DONE
+;;
+(defn- parse-while [stream]
+  (assert (= (stream :eat) :while))
+
+  (let [cond (parse-expression stream)
+        blck (parse-block stream)]
+    [:while cond blck]))
+
+;;
+;; IF i == 2;
+;; DO
+;;   PRINT ( "TWO" )
+;; DONE
+;;
+(defn- parse-if [stream]
+  (assert (= (stream :eat) :if))
+
+  (let [cond (parse-expression stream)
+        blck (parse-block stream)]
+    [:if cond blck]
     )
   )
+
+;;
+;; SUB ident ( param )
+;; DO
+;;   WHILE param < 10; DO
+;;     param += 1;
+;;   DONE
+;; DONE
+;;
+(defn parse-sub [stream]
+  (assert (= (stream :eat) :sub))
+
+  (let [identifier (parse-ident stream)
+        param-list (parse-param-list stream)
+        block      (parse-block stream)]
+    [:sub identifier param-list block]
+    )
+  )
+
+(defn- parse-top-level [stream]
+  (case (stream :peek)
+    :for (parse-for stream)
+    :while (parse-while stream)
+    :if (parse-if stream)
+    :sub (parse-sub stream)
+    true (parse-expression stream)
+    )
+  )
+
+(defn- parse [stream]
+  (loop [x []]
+    (if (= (stream :peek) :eof)
+      x
+      (recur (concat x (parse-top-level stream))))))
+
+(defn- token-stream [toks]
+  (let [idx (atom 0)]
+    (fn [action]
+      (case action
+        :peek (get toks idx)
+
+        :eat (let [ret (get toks idx)]
+               (swap! idx inc)
+               ret)
+        ))))
+
+
+;; called once when making the generator
+(defn- make-ast [text]
+  (parse (token-stream (map tokenize-source-thing (string/split text #" "))))
+  )
+
+;; Interface to language runtime
+(defn generate-program-context [text timeout]
+  (let [ast (make-ast text)
+        idx 0]
+    (fn [state] ;; action generator
+      (evaluate toks idx state)
+      )
+  ))


Updated grouper docs.

Updated grouper docs.

--- src/cbfg/grouper.cljs
+++ src/cbfg/grouper.cljs
@@ -2,16 +2,15 @@
   (:require-macros [cbfg.act :refer [act-loop achan aclose aalts]]))

 (defn make-grouper [actx put-ch take-all-ch max-entries-per-take]
-  "A grouper manages a put-ch, a take-all-ch, and a set of entries.
-   Multiple producers can put entries to the put-ch, and a consumer
-   can grab all the collected entries in one shot by a take on the
-   take-all-ch.  During a put, an entry is a [key update-fn], so
-   producers can merge or group entries, such as for de-dupe or
-   piggy-backing requests.  Puts will block if there are more than
-   max-entries-per-take number of entries.  During a take-all, the received
-   entries is an associative map of key to update-fn-result.
-   The grouper closes the take-all-ch after put-ch is closed
-   and all the entries are taken."
+  "A grouper manages a put-ch, take-all-ch, and a set of entries.
+   Multiple producers can put to the put-ch, and a consumer can grab
+   all the collected entries in one shot by a take on the take-all-ch.
+   During a put, an entry is a [key update-fn], so producers can merge
+   or group entries, to de-dupe or piggy-backing requests.  Puts will
+   block when there are more than max-entries-per-take number of
+   entries already.  A take on take-all-ch will receive a map of
+   key to update-fn-result.  grouper closes take-all-ch after put-ch
+   is closed and all entries are taken."
   (act-loop grouper actx
             [entries {}
              max-entries-per-take max-entries-per-take


pixel storage tests (success!)

pixel storage tests (success!)

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

--- acqEngine/src/org/micromanager/test.clj
+++ acqEngine/src/org/micromanager/test.clj
@@ -323,7 +323,9 @@
                   (.put queue
                         (image-to-byte-buffer
                           img
-                          (byte-buffer (* n 2)))))))
+                          (byte-buffer (* n 2)))
+                        )
+                  )))
       queue)))

 (defn shorts-test [n]
@@ -350,25 +352,34 @@
           (future (.force channel true))))
     (.force channel false)
     (.close file)))
+

 (defn acquire-and-save-test [n]
-    (let [buffer-queue (time (simple-byte-buffer-queue n))
-          filename (str "E:/acquisition/test" (rand-int 100000) ".dat")
-          file (RandomAccessFile. filename "rw")
-          channel (.getChannel file)
-          t0 (System/currentTimeMillis)]
-      (println filename)
-      (dotimes [i n]
-        (when (zero? (mod i 100))
-          (println i (- (System/currentTimeMillis) t0)))
-        (.write channel
-                (.take buffer-queue)
-               )
-        (when (zero? (mod i 100))
-          (future (.force channel true)))
-      )
-      (.close file)
-      filename))
+  (let [buffer-queue (time (simple-byte-buffer-queue n))
+        filename (str "E:/acquisition/test" (rand-int 100000) ".dat")
+        file (RandomAccessFile. filename "rw")
+        channel (.getChannel file)
+        t0 (System/currentTimeMillis)]
+    (println filename)
+    (dotimes [i n]
+      (when (zero? (mod i 100))
+        (println i (- (System/currentTimeMillis) t0)))
+      (let [buffer (.take buffer-queue)]
+        (.write channel buffer)
+        ))
+    (.close file)
+    filename))
+
+(defn acquire-and-store-in-ram [n]
+  (let [buffer-queue (time (simple-byte-buffer-queue n))
+       storage-queue (LinkedBlockingQueue.)
+       t0 (System/currentTimeMillis)]
+   (dotimes [i n]
+     (when (zero? (mod i 100))
+       (println i (- (System/currentTimeMillis) t0)))
+     (let [buffer (.take buffer-queue)]
+       (.put storage-queue buffer)))
+   (count storage-queue)))

 (defn run-in-parallel [n f]
   (doall (apply pcalls (repeat n f))))
@@ -389,3 +400,9 @@

+
+
+
+
+
+


Added assert args and used it for for's compile-time check.  Finalizes #20

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -209,7 +209,15 @@
      (when *assert*
        `(when-not ~x
           (throw (cljs.core/str
-                   "Assert failed: " ~message "\n" (cljs.core/pr-str '~x)))))))
+                  "Assert failed: " ~message "\n" (cljs.core/pr-str '~x)))))))
+
+(defmacro ^{:private true} assert-args [fnname & pairs]
+  `(do (when-not ~(first pairs)
+         (throw (IllegalArgumentException.
+                  ~(str fnname " requires " (second pairs)))))
+     ~(let [more (nnext pairs)]
+        (when more
+          (list* `assert-args fnname more)))))

 (defmacro for
   "List comprehension. Takes a vector of one or more
@@ -222,7 +230,9 @@

   (take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)]  [x y]))"
   [seq-exprs body-expr]
-  ;; TODO - Impl and use assert-args
+  (assert-args for
+     (vector? seq-exprs) "a vector for its binding"
+     (even? (count seq-exprs)) "an even number of forms in binding vector")
   (let [to-groups (fn [seq-exprs]
                     (reduce (fn [groups [k v]]
                               (if (keyword? k)


tools.reader is char based not int based

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -42,10 +42,10 @@
   CRLF to a single \\newline."
   [s]
   (let [c (.read s)]
-    (cond
-      (= c (int \newline)) :line-start
-      (= c -1) :stream-end
-      :else (do (.unread s c) :body))))
+    (case c
+      \newline :line-start
+      nil :stream-end
+      (do (.unread s c) :body))))

 (defn skip-whitespace
   "Skips whitespace characters on stream s. Returns :line-start, :stream-end,
@@ -58,12 +58,13 @@
   \\newline."
   [s]
   (loop [c (.read s)]
-    (cond
-      (= c (int \newline)) :line-start
-      (= c -1) :stream-end
-      (= c (int \;)) (do (.readLine s) :line-start)
-      (or (Character/isWhitespace (char c)) (= c (int \,))) (recur (.read s))
-      :else (do (.unread s c) :body))))
+    (case c
+      \newline :line-start
+      nil :stream-end
+      \; (do (.readLine s) :line-start)
+      (if (or (Character/isWhitespace c) (identical? c \,))
+        (recur (.read s))
+        (do (.unread s c) :body)))))

 (defn repl-read
   "Default :read hook for repl. Reads from *in* which must either be an


added /end-run which got lost in translation somewhere

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -1966,6 +1966,7 @@
         "/counter"    #(command-counter %1 %2 value)
         "/adv-counter" #(command-adv-counter %1 %2 value)
         "/jack-out"   #(when (= %2 :runner) (jack-out %1 %2 nil))
+        "/end-run"    #(when (= %2 :corp) (end-run %1 %2))
         "/discard"    #(move %1 %2 (nth (get-in @%1 [%2 :hand]) num nil) :discard)
         "/deck"       #(move %1 %2 (nth (get-in @%1 [%2 :hand]) num nil) :deck {:front true})
         nil


Switch port for standalone test.

Switch port for standalone test.

--- test/onyx/hornetq/standalone_test.clj
+++ test/onyx/hornetq/standalone_test.clj
@@ -15,17 +15,7 @@

 (def hornetq-host "localhost")

-(def hornetq-port 5446)
-
-(def hornetq-cluster-name "onyx-cluster")
-
-(def hornetq-group-address "231.7.7.7")
-
-(def hornetq-group-port 9876)
-
-(def hornetq-refresh-timeout 5000)
-
-(def hornetq-discovery-timeout 5000)
+(def hornetq-port 5465)

 (def hq-config {"host" hornetq-host "port" hornetq-port})


got tree-map working correctly with chroot and in a sane way

--- src/duffel/fs.clj
+++ src/duffel/fs.clj
@@ -134,7 +134,8 @@
 (defn chroot-tree
     [root dir-tree]
     "Makes sure that the entire tree is chrooted to a directory. The given directory
-    should not end in a /, unless it is just '/'"
+    should not end in a /. If you want to chroot to root itself (/) pass in a blank
+    string"
     (let [root-node  (first dir-tree)]
         (cons (assoc root-node :base-name root) (rest dir-tree))))

@@ -162,10 +163,10 @@

 (defn _tree-map
     [user-fn dir-tree abs local]
-    (let [ abs-a             (if (= abs "/") abs (append-slash abs))
-           new-dir-tree      (user-fn dir-tree abs-a local)
+    (let [ new-dir-tree      (user-fn dir-tree abs local)
            new-dir-tree-node (first new-dir-tree)
-           new-abs           (str abs-a (new-dir-tree-node :base-name))
+           new-dir-base-name (new-dir-tree-node :base-name)
+           new-abs           (append-slash (str abs   (new-dir-tree-node :base-name)))
            new-local         (append-slash (str local (new-dir-tree-node :full-name))) ]
         (map #(if (seq? %)
                   (_tree-map user-fn % new-abs new-local)


added in the tree-map function. it's like a little contained ball of horrible sludge

--- src/duffel/fs.clj
+++ src/duffel/fs.clj
@@ -61,7 +61,7 @@
     { :base-name base-name
       :specifier specifier
       :extension extension
-      :file-name file-name
+      :full-name file-name
       :is-dir?   false    }))

 (defmethod explode-file true [dir]
@@ -75,7 +75,7 @@
     { :base-name base-name
       :specifier specifier
       :extension extension
-      :file-name dir-name
+      :full-name dir-name
       :dir-ls    dir-ls
       :is-dir?   true    }))

@@ -130,3 +130,52 @@
          (list)
          (specify-files)
          (first)))
+
+(defn chroot-tree
+    [root dir-tree]
+    "Makes sure that the entire tree is chrooted to a directory. The given directory
+    should not end in a /, unless it is just '/'"
+    (let [root-node  (first dir-tree)]
+        (cons (assoc root-node :base-name root) (rest dir-tree))))
+
+(defn append-slash [dir-name] (str dir-name "/"))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;
+; I couldn't explain again how these work, but they do. You give tree-map a
+; function and a tree. The function should take three args, the first is a
+; tree, the second the absolute prefix for this tree, and three the local
+; duffel project prefix for this tree. The function should return the tree
+; modified to your liking. When returned tree map will find all sub-trees
+; (directories) in the tree you returned and run tree-map on them again, with
+; aboslute and local prefixes updated accordingly. I'm leaving test-map around
+; so you can see an example. It'll give each directory struct an :abs and a
+; :local key so you can see what the list was being run with.
+;
+(declare _tree-map)
+(defn tree-map
+    [user-fn dir-tree]
+    (let [ root-node  (first dir-tree)
+           root-abs   (root-node :base-name)
+           root-local "" ]
+        (_tree-map user-fn (chroot-tree "" dir-tree) root-abs root-local)))
+
+(defn _tree-map
+    [user-fn dir-tree abs local]
+    (let [ abs-a             (if (= abs "/") abs (append-slash abs))
+           new-dir-tree      (user-fn dir-tree abs-a local)
+           new-dir-tree-node (first new-dir-tree)
+           new-abs           (str abs-a (new-dir-tree-node :base-name))
+           new-local         (append-slash (str local (new-dir-tree-node :full-name))) ]
+        (map #(if (seq? %)
+                  (_tree-map user-fn % new-abs new-local)
+                  %)
+             new-dir-tree)))
+
+(defn test-map [dir-tree abs-prefix local-prefix]
+    (cons
+        (assoc (first dir-tree) :abs   abs-prefix
+                                :local local-prefix )
+        (rest dir-tree)))
+;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


#6 - Added styling and navigation.

#6 - Added styling and navigation.

--- src/biblecli/commands/staticpages.cljs
+++ src/biblecli/commands/staticpages.cljs
@@ -24,6 +24,42 @@

 (defn style []
 "
+body {
+  background-color: #EEE;
+}
+a:link, a:visited {
+  text-decoration: none;
+  color: #33f;
+}
+a:hover, a:active {
+  text-decoration: underline;
+  color: #77f;
+}
+.content {
+  width: 600px;
+  margin: 25px auto 15px auto;
+  padding: 25px;
+  border-left: #BBB;
+  border-right: #BBB;
+  background-color: #FFFFFF;
+  -webkit-box-shadow: 0px 0px 23px 3px rgba(135,135,135,0.77);
+  -moz-box-shadow: 0px 0px 23px 3px rgba(135,135,135,0.77);
+  box-shadow: 0px 0px 23px 3px rgba(135,135,135,0.77);
+}
+.menu {
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.menu2 {
+  font-family: Arial, sans-serif;
+  position: fixed;
+  background-color: #DDD;
+  border-right: 1px solid #BBB;
+  border-bottom: 1px solid #BBB;
+  padding: 6px;
+  border-bottom-right-radius: 4px;
+}
 .ref {
   display: none;
 }
@@ -158,8 +194,8 @@
     (rel-url book-id chap-num chap-cnt)))

 (defn toc-book [b]
-  [:p {:class "tocp"}
-    [:span {:class "chapter"} (book-name (:id b))]
+  [:p.tocp {:id (book-name (:id b))}
+    [:span.chapter (book-name (:id b))]
     " "
     (->> (:chapters b)
       (map (fn [ch]
@@ -172,17 +208,18 @@
         [:title "The King James Bible"]
         [:link {:rel "stylesheet" :type "text/css" :href "styles.css"}]]
       [:body
-        [:h1 "The King James Bible"]
-
-        [:h2 "The Old Testament"]
-        (->> m
-          (take 39)
-          (map toc-book))
-
-        [:h2 "The New Testament"]
-        (->> m
-          (drop 39)
-          (map toc-book))]]))
+        [:div.content
+          [:h1 "The King James Bible"]
+
+          [:h2 "The Old Testament"]
+          (->> m
+            (take 39)
+            (map toc-book))
+
+          [:h2 "The New Testament"]
+          (->> m
+            (drop 39)
+            (map toc-book))]]]))

 (defn chapters [m]
   (->> m
@@ -194,7 +231,8 @@
               {:book-id (:id b)
                :book-num (:num b)
                :chap-cnt (count (:chapters b))}))
-          (:chapters b))))))
+          (:chapters b))))
+    (vec)))

 (def ^:private beginbracket [:beginbracket "["])
 (def ^:private endbracket [:endbracket "]"])
@@ -262,21 +300,42 @@
       (number-markup i ch)
       (tokens-to-markup tokens)]))

+(defn chapter-url [ch inner]
+  (if ch
+    [:a {:href (rel-url ch)} inner]
+    inner))
+
 (defn chapter
   [{book-id :book-id
     chap-num :num
     chap-cnt :chap-cnt
     verses :verses
-    :as ch}]
+    :as ch}
+    prev-ch
+    next-ch]
   (html
     [:html
       [:head
         [:title (str (chapter-name ch) " - The King James Bible")]
         [:link {:rel "stylesheet" :type "text/css" :href "styles.css"}]]
       [:body
-        [:h2 {:class "chap"}
-          (chapter-name ch)]
-        (map-indexed #(verse %1 ch %2) verses)]]))
+        [:body.content
+          [:div.menu
+            [:div.menu2
+              (chapter-url prev-ch "<<")
+              " "
+              (chapter-url next-ch ">>")
+              " "
+              [:a {:href (str ".#" (book-name book-id))} (chapter-name ch)]]]
+          [:h1.chap
+            (chapter-name ch)]
+          (map-indexed #(verse %1 ch %2) verses)]]]))
+
+(defn next-chapter [all-chapters i]
+  (get all-chapters (inc i)))
+
+(defn prev-chapter [all-chapters i]
+  (get all-chapters (dec i)))

 (defn write! [dir filename content]
   (let [filepath (.join node-path dir filename)
@@ -284,8 +343,16 @@
     (.writeFileSync node-fs filepath buff)))

 (defn prepare! [parser src output-dir]
-  (let [m (parse parser src)]
+  (let [m (parse parser src)
+        all-chapters (chapters m)]
     (write! output-dir "styles.css" (style))
     (write! output-dir "7ce12f75-f371-4e85-a3e9-b7749a65f140.html" (toc m))
-    (doseq [ch (chapters m)]
-      (write! output-dir (rel-url ch) (chapter ch)))))+    (dorun
+      (map-indexed
+        #(write!
+          output-dir
+          (rel-url %2)
+          (chapter %2
+            (prev-chapter all-chapters %1)
+            (next-chapter all-chapters %1)))
+        all-chapters))))


Simplify

Simplify

--- src/discuss/auth.cljs
+++ src/discuss/auth.cljs
@@ -3,7 +3,6 @@
             [goog.crypt.base64 :as gtfo]
             [discuss.communication :as com]
             [discuss.config :as config]
-            [discuss.debug :as debug]
             [discuss.utils.common :as lib]))

 (defn success-login
@@ -14,14 +13,12 @@
     (lib/update-state-map! :user {:nickname   nickname
                                   :token      token
                                   :logged-in? true})
-    (lib/change-view! :discussion)
-    (com/init!)))
+    (lib/change-view! :discussion)))

 (defn ajax-login
   "Get cleaned data and send ajax request."
   [nickname password]
   (let [url (str (:base config/api) "login")]
-    (debug/update-debug :last-api url)
     (POST (com/make-url url)
           {:body            (lib/clj->json {:nickname nickname
                                             :password password})


Added configuration for REPL and app logging.

--- src/dragon/config.clj
+++ src/dragon/config.clj
@@ -15,8 +15,14 @@
    :posts-path "/blog/archives"
    :posts-path-src "./posts"
    :feed-count 20
+   :repl {
+     :log-level :info
+     :log-nss '[dragon]}
+   :app {
+     :log-level :warn
+     :log-nss '[dragon]}
    :cli {
-     :log-level :info
+     :log-level :error
      :log-nss '[dragon]}})

 (defn build


start adding transaction form

start adding transaction form

--- src/cljs/clj_money/views/accounts.cljs
+++ src/cljs/clj_money/views/accounts.cljs
@@ -1,6 +1,6 @@
 (ns clj-money.views.accounts
-  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
-  (:require [cljs.core.async :refer [<! >! chan]]
+  (:require-macros [cljs.core.async.macros :refer [go]])
+  (:require [cljs.core.async :refer [timeout]]
             [reagent.core :as r]
             [reagent-forms.core :refer [bind-fields]]
             [reagent.format :refer [currency-format]]
@@ -21,13 +21,14 @@
             [clj-money.x-platform.util :refer [desc-periodic-seq]]
             [clj-money.util :as util]
             [clj-money.forms :refer [text-input
+                                     number-input
                                      select-input
                                      typeahead-input
                                      required]]))

 (def ^:private *accounts* (r/atom []))
 (def ^:private *commodities* (r/atom []))
-#_(def ^:private *expansion-state* (r/atom {}))
+(def ^:private working-transaction (r/atom nil))

 (defn- delete
   [account]
@@ -116,10 +117,11 @@
 (defn- account-list
   []
   [:table.table.table-striped.table-hover
-   [:tbody
+   [:thead
     [:tr
      [:th "Name"]
-     [:th (util/space)]]
+     [:th (util/space)]]]
+   [:tbody
     (if (seq @*accounts*)
       (doall (mapcat #(account-type-rows %) (nest @*accounts*)))
       [:tr
@@ -242,6 +244,17 @@
   [account]
   [:section
    [:div.pull-right
+    (util/button "New"
+                 (fn []
+                   (reset! working-transaction {:account-id (:id account)
+                                                :transaction-date (f/unparse (f/formatter "M/d/yyyy") (t/today))})
+                   (go
+                     (timeout 500)
+                     (.focus (.getElementById js/document "transaction-date"))))
+                 {:icon :plus
+                  :class "btn btn-primary"
+                  :title "Click here to create a new transaction for this account."})
+    (util/space)
     [:a.btn.btn-info
      {:href "/accounts"
       :title "Click here to return to the account list."}
@@ -260,12 +273,13 @@
 (defn- items-table
   [items]
   [:table.table.table-striped.table-hover
-   [:tbody
+   [:thead
     [:tr
      [:th.col-sm-2.text-right "Date"]
      [:th.col-sm-6 "Description"]
      [:th.col-sm-2.text-right "Amount"]
-     [:th.col-sm-2.text-right "Balance"]]
+     [:th.col-sm-2.text-right "Balance"]]]
+   [:tbody
     (if @items
       (map item-row @items)
       [:tr [:td {:colSpan 4} [:span.inline-status "Loading..."]]])]])
@@ -299,6 +313,28 @@
            (get-items account items date-range)))
        notify/danger))))

+(def ^:private trx-form
+  [:form
+   (text-input :transaction-date :required)
+   (text-input :description :required)
+   (number-input :quantity :required)
+   (typeahead-input
+     :other-account-id
+     {:data-source accounts-source
+      :input-placeholder "Select the other account"
+      :in-fn (model-in-fn *accounts* :path)
+      :out-fn second
+      :result-fn first})])
+
+(defn- transaction-form []
+  (when @working-transaction
+    [:div.panel.panel-primary
+     [:div.panel-heading
+      [:h2.panel-title (if (:id @working-transaction)
+                         "Edit Transaction"
+                         "New Transaction")]]]
+    [bind-fields trx-form working-transaction]))
+
 (defn- show-account [id]
   (let [account (r/atom {})
         transaction-items (r/atom nil)]
@@ -309,10 +345,19 @@
                       notify/danger)

     (with-layout
-      [:div.row
-       [:div.col-md-6
-        [account-header account]
-        [items-table transaction-items]]])))
+      [:section
+       [:div.row
+        [:div.col-md-12
+         [account-header account]]]
+       [:div.row
+        [:div.col-md-6
+         [transaction-form]]
+        [:div.col-md-6
+         [:div.panel.panel-default
+          [:div.panel-heading
+           [:h2.panel-title "Transaction Items"]]
+          [:div.panel-body {:style {:height "40em" :overflow "auto"}}
+           [items-table transaction-items]]]]]])))

 (secretary/defroute new-account-path "/accounts/new" []
   (r/render [new-account] (app-element)))


Make channel-closer path root dynamic

Make channel-closer path root dynamic

If no binding is given, then the root of a channel closer for a bind!
is target atom for binding, else the binding is used.

--- src/cljs/hacker_agent/hacker-base.cljs
+++ src/cljs/hacker_agent/hacker-base.cljs
@@ -16,6 +16,8 @@

 (def top-stories (walk-root root [:topstories]))

+(def ^:dynamic closer-root nil)
+
 (defonce channel-closers (atom {}))

 (defonce type-chan?
@@ -23,12 +25,14 @@
     (fn [x] (= type-chan (type x)))))

 (defn- save-channel-closer! [data path channel]
-  (swap! channel-closers assoc-in
-         (conj (vec (cons data path)) :-closer)
-         channel))
+  (let [c-root (if closer-root closer-root data)]
+    (swap! channel-closers assoc-in
+           (conj (vec (cons c-root path)) :-closer)
+           channel)))

 (defn- close-channel! [data path]
-  (let [identifier (cons data path)]
+  (let [c-root (if closer-root closer-root data)
+        identifier (cons c-root path)]
     (when-let [closers (get-in @channel-closers identifier)]
       (walk/postwalk (fn [c]
                        (when (type-chan? c)
@@ -116,10 +120,14 @@
 (defn bind! [data path ref binder]
   (close-channel! data path)
   (let [close-chan (chan)
-        fbc (fb->chan ref close-chan)]
+        fbc (fb->chan ref close-chan)
+        cr closer-root
+        bind-fn (fn [data path msg]
+                  (binding [closer-root cr]
+                    (binder data path msg)))]
     (save-channel-closer! data path close-chan)
     (go-loop []
       (when-let [msg (<! fbc)]
-        (binder data path msg)
+        (bind-fn data path msg)
         (recur)))
     close-chan))


fixed a bug that broke the suspended banner on a build page

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -145,7 +145,8 @@
               (om/build project-common/trial-notice project-data))

             (when (plan-model/suspended? plan)
-              (om/build project-common/suspended-notice plan (:vcs_type project)))
+              (om/build project-common/suspended-notice {:plan plan
+                                                         :vcs_type (:vcs_type project)}))

             (when (and project (project-common/show-enable-notice project))
               (om/build project-common/enable-notice project))


Added glazing row.

Added glazing row.

--- src-cljs/kixi/hecuba/tabs/profiles.cljs
+++ src-cljs/kixi/hecuba/tabs/profiles.cljs
@@ -171,7 +171,7 @@
                (text-control profile_data state owner :flat_length_sheltered_wall "Length of Sheltered Wall (m)")
                (text-control profile_data state owner :flat_floor_heat_loss_type "Floor Heat Loss Type")])]))]))))

-(defn firepalces-row [profiles owner]
+(defn fireplaces-row [profiles owner]
   (reify
     om/IRenderState
     (render-state [_ state]
@@ -185,6 +185,27 @@
               [:div
                (text-control profile_data state owner :open_fireplaces "Number of Open Fireplaces")
                (text-control profile_data state owner :sealed_fireplaces "Number of Sealed Fireplaces")])]))]))))
+
+(defn glazing-row [profiles owner]
+  (reify
+    om/IRenderState
+    (render-state [_ state]
+      (html
+       [:div.col-md-12
+        (for [profile profiles]
+          (let [profile_data (:profile_data profile)]
+            [:div {:class (profile-column-width)}
+             (bs/panel
+              "Glazing"
+              [:div
+               (text-control profile_data state owner :glazing_area_glass_only "Glazing Area Glass Only")
+               (text-control profile_data state owner :glazing_area_percentage "Glazing Area (% if known)")
+               (text-control profile_data state owner :multiple_glazing_type "Multiple Glazing Type")
+               (text-control profile_data state owner :multiple_glazing_area_percentage "Multiple Glazing Area (% if known)")
+               (text-control profile_data state owner :multiple_glazing_u_value "Multiple Glazing U Value")
+               (text-control profile_data state owner :multiple_glazing_type_other "Multiple Glazing Type Other")
+               (text-control profile_data state owner :frame_type "Frame Type")
+               (text-control profile_data state owner :frame_type_other "Frame Type Other")])]))]))))

 (defn profile-rows [profiles owner]
@@ -200,8 +221,8 @@
          (om/build energy-row profiles)
          (om/build efficiency-row profiles)
          (om/build flats-row profiles)
-         (om/build firepalces-row profiles)
-         ;; (om/build glazing profiles)
+         (om/build fireplaces-row profiles)
+         (om/build glazing-row profiles)
          ;; (om/build issues profiles)
          ;; (om/build sap-results profiles)
          ;; (om/build documents profiles)


Remove println

Remove println

--- src/braid/client/ui/views/threads.cljs
+++ src/braid/client/ui/views/threads.cljs
@@ -29,7 +29,6 @@
   [props]
   (let [threads (r/atom [])
         reset-threads! (fn [new-threads]
-                         (println "reset!")
                          (reset! threads (vec new-threads)))
         update-threads! (fn [new-threads]
                           (swap! threads


bugfix: ez-form.core/valid? :__ez-form.form-name now also checks for a string

--- src/ez_form/core.cljc
+++ src/ez_form/core.cljc
@@ -45,11 +45,16 @@
   "Is the form valid? Runs a validate and checks for errors"
   ([form]
    (and
-    (= (get-in form [:params :__ez-form.form-name]) (get-in form [:options :name]))
+    ;; check for both keyword and string because ring's middleware for transforming
+    ;; the params map to keyword/string pairs doesn't seem to work
+    ;; with "_ez-form.form-name"
+    (or (= (get-in form [:params "__ez-form.form-name"]) (get-in form [:options :name]))
+        (= (get-in form [:params :__ez-form.form-name]) (get-in form [:options :name])))
     (every? nil? (map :errors (:fields (validate form))))))
   ([form params]
    (and
-    (= (get-in params [:__ez-form.form-name]) (get-in form [:options :name]))
+    (or (= (get-in params ["__ez-form.form-name"]) (get-in form [:options :name]))
+        (= (get-in params [:__ez-form.form-name]) (get-in form [:options :name])))
     (every? nil? (map :errors (:fields (validate form params)))))))


final (for now) changes to parallel pdgm display

--- src/clj/webapp/routes/multipdgmmod.clj
+++ src/clj/webapp/routes/multipdgmmod.clj
@@ -134,7 +134,7 @@
             pbody2 (clojure.string/replace pbody1 #" " "_")
             ]
         ;; add pdgm name to each row of pbody as first value
-        (clojure.string/replace pbody #"\r\n(\S)" (str "\r\n" pnum  ",$1"))))))
+        (clojure.string/replace pbody2 #"\r\n(\S)" (str "\r\n" pnum  ",$1"))))))

 (defn csv2pdgm
 "Takes sorted n-col csv list with vectors of pnames and headers, and outputs n+1-col html table with first col for pname ref; cols are draggable and sortable."
@@ -298,12 +298,22 @@
    (clojure.string/replace prow #"(.*),(.*?$)" "$1 $2")))
 ;;(clojure.string/replace (join "," row) #"(.*),(.*?$)" "$1 $2"))

-(defn pstring2map
+(defn pstring2maps
   "Used in handle-multimodplldisplay4. Takes pivot property out of comma-separated properties in pdgm string, and arranges the rest as a set of {:property-list 'token'} maps"
   [prmp]
   (let [hmap1 (split prmp #" ")
         hmap2 (apply hash-map hmap1)]
     (clojure.walk/keywordize-keys hmap2)))
+
+(defn join-pmaps
+  "Join individual '{:values token}' maps into single map"
+  [prmaps]
+  (for [prmap prmaps]
+    (if (> (count prmap) 1)
+      (apply conj prmap)
+      (apply conj (conj prmap {}))
+      )))
+      ;;(prmap))))

 (defn handle-multimodplldisplay
   "In this version pivot/keyset can be generalized beyond png any col (eventually any sequence of cols) between col-1 and token column. (Need to find out how to 'presort' cols before initial display?)"
@@ -327,18 +337,21 @@
         vvec (for [npdgm newpdgms] (val npdgm))
         pmapvec (for [vgroup vvec] (for [vrow vgroup] (vec2map vrow)))
         ;; transform pmaps to hash-maps
-        prmaps (for [prmap pmapvec] (for [prmp prmap] (pstring2map prmp)))
-        pmaps (for [prmap prmaps] (apply conj prmap))
+        prmaps (for [prmap pmapvec] (for [prmp prmap] (pstring2maps prmp)))
+        ;;pmaps (for [prmap prmaps] (apply conj prmap))
+        pmaps (join-pmaps prmaps)
         headerset3 (clojure.string/replace headerset2 #"[\[\]\"]" "")
         heads (split (str headerset3) #" ")
         ;;headvec (for [pivot pivotlist] (vec-remove heads pivotlist))
         pivotnames (vec (for [pivot pivots] (nth heads pivot)))
         headvec (vec (remove (set pivotnames) heads))
         ;; set of lists of vaue-combination-terms
-        keylists (set (for [pmap pmaps] (keys pmap)))
+        keylists (vec (for [pmap pmaps] (keys pmap)))
         ;;keylists (set (keys pmap))
-        ;; why is replace necessary; none of deleted chars should be in keys
-        keystring (clojure.string/replace (str keylists) #"[#(){}]" "")
+        ;; replace seems to be ad hoc cluj;
+        ;; only '[' and ']' appear in one-line paradigm keyvec (but should not)
+        ;; other deleted chars should not be in keys in the first place
+        keystring (clojure.string/replace (str keylists) #"[#(){}\[\]]" "")
         keyvec (split keystring #" ")
         ;; set of all value combinations, as strings, in the combined pdgms
         keyset (set keyvec)
@@ -372,7 +385,8 @@
                 (for [npg npgs]
                   [:td npg])
                 (for [pmap pmaps]
-               [:td (kstrkey pmap)])])]) ]]
+                  (let [pmap1 (clojure.string/replace (kstrkey pmap) #"_" " ")]
+               [:td pmap1]))])]) ]]
       [:p " "]
       [:p " "]
        [:div [:h4 "======= Debug Info: ======="]
@@ -383,19 +397,23 @@
         [:p "pivotnames: " (str pivotnames)]
         [:p "heads: " (str heads)]
         [:p "headvec: " (str headvec)]
-        ;;[:p "prows: "  (str prows) [:pre prows]]
-        ;;[:p "pcells: " (println (str pcells)) [:pre pcells]]
+        [:p "prows: "  (str prows) [:pre prows]]
+        [:p "pcells: " (println (str pcells)) [:pre pcells]]
         [:p "pivot-map: " [:pre pivot-map]]
-        ;;[:p "newpdgms: " [:pre newpdgms]]
+        [:p "newpdgms: " [:pre newpdgms]]
+        [:p "newpdgms: " (str newpdgms)]
         [:p "pvalvec: " (str pvalvec)]
         [:p "pdgmstr2: " [:pre pdgmstr2]]
-        ;;[:p "vvec: " [:pre vvec]]
-        ;;[:p "vvec: " (str vvec)]
-        ;;[:p "pmapvec: " [:pre pmapvec]]
-        ;;[:p "prmaps: " [:pre prmaps]]
+        ;;[:p "vvec: " [:pre vvec]] ;;!!raises "not valid element" exception
+        ;;[:p "vvec: " (str vvec)] ;; "not valid el." excp. with "!" in text
+        [:p "pmapvec: " [:pre pmapvec]]
+        [:p "pmapvec: " (str pmapvec)]
+        [:p "prmaps: " [:pre prmaps]]
         [:p "pmaps: " [:pre pmaps]]
-        ;;[:p "keylists: " [:pre keylists]]
-        ;;[:p "keystring: " [:pre keystring]]
+        [:p "keylists: " (str keylists)]
+        [:p "keystring: " [:pre keystring]]
+        [:p "keyvec: " [:pre keyvec]]
+        [:p "keyvec: " (str keyvec)]
         [:p "keyset: " [:pre keyset]]
         [:p "==========================="]]
       [:script {:src "js/goog/base.js" :type "text/javascript"}]


More accurate departure and arrival times

--- src/get_here/core.clj
+++ src/get_here/core.clj
@@ -15,7 +15,8 @@
             [clojure.data.json :as json]
             [clojure.walk :as walk]
             [get-here.ferry :as ferry]
-            [clj-time.coerce :as c])
+            [clj-time.coerce :as c]
+            [clj-time.core :as t])
   (:import [java.util Date]
            [java.time ZonedDateTime Instant ZoneId]))

@@ -40,10 +41,10 @@
                         {:query-params {:origin from
                                         :destination to
                                         :mode "transit"
-                                        :arrival_time (/ (.. arrive-by
-                                                             (toInstant)
-                                                             (toEpochMilli))
-                                                         1000)
+                                        :arrival_time (long (/ (.. arrive-by
+                                                                   (toInstant)
+                                                                   (toEpochMilli))
+                                                               1000))
                                         :key (google-api-key)}})
               (deref)
               (update :body json/read-str)
@@ -69,25 +70,30 @@
              (<= (.getHour arrival-instant) 20)))))

 (defn reformat-directions [body]
-  (let [directions (get-in body [:routes 0 :legs 0])]
+  (let [directions (get-in body [:routes 0 :legs 0])
+        route (->> (get-in directions [:steps])
+                   (filter transit-step?)
+                   (map (fn [step]
+                          {:origin      (get-in step [:transit_details :departure_stop :name])
+                           :destination (get-in step [:transit_details :arrival_stop :name])
+                           :towards     (get-in step [:transit_details :headsign])
+                           :route       (get-in step [:transit_details :line :name])
+                           :departure   (epoch-seconds->date (get-in step [:transit_details :departure_time :value]))
+                           :arrival     (epoch-seconds->date (get-in step [:transit_details :arrival_time :value]))}))
+                   (mapv (fn [step]
+                           (assoc step :peak (peak? step)))))
+        first-stop (first route)
+        last-stop (last route)]
     {:summary
-     {:origin      (get-in directions [:start_address])
-      :destination (get-in directions [:end_address])
-      :departure   (epoch-seconds->date (get-in directions [:departure_time :value]))
-      :arrival     (epoch-seconds->date (get-in directions [:arrival_time :value]))
-      :duration    (seconds->duration (get-in directions [:duration :value]))}
-     :route
-     (->> (get-in directions [:steps])
-          (filter transit-step?)
-          (map (fn [step]
-                 {:origin      (get-in step [:transit_details :departure_stop :name])
-                  :destination (get-in step [:transit_details :arrival_stop :name])
-                  :towards     (get-in step [:transit_details :headsign])
-                  :route       (get-in step [:transit_details :line :name])
-                  :departure   (epoch-seconds->date (get-in step [:transit_details :departure_time :value]))
-                  :arrival     (epoch-seconds->date (get-in step [:transit_details :arrival_time :value]))}))
-          (mapv (fn [step]
-                 (assoc step :peak (peak? step)))))}))
+     {:origin      (:origin first-stop)
+      :destination (:destination last-stop)
+      :departure   (:departure first-stop)
+      :arrival     (:arrival last-stop)
+      :duration    (-> (t/interval (c/from-date (:departure first-stop))
+                                   (c/from-date (:arrival last-stop)))
+                       (t/in-seconds)
+                       (seconds->duration))}
+     :route route}))

 (defroutes routes
   (GET "/" []


Fix path templating replacement, but url generation doesn't quite work yet

--- src/googlica/core.clj
+++ src/googlica/core.clj
@@ -53,32 +53,28 @@
                                  (mapv (comp (partial mapv ->kebab-case-symbol) keys)))]
     `[~@required {:keys ~optional}]))

+;; > ( template->path-vector "b/{fooBar}/o/{bar}" ["fooBar" "bar"])
+;; => ["/b/" foo-bar "/c/" bar ]
 (defn template->path-vector
-  ;;  "/b/{fooBar}/c/{bar} => ["/b/" foo-bar "/c/" bar ]"
   [path-template arg-names]
-  (loop [result []
-         vars arg-names
-         template path-template]
-    (println {:result result})
-    (println {:vars vars})
-    (println {:template template})
-    (if-let [var (first vars)]
-      (let [placeholder-re (re-pattern (str "\\{" var "\\}"))
-            value-symbol (symbol (->kebab-case var))
-            [pre post] (s/split template placeholder-re)]
-        (recur
-         ;; result
-         (concat
-          result
-          [pre value-symbol])
-         ;; vars
-         (rest vars)
-         ;; template
-         post
-         ))
-      result)))
+  (let [args->symbols (->> arg-names
+                           (mapv #(hash-map % (->kebab-case-symbol %)))
+                           (apply merge))]
+    (->> path-template
+         ;; Returns a list of vectors, where the first element is the match including
+         ;; the curly brackets, and the second element is without.
+         (re-seq #"\{(.+?)\}")
+         ;; Here we iterate on the template string, matching on the first pair of
+         ;; curly braces and adding the match to the result vector
+         (reduce (fn [[result template] [match arg]]
+                   (let [[pre post] (s/split template
+                                             (re-pattern (str "\\{" arg "\\}")))]
+                     [(concat result [pre (get args->symbols arg)])
+                      post]))
+                 [[] path-template])
+         first)))

-;; > (replace-path-vars "b/{bucket}/o/{object}")
+  ;; > (replace-path-vars "b/{bucket}/o/{object}")
 ;; => (str "b/" bucket "/o/" object)
 (defn generate-path [method]
   (let [path-vector (template->path-vector
@@ -102,4 +98,3 @@
      ~(generate-args method)
      (http/request ~(generate-request base-url method))))

-(generate-function-from-method base-url storage-object-get)


Removed older video-for-title fn

Removed older video-for-title fn

--- dev/user.clj
+++ dev/user.clj
@@ -41,9 +41,6 @@

 (def args [])
 (def options {:name hostname :port port :fake fake :encode encode :fetch fetch :format output-format :size output-size})
-
-(defn video-for-title [title]
-  (first (filter #(.contains ^String (:title %) title) (library/current-videos))))

 (defn title-for-title [title]
   (title-for-id (:title (video-key title))))


Renaming common's event-loop-interface

Renaming common's event-loop-interface

Now we can start again

--- src/com/frereth/server/auth_socket.clj
+++ src/com/frereth/server/auth_socket.clj
@@ -290,7 +290,7 @@

 (s/fdef ctor-interface
         :args (s/cat :_ any?)
-        :ret :com.frereth.common.async-zmq/event-pair-interface)
+        :ret :com.frereth.common.async-zmq/interface)
 (defn ctor-interface
   [_]
   (let [in-chan (async/chan)


mention that load-synthdef is synchronous

--- src/overtone/sc/machinery/synthdef.clj
+++ src/overtone/sc/machinery/synthdef.clj
@@ -215,10 +215,11 @@
 ;; created by Overtone and then loaded into the synth server using the synth
 ;; and inst forms and their derivatives.
 (defn load-synthdef
-  "Load an Overtone synth definition onto the audio server. The synthdef is also
-  stored so that it can be re-loaded if the server gets rebooted. If the server
-  is currently not running, the synthdef loading is delayed until the server has
-  succesfully connected."
+  "Synchronously load an Overtone synth definition onto the audio
+  server. The synthdef is also stored so that it can be re-loaded if the
+  server gets rebooted. If the server is currently not running, the
+  synthdef loading is delayed until the server has succesfully
+  connected."
   [sdef]
   (assert (synthdef? sdef))
   (dosync (alter loaded-synthdefs* assoc (:name sdef) sdef))


catalog-for-node: url-encode the node name

--- src/puppetlabs/puppetdb/cli/export.clj
+++ src/puppetlabs/puppetdb/cli/export.clj
@@ -51,7 +51,7 @@
      (let [{:keys [status body]} (client/get
                                   (format
                                    "http://%s:%s/%s/catalogs/%s"
-                                   host port (name version) node)
+                                   host port (name version) (url-encode node))
                                   {:accept :json})]
        (when (= status 200) body))))


Test unique react-keys

Test unique react-keys

--- src/devcards/discuss/devcards/lib.cljs
+++ src/devcards/discuss/devcards/lib.cljs
@@ -34,4 +34,7 @@
              (is (nil? (lib/get-reference "foo" refs)))
              (is (nil? (lib/get-reference -1 refs)))))

+         (testing "Generate unique react-key"
+           (is (not= (lib/get-unique-key) (lib/get-unique-key))))
+
          test-state)


Now have complete coverage over parser

Now have complete coverage over parser

--- test/aeolian/parser_test.clj
+++ test/aeolian/parser_test.clj
@@ -7,4 +7,11 @@
     (parser/line-width-from-metric "1 2 3") => 2)

   (fact "the complexity is the third value"
-    (parser/complexity-from-metric "1 2 3") => 3))
+    (parser/complexity-from-metric "1 2 3") => 3)
+
+  ; (fact "the line length must be numeric"
+  ;   (parser/complexity-from-metric "1 a 3") => (throws Exception))
+
+  (fact "complexity values default if not supplied"
+    (parser/complexity-from-metric "1 2") => 0)
+  	)


Test additional future keys

Test additional future keys

--- test/beehive/future_test.clj
+++ test/beehive/future_test.clj
@@ -26,7 +26,21 @@
           future (f/->BeehiveFuture eventual)]
       (is (= :pending (:status future)))
       (is (:pending? future))
+      (is (= [] (remove-false future
+                              :success?
+                              :error?
+                              :timeout?
+                              :rejected?
+                              :cancelled?
+                              :result
+                              :error)))
       (.complete eventual 4)
       (is (= :success (:status future)))
       (is (:success? future))
-      (is (= [] (remove-false future :pending?))))))
+      (is (= [] (remove-false future
+                              :pending?
+                              :error?
+                              :timeout?
+                              :rejected?
+                              :cancelled?
+                              :error))))))


Tests to verify the algorithm used is embedded on the resulting hash

I expect that the algorithm going missing would break hash verification,
so this one might be redundant, but it also acts as an example of what
the hasher is returning.

--- test/buddy/hashers_tests.clj
+++ test/buddy/hashers_tests.clj
@@ -65,3 +65,20 @@
     (is (= nil (hashers/check plain-password nil)))
     (is (= nil (hashers/check nil nil)))))

+
+;;;;
+;;;; Tests related to the resulting value's structure
+;;;;
+
+(deftest algorithm-embedded-in-hash
+  ;; Confirm that the algorithm used is always embedded at the start of the hash
+  (let [plain-password "my-test-password"]
+    (are [algorithm] (.startsWith (hashers/encrypt plain-password {:algorithm algorithm}) (name algorithm))
+                     :pbkdf2+sha1
+                     :pbkdf2+sha256
+                     :pbkdf2+sha3_256
+                     :bcrypt+sha512
+                     :scrypt
+                     :sha256
+                     :md5
+                     )))


Fix tests.

Fix tests.

--- test/promesa/core_tests.cljs
+++ test/promesa/core_tests.cljs
@@ -1,8 +1,7 @@
 (ns promesa.core-tests
   (:require [cljs-testrunners.node :as node]
             [cljs.test :as t]
-            [cats.protocols :as pt]
-            [cats.monad.promise :as p]
+            [promesa.core :as p]
             [cats.core :as m]))

 (defn error-promise


improve ITs

improve ITs

--- test/shuppet/integration.clj
+++ test/shuppet/integration.clj
@@ -40,9 +40,9 @@
            response => (contains {:status 200})))

    (fact "Test config is applied without errors"
-         (http-get  "/envs/poke/apps/test/clean") => (contains {:status 200})
-         (http-get  "/envs/poke/apps/test/apply") => (contains {:status 200})
-         (http-get  "/envs/poke/apps/test/apply") => (contains {:status 200})
-         (http-get  "/envs/poke/apps/test/clean"))
-
-   (future-fact "Correct branch is read from git"))
+         (http-get  "/envs/poke/apps/shuppetest/clean") => (contains {:status 200})
+         (let [response (http-get  "/envs/poke/apps/shuppetest/apply")
+               report (get-in response [:body :report])]
+           (:status response) => 200
+           (seq report) => truthy)
+         (http-get  "/envs/poke/apps/shuppetest/clean")))


Label the acq eng thread and always use core macro

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

--- acqEngine/src/org/micromanager/acq_engine.clj
+++ acqEngine/src/org/micromanager/acq_engine.clj
@@ -320,7 +320,7 @@
                 :snap (collect-snap-image)
                 :init-burst (collect-burst-image)
                 :collect-burst (collect-burst-image))]
-    (if (. mmc isBufferOverflowed)
+    (if (core isBufferOverflowed)
       (do (swap! state assoc :stop true)
           (ReportingUtils/showError "Circular buffer overflowed."))
       (do (log "collect-image: "
@@ -610,7 +610,8 @@
   (swap! (.state this) assoc :stop false :pause false :finished false)
   (let [out-queue (GentleLinkedBlockingQueue.)
         settings (convert-settings acq-settings)
-        acq-thread (Thread. #(run-acquisition this settings out-queue))
+        acq-thread (Thread. #(run-acquisition this settings out-queue)
+                     "Acquisition Engine Thread (Clojure)")
         processors (ProcessorStack. out-queue (.getTaggedImageProcessors acq-eng))
         out-queue-2 (.begin processors)
         display (LiveAcqDisplay. mmc out-queue-2 (make-summary-metadata settings)


#7 add url metadata to md

#7 add url metadata to md

--- src/kalar_plugins/templates/hiccup.clj
+++ src/kalar_plugins/templates/hiccup.clj
@@ -38,8 +38,10 @@
   (let [input    (new StringReader (slurp file))
         output   (new StringWriter)
         metadata (md/md-to-html input output :parse-meta? true :heading-anchors true)
-        html     (.toString output)]
-    (merge metadata {:body html})))
+        html     (.toString output)
+        url (string/replace (string/replace file (re-pattern (str "^" (kfile/find-resources-dir))) "") #"\..*$" ".html")]
+    (println url)
+    (merge metadata {:body html :url url})))

 (defn load-md-excerpt [^String md]
   (let [compiled (load-markdown md)


#1 def-template

#1 def-template

--- src/kalar_plugins/templates/hiccup.clj
+++ src/kalar_plugins/templates/hiccup.clj
@@ -1,6 +1,8 @@
 (ns kalar-plugins.templates.hiccup
   (:require [kalar-core.plugin :as plugin]
-            [kalar-core.config :as config]))
+            [kalar-core.config :as config]
+            [kalar-core.file :as kfile]
+            [clojure.java.io :as io]))

 (defprotocol HiccupPlugin
   (hiccup-compile [this]))
@@ -15,10 +17,14 @@
       (dorun
         (for [f (filter #(satisfies? HiccupPlugin (-> % var-get))
                         (-> hpnamespace ns-publics vals))]
-          (hiccup-compile (var-get f)) )))))
+          (println (hiccup-compile (var-get f))))))))

-(defmacro def-template [& body]
+(defmacro def-template [path & body]
   `(def hiccup#
-      (reify HiccupPlugin (hiccup-compile [this] ~@body))))
+     (reify HiccupPlugin
+       (hiccup-compile [this]
+         (let [f# (io/file (kfile/find-dest) ~path)]
+           (kfile/prepare-write-file f#)
+           (spit  f#  (let [] ~@body)))))))


Fix tests

Fix tests

--- src/kixi/datastore/transport_specs.clj
+++ src/kixi/datastore/transport_specs.clj
@@ -18,7 +18,7 @@
                 ::ms/size-bytes
                 ::ms/provenance
                 ::ms/sharing]
-          :opt [::ss/id
+          :opt [::ss/id
                 ::ms/file-type
                 ::ms/header]))

@@ -50,13 +50,13 @@
                            (::ms/type file-metadata))
                         (= "stored"
                            (::ms/type file-metadata)))
-                    (case (or (::ms/file-type meta)
-                              (::ms/file-type file-metadata))
+                    (case (or (::ms/file-type meta)
+                              (::ms/file-type file-metadata))
                       "csv" (if-not (nil? (::ms/header meta))
-                              (= (::ms/header meta)
+                              (= (::ms/header meta)
                                  (::ms/header file-metadata))
                               (true? (::ms/header file-metadata)))
-                      false)))
+                      true)))
         :ret ::ms/file-metadata)

 (defn raise-schema
@@ -78,7 +78,7 @@
         with-file-type (merge (get file-type->default-metadata
                                    (::ms/file-type with-primaries))
                               with-primaries)
-        with-schema (raise-schema with-file-type
+        with-schema (raise-schema with-file-type
                                   (get-in transport [::ms/provenance :kixi.user/id]))]
     with-schema))

@@ -111,7 +111,7 @@
                           % 2))
       m')))

-(s/fdef schema-transport->internal
+(s/fdef schema-transport->internal
         :ret ::ss/create-schema-request)

 (defn schema-transport->internal


Update figwheel to 0.1.4-SNAPSHOT

Update figwheel to 0.1.4-SNAPSHOT

--- src/leiningen/new/chestnut/project.clj
+++ src/leiningen/new/chestnut/project.clj
@@ -12,7 +12,7 @@
                  [compojure "1.1.8"]
                  [enlive "1.1.5"]
                  [om "0.7.1"]
-                 [figwheel "0.1.3-SNAPSHOT"]
+                 [figwheel "0.1.4-SNAPSHOT"]
                  [environ "0.5.0"]]

   :plugins [[com.cemerick/austin "0.1.5-SNAPSHOT"]
@@ -32,7 +32,7 @@
                                         :pretty-print  true}}}}

   :profiles {:dev {:repl-options {:init-ns {{name}}.server}
-                   :plugins [[lein-figwheel "0.1.3-SNAPSHOT"]]
+                   :plugins [[lein-figwheel "0.1.4-SNAPSHOT"]]
                    :figwheel {:http-server-root "public"
                               :port 3449 }}


bump figwheel version, #29;

bump figwheel version, #29;

--- src/leiningen/new/re_frame/project.clj
+++ src/leiningen/new/re_frame/project.clj
@@ -41,7 +41,7 @@
   :profiles
   {:dev
    {:dependencies [[binaryage/devtools "0.6.1"]{{#cider?}}
-                   [figwheel-sidecar "0.5.3"]
+                   [lein-figwheel "0.5.4-3"]
                    [com.cemerick/piggieback "0.2.1"]{{/cider?}}]

     :plugins      [[lein-figwheel "0.5.3"]{{#test?}}


removed google billing project field on profile page

--- src/cljs/org/broadinstitute/firecloud_ui/page/profile.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/page/profile.cljs
@@ -133,7 +133,6 @@
             [:div {:style {:marginBottom "1em" :fontSize "88%"}} "*NonProfit Status"
               (react/call :render-radio-field this :nonProfitStatus "Profit")
               (react/call :render-radio-field this :nonProfitStatus "Non-Profit")]
-            (react/call :render-field this :billingAccountName "Google Billing Account Name" false)
             (when-not (:new-registration? props)
               [:div {} [NihLink {:parent-nav-context (:parent-nav-context props)}]])]
            :else [components/Spinner {:text "Loading User Profile..."}]))


Update neko

Update neko

--- src/clojure/leiningen/new/game_clojure/android-project.clj
+++ src/clojure/leiningen/new/game_clojure/android-project.clj
@@ -3,7 +3,7 @@

   :dependencies [[com.badlogicgames.gdx/gdx "0.9.9" :use-resources true]
                  [com.badlogicgames.gdx/gdx-backend-android "0.9.9"]
-                 [neko/neko "3.0.0-preview3"]
+                 [neko/neko "3.0.0-preview4"]
                  [org.clojure-android/clojure "1.5.1-jb" :use-resources true]]
   :repositories [["sonatype"
                   "https://oss.sonatype.org/content/repositories/snapshots/"]]


Fixed TR constructor.

Fixed TR constructor.

--- src/clojure/uncomplicate/neanderthal/impl/buffer_block.clj
+++ src/clojure/uncomplicate/neanderthal/impl/buffer_block.clj
@@ -585,12 +585,6 @@
   (.write w (format "%s%s" (str a) (pr-str (seq a)))))

 ;; =================== Real Triangular Matrix ==================================
-
-(defn left-index ^long [^long diag-pad ^long ld ^long i ^long j]
-  (+ (* (inc ld) j) (+ i diag-pad)))
-
-(defn right-index ^long [^long diag-pad ^long ld ^long i ^long j]
-  (+ (* ld (+ j diag-pad)) i))

 (deftype RealTRMatrix [^IFn$LLLL index* ^IFn$OLLD get* ^IFn$OLLDD set*
                        ^IFn$LLL start* ^IFn$LLL end*
@@ -754,8 +748,8 @@
            left (if no-trans (= LOWER uplo) (= UPPER uplo))
            accessor (data-accessor fact)]
        (RealTRMatrix. (if no-trans no-trans-index trans-index)
-                      (if no-trans straight-cut cross-cut)
-                      (if no-trans cross-cut straight-cut)
+                      (if no-trans no-trans-get trans-set)
+                      (if no-trans no-trans-get trans-get)
                       (if left (if non-unit id inc-id) zero)
                       (if left end (if non-unit inc-id id))
                       (if no-trans col row)


Sanity check Mastermind

Sanity check Mastermind

--- src/clojush/problems/software/benchmarks_v2/mastermind.clj
+++ src/clojush/problems/software/benchmarks_v2/mastermind.clj
@@ -29,29 +29,35 @@

 ; Atom generators
 (def mastermind-atom-generators
-  (concat (list
-            \B
-            \R
-            \W
-            \Y
-            \O
-            \G
-            ;;; end constants
-            ;;; end ERCs
-            (tag-instruction-erc [:integer :exec :boolean :string :char] 1000)
-            (tagged-instruction-erc 1000)
-            ;;; end tag ERCs
-            'in1
-            'in2
-            ;;; end input instructions
-            )
-          (registered-for-stacks [:integer :exec :string :char :boolean])))
+  (make-proportional-atom-generators
+   (concat
+    (registered-for-stacks [:integer :exec :boolean :string :char])
+    (list (tag-instruction-erc [:integer :exec :boolean :string :char] 1000) ; tags
+          (tagged-instruction-erc 1000)))
+   (list 'in1 'in2) ; inputs
+   (list 0
+         1
+         \B
+         \R
+         \W
+         \Y
+         \O
+         \G) ; constants
+   {:proportion-inputs 0.15
+    :proportion-constants 0.05}))

 ;; Define test cases
+(defn mastermind-one-string
+  "Makes a 4-char mastermind string"
+  []
+  (apply str (repeatedly 4
+                         #(rand-nth "BRWYOG"))))
+
 (defn mastermind-input
   "Makes a mastermind input."
   []
-  (vector (apply str (repeatedly 4 #(rand-nth "BRWYOG"))) (apply str (repeatedly 4 #(rand-nth "BRWYOG")))))
+  (vec (repeatedly 2 mastermind-one-string)))
+

 ;; A list of data domains for the problem. Each domain is a vector containing
 ;; a "set" of inputs and two integers representing how many cases from the set
@@ -64,8 +70,25 @@
           ["WYYW" "BBOG"]
           ["GGGB" "BGGG"]
           ["BBBB" "OOOO"]
-          ) 5 0]
-   [(fn [] (mastermind-input)) 195 2000]
+          ["BWYG" "YWBG"]
+          ["RGOW" "OGWR"]
+          ["YGGB" "GYGB"]
+          ["YGGB" "GYBG"]
+          ["GOGY" "OGGO"]
+          ["GOGR" "GOYR"]
+          ["YMOO" "YMRG"]
+          ["GROY" "BGOW"]
+          ["GGYG" "BYBB"]
+          ["WWWW" "BYWR"]
+          ["RBYO" "BWBB"]
+          ["RBRB" "ORBY"]
+          ["WORR" "BYOW"]
+          ["YOWW" "YWWR"]
+          ["BRYB" "WOGG"]
+          ) 20 0]
+   [(fn [] (let [s (mastermind-one-string)]
+             [s s])) 10 200] ; all the same
+   [(fn [] (mastermind-input)) 170 1800]
   ])

 ;;Can make mastermind test data like this:
@@ -181,7 +204,7 @@
 ; Define the argmap
 (def argmap
   {:error-function (make-mastermind-error-function-from-cases (first mastermind-train-and-test-cases)
-                                                                  (second mastermind-train-and-test-cases))
+                                                              (second mastermind-train-and-test-cases))
    :atom-generators mastermind-atom-generators
    :max-points 2000
    :max-genome-size-in-initial-program 250


cleanup

cleanup

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -170,22 +170,20 @@
 ;; TODO: make this non-recursive by using mapcat.
 (defn add-all-comps-with-paths [bolts language-model total-depth comp-paths truncate-children max-total-depth]
   (if (not (empty? comp-paths))
-    (let [path (first comp-paths)
-          result
-             (lazy-mapcat
-              (fn [bolt]
-                (add-complement-to-bolt bolt path
-                                        language-model (+ total-depth (count path))
-                                        :max-total-depth max-total-depth
-                                        :truncate-children truncate-children))
-              bolts)]
-      (add-all-comps-with-paths
-       result
-       language-model
-       total-depth
-       (rest comp-paths)
-       truncate-children
-       max-total-depth))
+    (add-all-comps-with-paths
+     (lazy-mapcat
+      (fn [bolt]
+        (let [path (first comp-paths)]
+          (add-complement-to-bolt bolt path
+                                  language-model (+ total-depth (count path))
+                                  :max-total-depth max-total-depth
+                                  :truncate-children truncate-children)))
+      bolts)
+     language-model
+     total-depth
+     (rest comp-paths)
+     truncate-children
+     max-total-depth)
     bolts))

 (defn bolt-depth [bolt]


+(defn morph-ps [expr])

+(defn morph-ps [expr])

--- src/babel/italiano.cljc
+++ src/babel/italiano.cljc
@@ -28,12 +28,17 @@
               (cons surface-string patterns))))
    (string/trim)))

-(defn morph-ps [expr model & {:keys [from-language show-notes]
-                     :or {from-language nil
-                          show-notes true}}]
-  ;; modeled after babel.english/morph:
-  ;; most arguments are simply discarded for italian.
-  (parse/fo-ps expr (:morph-ps model)))
+(defn morph-ps
+  ([expr]
+   (let [model @@(get babel.directory/models :it)]
+     (morph-ps expr)))
+
+  ([expr model & {:keys [from-language show-notes]
+                  :or {from-language nil
+                       show-notes true}}]
+   ;; modeled after babel.english/morph:
+   ;; most arguments are simply discarded for italian.
+   (parse/fo-ps expr (:morph-ps model))))

 (defn fo-ps [expr]
   (parse/fo-ps expr #(get-string (get-in % [:italiano]))))


Webserver to indicate determined port

Webserver to indicate determined port

--- modules/http-kit/src/modular/http_kit.clj
+++ modules/http-kit/src/modular/http_kit.clj
@@ -17,7 +17,7 @@
       (let [h (ring-handler provider)]
         (assert h)
         (let [server (run-server h {:port port})]
-          (assoc this :server server)))
+          (assoc this :server server :port port)))
       (throw (ex-info (format "http-kit module requires the existence of a component that satisfies %s" modular.ring/RingHandler) {:this this}))))

   (stop [this]


Only 'describe' defs a Var at top level

Only 'describe' defs a Var at top level

--- src/main/clojure/lazytest/describe.clj
+++ src/main/clojure/lazytest/describe.clj
@@ -109,8 +109,7 @@
 	  fixtures (map (fn [x] `(function-fixture (fn ~(find-locals &env) ~x)))
 			(seconds bindings))
 	  local-bindings (vec (interleave binding-forms fixtures))]
-      `(def-unless-nested
-	 (wrap-local-scope ~local-bindings (test-group ~children ~metadata))))))
+      `(wrap-local-scope ~local-bindings (test-group ~children ~metadata)))))

 (defmacro using [& decl]
   (let [[doc decl] (get-arg string? decl)
@@ -123,14 +122,12 @@
     (let [binding-forms (firsts bindings)
 	  fixtures (seconds bindings)
 	  local-bindings (vec (interleave binding-forms fixtures))]
-      `(def-unless-nested
-	 (wrap-local-scope ~local-bindings (test-group ~children ~metadata))))))
+      `(wrap-local-scope ~local-bindings (test-group ~children ~metadata)))))

 (defmacro it [& decl]
   (let [[sym decl] (get-arg symbol? decl)
 	[doc decl] (get-arg string? decl)
 	[attr-map body] (get-arg map? decl)
 	metadata (merged-metadata &form doc attr-map)]
-    `(def-unless-nested
-       (test-case ~(find-locals &env)
-		  (fn ~(find-local-binding-forms &env) ~@body) ~metadata))))
+    `(test-case ~(find-locals &env)
+		(fn ~(find-local-binding-forms &env) ~@body) ~metadata)))


Making add-projects responsive

Making add-projects responsive

--- frontend/components/add_projects.cljs
+++ frontend/components/add_projects.cljs
@@ -61,19 +61,19 @@
             controls-ch (om/get-shared owner [:comms :controls])]
         (html [:div
             [:div.overview
-             [:p
-              "Choose a repo in GitHub from one of your organizations, your own repos, or repos you share with others, and we'll watch it for you. We'll show you the first build immediately, and a new build will be initiated each time someone pushes commits; come back here to follow more projects."]]
-            [:div.wordy-hr [:span "1. Choose a GitHub Account"]]
-            (map (fn [org] (side-item org settings controls-ch))
-                  (:organizations user))
-            (map (fn [org] (side-item org settings controls-ch))
-                  (filter (fn [org] (= (:login user) (:login org)))
-                          (:collaborators user)))
-             [:div
-              [:h4 "Users & organizations with forks of your repos"]
-              (map (fn [org] (side-item org settings controls-ch))
-                   (remove (fn [org] (= (:login user) (:login org)))
-                           (:collaborators user)))]])))))
+             [:span.big-number "1."]
+             [:div.instruction "Choose an GitHub account that you are a member of or have access to. "]]
+            [:div.organizations
+             (map (fn [org] (side-item org settings controls-ch))
+                   (:organizations user))
+             (map (fn [org] (side-item org settings controls-ch))
+                   (filter (fn [org] (= (:login user) (:login org)))
+                           (:collaborators user)))
+              [:div
+               [:h4 "Users & organizations with forks of your repos"]
+               (map (fn [org] (side-item org settings controls-ch))
+                    (remove (fn [org] (= (:login user) (:login org)))
+                            (:collaborators user)))]]])))))

 (def repos-explanation
   [:div.add-repos
@@ -236,9 +236,12 @@
            [:div.org-listing
             (om/build org-sidebar {:user user
                                    :settings settings})]
+           [:hr]
            [:div.project-listing
-            [:div.wordy-hr [:span "2. Choose a Repo"]]
+            [:div.overview
+             [:span.big-number "2."]
+             [:div.instruction "Choose a repo, and we'll watch it for you. We'll show you the first build immediately, and a new build will be initiated each time someone pushes commits."]]
             (om/build main {:user user
                             :repos repos
                             :settings settings})]
-           [:div.sidebar]]])))))
+           ]])))))


adds projects to org page

adds projects to org page

--- frontend/components/org_settings.cljs
+++ frontend/components/org_settings.cljs
@@ -15,8 +15,10 @@
             [sablono.core :as html :refer-macros [html]]
             [clojure.string :as string]
             [goog.string :as gstring]
-            [goog.string.format])
-  (:require-macros [cljs.core.async.macros :as am :refer [go go-loop alt!]]))
+            [goog.string.format]
+            [goog.style])
+  (:require-macros [cljs.core.async.macros :as am :refer [go go-loop alt!]]
+                   [dommy.macros :refer [node sel sel1]]))

 (defn sidebar [{:keys [subpage plan]} owner]
   (reify
@@ -73,7 +75,7 @@
       (let [users (get-in data state/org-users-path)
             projects (get-in data state/org-projects-path)
             org-name (get-in data state/org-name-path)
-            projects-by-follower (utils/inspect (org-model/projects-by-follower projects))
+            projects-by-follower (org-model/projects-by-follower projects)
             sorted-users (sort-by (fn [u]
                                     (- (count (get projects-by-follower (:login u)))))
                                   users)]
@@ -109,6 +111,96 @@
                                                              :repo (vcs-url/repo-name vcs-url)})}
                      (vcs-url/project-name vcs-url)]])]]])]]])))))

+(defn equalize-size
+  "Given a node, will find all elements under node that satisfy selector and change
+   the size of every element so that it is the same size as the largest element."
+  [node selector]
+  (let [items (sel node selector)
+        sizes (map goog.style/getSize items)
+        max-width (apply max (map #(.-width %) sizes))
+        max-height (apply max (map #(.-height %) sizes))]
+    (doseq [item items]
+      (goog.style/setSize item max-width max-height))))
+
+(defn followers-container [followers owner]
+  (reify
+    om/IDidMount
+    (did-mount [_]
+      (equalize-size (om/get-node owner) ".follower-container"))
+    om/IDidUpdate
+    (did-update [_ _ _]
+      (equalize-size (om/get-node owner) ".follower-container"))
+    om/IRender
+    (render [_]
+      (html
+       [:div.followers-container.row-fluid
+        [:div.row-fluid
+         (for [follower followers]
+           [:span.follower-container
+            {:style {:display "inline-block"}}
+            [:img.gravatar
+             {:src (gh-utils/gravatar-url {:size 30 :login (:login follower)
+                                           :gravatar_id (:gravatar_id follower)})}]
+            " "
+            [:span (:login follower)]])]]))))
+
+(defn projects [data owner]
+  (reify
+    om/IRender
+    (render [_]
+      (let [users (get-in data state/org-users-path)
+            projects (get-in data state/org-projects-path)
+            {followed-projects true unfollowed-projects false} (group-by #(pos? (count (:followers %)))
+                                                                         projects)
+            org-name (get-in data state/org-name-path)]
+        (html
+         [:div
+          [:div.followed-projects.row-fluid
+           [:h2 "Followed projects"]
+           (if-not (seq followed-projects)
+             [:h4 "No followed projects found."]
+
+             [:div.span8
+              (for [project followed-projects
+                    :let [vcs-url (:vcs_url project)]]
+                [:div.row-fluid
+                 [:div.span12.success.well
+                  [:div.row-fluid
+                   [:div.span12
+                    [:h4
+                     [:a {:href (routes/v1-project-dashboard {:org (vcs-url/org-name vcs-url)
+                                                              :repo (vcs-url/repo-name vcs-url)})}
+                      (vcs-url/project-name vcs-url)]
+                     " "
+                     [:a.edit-icon {:href (routes/v1-project-settings {:org (vcs-url/org-name vcs-url)
+                                                                       :repo (vcs-url/repo-name vcs-url)})}
+                      [:i.fa.fa-gear]]
+                     " "
+                     [:a.github-icon-link {:href vcs-url}
+                      [:i.fa.fa-github]]]]]
+                  (om/build followers-container (:followers project))]])])]
+          [:div.row-fluid
+           [:h2 "Untested repos"]
+           (if-not (seq unfollowed-projects)
+             [:h4 "No untested repos found."]
+
+             [:div.span8
+              (for [project unfollowed-projects
+                    :let [vcs-url (:vcs_url project)]]
+                [:div.row-fluid
+                 [:div.fail.span12.well
+                  [:h4
+                   [:a {:href (routes/v1-project-dashboard {:org (vcs-url/org-name vcs-url)
+                                                            :repo (vcs-url/repo-name vcs-url)})}
+                    (vcs-url/project-name vcs-url)]
+                   " "
+                   [:a.edit-icon {:href (routes/v1-project-settings {:org (vcs-url/org-name vcs-url)
+                                                                     :repo (vcs-url/repo-name vcs-url)})}
+                    [:i.fa.fa-gear]]
+                   " "
+                   [:a.github-icon-link {:href vcs-url}
+                    [:i.fa.fa-github]]]]])])]])))))
+
 (def main-component
   {:users users
    :projects projects


make smiley paredit friendly

make smiley paredit friendly

fixes #568

--- sidecar/src/figwheel_sidecar/config.clj
+++ sidecar/src/figwheel_sidecar/config.clj
@@ -845,7 +845,7 @@
                          (utils/slow-output
                           (print-validate-config-data config-data)))
                   (do
-                    (println (color-text "Figwheel: Configuration Valid :)" :green))
+                    (println (color-text "Figwheel: Configuration Valid ;)" :green))
                     config-data)
                   (do
                     (when (:read-exception config-data)


updated reagent for flatten-nodes

updated reagent for flatten-nodes

--- src/kioo/reagent.cljs
+++ src/kioo/reagent.cljs
@@ -1,5 +1,6 @@
 (ns kioo.reagent
-  (:require [kioo.core :as core :refer [flatten-nodes]]
+  (:require [kioo.core :as core]
+            [kioo.util :as util :refer [flatten-nodes]]
             [reagent.impl.template :refer [as-component]]))

 (defn make-dom [node]


default canvas and layer

default canvas and layer

--- src/cljs/infinitelives/pixi/canvas.cljs
+++ src/cljs/infinitelives/pixi/canvas.cljs
@@ -10,28 +10,13 @@
   (:require-macros [cljs.core.async.macros :refer [go]])
 )

-(def canvas-store (atom {}))
-
-(defn add!
-  ([key canvas]
-   (swap! canvas-store assoc key canvas))
-  ([canvas]
-   (add! :default canvas)))
-
-(defn set-default-once!
-  [canvas]
-  (when-not (:default @canvas-store)
-    (add! canvas)))
-
-(defn remove!
-  ([key]
-   (swap! canvas-store dissoc key)))
-
-(defn get
-  ([key]
-   (key @canvas-store))
-  ([]
-   (:default @canvas-store)))
+(def ^:dynamic *default-canvas* nil)
+(defn get-default-canvas [] *default-canvas*)
+(defn set-default-canvas! [canvas] (set! *default-canvas* canvas))
+
+(def ^:dynamic *default-layer* nil)
+(defn get-default-layer [] *default-layer*)
+(defn set-default-layer! [layer] (set! *default-layer* layer))

 (defn make
   "make a new pixi canvas, or initialise pixi with an existing canvas.
@@ -40,6 +25,8 @@

   :expand        if true makes the canvas take the entire window
   :engine        can be :webgl :canvas or :auto (default :auto)
+  :default       true or false to set the default canvas to this
+                 created one. defaults to true.

   and either:

@@ -51,14 +38,15 @@
   :y             y position for the new canvas
   :width         width of new canvas
   :height        height of new canvas"
-  [{:keys [expand x y width height canvas engine background]
+  [{:keys [expand x y width height canvas engine background default]
     :or {expand false
          x 0
          y 0
          width 800
          height 600
          background 0x500000
-         engine :auto}}]
+         engine :auto
+         default true}}]
   (let [fswidth (.-innerWidth js/window)
         fsheight (.-innerHeight js/window)

@@ -107,8 +95,7 @@
     ;; return canvas and pixi renderer
     {
      :renderer rend
-     :canvas (or canvas actual-canvas)
-     }))
+     :canvas (or canvas actual-canvas)}))

 (defn make-stage
   "Layout the stage structure"
@@ -206,6 +193,8 @@
   :origins       A mapping of layer names to their origin positions. Default
                  position is center. Positions can be :center :top :bottom
                  :left :right :top-left :top-right :bottom-left :bottom-right
+  :default       if true this becomes the default canvas
+  :default-layer specify a default layer. If unspecified, is the top layer

   and either:

@@ -220,7 +209,9 @@
   "
   [opts]
   (let [{:keys [renderer canvas layer layers stage
-                origins fullscreen-button] :or {origins {}} :as world}
+                origins fullscreen-button default
+                default-layer] :or {origins {}
+                                    default true} :as world}
         (into (make opts)
               (make-stage opts))]
     ;; add the stages to the canvas
@@ -297,7 +288,13 @@
                      :resize-fn resize-fn
                      :fullscreen-fn fullscreen-fn
                      :expand-fn expand-fn})]
-        (set-default-once! canvas)
+        (when default
+          (set-default-canvas! canvas))
+
+        (if default-layer
+          (set-default-layer! default-layer)
+          (set-default-layer! (last layers)))
+
         canvas))))

 (defn add-fullscreen-button! [{:keys [fullscreen-fn]}]


add missing find-namespace methods back now that it is shadowing clojure.contrib

--- src/clojure/contrib/find_namespaces.clj
+++ src/clojure/contrib/find_namespaces.clj
@@ -1,3 +1,4 @@
+-;; copied from clojure.contrib.find-namespaces
 ;;; find_namespaces.clj: search for ns declarations in dirs, JARs, or CLASSPATH

 ;; by Stuart Sierra, http://stuartsierra.com/
@@ -11,13 +12,17 @@
 ;; agreeing to be bound by the terms of this license.  You must not
 ;; remove this notice, or any other, from this software.

-;; copied from clojure.contrib.find-namespaces

 (ns
-  #^{:author "Stuart Sierra"
+  #^{:author "Stuart Sierra",
      :doc "Search for ns declarations in dirs, JARs, or CLASSPATH"}
   clojure.contrib.find-namespaces
-  (import (java.io File FileReader BufferedReader PushbackReader InputStreamReader)))
+  (:require [clojure.contrib.classpath :as cp]
+            [clojure.contrib.jar :as jar])
+  (import (java.io File FileReader BufferedReader PushbackReader
+                   InputStreamReader)
+          (java.util.jar JarFile)))
+

 ;;; Finding namespaces in a directory tree

@@ -77,3 +82,56 @@
   source files; returns the symbol names of the declared namespaces."
   [#^File dir]
   (map second (find-ns-decls-in-dir dir)))
+
+
+;;; Finding namespaces in JAR files
+
+(defn clojure-sources-in-jar
+  "Returns a sequence of filenames ending in .clj found in the JAR file."
+  [#^JarFile jar-file]
+  (filter #(.endsWith % ".clj") (jar/filenames-in-jar jar-file)))
+
+(defn read-ns-decl-from-jarfile-entry
+  "Attempts to read a (ns ...) declaration from the named entry in the
+  JAR file, and returns the unevaluated form.  Returns nil if the read
+  fails, or if the first form is not a ns declaration."
+  [#^JarFile jarfile #^String entry-name]
+  (with-open [rdr (PushbackReader.
+                   (BufferedReader.
+                    (InputStreamReader.
+                     (.getInputStream jarfile (.getEntry jarfile entry-name)))))]
+    (read-ns-decl rdr)))
+
+(defn find-ns-decls-in-jarfile
+  "Searches the JAR file for Clojure source files containing (ns ...)
+  declarations; returns the unevaluated ns declarations."
+  [#^JarFile jarfile]
+  (filter identity
+          (map #(read-ns-decl-from-jarfile-entry jarfile %)
+               (clojure-sources-in-jar jarfile))))
+
+(defn find-namespaces-in-jarfile
+  "Searches the JAR file for Clojure source files containing (ns ...)
+  declarations.  Returns a sequence of the symbol names of the
+  declared namespaces."
+  [#^JarFile jarfile]
+  (map second (find-ns-decls-in-jarfile jarfile)))
+
+
+;;; Finding namespaces anywhere on CLASSPATH
+
+(defn find-ns-decls-on-classpath
+  "Searches CLASSPATH (both directories and JAR files) for Clojure
+  source files containing (ns ...) declarations.  Returns a sequence
+  of the unevaluated ns declaration forms."
+  []
+  (concat
+   (mapcat find-ns-decls-in-dir (cp/classpath-directories))
+   (mapcat find-ns-decls-in-jarfile (cp/classpath-jarfiles))))
+
+(defn find-namespaces-on-classpath
+  "Searches CLASSPATH (both directories and JAR files) for Clojure
+  source files containing (ns ...) declarations.  Returns a sequence
+  of the symbol names of the declared namespaces."
+  []
+  (map second (find-ns-decls-on-classpath)))


Change the log to a sorted map.

Change the log to a sorted map.

--- src/clojure/my/stuff/fitlogger/main.clj
+++ src/clojure/my/stuff/fitlogger/main.clj
@@ -51,7 +51,7 @@
           lst)
      (join "\n")))

-(def listing (atom {}))
+(def listing (atom (sorted-map)))

 (defn update-ui [activity]
   (set-elmt activity ::listing (format-listing @listing))


PDB-473 Convert submit-command-via-http! to use application/json POST

Signed-off-by: Ken Barber <470bc578162732ac7f9d387d34c4af4ca6e1b6f7@bob.sh>

--- src/com/puppetlabs/puppetdb/command.clj
+++ src/com/puppetlabs/puppetdb/command.clj
@@ -221,13 +221,11 @@
             (integer? port)
             (map? command-map)]}
      (let [message (json/generate-string command-map)
-           body    (format "checksum=%s&payload=%s"
-                           (kitchensink/utf8-string->sha1 message)
-                           (url-encode message))
-           url     (format "http://%s:%s/v3/commands" host port)]
-       (client/post url {:body               body
+           checksum (kitchensink/utf8-string->sha1 message)
+           url     (format "http://%s:%s/v3/commands?checksum=%s" host port checksum)]
+       (client/post url {:body               message
                          :throw-exceptions   false
-                         :content-type       :x-www-form-urlencoded
+                         :content-type       :json
                          :character-encoding "UTF-8"
                          :accept             :json}))))


give drawings some border

give drawings some border

--- src/pc/render.clj
+++ src/pc/render.clj
@@ -37,10 +37,10 @@
         height (if (pos? min-y)
                  max-y
                  (- max-y min-y))]
-    (html [:svg.svg-line-graph.hello {:width width
-                                      :height height
-                                      :style "background: #333"
-                                      :xmlns "http://www.w3.org/2000/svg"
-                                      :xmlns:xlink "http://www.w3.org/1999/xlink"
-                                      :version "1.1"}
+    (html [:svg {:width (+ width 500)
+                 :height (+ height 500)
+                 :style "background: #333"
+                 :xmlns "http://www.w3.org/2000/svg"
+                 :xmlns:xlink "http://www.w3.org/1999/xlink"
+                 :version "1.1"}
            (map svg-element (filter #(not= :layer.type/group (:layer/type %)) layers))])))


Factor out into separate protocols

Factor out into separate protocols

--- src/tick/core.clj
+++ src/tick/core.clj
@@ -312,7 +312,9 @@
   (< [x y] "Is x before y?")
   (<= [x y] "Is x before or at the same time as y?")
   (> [x y] "Is x after y?")
-  (>= [x y] "Is x after or at the same time as y?"))
+  (>= [x y] "Is x after or at the same time as y?")
+  (maximum [_ _] "Return maximum")
+  (minimum [_ _] "Return minimum"))

 (extend-protocol ITimeComparison
   Instant
@@ -320,26 +322,69 @@
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
   LocalDateTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
+  ;; TODO: Rename maximum to 'greater' and minimum to 'lesser'
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
   LocalTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
+  LocalDate
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
   OffsetDateTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
   (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ZonedDateTime
   (< [x y] (.isBefore x y))
   (<= [x y] (not (.isAfter x y)))
   (> [x y] (.isAfter x y))
-  (>= [x y] (not (.isBefore x y))))
+  (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
+  YearMonth
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
+  Year
+  (< [x y] (.isBefore x y))
+  (<= [x y] (not (.isAfter x y)))
+  (> [x y] (.isAfter x y))
+  (>= [x y] (not (.isBefore x y)))
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y))
+
+  Duration
+  (maximum [x y] (if (neg? (compare x y)) y x))
+  (minimum [x y] (if (neg? (compare x y)) x y)))

 (defprotocol ITimeRangeable
   (range [_] [_ _] [_ _ _] "Returns a lazy seq of times from start (inclusive) to end (exclusive, nil means forever), by step, where start defaults to 0, step to 1, and end to infinity."))
@@ -353,11 +398,11 @@

 (defprotocol ITimeArithmetic
   (+ [_ _] "Add time")
-  (- [_ _] "Subtract time")
+  (- [_ _] "Subtract time"))
+
+(defprotocol ITimeIncDec
   (inc [_] "Increment time")
-  (dec [_] "Decrement time")
-  (maximum [_ _] "Return maximum")
-  (minimum [_ _] "Return minimum"))
+  (dec [_] "Decrement time"))

 (defn max [arg & args]
   (reduce #(maximum %1 %2) arg args))
@@ -369,10 +414,11 @@
   ITimeArithmetic
   (+ [t x] (.plus t x))
   (- [t x] (.minus t x))
+
+  ITimeIncDec
   (inc [t] (+ t (seconds 1)))
   (dec [t] (- t (seconds 1)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ITimeRangeable
   (range
     ([from] (iterate #(.plusSeconds % 1) from))
@@ -385,10 +431,11 @@
   ITimeArithmetic
   (+ [t x] (.plus t x))
   (- [t x] (.minus t x))
+
+  ITimeIncDec
   (inc [t] (+ t (seconds 1)))
   (dec [t] (- t (seconds 1)))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ITimeRangeable
   (range
     ([from] (iterate #(.plusSeconds % 1) from))
@@ -401,10 +448,11 @@
   ITimeArithmetic
   (+ [t x] (.plus t x))
   (- [t x] (.minus t x))
+
+  ITimeIncDec
   (inc [t] (.plusDays t 1))
   (dec [t] (.minusDays t 1))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ITimeRangeable
   (range
     ([from] (iterate #(.plusDays % 1) from))
@@ -423,11 +471,11 @@
   ITimeArithmetic
   (+ [t x] (.plus t x))
   (- [t x] (.minus t x))
+
+  ITimeIncDec
   (inc [t] (+ t (seconds 1)))
   (dec [t] (- t (seconds 1)))
-  ;; TODO: Rename maximum to 'greater' and minimum to 'lesser'
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ITimeRangeable
   (range
     ([from] (iterate #(.plusSeconds % 1) from))
@@ -439,19 +487,17 @@
 (extend-type LocalTime
   ITimeArithmetic
   (+ [t x] (.plus t x))
-  (- [t x] (.minus t x))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
-  )
+  (- [t x] (.minus t x)))

 (extend-type YearMonth
   ITimeArithmetic
   (+ [t x] (.plus t x))
   (- [t x] (.minus t x))
+
+  ITimeIncDec
   (inc [t] (.plusMonths t 1))
   (dec [t] (.minusMonths t 1))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ITimeRangeable
   (range
     ([from] (iterate #(.plusMonths % 1) from))
@@ -464,10 +510,11 @@
   ITimeArithmetic
   (+ [t x] (.plus t x))
   (- [t x] (.minus t x))
+
+  ITimeIncDec
   (inc [t] (.plusYears t 1))
   (dec [t] (.minusYears t 1))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   ITimeRangeable
   (range
     ([from] (iterate #(.plusYears % 1) from))
@@ -490,10 +537,11 @@
   ITimeArithmetic
   (+ [d x] (.plus d x))
   (- [d x] (.minus d x))
+
+  ITimeIncDec
   (inc [d] (.plusSeconds d 1))
   (dec [d] (.minusSeconds d 1))
-  (maximum [x y] (if (neg? (compare x y)) y x))
-  (minimum [x y] (if (neg? (compare x y)) x y))
+
   IDivisible
   (/ [d x] (divide-duration x d)))


more doc

more doc

--- src/bitcoinrpc/core.clj
+++ src/bitcoinrpc/core.clj
@@ -40,14 +40,19 @@
 (s/def ::hex-string hex-string?)
 (s/def ::address string?)
 (s/def ::signature string?)
-(defn help
+
+(defn split [s] (.split s "\n"))
+
+
+
+(defn split-help
   ([]
-    (.split (btc-rpc "help") "\n"))
+    (split (btc-rpc "help")))
   ([cmd]
-    (.split (btc-rpc "help" cmd) "\n")))
+    (split (btc-rpc "help" cmd))))

 (defn get-description [name]
-  (loop [r (rest (help name))]
+  (loop [r (rest (split-help name))]
     (if (empty? (first r))
       (recur (rest r))
       (first r))))
@@ -240,19 +245,19 @@
 (defn print-it [a-list]
   (doseq [l a-list] (println l)))

-(defn print-help
+(defmacro print-help
   ([]
-    (print-it (.split (btc-rpc "help") "\n")))
+    (print-it (split-help)))
   ([cmd]
-    (print-it (.split (btc-rpc "help" cmd) "\n"))))
-
-(defn get-rpcs [] (map (fn [v] (symbol (first (.split v " ")))) (filter #(not (.startsWith % "==")) (help))))
+    (print-it (split-help cmd))))
+
+(defn get-rpcs [] (map (fn [v] (symbol (first (.split v " ")))) (filter #(not (.startsWith % "==")) (split-help))))

 (defn print-rpcs [] (doseq [s (get-rpcs)] (println s)))

 ;;---------------------------------------------------------------------------------
-;experimental
+;experiment

 (def help-parser
   (insta/parser


Add IBufferBytes implementation to ES6 DataView

--- src/bytebuf/buffer.cljx
+++ src/bytebuf/buffer.cljx
@@ -165,16 +165,16 @@
   (read-byte [buff pos]
     (.getInt8 buff pos))
   (write-byte [buff pos value]
-    (.setInt8 buff pos value)))
-
-  ;; IBufferBytes
-  ;; (read-bytes [buff pos size]
-  ;;   (let [offset (.-byteOffset buff)
-  ;;         buffer (.-buffer buff)]
-  ;;     (js/Int8Array. buffer (+ offset pos) size)))
-  ;; (write-bytes [buff pos size data]
-  ;;   (doseq [i (range (.-length data))]
-  ;;     (.setInt8 buff (+ pos i) (aget data i)))))
+    (.setInt8 buff pos value))
+
+  IBufferBytes
+  (read-bytes [buff pos size]
+    (let [offset (.-byteOffset buff)
+          buffer (.-buffer buff)]
+      (js/Int8Array. buffer (+ offset pos) size)))
+  (write-bytes [buff pos size data]
+    (doseq [i (range (.-length data))]
+      (.setInt8 buff (+ pos i) (aget data i)))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Public Api


fix namespace name

fix namespace name

--- src/ca_recipe/queue.clj
+++ src/ca_recipe/queue.clj
@@ -1,4 +1,4 @@
-(ns ch5.jqueue
+(ns ca-recipe.jqueue
   (:import [java.util.concurrent LinkedBlockingQueue]))

 (defn pusher [q n]


Add defbindings

Add defbindings

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -121,3 +121,12 @@
            `(def ~const
               (~(java-call-sym c-name) sodium)))))

+(defmacro defbindings
+  [fs]
+  `(do ~@(for [f fs
+               :let [c-name (c-name *ns* f)
+                     args (->> (bound-fns c-name)
+                               (mapv (fn [args] (with-meta args {}))))]]
+           `(defn ~f
+              ~args
+              (~(java-call-sym c-name) sodium ~@args)))))


Add TODO about require time side effects

--- src/caesium/binding.clj
+++ src/caesium/binding.clj
@@ -94,6 +94,8 @@
     (.load loader "sodium")))

 (assert (#{0 1} (.sodium_init sodium)))
+;; TODO When does this get called? Guaranteed from 1 thread?
+

 (defmacro defconsts
   "Given constant names (syms) in the C pseudo-namespace corresponding


tseitin and validity check fixed

tseitin and validity check fixed

--- src/logic/tseitin.clj
+++ src/logic/tseitin.clj
@@ -15,6 +15,7 @@

       (if (= op 'not)
         (list 'and
+          (list 'or t a)
           (list 'or nt na))

         (let [b (when (> (count formula) 2) (nth formula 2))


Fix XML-defaulting for all inserted content

--- src/uruk/core.clj
+++ src/uruk/core.clj
@@ -552,7 +552,8 @@
 (defn element->content
   "Given a clojure.data.xml.Element, returns a MarkLogic XCC Content
   object suitable for inserting to a database. Optionally takes a map
-  of content creation options per `content-creation-options`.
+  of content creation options per `content-creation-options`. Defaults
+  to XML-formatted documents.

   See https://docs.marklogic.com/javadoc/xcc/com/marklogic/xcc/Content.html
   and https://docs.marklogic.com/javadoc/xcc/com/marklogic/xcc/ContentFactory.html"
@@ -560,7 +561,8 @@
    (element->content uri element {:format :xml}))
   ([uri element options]
    (ContentFactory/newContent uri (xml/emit-str element)
-                              (content-creation-options options))))
+                              (content-creation-options (merge {:format :xml}
+                                                               options)))))

 (defn insert-element
   "Inserts the given clojure.data.xml.Element `element` at the given