Allow cycles of size 2

Allow cycles of size 2

--- src/qttt/game.cljs
+++ src/qttt/game.cljs
@@ -7,8 +7,8 @@

 (def ^:dynamic *speculative* false)

-;; TODO: make cycles of size 2 work
-;; TODO: make hover highlighting work (third top-level activity)
+;; TODO: make cycles of size 2 work (approach: become aware of the turn they were played on)
+;; TODO: make hover highlighting work (approach: third top-level activity)
 ;; TODO: make cycle collapse work

 (comment
@@ -44,12 +44,18 @@
   (mod (inc player) num-players))

 (defn get-entanglements
-  "Return a set of cells entangled with the given cell"
+  "Return information regarding cells entangled with the given cell.
+
+   Return value is a seq of [cell turn] tuples, where turn
+   is the turn the spooky mark was placed. Also exclude
+   entanglements which have a classical value already."
+
   [game cell]
   (->> (get-in game [:board cell :entanglements])
     (vals)
-    (keep :pair)
-    (filter (fn [pair] (not (get-in game [:board pair :classical]))))))
+    (keep (fn [e] (when (and (:pair e)
+                         (not (get-in game [:board (:pair e) :classical])))
+                   [(:pair e) (:turn e)])))))

 (defn index-of
   "Return the index of an item in a vector, if present. If not present return nil"
@@ -59,25 +65,22 @@
            v)))

 (defn cycle-search
-  "Generic depth-first search, tracking visited nodes.
-
-   Return a seq of cycles discovered."
-  [node edges visited prev]
-  (set (mapcat (fn [edge]
-                 (if-let [idx (index-of visited edge)]
-                   [(set (conj (subvec visited idx) node))]
-                   (cycle-search edge edges (conj visited node) node)))
-         (disj (set (edges node)) prev))))
+  "Return a seq of cell cycles discovered"
+  [game cell visited from-turn]
+  (set (mapcat (fn [[edge turn]]
+                 (when-not (= turn from-turn)
+                   (if-let [idx (index-of visited edge)]
+                     [(set (conj (subvec visited idx) cell))]
+                     (cycle-search game edge (conj visited cell) turn))))
+         (get-entanglements game cell))))

 (defn detect-cycles
   "Return a sequence of all entanglement cycles present in the given board"
   [game]
-  (let [edges (fn [cell-id]
-                (get-entanglements game cell-id))]
-    ;; Not 100% efficient, but we need some way of detecting multiple disjoint graphs.
-    ;; Should be fine for small N. Using sets removes redundancies. If we run into perf
-    ;; trouble we can track which nodes we've visited *at all* and never revisit them.
-    (apply set/union (map #(cycle-search % edges [] nil) (keys (:board game))))))
+  ;; Not 100% efficient, but we need some way of detecting multiple disjoint graphs.
+  ;; Should be fine for small N. Using sets removes redundancies. If we run into perf
+  ;; trouble we can track which nodes we've visited *at all* and never revisit them.
+  (apply set/union (map #(cycle-search game % [] -1) (keys (:board game)))))

 (defn check-collapses
   "Given a game, check if there are any collapses happening


Added comment to helpers

Added comment to helpers

--- src/skat/helpers.clj
+++ src/skat/helpers.clj
@@ -11,5 +11,5 @@
       (let [[h & t] appended]
         (recur (conj result h) t)))))

-(defn property-matches? [n v c]
+(defn property-matches? "Whether card's property as given" [n v c]
   (identical? (n c) v))


new demo text

new demo text

--- src/splash/core.cljs
+++ src/splash/core.cljs
@@ -67,13 +67,13 @@
                                     ))
 (defonce scroll-text
   (font/make-text "100 24px Indie Flower"
-                  ". .. ... Old School Demo on a New School platform! This will eventually be the index page for my game jam submissions. \"Alien Forest Explorer\" from Global Game Jam 2015, and \"Marty Funk\" and \"Monster Simulator?\" from Ludum Dare 32 and 33. These HTML5 games were all developed with free and open source software on a linux platform. I use pixi.js as the underlying framework but target it through infinitelives.pixi using clojurescript. If you haven't tried clojure or clojurescript you should definitely try them. This of course wouldn't have been possible without the work of so many other people. Those involved in the creation of clojure and clojurescript, in pixi.js and in the many tools I use, like grafx2, impulse tracker and sfxr. A big shout out to the other farnarkler and to the Inversion crew. Best wishes to everyone out there and enjoy! ...  .. .\n"))
+                  ". .. ... Old School Demo on a New School platform??! This is Crispin, here, paying homage to the 8-bit wonderboxes of our childhoods. All music, graphics and code in this homage by me! This will eventually be the index page for my game jam submissions. \"Alien Forest Explorer\" from Global Game Jam 2015, and \"Marty Funk\" and \"Monster Simulator?\" from Ludum Dare 32 and 33. These HTML5 games were all developed with free and open source software on a linux platform. I use pixi.js as the underlying framework but target it through infinitelives.pixi using clojurescript. If you haven't tried clojure or clojurescript you should definitely try them. This of course wouldn't have been possible without the work of so many other people. Those involved in the creation of clojure and clojurescript, in pixi.js and in the many tools I use, like grafx2, impulse tracker and sfxr. A big shout out to Team Farnarkle and to the Inversion crew. Best wishes to everyone out there and enjoy the games! ...  .. .\n"))

 ;;
 ;; font preloader channel
 ;;
 (defonce render! (go
-                   (<! (events/wait-time 1500))
+                   (<! (events/wait-time 2000))
                    (sprite/set-pos! dummy-text -100000 -10000)
                    (sprite/set-pos! test-text 0 0)
                    (.addChild (-> canvas :layer :ui) dummy-text)


Fix Eden Fragment message so that it dosen't expose the ICE installed

--- src/clj/game/cards-agendas.clj
+++ src/clj/game/cards-agendas.clj
@@ -162,7 +162,7 @@
                {:req (req (and (is-type? target "ICE")
                                (empty? (let [cards (map first (turn-events state side :corp-install))]
                                          (filter #(is-type? % "ICE") cards)))))
-                :msg (msg "ignore the install cost of " (:title target))}}}
+                :msg (msg "ignore the install cost of the first ICE this turn")}}}

    "Efficiency Committee"
    {:effect (effect (add-prop card :counter 3))


working

working

--- src/cljs/devplatform/core.cljs
+++ src/cljs/devplatform/core.cljs
@@ -10,6 +10,8 @@
 (def WIDTH 60)
 (def HEIGHT-HOUR 20)
 (def HEIGHT (* 8 HEIGHT-HOUR))
+(def DAYS ["Mo" "Di" "Mi" "Do" "Fr" "Sa" "So"])
+(def HOURS (range 24))

 (defn shift-color [name]
   (let [toNumber #(-> (window/parseInt (nth (lower-case %1) %2) 36)
@@ -18,18 +20,15 @@
                      (int))]
     (str "rgb(" (join "," [(toNumber name 0) (toNumber name 1) (toNumber name 2)]) ")")))

-(println (shift-color "Wally"))
-(println (shift-color "bob"))
-
 (defn plotPlan [plan]
   (let [jsPlan (clj->js plan)
         dataSet (-> d3
                     (.select "#canvas")
                     (.selectAll "g")
-                    (.data jsPlan (fn [key] (println key) (str
-                                                            (.-day key)
-                                                            (.-shift key)
-                                                            (.-name key)))))
+                    (.data jsPlan (fn [key] (str
+                                              (.-day key)
+                                              (.-shift key)
+                                              (.-name key)))))
         enterSet (.enter dataSet)
         enterGroup (-> enterSet
                      (.append "g")
@@ -67,12 +66,38 @@
        (map #(zipmap [:day :shift :name] %))))

 (defn updatePlan [e]
-  (println e)
   (let [v (.-value planInput)
         p (extractPlan v)]
     (plotPlan p)))

+(defn prepareCanvas! []
+  (-> d3
+      (.select "#canvas")
+      (.selectAll "text.days")
+      (.data (clj->js DAYS))
+      (.enter)
+      (.append "text")
+      (.attr #js {:class "days"})
+      (.attr "transform" #(str "translate("
+                               (+ 5 (* WIDTH (inc %2)))
+                               ",20)"))
+      (.text #(str %)))
+  (-> d3
+      (.select "#canvas")
+      (.selectAll "text.hours")
+      (.data (clj->js HOURS))
+      (.enter)
+      (.append "text")
+      (.attr #js {:class "dahoursys"})
+      (.attr "transform" #(str "translate(" (- WIDTH 20) ", "
+                               (+ HEIGHT-HOUR ;; offset legend
+                                  (/ HEIGHT-HOUR 2) ;; text to the middle
+                                  (* HEIGHT-HOUR (inc %2)))
+                               ")"))
+      (.text #(str %))))
+
 (defn setup! []
+  (prepareCanvas!)
   (.addEventListener renderInput "click" updatePlan))

 (setup!)


Add add-map-move in the clj-chess.game namespace.

Equivalent to the older add-san-move and add-uci-move functions, but
this one handles map moves, as described in the clj-chess.board
namespace.

--- src/clojure/clj_chess/game.clj
+++ src/clojure/clj_chess/game.clj
@@ -172,6 +172,15 @@
   game is used."
   [game uci-move & [node-id]]
   (add-move game board/move-from-uci uci-move
+            (or node-id (-> game :current-node :node-id))))
+
+
+(defn add-map-move
+  "Adds a map move (see documentation for clj-chess.board/board-to-map) to a
+  game at a given node id. The move is added as the last child. If no node id
+  is supplied, the current node of the game is used."
+  [game map-move & [node-id]]
+  (add-move game board/move-from-map map-move
             (or node-id (-> game :current-node :node-id))))


Switched to proxy implementation so that I can get watches and notification working - should probably use gen-class so that I can get a type name in there.

--- src/clojure/freactive/core.clj
+++ src/clojure/freactive/core.clj
@@ -58,64 +58,110 @@

 (defrecord ReactiveState [dirty value f deps sully-fn])

-(defprotocol IReactive
-  (force-recompute! [this])
-  (rebind! [this f])
-  (deactivate! [this]))
+;; (defprotocol IReactive
+;;   (force-recompute! [this])
+;;   (rebind! [this f])
+;;   (deactivate! [this]))

-(defrecord Reactive [data]
-  IReactive
-  (force-recompute! [this] (clojure.core/swap! data merge {:dirty true :deps nil}))
-  (rebind! [this f] (clojure.core/swap! data merge {:dirty true :f f :deps nil}))
-  (deactivate! [this]
-    (clojure.core/swap! data (fn [{:keys [deps sully-fn] :as state}]
-                  (doseq [d deps] (remove-watch d sully-fn))
-		  (merge state {:deps nil :dirty false}))))
-  clojure.lang.IDeref
-  (deref [this]
-    (*register-dep* this)
-    (let [^ReactiveState {:keys [dirty value]} @data]
-      (if-not dirty
-        value
-        (:value
-         (clojure.core/swap!
-          data
-          (fn recompute-fn [^ReactiveState {:keys [dirty value f deps sully-fn] :as state}]
-            (if-not dirty
-              state
-              (let [simple (:simple (meta f))]
-                (if (and simple deps)
-                  (binding [*register-dep* (constantly nil)]
-                    (merge state {:value (f) :dirty false}))
-                  (binding [*deps* #{}
-                            *register-dep* (fn [x] (set! *deps* (conj *deps* x)))]
-                    (let [new-value (f)]
-                      (let [removed (clojure.set/difference deps *deps*)
-                            added (clojure.set/difference *deps* deps)]
-                        (doseq [r removed]
-                          (remove-watch r sully-fn))
-                        (doseq [a added]
-                          (add-watch a sully-fn sully-fn))
-                        (merge state {:value new-value :dirty false :deps *deps*}))))))))))))))
+;; (defn reactive-proxy [data]
+;;   )

-(defmethod print-method Reactive [o ^java.io.Writer w]
-  (#'clojure.core/print-sequential (format "#<%s@%x%s: "
-                            (.getSimpleName (class o))
-                            (System/identityHashCode o)
-                            "")
-                    #'clojure.core/pr-on, "", ">", (list @o), w))
+;; (defrecord Reactive [data]
+;;   IReactive
+;;   (force-recompute! [this] (clojure.core/swap! data merge {:dirty true :deps nil}))
+;;   (rebind! [this f] (clojure.core/swap! data merge {:dirty true :f f :deps nil}))
+;;   (deactivate! [this]
+;;     (clojure.core/swap! data (fn [{:keys [deps sully-fn] :as state}]
+;;                   (doseq [d deps] (remove-watch d sully-fn))
+;; 		  (merge state {:deps nil :dirty false}))))
+;;   clojure.lang.IDeref
+;;   (deref [this]
+;;     (*register-dep* this)
+;;     (let [^ReactiveState {:keys [dirty value]} @data]
+;;       (if-not dirty
+;;         value
+;;         (:value
+;;          (clojure.core/swap!
+;;           data
+;;           (fn recompute-fn [^ReactiveState {:keys [dirty value f deps sully-fn] :as state}]
+;;             (if-not dirty
+;;               state
+;;               (let [simple (:simple (meta f))]
+;;                 (if (and simple deps)
+;;                   (binding [*register-dep* (constantly nil)]
+;;                     (merge state {:value (f) :dirty false}))
+;;                   (binding [*deps* #{}
+;;                             *register-dep* (fn [x] (set! *deps* (conj *deps* x)))]
+;;                     (let [new-value (f)]
+;;                       (let [removed (clojure.set/difference deps *deps*)
+;;                             added (clojure.set/difference *deps* deps)]
+;;                         (doseq [r removed]
+;;                           (remove-watch r sully-fn))
+;;                         (doseq [a added]
+;;                           (add-watch a sully-fn sully-fn))
+;;                         (merge state {:value new-value :dirty false :deps *deps*}))))))))))))))

+;; (defmethod print-method Reactive [o ^java.io.Writer w]
+;;   (#'clojure.core/print-sequential (format "#<%s@%x%s: "
+;;                             (.getSimpleName (class o))
+;;                             (System/identityHashCode o)
+;;                             "")
+;;                     #'clojure.core/pr-on, "", ">", (list @o), w))
+
+;; (definterface IReactive
+;;   (forceRecompute [])
+;;   (deactivate [])
+;;   (rebind [f]))

 (defn reactive [f]
-  (let [data (clojure.core/atom nil)]
-    (clojure.core/reset!
-     data
-     (ReactiveState. true nil f nil
-                     (fn sully-fn [& _]
-                       (clojure.core/swap!
-                        data
-                        (fn do-sully [^ReactiveState state] (assoc state :dirty true))))))
-    (Reactive. data)))
+  (let [data (clojure.core/atom nil)
+
+        sully-fn (fn sully-fn [& _]
+                   (clojure.core/swap!
+                    data
+                    (fn do-sully [^ReactiveState state] (assoc state :dirty true))))
+
+        reactive-proxy
+        (proxy [clojure.lang.ARef] []
+          (setValidator [vf]
+            (.deref this)
+            (.setValidator data (fn validator-wrapper [state]
+                                  (vf (:value state)))))
+          (deref []
+            (*register-dep* this)
+            (let [^ReactiveState {:keys [dirty value]} @data]
+              (if-not dirty
+                value
+                (:value
+                 (clojure.core/swap!
+                  data
+                  (fn recompute-fn [^ReactiveState {:keys [dirty value f deps sully-fn] :as state}]
+                    (if-not dirty
+                      state
+                      (let [simple (:simple (meta f))]
+                        (if (and simple deps)
+                          (binding [*register-dep* (constantly nil)]
+                            (merge state {:value (f) :dirty false}))
+                          (binding [*deps* #{}
+                                    *register-dep*
+                                    (fn register-dep [x]
+                                      (when (not= x this) (set! *deps* (conj *deps* x))))]
+                            (let [new-value (f)]
+                              (let [removed (clojure.set/difference deps *deps*)
+                                    added (clojure.set/difference *deps* deps)]
+                                (doseq [r removed]
+                                  (remove-watch r sully-fn))
+                                (doseq [a added]
+                                  (add-watch a sully-fn sully-fn))
+                                (merge state {:value new-value :dirty false :deps *deps*}))))))))))))))]
+   (clojure.core/reset! data (ReactiveState. true nil f nil sully-fn))
+    (.addWatch data :proxy-forward
+               (fn notify-forwarder [k r old-value new-value]
+                 (let [old-value (:value old-value)
+                       new-value (:value new-value)]
+                   (when (not= old-value new-value)
+                     (.notifyWatches reactive-proxy old-value new-value)))))
+    reactive-proxy))

 (defn simple [f] (with-meta f (merge (meta f) {:simple true})))

@@ -127,6 +173,7 @@
 ;;      (dotimes [i 100000]
 ;;        (swap! a inc)
 ;;        (swap! b inc)
-;;        @c))))
+;;        @c))
+;;     (println @a @b (+ @a @b) @c)))

 ;; (test1)


Clean up file path code

Clean up file path code

--- src/clojure/nightcode/lein.clj
+++ src/clojure/nightcode/lein.clj
@@ -60,7 +60,9 @@
   (let [home (System/getProperty "user.home")
         dir (System/getProperty "SandboxDirectory")]
     (if (and home dir (nil? (:local-repo project)))
-      (assoc project :local-repo (str home "/" dir "/.m2"))
+      (some->> (io/file home dir ".m2")
+               .getCanonicalPath
+               (assoc project :local-repo))
       project)))

 (defn add-props


Improve dux output shape function docstrings.

--- src/clojure/parkour/io/dux.clj
+++ src/clojure/parkour/io/dux.clj
@@ -159,20 +159,23 @@

 (def ^{:arglists '([oname] [context coll])}
   named-keyvals
-  "Sink as key-val pairs to named output, with name provided as `oname` or as
-first element of three-element tuples."
+  "Sink as key-val pairs to named output.  If used directly as a shaping
+function, tuples should be doubles of output name and content.  If invoked with
+an output name `oname`, expects just output content."
   (partial named snk/emit-keyval))

 (def ^{:arglists '([oname] [context coll])}
   named-keys
-  "Sink as keys to named output, with name provided as `oname` or as first
-element of two-element tuples."
+  "Sink as keys to named output.  If used directly as a shaping function, tuples
+should be doubles of output name and content.  If invoked with an output name
+`oname`, expects just output content."
   (partial named snk/emit-key))

 (def ^{:arglists '([oname] [context coll])}
   named-vals
-  "Sink as values to named output, with name provided as `oname` or as first
-element of two-element tuples."
+  "Sink as values to named output If used directly as a shaping function, tuples
+should be doubles of output name and content.  If invoked with an output name
+`oname`, expects just output content."
   (partial named snk/emit-val))

 (defn ^:private prefix
@@ -191,20 +194,27 @@
                  (f sink t)))
              nil coll)))

-(def ^{:arglists '([oname])}
+(def ^{:arglists '([oname] [context coll])}
   prefix-keyvals
-  "Sink as key-val pairs to named output `oname`, with file prefix as first
-element of three-element tuples."
+  "Sink as key-val pairs to named output and file prefix.  If used directly as
+shaping function, tuples should be triples of output name, prefix, and content.
+If invoked wih an output name `oname`, tuples should be pairs of prefix and
+content."
+
   (partial prefix snk/emit-keyval))

-(def ^{:arglists '([oname])}
+(def ^{:arglists '([oname] [context coll])}
   prefix-keys
-  "Sink as keys to named output `oname`, with file prefix as first element of
-two-element tuples."
+  "Sink as keys to named output and file prefix.  If used directly as shaping
+function, tuples should be triples of output name, prefix, and content.  If
+invoked wih an output name `oname`, tuples should be pairs of prefix and
+content."
   (partial prefix snk/emit-key))

-(def ^{:arglists '([oname])}
+(def ^{:arglists '([oname] [context coll])}
   prefix-vals
-  "Sink as values to named output `oname`, with file prefix as first element of
-two-element tuples."
+  "Sink as values to named output and file prefix.  If used directly as shaping
+function, tuples should be triples of output name, prefix, and content.  If
+invoked wih an output name `oname`, tuples should be pairs of prefix and
+content."
   (partial prefix snk/emit-val))


remove exclusion of reflexive verbs from encyclopedia inference rules

--- src/babel/encyclopedia.cljc
+++ src/babel/encyclopedia.cljc
@@ -23,7 +23,6 @@
 (def verbs
   (map (fn [sem]
          (unify! {:synsem {:aux false
-                           :sem {:shared-with-obj false} ;; prevent matching reflexive verbs.
                            :cat :verb}}
                  {:synsem {:sem sem}}))


cleanup whitespace

cleanup whitespace

--- src/babel/italiano/lab.cljc
+++ src/babel/italiano/lab.cljc
@@ -292,6 +292,3 @@
                    spec))
                chosen-spec (unify root-spec tense-spec)]
            (target-generation chosen-spec verbcoach-lexical-lookup model)))))))
-
-
-


Minor refactoring to make testing easier

--- src/refactor_nrepl/artifacts.clj
+++ src/refactor_nrepl/artifacts.clj
@@ -10,12 +10,17 @@
 (def millis-per-day (* 24 60 60 1000))

 (defn get-artifacts-from-clojars! []
-  (let [rdr (io/reader (java.net.URL. "https://clojars.org/repo/all-jars.clj"))
-        add-lib (fn [line]
-                  ;; each line looks like [some/lib "0.1"]
-                  (let [lib (edn/read-string line)]
-                    (swap! artifacts update-in [(str (first lib))] conj (second lib))))]
-    (dorun (map add-lib (line-seq rdr)))))
+  "Returns a vector of [[some/lib \"0.1\"]...]."
+  (->> "https://clojars.org/repo/all-jars.clj"
+       java.net.URL.
+       io/reader
+       line-seq
+       (map edn/read-string)))
+
+(defn add-artifacts-from-clojars! []
+  (->> (get-artifacts-from-clojars!)
+       (map #(swap! artifacts update-in [(str (first %))] conj (second %)))
+       dorun))

 (defn- stale-cache? []
   (or (empty? @artifacts)
@@ -30,6 +35,7 @@
     (map :a (-> search-result :body :response :docs))))

 (defn- get-versions! [artifact]
+  "Gets all the versions from an artifact belonging to the org.clojure."
   (->> (http/get (str "http://search.maven.org/solrsearch/select?"
                       "q=g:%22org.clojure%22+AND+a:%22"
                       artifact
@@ -53,9 +59,9 @@
   (->> artifacts
        (partition-all 2)
        (map #(future (->> %
-                         (map collate-artifact-and-versions)
-                         (map add-artifact)
-                         dorun)))))
+                          (map collate-artifact-and-versions)
+                          (map add-artifact)
+                          dorun)))))

 (defn- get-artifacts-from-mvn-central! []
   (-> (get-all-clj-artifacts!)
@@ -63,7 +69,7 @@

 (defn- update-artifact-cache! []
   (let [mvn-central-futures (get-artifacts-from-mvn-central!)
-        clojars-future (future (get-artifacts-from-clojars!))]
+        clojars-future (future (add-artifacts-from-clojars!))]
     (-> (map deref mvn-central-futures) dorun)
     @clojars-future)
   (alter-meta! artifacts update-in [:last-modified]


New byte buffer vs byte-array semantics for sign

--- src/caesium/crypto/sign.clj
+++ src/caesium/crypto/sign.clj
@@ -1,7 +1,7 @@
 (ns caesium.crypto.sign
   (:refer-clojure :exclude [bytes])
   (:require [caesium.binding :as b]
-            [caesium.byte-bufs :refer [buflen]]))
+            [caesium.byte-bufs :as bb]))

 (b/defconsts [bytes seedbytes publickeybytes secretkeybytes primitive])

@@ -12,17 +12,16 @@

   A map of the secret seed and public-key is returned."
   ([]
-   (let [pk (byte-array publickeybytes)
-         sk (byte-array secretkeybytes)]
-     (.crypto_sign_keypair b/sodium pk sk)
-     {:public pk
-      :secret sk}))
+   (let [pk (bb/alloc publickeybytes)
+         sk (bb/alloc secretkeybytes)]
+     (b/✨ sign-keypair pk sk)
+     {:public pk :secret sk}))
   ([seed]
-   (let [pk (byte-array publickeybytes)
-         sk (byte-array secretkeybytes)]
-     (.crypto_sign_seed_keypair b/sodium pk sk seed)
-     {:public pk
-      :secret sk})))
+   (let [pk (bb/alloc publickeybytes)
+         sk (bb/alloc secretkeybytes)
+         seed (bb/->indirect-byte-buf seed)]
+     (b/✨ sign-seed-keypair pk sk seed)
+     {:public pk :secret sk})))

 (def ^:deprecated generate-signing-keys
   "Deprecated alias for [[keypair!]]."
@@ -31,28 +30,36 @@
 (defn signed-to-buf!
   "Puts a signed version of the given message using given secret key into the
   given out buffer."
-  [out sk m]
-  (.crypto_sign b/sodium out nil m (buflen m) sk)
-  out)
+  [sm sk m]
+  (b/✨ sign sm m sk)
+  sm)

 (defn signed
   "Produces a signed version of the given message m using given secret key."
   [sk m]
-  (let [sm (byte-array (+ bytes (buflen m)))]
-    (signed-to-buf! sm sk m)))
+  (let [sm (bb/alloc (+ bytes (bb/buflen m)))]
+    (signed-to-buf!
+     sm
+     (bb/->indirect-byte-buf sk)
+     (bb/->indirect-byte-buf m))
+    (bb/->bytes sm)))

 (defn sign-to-buf!
   "Puts a signature of the given message using given secret key into the given
   out buffer."
-  [out sk m]
-  (.crypto_sign_detached b/sodium out nil m (buflen m) sk)
-  out)
+  [sig sk m]
+  (b/✨ sign-detached sig m sk)
+  sig)

 (defn sign
   "Produces a detached signature for a message m using given secret key."
   [sk m]
-  (let [sig (byte-array bytes)]
-    (sign-to-buf! sig sk m)))
+  (let [sig (bb/alloc bytes)]
+    (sign-to-buf!
+     sig
+     (bb/->indirect-byte-buf sk)
+     (bb/->indirect-byte-buf m))
+    (bb/->bytes sig)))

 (defn verify
   "Verify a signed message or a message and a detached signature.
@@ -61,14 +68,17 @@
   message. When given a valid signature, returns nil. When given an
   invalid signed message or signature, raises RuntimeException."
   ([pk sm]
-   (let [smlen (buflen sm)
-         m (byte-array (- smlen bytes))
-         res (.crypto_sign_open b/sodium m nil sm smlen pk)]
+   (let [m (bb/alloc (- (bb/buflen sm) bytes))
+         sm (bb/->indirect-byte-buf sm)
+         pk (bb/->indirect-byte-buf pk)
+         res (b/✨ sign-open m sm pk)]
      (if (zero? res)
-       m
+       (bb/->bytes m)
        (throw (RuntimeException. "Signature validation failed")))))
-  ([pk msg sig]
-   (let [mlen (buflen msg)
-         res (.crypto_sign_verify_detached b/sodium sig msg mlen pk)]
+  ([pk m sig]
+   (let [sig (bb/->indirect-byte-buf sig)
+         m (bb/->indirect-byte-buf m)
+         pk (bb/->indirect-byte-buf pk)
+         res (b/✨ sign-verify-detached sig m pk)]
      (when-not (zero? res)
        (throw (RuntimeException. "Signature validation failed"))))))


simplify periodic task

simplify periodic task

--- src/spq/server.clj
+++ src/spq/server.clj
@@ -144,8 +144,8 @@
                                      (get (val %) :retry-timeout-minutes))))]
           (when (seq to-retry)
             (timbre/info "periodic task found" (count to-retry) "tasks to retry")
-            (->> to-retry (map val) (map :task) (map dq/retry!) dorun)
-            (doseq [id (keys to-retry)]
+            (doseq [[id val] to-retry]
+              (dq/retry! (:task val))
               (swap! state update-in [:tasks] dissoc id))))
         (time/in (conf :server :period-millis) #(periodic-task stop-periodic-task))
         (catch Throwable ex


specialize state passed to sub components even more

--- src/chessground/render.cljs
+++ src/chessground/render.cljs
@@ -14,37 +14,40 @@
 (q/defcomponent Piece
   "A piece in a square"
   [[{color :color role :role} targets] channels]
-  ; (pp "render piece")
+  ; (pp (str "render " color " " role))
   (let [piece (d/div {:className (class-name #{"piece" (name color) (name role)})})]
     (if targets (drag/make channels piece targets) piece)))

 (q/defcomponent Square
   "One of the 64 board squares"
-  [{selected :selected movable :movable chess :chess} key channels]
+  [{selected :selected targets :targets piece :piece} key channels]
   ; (pp (str "render square " key))
   (let [attributes {:className (class-name #{"square"
                                              (when selected "selected")})
                     :key (name key) ; react.js key just in case it helps performance
                     :data-key (name key)}
-        targets (if (:free movable) :all (-> movable :valid key))
         behaviors (when targets {:onClick #(push! (:select-square channels) key)
                                  :onTouchStart (fn [event]
                                                  (.preventDefault event)
                                                  (push! (:select-square channels) key))})]
     (d/div (merge attributes behaviors)
-           (when-let [piece (chess/get-piece chess key)]
-             (Piece [piece targets] channels)))))
+           (when piece (Piece [piece targets] channels)))))

 (q/defcomponent Board
   "The whole board"
   [state channels]
   ; (pp "render board")
   (let [white (= (:orientation state) :white)
+        movable (:movable state)
+        c (:chess state)
+        selected (:selected state)
         squares (for [rank (if white (range 8 0 -1) (range 1 9))
-                      file (seq (if white "abcdefgh" "hgfedcba"))]
-                  (Square {:selected (= (:selected state) key)
-                           :movable (:movable state)
-                           :chess (:chess state)} (keyword (str file rank)) channels))]
+                      file (seq (if white "abcdefgh" "hgfedcba"))
+                      :let [key (keyword (str file rank))]]
+                  (Square {:selected (= selected key)
+                           :piece (chess/get-piece c key)
+                           :targets (if (:free movable) :all (-> movable :valid key))}
+                          key channels))]
     (apply d/div {:className "board"} squares)))

 (q/defcomponent App


Basic Movement

Basic Movement

--- src/tester/core.cljs
+++ src/tester/core.cljs
@@ -9,8 +9,10 @@

 (def board-size 3)

-(def screen-width (.-innerWidth js/window))
-(def screen-height (.-innerHeight js/window))
+;; (def screen-width (.-innerWidth js/window))
+;; (def screen-height (.-innerHeight js/window))
+(def screen-width 500)
+(def screen-height 500)

 (def tile-width (/ (min screen-height screen-width) board-size))

@@ -88,17 +90,29 @@
         new-tile {::value new-value ::position new-position}]
     (cons new-tile (drop 2 tiles))))

+(s/fdef shift-in-direction
+        :args (s/cat :direction ::direction :tiles (s/and (s/coll-of ::tile) #(< 0 (count %))))
+        :ret (s/coll-of ::tile))
+
+(defn shift-in-direction
+  [direction tiles]
+  (case direction
+    ::up (map-indexed (fn [i t] (assoc-in t [::position ::y] (- board-size i 1))) (reverse tiles))
+    ::down (map-indexed (fn [i t] (assoc-in t [::position ::y] i)) (reverse tiles))
+    ::right (map-indexed (fn [i t] (assoc-in t [::position ::x] (- board-size i 1))) (reverse tiles))
+    ::left (map-indexed (fn [i t] (assoc-in t [::position ::x] i)) (reverse tiles))))
+
 (s/fdef move-direction
-        :args (s/cat :board ::game-board :direction ::direction))
+        :args (s/cat :board ::game-board :direction ::direction)
+        :ret ::game-board)

 (defn move-direction
   [board direction]
   (->> (group-by-direction direction board)
        (vals)
        (map (partial sort-tiles-by-priority direction))
-       (mapcat join-first)
-       #_(mapcat (partial shift-in-direction direction))
-       ))
+       (map join-first)
+       (mapcat (partial shift-in-direction direction))))

 (defn update-state
   [state [event-type & params]]


Fix code formatting issues

Fix code formatting issues

--- src/cljs/koeeoadi/code.cljs
+++ src/cljs/koeeoadi/code.cljs
@@ -120,10 +120,10 @@
                                      "limit"
                                      ,:code-chunk/line-chunk 7007}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     ")"
+                                     ") - 2;"
                                      ,:code-chunk/line-chunk 7008}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     " - 2;\n        "
+                                     "        "
                                      ,:code-chunk/line-chunk 8001}
                                     {:code-chunk/face [:faces/by-name "keyword"],:code-chunk/string
                                      "var"
@@ -333,10 +333,10 @@
                                      "j"
                                      ,:code-chunk/line-chunk 15003}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     "]"
+                                     "] = 0;"
                                      ,:code-chunk/line-chunk 15004}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     " = 0;\n        "
+                                     "        "
                                      ,:code-chunk/line-chunk 16001}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
                                      "}"
@@ -432,10 +432,10 @@
                                      "p"
                                      ,:code-chunk/line-chunk 20003}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     ")"
+                                     ");"
                                      ,:code-chunk/line-chunk 20004}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     ";\n        "
+                                     "        "
                                      ,:code-chunk/line-chunk 21001}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
                                      "}"
@@ -480,10 +480,10 @@
                                      "100"
                                      ,:code-chunk/line-chunk 26006}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     ")"
+                                     ");"
                                      ,:code-chunk/line-chunk 26007}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     ";\n "
+                                     " "
                                      ,:code-chunk/line-chunk 27001}
                                     {:code-chunk/face [:faces/by-name "keyword"],:code-chunk/string
                                      "if"
@@ -726,10 +726,10 @@
                                      "* i i"
                                      ,:code-chunk/line-chunk 9005}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     ")"
+                                     ") to limit by i"
                                      ,:code-chunk/line-chunk 9006}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                                     " to limit by i\n                   do "
+                                     "                   do "
                                      ,:code-chunk/line-chunk 10001}
                                     {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
                                      "("
@@ -1543,7 +1543,7 @@
                                "  \n"
                                ,:code-chunk/line-chunk 7001}
                               {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
-                               "("
+                               "   ("
                                ,:code-chunk/line-chunk 7002}
                               {:code-chunk/face [:faces/by-name "default"],:code-chunk/string
                                "i**2..n"


correct config path

correct config path

--- src/cljs/server/config.cljs
+++ src/cljs/server/config.cljs
@@ -2,4 +2,4 @@
   (:require [cljs.nodejs :as nodejs]))

 ;; keep config in javascript since we are mostly passing values to other JS libs
-(def config (nodejs/require "../../application.json"))
+(def config (nodejs/require "../../resources/config/application.json"))


no more session cookies

no more session cookies

--- src/cljs/tictag/events.cljs
+++ src/cljs/tictag/events.cljs
@@ -369,7 +369,7 @@
  :set-cookie
  (fn [kv]
    (doseq [[k v] kv]
-     (.set goog.net.cookies (name k) v))))
+     (.set goog.net.cookies (name k) v (* 60 60 24 365 2)))))

 (defonce !chsk (atom nil))
 (defonce !ch-chsk (atom nil))


Check that event is not nill in modal hide functions

Hoping this will help resolve some weird production errors

--- src/cljs/zetawar/views.cljs
+++ src/cljs/zetawar/views.cljs
@@ -257,7 +257,9 @@
   (let [unit-types @(subs/available-unit-types conn)
         cur-faction @(subs/current-faction conn)
         color (name (:faction/color cur-faction))
-        hide-picker #(dispatch [::events.ui/hide-unit-picker])]
+        hide-picker (fn [ev]
+                      (when ev (.preventDefault ev))
+                      (dispatch [::events.ui/hide-unit-picker]))]
     [:> js/ReactBootstrap.Modal {:show @(subs/picking-unit? conn)
                                  :on-hide hide-picker}
      [:> js/ReactBootstrap.Modal.Header {:close-button true}
@@ -328,9 +330,9 @@
 (defn new-game-settings [{:as view-ctx :keys [conn dispatch translate]}]
   (with-let [default-scenario-id :sterlings-aruba-multiplayer
              selected-scenario-id (r/atom default-scenario-id)
-             hide-settings #(do
-                              (.preventDefault %)
-                              (dispatch [::events.ui/hide-new-game-settings]))
+             hide-settings (fn [ev]
+                             (when ev (.preventDefault ev))
+                             (dispatch [::events.ui/hide-new-game-settings]))
              select-scenario #(reset! selected-scenario-id (keyword (.-target.value %)))
              start-new-game #(do
                                (.preventDefault %)


append tagged literal syntax forms with expected forms that follow (close #89)

--- src/cljs_api_gen/syntax.clj
+++ src/cljs_api_gen/syntax.clj
@@ -79,10 +79,10 @@
    {:desc "Infinity" :type "special symbol" :form ["Infinity" "-Infinity" "+Infinity"]}

    ;; available tagged literals
-   {:desc "uuid-tag"  :type "tagged literal" :form "#uuid" :clj-doc doc-clj-tags :edn-doc (edn-doc "uuid-f81d4fae-7dec-11d0-a765-00a0c91e6bf6") :clj-added "1.4.0"}
-   {:desc "inst-tag"  :type "tagged literal" :form "#inst" :clj-doc doc-clj-tags :edn-doc (edn-doc "inst-rfc-3339-format") :clj-added "1.4.0"}
-   {:desc "queue-tag" :type "tagged literal" :form "#queue"}
-   {:desc "js-tag"    :type "tagged literal" :form "#js"}
+   {:desc "uuid-tag"  :type "tagged literal" :form "#uuid \"\"" :clj-doc doc-clj-tags :edn-doc (edn-doc "uuid-f81d4fae-7dec-11d0-a765-00a0c91e6bf6") :clj-added "1.4.0"}
+   {:desc "inst-tag"  :type "tagged literal" :form "#inst \"\"" :clj-doc doc-clj-tags :edn-doc (edn-doc "inst-rfc-3339-format") :clj-added "1.4.0"}
+   {:desc "queue-tag" :type "tagged literal" :form "#queue []"}
+   {:desc "js-tag"    :type "tagged literal" :form ["#js {}" "#js []"]}

    ;; special namespaces
    {:desc "js-ns"   :type "special namespace" :form "js/"}


Fix errors

Fix errors

--- src/clopack_native/core.clj
+++ src/clopack_native/core.clj
@@ -1,15 +1,28 @@
-(ns clopack-native.core)
+(ns clopack-native.core
+  (:gen-class))

 (require '[net.n01se.clojure-jna :as jna])

-; Refer to 'clopack_native' as 'cn'.
-(jna/to-ns cn clopack_native)
+(defn- dev-open [interface]
+  (jna/invoke Integer clopack_native/dev_open interface))

-(defn create-ctx [interface]
+(defn- dev-read [handle buf buf-len]
+  (jna/invoke Integer clopack_native/dev_read handle buf buf-len))
+
+(defn- dev-write [handle buf buf-len]
+  (jna/invoke Integer clopack_native/dev_write handle buf buf-len))
+
+(defn- dev-close [handle]
+  (jna/invoke Integer clopack_native/dev_close handle))
+
+(defn- dev-buf-len []
+  (jna/invoke Integer clopack_native/dev_buf_len))
+
+(defn create-context [interface]
   "Creates a new packet context with the given interface.
    Returns a packet context on success, nil on errors."
-  (let [handle  jna/invoke Integer cn/dev_open interface
-        buf-len jna/invoke Integer cn/dev_buf_len]
+  (let [handle  (dev-open interface)
+        buf-len (dev-buf-len)]
     (when-not (= handle -1)
       {:handle  handle
        :buf-len buf-len})))
@@ -20,7 +33,7 @@
   (let [handle    (:handle ctx)
         buf-len   (:buf-len ctx)
         buf       (byte-array buf-len)
-        num-read  (jna/invoke Integer cn/dev_read handle buf buf-len)]
+        num-read  (dev-read handle buf buf-len)]
     (when-not (= num-read -1)
       (take num-read buf))))

@@ -29,11 +42,11 @@
    Returns the number of bytes written on success, nil otherwise."
   (let [handle      (:handle ctx)
         buf-len     (count buf)
-        num-written (jna/invoke Integer cn/dev_write handle buf buf-len)]
+        num-written (dev-write handle buf buf-len)]
     (when-not (= num-written -1)
       num-written)))

-(defn destroy-ctx [ctx]
+(defn destroy-context [ctx]
   "Destroys a packet context."
-  (jna/invoke Integer cn/dev_close (:handle ctx))
+  (dev-close (:handle ctx))
   nil)


Fix missing trailing ] in todomvc :dependencies

--- examples/todomvc/project.clj
+++ examples/todomvc/project.clj
@@ -5,7 +5,7 @@
                  [re-frame "0.10.5"]
                  [binaryage/devtools "0.9.10"]
                  [secretary "1.2.3"]
-                 [day8.re-frame/tracing "0.5.1"]
+                 [day8.re-frame/tracing "0.5.1"]]

   :plugins [[lein-cljsbuild "1.1.7"]


todomvc: be able to get carry-history from Clojars

--- examples/todomvc/project.clj
+++ examples/todomvc/project.clj
@@ -29,6 +29,7 @@
              :clojars-deps {:dependencies [[carry "0.1.0"]
                                            [carry-reagent "0.1.0"]
                                            [carry-logging "0.1.0"]
+                                           [carry-history "0.1.0"]

                                            ; required by carry-devtools:
                                            [cljsjs/jquery-ui "1.11.4-0"]
@@ -36,7 +37,6 @@

   :cljsbuild {:builds [{:id           "clojars-deps"
                         :source-paths ["src"
-                                       "../../contrib/history/src"
                                        "../../contrib/persistence/src"
                                        "../../contrib/devtools/src"
                                        "../../contrib/schema/src"]


Cleanup dummy data

Cleanup dummy data

--- src/gigrig/components/app.cljs
+++ src/gigrig/components/app.cljs
@@ -5,28 +5,18 @@
             [gigrig.components.diagram :as diagram]
             [gigrig.components.pedal-search :as pedal-search]))

-(def old-data
-  {:type :distributor
-   :children [
-              {:type :pedal
-               :name "Fuzz Factory"}
-              {:type :pedal
-               :name "Whammy"}
-              {:type :pedal
-               :name "Quartermaster"}
-              {:type :isolator
-               :children [{:type :distributor
-                           :children [{:type :pedal
-                                       :name "dd2"}]}
-                          {:type :pedal
-                           :name "TS-9"}]}
-              {:type :pedal
-               :name "DD-20 Giga-Delay"}
-              {:type :distributor
-               :children [{:type :pedal
-                           :name "A Pedal"}
-                          {:type :pedal
-                           :name "Earthquaker Bit Commander"}]}]})
+(def test-tree
+  [:distributor
+   [[:pedal "pedal1"]
+    [:pedal "pedal2"]
+    [:pedal "pedal3"]
+    [:pedal "pedal4"]
+    [:pedal "pedal5"]
+    [:distributor [[:pedal "pedal 6"]
+                   [:pedal "pedal 7"]
+                   [:distributor [[:pedal "pedal 8"]]]
+                   [:distributor [[:pedal "pedal 9"]
+                                  [:pedal "pedal 10"]]]]]]])

 (defn component
   [state]
@@ -36,4 +26,4 @@
      ^{:key id}
      [pedal-search/component (assoc field :id id)])
    [:button {:on-click #(dispatch! a/add-pedal-button-clicked)} "+ Add pedal"]
-   [diagram/component {:zipper (gzip/zipper [:distributor [[:pedal "pedal1"] [:pedal "pedal2"]]])}]])
+   [diagram/component {:zipper (gzip/zipper test-tree)}]])


color the js-core layers

color the js-core layers

--- src/solar_system_of_js/core.cljs
+++ src/solar_system_of_js/core.cljs
@@ -124,18 +124,39 @@

   (restore!))

+(def core-layers
+  "colors of js-core layers"
+  [{:name "ES3"
+    :color "#DDD"
+    }
+   {:name "ES5"
+    :color "#BBB"
+    }
+   {:name "ES6"
+    :color "#999"
+    }
+   {:name "ES7"
+    :color "#777"
+    }
+   {:name "ES8"
+    :color "#555"
+    }
+   ])
+
 (defn draw-js-core!
   [{:keys [x y r alpha]}]
   (save!)
   (global-alpha! alpha)
-  (stroke-style! "#222")
-  (doseq [[i label] (reverse (map-indexed vector ["ES3" "ES5" "ES6" "ES7" "ES8"]))]
-    (let [cr (* (inc i) (/ r 5))]
+  (stroke-style! "#EEE")
+  (doseq [[i layer] (reverse (map-indexed vector core-layers))]
+    (let [cr (* (inc i) (/ r (count core-layers)))]
       (circle! x y cr)
-      (line-width! 10)
-      (stroke!)
-      (fill-style! "#f7df1e")
+      (fill-style! (:color layer))
       (fill!)))
+  (circle! x y r)
+  (stroke-style! "#f7df1e")
+  (line-width! 10)
+  (stroke!)
   (restore!)
   )

@@ -271,7 +292,7 @@
           #(swap! state assoc-in [:js-face :alpha] %)
           {:a 0 :b 1 :duration 1}
           #(swap! state assoc-in [:js-core :alpha] %)
-          {:a 1 :b 1.5 :duration 1}
+          {:a 1 :b 2 :duration 2}
           #(swap! state assoc-in [:cam :zoom] %)
           ))))


this link doesn't exist

this link doesn't exist

--- src/klangmeister/ui/about.cljs
+++ src/klangmeister/ui/about.cljs
@@ -13,6 +13,6 @@
      [:p "Klangmeister is a live coding environment for the browser. It lets you design synthesisers and compose music using
          computer code - without having to install anything on your own computer. Klangmeister works best in Chrome, because
          the synthesis features that it relies on have patchy support across the other browsers."]
-     [:p [:a {:href "https://twitter.com/ctford"} "I"] " recommend starting with the " [:a {:href "/synthesis"} "synthesis tutorial"] "."]
+     [:p [:a {:href "https://twitter.com/ctford"} "I"] " recommend starting with the " [:a {:href "/klangmeister/synthesis"} "synthesis tutorial"] "."]
      [editor/render :about code handle! @state-atom]
      [controls :about handle! @state-atom]]))


Fix issue #126 with Leiningen 2.5.0 due to auto-cleaning of targets

--- src/leiningen/ring/uberjar.clj
+++ src/leiningen/ring/uberjar.clj
@@ -2,12 +2,21 @@
   (:use [leiningen.ring.util :only (ensure-handler-set!)]
         [leiningen.ring.server :only (add-server-dep)])
   (:require [leiningen.ring.jar :as jar]
+            [leiningen.clean :as clean]
             leiningen.uberjar))
+
+(defn- no-uberjar-clean [project]
+  "Modifies the uberjar profile so that no auto-clean is performed
+  when leiningen takes control, thus avoiding the autogenerated main files
+  from being wiped."
+  (vary-meta project assoc-in [:profiles :uberjar :auto-clean] false))

 (defn uberjar
   "Create an executable $PROJECT-$VERSION.jar file with dependencies."
   [project]
   (ensure-handler-set! project)
-  (let [project (-> project add-server-dep jar/add-main-class)]
+  (when (:auto-clean project true)
+    (clean/clean project))
+  (let [project (-> project add-server-dep jar/add-main-class no-uberjar-clean)]
     (jar/compile-main project)
     (leiningen.uberjar/uberjar project)))


finish speccing voke.entity

finish speccing voke.entity

--- src/voke/entity.cljs
+++ src/voke/entity.cljs
@@ -1,20 +1,15 @@
 (ns voke.entity
-  (:require [cljs.spec :as s]
-            [voke.schemas :refer [Input Entity Weapon]])
-  (:require-macros [schema.core :as sm]))
+  (:require [cljs.spec :as s]))
+
+;; Specs
+
+(s/def :entity/id int?)

 (s/def :geometry/x (s/and number? pos?))
 (s/def :geometry/y (s/and number? pos?))
 (s/def :geometry/vector2 (s/keys :req [:geometry/x :geometry/y]))
 (s/def :geometry/direction (s/nilable number?))

-;;; Specs
-
-(s/def :entity/id int?)
-
-
-; Component specs
-
 (s/def :shape/type #{:rectangle})
 (s/def :shape/width number?)
 (s/def :shape/height number?)
@@ -24,9 +19,8 @@
                                 :opt [:shape/width :shape/height]))

 (s/def :input/intended-direction #{:up :left :down :right})
-(s/def :input/intended-direction-set (s/coll-of :input/intended-direction :kind set?))
-(s/def :input/intended-move-direction :input/intended-direction-set)
-(s/def :input/intended-fire-direction :input/intended-direction-set)
+(s/def :input/intended-move-direction (s/coll-of :input/intended-direction :kind set?))
+(s/def :input/intended-fire-direction (s/coll-of :input/intended-direction))

 (s/def :component/input (s/keys :req [:input/intended-move-direction :input/intended-fire-direction]))

@@ -45,12 +39,16 @@
 (s/def :weapon/last-attack-timestamp int?)
 (s/def :weapon/fire-direction :geometry/direction)
 (s/def :weapon/shots-per-second int?)
+(s/def :weapon/shot-speed (s/and number? pos?))
+(s/def :weapon/projectile-color number?)
 (s/def :weapon/projectile-shape (s/keys :req [:shape/type]
                                         :opt [:shape/width :shape/height]))

 (s/def :component/weapon (s/keys :req [:weapon/last-attack-timestamp
                                        :weapon/fire-direction
                                        :weapon/shots-per-second
+                                       :weapon/shot-speed
+                                       :weapon-projectile-color
                                        :weapon/projectile-shape]))

 (s/def :collision/type #{:good-guy
@@ -83,7 +81,7 @@
                                     :component/weapon
                                     :component/input]))

-
+;; Private functions

 (defonce next-entity-id (atom 0))

@@ -92,89 +90,114 @@
     (swap! next-entity-id inc)
     id-to-return))

-(sm/defn make-entity :- Entity
+(s/fdef get-next-entity-id
+  :ret :entity/id)
+
+(defn make-entity
   [entity-map]
   (assoc entity-map :id (get-next-entity-id)))

-(sm/defn make-input :- Input
+(s/fdef make-entity
+  :ret :entity/entity)
+
+(defn make-input
   []
   {:intended-move-direction #{}
    :intended-fire-direction []})

-(sm/defn make-weapon :- Weapon
+(s/fdef make-input
+  :ret :component/input)
+
+(defn make-weapon
   [fire-direction projectile-color]
-  {:last-attack-timestamp 0
-   ; XXXX nuke fire-direction arg, just temporary thing for testing
-   :fire-direction        fire-direction
-   :shots-per-second      21
-   :shot-speed            5
-   :projectile-color      projectile-color
-   :projectile-shape      {:type   :rectangle
-                           :width  10
-                           :height 10}})
+  #:weapon {:last-attack-timestamp 0
+            ; XXXX nuke fire-direction arg, just temporary thing for testing
+            :fire-direction        fire-direction
+            :shots-per-second      21
+            :shot-speed            5
+            :projectile-color      projectile-color
+            :projectile-shape      #:shape {:type   :rectangle
+                                            :width  10
+                                            :height 10}})
+
+(s/fdef make-weapon
+  :ret :component/weapon)

 ;; Public

-(sm/defn player :- Entity
+(defn player
   [x y]
   (make-entity
-    {:shape       {:width  25
-                   :height 25
-                   :type   :rectangle
-                   :center {:x x :y y}}
-     :motion      {:velocity             {:x 0 :y 0}
-                   :affected-by-friction true
-                   :direction            nil
-                   :max-acceleration     2.0
-                   :max-speed            11}
-     :collision   {:type :good-guy}
-     :render-info {:fill 0x333333}
-     :weapon      (make-weapon nil 0x666666)
-     :input       (make-input)}))
-
-(sm/defn monster :- Entity
+    #:component {:shape     {:shape/width  25
+                             :shape/height 25
+                             :shape/type   :rectangle
+                             :shape/center {:x x :y y}}
+                 :motion    {:motion/velocity             {:x 0 :y 0}
+                             :motion/affected-by-friction true
+                             :motion/direction            nil
+                             :motion/max-acceleration     2.0
+                             :motion/max-speed            11}
+                 :collision {:collision/type :good-guy}
+                 :render    {:render/fill 0x333333}
+                 :weapon    (make-weapon nil 0x666666)
+                 :input     (make-input)}))
+
+(s/fdef player
+  :ret :entity/entity)
+
+(defn monster
   [x y]
   (make-entity
-    {:shape       {:width  25
-                   :height 25
-                   :type   :rectangle
-                   :center {:x x :y y}}
-     :motion      {:velocity             {:x 0 :y 0}
-                   :affected-by-friction true
-                   :direction            nil
-                   :max-acceleration     1.5
-                   :max-speed            4}
-     :collision   {:type :bad-guy}
-     :weapon      nil #_(make-weapon (- (/ Math/PI 2))
-                                     0xFF0A00)
-     ; xxx not schema'd / standardized yet, these are just some example values
-     :ai          {:movement :basic
-                   :attack   :basic}
-     :render-info {:fill 0xB22822}}))
-
-(sm/defn wall :- Entity
+    #:component {:shape     {:shape/width  25
+                             :shape/height 25
+                             :shape/type   :rectangle
+                             :shape/center {:x x :y y}}
+                 :motion    {:motion/velocity             {:x 0 :y 0}
+                             :motion/affected-by-friction true
+                             :motion/direction            nil
+                             :motion/max-acceleration     1.5
+                             :motion/max-speed            4}
+                 :collision {:collision/type :bad-guy}
+                 ;:weapon      nil
+                 #_(make-weapon (- (/ Math/PI 2))
+                                0xFF0A00)
+                 ; xxx not spec'd / standardized yet, these are just some example values
+                 :ai        {:movement :basic
+                             :attack   :basic}
+                 :render    {:render/fill 0xB22822}}))
+
+(s/fdef monster
+  :ret :entity/entity)
+
+(defn wall
   [x y width height]
   (make-entity
-    {:shape       {:width  width
-                   :height height
-                   :type   :rectangle
-                   :center {:x x :y y}}
-     :collision   {:type :obstacle}
-     :render-info {:fill 0x333333}}))
-
-(sm/defn projectile :- Entity
+    #:component {:shape     {:shape/width  width
+                             :shape/height height
+                             :shape/type   :rectangle
+                             :shape/center {:x x :y y}}
+                 :collision {:collision/type :obstacle}
+                 :render    {:render/fill 0x333333}}))
+
+(s/fdef wall
+  :ret :entity/entity)
+
+(defn projectile
   [owner-id position collides-with projectile-shape projectile-color x-velocity y-velocity]
   (make-entity
-    {:shape       (assoc projectile-shape
-                         :center position)
-     :owner-id    owner-id
-     :collision   {:type                 :projectile
-                   :collides-with        collides-with
-                   :destroyed-on-contact true}
-     :render-info {:fill projectile-color}
-     :motion      {:velocity             {:x x-velocity
-                                          :y y-velocity}
-                   :direction            nil
-                   :affected-by-friction false
-                   :max-speed            (max x-velocity y-velocity)
-                   :max-acceleration     0}}))
+    #:component {:shape     (assoc projectile-shape
+                                   :shape/center position)
+                 :owned     {:owner/id owner-id}
+                 :collision {:collision/type                 :projectile
+                             :collision/collides-with        collides-with
+                             :collision/destroyed-on-contact true}
+                 :render    {:render/fill projectile-color}
+                 :motion    {:motion/velocity             {:x x-velocity
+                                                           :y y-velocity}
+                             :motion/direction            nil
+                             :motion/affected-by-friction false
+                             :motion/max-speed            (max x-velocity y-velocity)
+                             :motion/max-acceleration     0}}))
+
+(s/fdef projectile
+  :ret :entity/entity)


Allo to play against alamo

Allo to play against alamo

--- src/obb_demo/views/player.cljs
+++ src/obb_demo/views/player.cljs
@@ -9,6 +9,7 @@
             [obb-demo.processor :as processor]
             [obb-demo.views.power-bar :as power-bar]
             [obb-rules.ai.firingsquad :as firingsquad]
+            [obb-rules.ai.alamo :as alamo]
             [obb-rules.math :as math]
             [obb-rules.game-mode :as game-mode]
             [obb-rules.laws :as laws]
@@ -48,10 +49,10 @@

 (defn- players
   "Displays the players and the current to play"
-  [game]
+  [game-data game]
   (let [player (game/state game)]
     [:div
-      [(selected-player player :p2) "Firingsquad"]
+      [(selected-player player :p2) (or (:bot game-data) "Firingsquad")]
       " vs "
       [(selected-player player :p1) "Player 1"]]))

@@ -83,12 +84,21 @@
 (defn- reset-turn
   "Resets the actions on the current turn"
   [game-data]
-  (state/set-page-data! {:game (dissoc (:original-game game-data) :action-results)
+  (state/set-page-data! {:game (-> (:original-game game-data)
+                                   (dissoc :action-results)
+                                   (dissoc :removed-elements))
                          :original-game (:original-game game-data)
                          :previous-game (:original-game game-data)
                          :previous-player :p2
+                         :bot (:bot game-data)
                          :action-points 0
                          :turn-num 0}))
+
+(defn- bot-turn
+  [game-data game]
+  (if (= "Alamo" (:bot game-data))
+    (alamo/actions game :p2)
+    (firingsquad/actions game :p2)))

 (defn- play-turn
   "Resets the actions on the current turn"
@@ -98,7 +108,7 @@
                  (game-mode/process)
                  (dissoc :action-results))
         turn-num (:turn-num game-data)
-        actions (firingsquad/actions game :p2)
+        actions (time (bot-turn game-data game))
         result (turn/process-actions game :p2 actions)]
     (println actions)
     (if (result/succeeded? result)
@@ -108,6 +118,7 @@
                                :original-game new-game
                                :previous-game new-game
                                :previous-player :p2
+                               :bot (:bot game-data)
                                :action-points 0
                                :turn-num (+ 1 turn-num)}))
         (println result))))
@@ -216,6 +227,20 @@
        ]]
   )))

+(defn- set-bot
+  "Sets the current bot to play"
+  [game-data ev]
+  (if (= 0 (-> ev .-target .-selectedIndex))
+    (state/set-page-data! (assoc game-data :bot "Firingsquad"))
+    (state/set-page-data! (assoc game-data :bot "Alamo"))))
+
+(defn- challenger-selector
+  "Selects the bot to play"
+  [game-data]
+  [:select {:value (or (:bot game-data) "Firingsquad")
+            :on-change (partial set-bot game-data)}
+   [:option "Firingsquad"]
+   [:option "Alamo"]])

 (defn render
   [state]
@@ -223,8 +248,9 @@
         game (:game game-data)]
     [:div.row
       [:div.col-lg-2
+       (challenger-selector game-data)
        (game-turn game-data)
-       (players game)
+       (players game-data game)
        (power-bar/render game)
        (action-points game-data)
        [:button.btn.btn-primary {:on-click (partial play-turn game-data)} "Play turn"]


Add multiple metrics when seeding usages

--- ssclj/jar/src/test/clojure/com/sixsq/slipstream/ssclj/usage/seeds/usages.clj
+++ ssclj/jar/src/test/clojure/com/sixsq/slipstream/ssclj/usage/seeds/usages.clj
@@ -13,17 +13,19 @@
   (str (time/plus (time/today-at-midnight) (time/days n))))

 (defn- daily-usage
-  [username cloud day-number metric-name metric-value]
+  [username cloud day-number metrics-map]
   {:user            username
    :cloud           cloud
    :start_timestamp (days-from-now day-number)
    :end_timestamp   (days-from-now (inc day-number))
-   :usage           {metric-name {:unit_minutes metric-value}}})
+   :usage           (->> metrics-map
+                         (map (fn [[k v]] {k {:unit_minutes v}}))
+                         (into {}))})

 (defn usages
   [nb username clouds]
   (for [day-number (range nb) cloud clouds]
-    (daily-usage (name username) cloud day-number :ram 100.0)))
+    (daily-usage (name username) cloud day-number {:ram 100.0 :disk 140000 :cpu 8})))

 (defn insert-to-db
   [usages]


cleanup

cleanup

--- test/babel/test/it.cljc
+++ test/babel/test/it.cljc
@@ -3,7 +3,7 @@
   (:require
    [babel.directory :refer [models]]
    [babel.generate :as generate]
-   [babel.italiano :as italiano :refer [create-model morph preprocess]]
+   [babel.italiano :as italiano :refer [morph preprocess]]
    [babel.italiano.grammar :as grammar]
    [babel.italiano.lexicon :as lexicon]
    [babel.italiano.morphology :as morph :refer [analyze-regular]]


Fix tests related to last changes on hmac and poly1305 mac.

--- test/buddy/test_buddy_core_mac.clj
+++ test/buddy/test_buddy_core_mac.clj
@@ -28,8 +28,8 @@
         path      "test/_files/pubkey.ecdsa.pem"]

     (testing "Multiple sign using hmac sha256"
-      (is (Arrays/equals (hmac/hmac "foo" secretkey :sha256)
-                         (hmac/hmac "foo" secretkey :sha256))))
+      (is (Arrays/equals (hmac/hash "foo" secretkey :sha256)
+                         (hmac/hash "foo" secretkey :sha256))))

     (testing "Test Vector"
       (let [key (hex->bytes (str "aaaaaaaaaaaaaaaaaaaaaaaaaa"
@@ -45,26 +45,26 @@
                                  "aa"))
             data (str->bytes "Test Using Larger Than Block-Size Key - Hash Key First")
             result "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54"]
-        (is (= result (bytes->hex (hmac/hmac data key :sha256))))))
+        (is (= result (bytes->hex (hmac/hash data key :sha256))))))

     (testing "Sign/Verify string"
-      (let [sig (hmac/hmac "foo" secretkey :sha384)]
+      (let [sig (hmac/hash "foo" secretkey :sha384)]
         (is (true? (hmac/verify "foo" sig secretkey :sha384)))))

     (testing "Sign/Verify input stream"
-      (let [sig (hmac/hmac (io/input-stream path) secretkey :sha512)]
+      (let [sig (hmac/hash (io/input-stream path) secretkey :sha512)]
         (is (true? (hmac/verify (io/input-stream path) sig secretkey :sha512)))))

     (testing "Sign/Verify file"
-      (let [sig (hmac/hmac (java.io.File. path) secretkey :sha512)]
+      (let [sig (hmac/hash (java.io.File. path) secretkey :sha512)]
         (is (true? (hmac/verify (java.io.File. path) sig secretkey :sha512)))))

     (testing "Sign/Verify url"
-      (let [sig (hmac/hmac (.toURL (java.io.File. path)) secretkey :sha512)]
+      (let [sig (hmac/hash (.toURL (java.io.File. path)) secretkey :sha512)]
         (is (true? (hmac/verify (.toURL (java.io.File. path)) sig secretkey :sha512)))))

     (testing "Sign/Verify uri"
-      (let [sig (hmac/hmac (.toURI (java.io.File. path)) secretkey :sha512)]
+      (let [sig (hmac/hash (.toURI (java.io.File. path)) secretkey :sha512)]
         (is (true? (hmac/verify (.toURI (java.io.File. path)) sig secretkey :sha512)))))

     (testing "Sign/Verify salted hmac with string"
@@ -72,38 +72,27 @@
         (is (true? (shmac/verify "foo" sig secretkey "salt" :sha256)))))))

 (deftest buddy-core-mac-poly1305
-  (let [iv        (byte-array 16) ;; 16 bytes array filled with 0
-        plaintext "text"
+  (let [plaintext "text"
         secretkey "secret"]
     (testing "Poly1305 encrypt/verify (using string key)"
-      (let [mac-bytes1 (poly/poly1305 plaintext secretkey iv :aes)
-            mac-bytes2 (poly/poly1305 plaintext secretkey iv :aes)]
-      (is (= (Arrays/equals mac-bytes1 mac-bytes2)))))
+      (let [mac-bytes1 (poly/poly1305 plaintext secretkey :aes)
+            mac-bytes2 (poly/poly1305 plaintext secretkey :aes)]
+        (is (not (Arrays/equals mac-bytes1 mac-bytes2))))

-  (testing "Poly1305 explicit encrypt/verify (using string key)"
-    (let [mac-bytes1 (poly/poly1305 plaintext secretkey iv :aes)]
-      (is (= (-> mac-bytes1 (bytes->hex)) "98a94ff88861bf9b96bcb7112b506579"))))
+      (let [mac-bytes1 (poly/hash plaintext secretkey :aes)
+            mac-bytes2 (poly/hash plaintext secretkey :aes)]
+        (is (not (Arrays/equals mac-bytes1 mac-bytes2)))))

   (testing "File mac"
     (let [path       "test/_files/pubkey.ecdsa.pem"
-          macbytes   (poly/poly1305 (io/input-stream path) secretkey iv :aes)]
-      (is (poly/verify (io/input-stream path) macbytes secretkey iv :aes))))
-
-  (testing "Poly1305-AES enc/verify using key with good iv"
-    (let [iv1      (make-random-bytes 16)
-          iv2      (make-random-bytes 16)
-          macbytes (poly/poly1305 plaintext secretkey iv1 :aes)]
-      (is (poly/verify plaintext macbytes secretkey iv1 :aes))
-      (is (not (poly/verify plaintext macbytes secretkey iv2 :aes)))))
+          macbytes   (poly/poly1305 (io/input-stream path) secretkey :aes)]
+      (is (poly/verify (io/input-stream path) macbytes secretkey :aes))))

   (testing "Poly1305-Twofish env/verify"
-    (let [iv2 (make-random-bytes 16)
-          signature (poly/poly1305 plaintext secretkey iv2 :twofish)]
-      (is (poly/verify plaintext signature secretkey iv2 :twofish))
-      (is (not (poly/verify plaintext signature secretkey iv :twofish)))))
+    (let [signature (poly/poly1305 plaintext secretkey :twofish)]
+      (is (poly/verify plaintext signature secretkey :twofish))))

   (testing "Poly1305-Serpent env/verify"
-    (let [iv2 (make-random-bytes 16)
-          signature (poly/poly1305 plaintext secretkey iv2 :serpent)]
-      (is (poly/verify plaintext signature secretkey iv2 :serpent))
-      (is (not (poly/verify plaintext signature secretkey iv :serpent)))))))
+    (let [signature (poly/poly1305 plaintext secretkey :serpent)]
+      (is (poly/verify plaintext signature secretkey :serpent))))
+))


fixed query test

fixed query test

--- test/ctia/stores/es/query_test.clj
+++ test/ctia/stores/es/query_test.clj
@@ -25,7 +25,8 @@

 (deftest indicators-by-judgements-query-test
   (is (= {:filtered
-          {:filter
+          {:query {:match_all {}}
+           :filter
            {:bool
             {:must
              {:terms


Refactor deflog

Refactor deflog


We can't make an assertion this accurate when using tagged constraints.

--- test/onyx/log/generators.clj
+++ test/onyx/log/generators.clj
@@ -205,6 +205,11 @@

              (not= (set (:jobs old-replica))
                    (set (:jobs new-replica)))
+
+             ;; All bets are off about churn when using tags since
+             ;; we can't use our typical jitter constraints in BtrPlace.
+             (some (set (:jobs new-replica))
+                   (set (keys (:required-tags new-replica))))

              (<= n-reallocations n-expected-reallocs))
             (pr-str (format "Potentionally bad reallocations. Expected %s, actually performed %s"


defonce

defonce

--- examples/src/famous_examples/core.cljs
+++ examples/src/famous_examples/core.cljs
@@ -5,11 +5,11 @@
 (enable-console-print!)

-(def famous js/famous)
-(def DOMElement (.. famous -domRenderables -DOMElement))
-(def FamousEngine (.. famous -core -FamousEngine))
+(defonce famous js/famous)
+(defonce DOMElement (.. famous -domRenderables -DOMElement))
+(defonce FamousEngine (.. famous -core -FamousEngine))

-(def logo (.. FamousEngine createScene addChild))
+(defonce logo (.. FamousEngine createScene addChild))
 (.. (DOMElement. logo (clj->js {"tagName" 'img})) (setAttribute "src" "./images/famous_logo.png"))

 (.. logo
@@ -20,20 +20,19 @@
     (setOrigin 0.5 0.5)
     )

-(def spinner (.. logo (addComponent (clj->js {:onUpdate          (fn [time]
-                                                                     (.. logo
-                                                                         (setRotation 0 (/ time 1000.0))
-                                                                         (requestUpdateOnNextTick spinner))
-                                                                     (println "time=" time))
-                                              :onMount           (fn [node]
-                                                                     (println "onMount called: " (.. node getLocation))
-                                                                     )
-                                              :onTransformChange (fn []
-                                                                     (println "onTransformChange called")
-                                                                     )}
-                                             ))))
-
-(.. logo (requestUpdate spinner))
+(defonce spinner (clj->js {:onUpdate          (fn [time]
+                                                  (.. logo
+                                                      (setRotation 0 (/ time 1000.0))
+                                                      (requestUpdateOnNextTick spinner-id)))
+                           :onMount           (fn [node]
+                                                  (println "onMount called: " (.. node getLocation))
+                                                  )
+                           :onTransformChange (fn []
+                                                  (println "onTransformChange called")
+                                                  )}
+                          ))
+(defonce spinner-id (.. logo (addComponent spinner)))
+(.. logo (requestUpdateOnNextTick spinner-id))
 (.. FamousEngine init)

 ;(reagent/render [msg] (.. js/document (getElementById "msg")))


Took out unecessary function decrlation

Took out unecessary function decrlation

--- src/polismath/conversation.clj
+++ src/polismath/conversation.clj
@@ -344,7 +344,6 @@
 (def large-conv-update (eager-profiled-compiler large-conv-update-graph))

-(declare conv-update-dump)
 (defn conv-update
   "This function dispatches to either small- or large-conv-update, depending on the number
   of participants (as decided by call to sample-size-fn)."


(EZ-124) Use consistent timestamps

(EZ-124) Use consistent timestamps

We use timestamps for two separate parts of the `stage` action. Since
the timestamps only record the time to the minute, this only causes
issues when the timing is just right, but when it does it leads to
a mismatch in package version and the directory the packages are shipped
to.

This commit updates the stage action to generate the timestamp once and
pass it through to the functions that ultimately end up setting the
release field in ezbake.rb and tagging the git repo so we can be sure
we're using the same timestamp for both.

--- src/puppetlabs/ezbake/core.clj
+++ src/puppetlabs/ezbake/core.clj
@@ -446,13 +446,13 @@
       (str/replace "-" ".")))

 (defn generate-git-tag-from-version
-  [lein-version]
+  [lein-version timestamp]
   {:pre [(string? lein-version)]
    :post [(string? %)]}
   (if (.endsWith lein-version "-SNAPSHOT")
     (format "%s.%s"
             (str/replace lein-version "-" ".")
-            (get-timestamp-string))
+            timestamp)
     lein-version))

 (defn generate-package-version-from-version
@@ -465,13 +465,13 @@
     lein-version))

 (defn generate-package-release-from-version
-  [lein-version]
+  [lein-version timestamp]
   {:pre [(string? lein-version)]
    :post [(string? %)]}
   (if (.endsWith lein-version "-SNAPSHOT")
     (format "%s.%s"
             (str/replace lein-version #".*-" "0.1")
-            (get-timestamp-string))
+            timestamp)
     "1"))

 ;; TODO: this is a horrible, horrible hack; I can't yet see a good way to
@@ -479,14 +479,14 @@
 ;; up a git tag; it seems like the packaging code is pretty well hard-coded
 ;; to try to pull this info from git.
 (defn create-git-repo
-  [lein-project]
+  [lein-project timestamp]
   (lein-main/info "Creating temporary git repo")
   (exec/exec "git" "init" staging-dir)
   (lein-main/info "Adding all files to git repo")
   (staging-dir-git-cmd "add" "*")
   (lein-main/info "Committing git repo")
   (staging-dir-git-cmd "commit" "-m" "'Temporary git repo to house packaging code'")
-  (let [git-tag (generate-git-tag-from-version (:version lein-project))]
+  (let [git-tag (generate-git-tag-from-version (:version lein-project) timestamp)]
     (lein-main/info "Tagging git repo at" git-tag)
     (staging-dir-git-cmd "tag" "-a" git-tag "-m" "Tag for packaging code")))

@@ -505,7 +505,7 @@

 (defn make-template-map
   "Construct the map of variables to pass on to the ezbake.rb template"
-  [lein-project build-target config-files system-config-files cli-app-files bin-files terminus-files upstream-ezbake-configs additional-uberjars]
+  [lein-project build-target config-files system-config-files cli-app-files bin-files terminus-files upstream-ezbake-configs additional-uberjars timestamp]
   (let [termini (for [[name version files] terminus-files]
                   {:name name
                    :version version
@@ -519,7 +519,7 @@
                                                       variable)))]
     {:project                            (:name lein-project)
      :packaging-version                  (generate-package-version-from-version (:version lein-project))
-     :packaging-release                  (generate-package-release-from-version (:version lein-project))
+     :packaging-release                  (generate-package-release-from-version (:version lein-project) timestamp)
      :real-name                          (get-real-name (:name lein-project))
      :user                               (get-local-ezbake-var lein-project :user
                                                       (:name lein-project))
@@ -595,7 +595,8 @@
    bin-files
    terminus-files
    upstream-ezbake-configs
-   additional-uberjars]
+   additional-uberjars
+   timestamp]
   (lein-main/info "generating ezbake config file")
   (spit
    (fs/file staging-dir "ezbake.rb")
@@ -609,7 +610,8 @@
                        bin-files
                        terminus-files
                        upstream-ezbake-configs
-                       additional-uberjars))))
+                       additional-uberjars
+                       timestamp))))

 (defn generate-project-data-yaml
   [lein-project build-target additional-uberjars]
@@ -821,7 +823,8 @@
           terminus-files  (cp-terminus-files dependencies build-target)
           upstream-ezbake-configs (get-upstream-ezbake-configs lein-project)
           additional-uberjar-info (build-additional-uberjars! lein-project)
-          additional-uberjar-filenames (map #(fs/base-name (:uberjar %)) additional-uberjar-info)]
+          additional-uberjar-filenames (map #(fs/base-name (:uberjar %)) additional-uberjar-info)
+          timestamp (get-timestamp-string)]
       (cp-shared-files dependencies get-cli-defaults-files-in)
       (cp-shared-files dependencies get-build-scripts-files-in)
       (if cli-app-files
@@ -837,12 +840,13 @@
                                     bin-files
                                     terminus-files
                                     upstream-ezbake-configs
-                                    additional-uberjar-filenames)
+                                    additional-uberjar-filenames
+                                    timestamp)
       (let [project-w-deployed-version (assoc lein-project :version deployed-version)]
         (generate-project-data-yaml project-w-deployed-version build-target additional-uberjar-filenames)
         (generate-manifest-file project-w-deployed-version additional-uberjar-info))
       (generate-build-metadata-files lein-project)
-      (create-git-repo lein-project))))
+      (create-git-repo lein-project timestamp))))

 (defmethod action "build"
   [_ lein-project build-target]


Bump db version after citation-needed fix

--- src-clj/acha/db.clj
+++ src-clj/acha/db.clj
@@ -9,7 +9,7 @@
     [acha.achievement-static :as static])
   (:import com.mchange.v2.c3p0.ComboPooledDataSource))

-(def ^:const ^:private db-version "0.2.3")
+(def ^:const ^:private db-version "0.2.4")

 (def ^:private gen-id-key (keyword "last_insert_rowid()"))


Add parse-binary-file function

Add parse-binary-file function

Signed-off-by: Yen-Chin Lee <082d453d72dce940e12089a4ad48b97cfe1f3ec4@gmail.com>

--- src/emulator_4917/core.cljc
+++ src/emulator_4917/core.cljc
@@ -1,7 +1,8 @@
 (ns emulator-4917.core
   (:require #?(:cljs [cljs.nodejs :as nodejs])
             #?(:cljs [goog.crypt :as gcrypt])
-            [clojure.string :as str]))
+            [clojure.string :as str])
+  #?(:clj (:gen-class)))

 ;; enable *print-fn* in clojurescript
 #?(:cljs (enable-console-print!))
@@ -174,21 +175,23 @@
         l (bit-and s 0x0f)]                    ;; 0xf4 & 0x0f => 4
     [h l]))

+(defn parse-binary-file
+  [file]
+  #?(:clj
+     (with-open [out (java.io.ByteArrayOutputStream.)]
+       (clojure.java.io/copy (clojure.java.io/input-stream file) out)
+       (.toByteArray out))
+     :cljs
+     (->  (nodejs/require "fs")
+          (.readFileSync file "binary")
+          .toString
+          gcrypt/stringToByteArray)))
+
 (defn parse-rom
   "Parse binary file and convert contents to vector."
   [file]
   (flatten
-   (map to-4bit-array
-        #?(:clj
-           (with-open [out (java.io.ByteArrayOutputStream.)]
-             (clojure.java.io/copy (clojure.java.io/input-stream file) out)
-             (.toByteArray out))
-           :cljs
-           (->  (nodejs/require "fs")
-                (.readFileSync file "binary")
-                .toString
-                gcrypt/stringToByteArray))
-        )))
+   (map to-4bit-array (parse-binary-file file))))

 (defn -main [& args]
   (let [arg1 (nth args 0)]


more docs

more docs

--- src/advent/core.clj
+++ src/advent/core.clj
@@ -215,7 +215,8 @@

 (defn build-circuit
   "returns a map of input's data
-  Usage: (build-circuit \"day-7-data.txt\")"
+  Usage: (build-circuit \"day-7-data.txt\")
+  {:i [\"NOT\" \"y\"], :h [\"NOT\" \"x\"], :g [\"y\" \"RSHIFT\" \"2\"], :f [\"x\" \"LSHIFT\" \"2\"], :e [\"x\" \"OR\" \"y\"], :d [\"x\" \"AND\" \"y\"], :y :456, :x :123}"
   [circuit-input]
   (map-values (parse-circuit-data-into-map (str/split (slurp circuit-input) #"\n")) single-values-to-keywords))


improved move counter

improved move counter

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -221,7 +221,7 @@

 (om/root
-    (fn [{:keys [stream cells win-state moves tick-ms grid-size media-error? show-nums] :as app} _]
+    (fn [{:keys [stream cells win-state moves tick tick-ms grid-size media-error? show-nums] :as app} _]
       (reify
         om/IDidMount
         (did-mount [_]
@@ -259,9 +259,9 @@
                     (when (= cells win-state)
                       (dom/h1 nil "You win!"))

-                    (dom/p
+                    (dom/label
                       #js {:className "move-count"}
-                      (str move-count " move" (when (> move-count 1) "s")))
+                      (str (inc tick) \/ move-count))

                     (dom/label nil "show numbers?")
                     (dom/input #js {


Enhanced docstring for set-of

Enhanced docstring for set-of

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

--- src/conexp/util.clj
+++ src/conexp/util.clj
@@ -296,7 +296,21 @@
   `(not ~(expand-bindings (map vec (partition 2 bindings)) `(not ~condition))))

 (defmacro set-of
-  "Macro for writing sets as mathematicians do (at least similar to it.)"
+  "Macro for writing sets as mathematicians do (at least similar to
+  it.) The following syntax constructions are supported:
+
+    (set-of x [x [1 2 3]])
+      for the set of all x with x in [1 2 3]
+
+    (set-of x | x [1 2 3])
+      for the same set
+
+    (set-of [x y] [x [1 2 3], y [4 5 6] :when (= 1 (gcd x y))])
+      for the set of all pairs [x y] with x in [1 2 3], y in [4 5 6]
+      and x and y are coprime.
+
+  In general, the condition vector (or the sequence after |) must be
+  suitable for doseq."
   [thing & condition]
   (let [condition (if (= '| (first condition))
                     (vec (rest condition))


Fixed tests.

Fixed tests.

--- app/test/clj_web_example/test_utils.clj
+++ app/test/clj_web_example/test_utils.clj
@@ -18,7 +18,7 @@

 (defn get-database
   []
-  (get-in test-utils/test-system [:mongodb :database]))
+  (get-in test-system [:mongodb :database]))

 (defn http-get
   [url]


changed to init the StringBuilder with a size

--- src/gif_to_html/convert.clj
+++ src/gif_to_html/convert.clj
@@ -17,10 +17,10 @@
         idx (if (zero? max-color) max-items (int (* max-items (/ max-color 255))))]
     (nth ascii (max idx 0))))

-(defn to-ascii [^BufferedImage img]
+(defn to-ascii [^BufferedImage img ^Integer size]
   (let [width  (.getWidth img)
         height (.getHeight img)
-        sb     (StringBuilder.)]
+        sb     (StringBuilder. size)]
     (dotimes [y height]
       (dotimes [x width]
         (.append sb (ascii-color img y x)))
@@ -44,7 +44,7 @@
     (catch Exception _ 0)))

 (defn gif->html [input]
-  (let [rdr  ^ ImageReader (.next (ImageIO/getImageReadersByFormatName "gif"))
+  (let [rdr  ^ImageReader (.next (ImageIO/getImageReadersByFormatName "gif"))
         ciis (ImageIO/createImageInputStream input)]
     (.setInput rdr ciis false)
     (let [frame-count (.getNumImages rdr true)
@@ -62,7 +62,7 @@
                   [:pre
                    {:id (str "frame-" i)
                     :style "font-size:5pt;line-height:5pt;letter-spacing:1px;font-weight:bold;display:none;font-family:monospace;"}
-                   (to-ascii (scale-image (.read ^ImageReader rdr i) w h))])
+                   (to-ascii (scale-image (.read ^ImageReader rdr i) w h) (+ h (* h w)))])
                (range frame-count))])
        :delay  (if (pos? frame-delay) frame-delay 10)
        :frames frame-count})))


fix: brain fart multiply, lets really cleanup

--- src/gml_to_featured/api.clj
+++ src/gml_to_featured/api.clj
@@ -121,7 +121,7 @@

 (defn handle-xml2json-req [stats process-chan http-request]
   "Get the properties from the request and start an async xml2json operation"
-  (future (fs/cleanup-old-files (* 3600 * 24 * config/cleanup-threshold)))
+  (future (fs/cleanup-old-files (* 3600 24 config/cleanup-threshold)))
   (let [request (:body http-request)
         dataset (:dataset request)
         mapping (:mapping request)


Fix commit-details test, just don't check branch

--- test/circle/backend/test_git.clj
+++ test/circle/backend/test_git.clj
@@ -34,7 +34,8 @@
              :author_date "1329447089"
              :committer_name "Paul Biggar"
              :body ""
-             :branch #"remotes/origin/(HEAD|master)~\d+"
+             ;:branch #"remotes/origin/(HEAD|master)~\d+" # this data isn't
+             ;reliable, use the data from github's pushlog instead.
              :committer_email "paul.biggar@gmail.com"}))

 (fact "committer-email works"


Specify the default layout before parse-defaults.

--- src/incise/parsers/html.clj
+++ src/incise/parsers/html.clj
@@ -60,9 +60,9 @@
   [content-fn ^File file]
   (let [file-str (slurp file)
         parse-meta-from-file (read-edn-map-from-beggining-of-string file-str)
-        parse-meta (merge (conf/get :parse-defaults)
-                          {:title (name-without-extension file)
-                           :layout :html-skeleton}
+        parse-meta (merge {:layout :html-skeleton}
+                          (conf/get :parse-defaults)
+                          {:title (name-without-extension file)}
                           parse-meta-from-file)
         content (content-fn (if parse-meta-from-file
                               (second (s/split file-str #"\}" 2))


MMT-1490: update commit hash for preview gem

* updated RelatedUrl enums for UMM-C update to v1.12

--- collection-renderer-lib/project.clj
+++ collection-renderer-lib/project.clj
@@ -14,7 +14,7 @@
    the hardcoded commit id during dev integration with cmr_metadata_preview project.
    The hardcoded commit id should be updated when MMT releases a new version of the gem."
   (or (System/getenv "CMR_METADATA_PREVIEW_COMMIT")
-      "a3d370d2e34"))
+      "a15d2e041b3"))

 (def gem-install-path
   "The directory within this library where Ruby gems are installed."


Convert lat/lon to Double.

Convert lat/lon to Double.

--- src/clj/forma/gfw/cdm.clj
+++ src/clj/forma/gfw/cdm.clj
@@ -105,7 +105,9 @@
 (defn latlon->tile
   [lat lon zoom]
   "Returns tile [x y zoom] corresponding to a lat/lon at the given zoom."
-  (let [alert (Alert. lat lon zoom)
+  (let [lat (Double/parseDouble lat)
+        lon (Double/parseDouble lon)
+        alert (Alert. lat lon zoom)
         tile (get-maptile alert)
         {:keys [coordinate zoom]} tile
         {:keys [x y]} coordinate]


Fix bug introduced with capturing-armor fix

--- src/clj/zetawar/game.cljs
+++ src/clj/zetawar/game.cljs
@@ -973,13 +973,12 @@
                    :unit-type/max-range (:max-range unit-def)
                    :unit-type/armor-type (-> unit-def :armor-type to-armor-type)
                    :unit-type/armor armor
-                   ;; FIXME: this should be getting capturing armor
                    :unit-type/capturing-armor (or capturing-armor armor)
                    :unit-type/repair (:repair unit-def)
                    :unit-type/state-map [:unit-state-map/id unit-state-map-id]
                    :unit-type/image (:image unit-def)}]
-                 (into (attack-strengths-tx db unit-type-eid attack-strengths))
-                 (into (terrain-effects-tx db unit-type-eid terrain-effects))))))
+                 (into (attack-strengths-tx db unit-type-eid (:attack-strengths unit-def)))
+                 (into (terrain-effects-tx db unit-type-eid (:terrain-effects unit-def)))))))
         units-def))

 (defn unit-states-tx [state-map-name states]


Rename SegmentContainer :segments -> :edges

--- src/cljs/fatlip/core.cljs
+++ src/cljs/fatlip/core.cljs
@@ -7,7 +7,7 @@
 (defrecord Node [id layer-id characters])
 (defrecord Edge [src dest characters])
 (defrecord Layer [id duration nodes])
-(defrecord SegmentContainer [segments])
+(defrecord SegmentContainer [edges])
 (defrecord AccumulatorNode [weight node-edges is-seg-c])

@@ -179,7 +179,7 @@

 (defn replace-ps
-  "Step 1 of ESK - replace all p nodes with segments and merge segment containers"
+  "Step 1 of ESK - replace all p nodes with edges and merge segment containers"
   [graph layer]
   (->> (:ordered layer)
        (map #(if (contains? (:p graph) %)
@@ -188,7 +188,7 @@
                %))
        (reduce #(if (and (instance? SegmentContainer (peek %1))
                          (instance? SegmentContainer %2))
-                  (update-in %1 [(dec (count %1)) :segments] rrb/catvec (:segments %2))
+                  (update-in %1 [(dec (count %1)) :edges] rrb/catvec (:edges %2))
                   (conj %1 %2))
                [])
        (assoc layer :minus-ps)))
@@ -199,7 +199,7 @@
   next layer. ESK's description of the position algorithm is almost willfully circuitous
   and obtuse, so here's a simplified description: An item's position in an ordered layer
   is the sum of the size of all previous items, plus 1, where the size of a segment
-  container is the number of segments it contains, and the size of a node is 1.
+  container is the number of edges it contains, and the size of a node is 1.

   Also, it doesn't really matter what seed you choose for the initial value of the sum. I
   chose -1, which is implied by the description in ESK."
@@ -211,7 +211,7 @@
       (assoc layer :positions positions)
       (let [item (first minus-ps)
             c-p (if (instance? SegmentContainer item)
-                  (+ current-position (count (:segments item)))
+                  (+ current-position (count (:edges item)))
                   (inc current-position))]
         (recur (rest minus-ps) c-p (assoc positions item (inc current-position)))))))

@@ -278,12 +278,12 @@
                            node-measure (get measures node-1)
                            seg-position (get pos seg-1)
                            node-first (<= node-measure seg-position)
-                           seg-first (>= node-measure (+ seg-position (count (:segments seg-1))))]
+                           seg-first (>= node-measure (+ seg-position (count (:edges seg-1))))]
                        (cond node-first (recur (rest nodes) segments pos (conj ord node-1))
                              seg-first (recur nodes (rest segments) pos (conj ord seg-1))
                              :else (let [k (.ceil js/Math (- node-measure seg-position))
-                                         s-1 (update-in seg-1 [:segments] rrb/subvec 0 k)
-                                         s-2 (update-in seg-1 [:segments] rrb/subvec k)]
+                                         s-1 (update-in seg-1 [:edges] rrb/subvec 0 k)
+                                         s-2 (update-in seg-1 [:edges] rrb/subvec k)]
                                      (recur
                                       (rest nodes)
                                       (cons s-2 segments)
@@ -299,7 +299,7 @@
   (let [qs (:qs next-layer)
         flat (->> (:minus-qs next-layer)
                   (mapcat #(if (instance? SegmentContainer %)
-                             (:segments %)
+                             (:edges %)
                              [%]))
                   (map #(if (and (instance? Edge %)
                                  (contains? qs (:dest %)))
@@ -309,13 +309,13 @@
                        seg-c (first segment-containers)
                        layer []]
                   (if (empty? f)
-                    (if (empty? (:segments seg-c))
+                    (if (empty? (:edges seg-c))
                       layer
                       (conj layer seg-c))
                     (let [item (first f)]
                       (if (instance? Edge item)
-                        (recur (rest f) (update-in seg-c [:segments] conj item) layer)
-                        (if (empty? (:segments seg-c))
+                        (recur (rest f) (update-in seg-c [:edges] conj item) layer)
+                        (if (empty? (:edges seg-c))
                           (recur (rest f) seg-c (conj layer item))
                           (recur (rest f) (first segment-containers) (conj layer seg-c item)))))))]
     (assoc next-layer :ordered ordered)))
@@ -339,7 +339,7 @@
                    (map (juxt identity
                               (fn [seg-c]
                                 (mapcat #(-> % :characters)
-                                        (:segments seg-c)))))
+                                        (:edges seg-c)))))
                    (map (fn [[seg-c characters]]
                           [seg-c #{(Edge. seg-c seg-c characters)}]))
                    (into {})