added zippers

added zippers

--- src/seqs.clj
+++ src/seqs.clj
@@ -1,4 +1,5 @@
-(ns seqs)
+(ns seqs
+  (:require [clojure.zip :as zip]))

 (def data
   {:headers {"Content-Type" "text/html"}
@@ -6,6 +7,62 @@
           :images "/img/path-to-img.jpg"}})

 (assoc-in data [:body :text] "Hello Planet" )
+
+
+(def matrix [[1 2 3 4 5]
+             ["a" "b" "c" "d" "e"]
+             ["hello" "thanks" "hola" "namaste" "hi"]])
+
+;;;;;;;;;
+;; Zip
+
+;; example from clojure source: zip.clj
+
+(def zip1 [1 '(a b c) 2])
+
+(def root-loc (zip/seq-zip (seq zip1)))
+
+(def data '[[a * b] + [c * d]])
+(def dz (vector-zip data))
+
+(right (down (right (right (down dz)))))
+(lefts (right (down (right (right (down dz))))))
+(rights (right (down (right (right (down dz))))))
+(up (up (right (down (right (right (down dz)))))))
+(path (right (down (right (right (down dz))))))
+
+(-> dz down right right down right)
+(-> dz down right right down right (replace '/) root)
+(-> dz next next (edit str) next next next (replace '/) root)
+(-> dz next next next next next next next next next remove root)
+(-> dz next next next next next next next next next remove (insert-right 'e) root)
+(-> dz next next next next next next next next next remove up (append-child 'e) root)
+
+(end? (-> dz next next next next next next next next next remove next))
+
+(-> dz next remove next remove root)
+
+(loop [loc dz]
+  (if (end? loc)
+    (root loc)
+    (recur (next (if (= '* (node loc))
+                   (replace loc '/)
+                   loc)))))
+
+(loop [loc dz]
+  (if (end? loc)
+    (root loc)
+    (recur (next (if (= '* (node loc))
+                   (remove loc)
+                   loc)))))
+
+(defn print-tree [original]
+  (loop [loc (zip/seq-zip (seq original))]
+    (if (zip/end? loc)
+      (zip/root loc)
+      (recur (zip/next
+                (do (println (zip/node loc))
+                    loc))))))

 ;;;;;;;;;
 ;; pmap


right, so it's because of ns-unmap not defalias

--- src/runtime/q.clj
+++ src/runtime/q.clj
@@ -46,7 +46,7 @@

 (defmacro redefmacro [name & restt]
   `(do
-     (ns-unmap *ns* '~name)
+     ;(ns-unmap *ns* '~name)
      ;(println *ns*)
      ;(ns-unmap (find-ns 'runtime.q) '~name)
      (defmacro ~name ~@restt)


debugger: even cleaner list style

debugger: even cleaner list style

--- examples/_common/middleware/devtools.cljs
+++ examples/_common/middleware/devtools.cljs
@@ -352,8 +352,8 @@
                  :on-click #(dispatch [::on-toggle-action id])}
            [:div {:title "Click to enable/disable this action"}
             (if (coll? action)
-              [:div [:strong (pr-str (first action))] " " (clojure.string/join " " (map pr-str (rest action)))]
-              [:div [:strong (pr-str action)]])]
+              [:div (pr-str (first action)) " " (clojure.string/join " " (map pr-str (rest action)))]
+              [:div (pr-str action)])]

            (when enabled?
              [:div {:style    {:cursor           "pointer"


Add path to Parse.

Add path to Parse.

--- src/incise/parsers/core.clj
+++ src/incise/parsers/core.clj
@@ -12,6 +12,7 @@
                   ^String content
                   ^String date
                   ^String layout
+                  ^String path
                   ^clojure.lang.Seqable tags
                   ^String category])


[fix 7380] bubble width on small devices

--- src/status_im/ui/screens/chat/styles/message/message.cljs
+++ src/status_im/ui/screens/chat/styles/message/message.cljs
@@ -29,13 +29,11 @@
   (let [align (if outgoing :flex-end :flex-start)
         direction (if outgoing :row-reverse :row)]
     (merge {:flex-direction direction
-            :width          230
             :padding-top    (message-padding-top message)
             :align-self     align
             :align-items    align}
            (when display-photo?
-             {:padding-right 8
-              :padding-left  8}))))
+             {:padding-left  8}))))

 (def message-timestamp
   {:font-size      10
@@ -66,8 +64,11 @@
    :font-size   12
    :color       colors/text-gray})

-(defn group-message-wrapper [message]
+(defn group-message-wrapper [{:keys [outgoing] :as message}]
   (merge {:flex-direction :column}
+         (if outgoing
+           {:margin-left 64}
+           {:margin-right 64})
          (last-message-padding message)))

 (defn timestamp-content-wrapper [{:keys [outgoing]}]
@@ -76,11 +77,13 @@
 (defn group-message-view
   [outgoing message-type]
   (let [align (if outgoing :flex-end :flex-start)]
-    {:flex-direction :column
-     :width          320
-     :padding-left   8
-     :padding-right  8
-     :align-items    align}))
+    (merge {:flex 1
+            :flex-direction :column
+            :max-width      320
+            :align-items    align}
+           (if outgoing
+             {:margin-right 8}
+             {:margin-left 8}))))

 (defn delivery-status [outgoing]
   (if outgoing


Supervisor should kill/restart if existing worker has changed assignments

--- storm-core/src/clj/org/apache/storm/daemon/supervisor.clj
+++ storm-core/src/clj/org/apache/storm/daemon/supervisor.clj
@@ -578,7 +578,11 @@
           assigned-storm-ids (assigned-storm-ids-from-port-assignments new-assignment)
           localizer (:localizer supervisor)
           checked-downloaded-storm-ids (set (verify-downloaded-files conf localizer assigned-storm-ids all-downloaded-storm-ids))
-          downloaded-storm-ids (set/difference all-downloaded-storm-ids checked-downloaded-storm-ids)]
+          downloaded-storm-ids (set/difference all-downloaded-storm-ids checked-downloaded-storm-ids)
+          assigned-executors (or (ls-local-assignments local-state) {})
+          allocated (read-allocated-workers supervisor assigned-executors (Time/currentTimeSecs))
+          valid-allocated (filter-val (fn [[state _]] (= state :valid)) allocated)
+          port->worker-id (clojure.set/map-invert (map-val #((nth % 1) :port) valid-allocated))]

       (log-debug "Synchronizing supervisor")
       (log-debug "Storm code map: " storm-code-map)
@@ -611,6 +615,10 @@
       (doseq [p (set/difference (set (keys existing-assignment))
                                 (set (keys new-assignment)))]
         (.killedWorker isupervisor (int p)))
+      (doseq [p (set/intersection (set (keys existing-assignment))
+                                  (set (keys new-assignment)))]
+        (if (not= (:executors (existing-assignment p)) (:executors (new-assignment p)))
+          (shutdown-worker supervisor (port->worker-id p))))
       (.assigned isupervisor (keys new-assignment))
       (ls-local-assignments! local-state
             new-assignment)


(MAINT) Simplify SSL cert generation in tests

This commit updates testutils to use the new jvm-ssl-utils 'simple' API
for generating certificates.

--- test/puppetlabs/trapperkeeper/authorization/testutils.clj
+++ test/puppetlabs/trapperkeeper/authorization/testutils.clj
@@ -1,36 +1,15 @@
 (ns puppetlabs.trapperkeeper.authorization.testutils
-  (:require [puppetlabs.ssl-utils.core :as ssl])
-  (:import (org.joda.time DateTime Period)))
+  (:require [puppetlabs.ssl-utils.simple :as ssl]))

 (defn request
   "Builds a ring request"
   [path method certificate ip]
   {:uri path :request-method method :remote-addr ip :ssl-client-cert certificate})

-;; Extracted from ssl-utils test
-
-(defn- generate-not-before-date []
-  (-> (DateTime/now)
-      (.minus (Period/days 1))
-      (.toDate)))
-
-(defn- generate-not-after-date []
-  (-> (DateTime/now)
-      (.plus (Period/years 5))
-      (.toDate)))
-
 (defn create-certificate
   [cn]
-  (let [subject (ssl/cn cn)
-        key-pair (ssl/generate-key-pair 512)
-        subj-pub (ssl/get-public-key key-pair)
-        issuer (ssl/cn "my ca")
-        issuer-key-pair (ssl/generate-key-pair 512)
-        issuer-priv (ssl/get-private-key issuer-key-pair)
-        not-before (generate-not-before-date)
-        not-after (generate-not-after-date)
-        serial 42]
-    (ssl/sign-certificate issuer issuer-priv serial not-before not-after subject subj-pub)))
+  (let [cacert (ssl/gen-self-signed-cert "my ca" 41 {:keylength 512})]
+    (:cert (ssl/gen-cert cn cacert 42 {:keylength 512}))))

 (def test-domain-cert (create-certificate "test.domain.org"))
 (def test-other-cert (create-certificate "www.other.org"))


added past particple come

added past particple come

--- src/babel/english/lexicon-verbcoach.clj
+++ src/babel/english/lexicon-verbcoach.clj
@@ -505,7 +505,8 @@
    "come" {:synsem {:cat :verb
                     :sem {:pred :come}
                     :subcat {:2 '()}}
-           :english {:past "came"}}
+           :english {:past "came"}
+         {:past-participle "come"}}

    "comment" {:synsem {:cat :verb
                        :sem {:pred :comment}}}


CPPAST -> IAST

CPPAST -> IAST

--- src/atom_finder/ast_spec.clj
+++ src/atom_finder/ast_spec.clj
@@ -1,18 +1,19 @@
 (ns atom-finder.ast-spec
   (:import [org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTLiteralExpression])
+  (:import [org.eclipse.cdt.core.dom.ast IASTLiteralExpression])
   (:require [clojure.spec :as s]
             [clojure.spec.gen :as gen]))

 (def gen-literal-expression-args
  (gen/one-of
   [
-   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_char_constant})
+   (gen/tuple (s/gen #{IASTLiteralExpression/lk_char_constant})
               (gen/char-ascii))
-   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_float_constant})
+   (gen/tuple (s/gen #{IASTLiteralExpression/lk_float_constant})
               (gen/double))
-   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_integer_constant})
+   (gen/tuple (s/gen #{IASTLiteralExpression/lk_integer_constant})
               (s/gen (s/int-in -2147483648 2147483647)))
-   (gen/tuple (s/gen #{CPPASTLiteralExpression/lk_string_literal})
+   (gen/tuple (s/gen #{IASTLiteralExpression/lk_string_literal})
               (gen/string))]))

 (def gen-literal-expression


fix fungsi actualize)

fix fungsi actualize)

--- src/clj/mobile_survey/models/schema.clj
+++ src/clj/mobile_survey/models/schema.clj
@@ -12,4 +12,4 @@
   []
   (empty? (pending-migrations)))

-(defn [] actualize (binding [lm/*src-directory* "src/clj"] (migrate)))
+(defn actualize [] (binding [lm/*src-directory* "src/clj"] (migrate)))


Ensure no nil routes are passed along.

Ensure no nil routes are passed along.

--- src/cmr/plugin/jar/types/web/routes.clj
+++ src/cmr/plugin/jar/types/web/routes.clj
@@ -12,7 +12,9 @@

 (defn resolve-routes
   [routes-symbols]
-  (map #(util/resolve-fully-qualified-fn %) routes-symbols))
+  (->> routes-symbols
+       (map #(util/resolve-fully-qualified-fn %))
+       (remove nil?)))

 (defn plugin-routes
   [^JarFile jarfile in-jar-filepath route-keys ^Keyword api-key ^Keyword site-key]


Remove leftover println

Remove leftover println

--- src/braid/client/router.cljs
+++ src/braid/client/router.cljs
@@ -10,7 +10,6 @@
     {:nav-handler (fn [path]
                     (secretary/dispatch! path))
      :path-exists? (fn [path]
-                     (println "path exists?" path (secretary/locate-route path))
                      (secretary/locate-route path))}))

 (defn dispatch-current-path! []


Don't clobber meta in react dom

Don't clobber meta in react dom

--- src/breeze/quiescent/dom.clj
+++ src/breeze/quiescent/dom.clj
@@ -1,5 +1,5 @@
 (ns breeze.quiescent.dom
-  (:refer-clojure :exclude [map time])
+  (:refer-clojure :exclude [map meta time])
   (:require cljs.tagged-literals)
   (:import (cljs.tagged_literals JSValue)))

@@ -32,7 +32,7 @@
   Props will be converted to plain js objects shallowly (and at compile time if
   possible)."
   ([component]
-   (with-meta `(RE ~component nil) (meta &form)))
+   (with-meta `(RE ~component nil) (clojure.core/meta &form)))
   ([component props & children]
    (let [p (js-props* props)]
      (with-meta `(~'js/React.createElement ~component ~p ~@children) (clojure.core/meta &form)))))


fix problem and add test for throwing an exception when trying to get the speed of an unknown parrot type

--- Clojure/parrot-refactoring/src/parrot_refactoring/core.clj
+++ Clojure/parrot-refactoring/src/parrot_refactoring/core.clj
@@ -14,4 +14,4 @@
     :norwegian-blue-parrot (if (:nailed parrot)
                              0.0
                              (compute-base-speed-for-voltage (:voltage parrot)))
-    (throw "Should be unreachable!")))
+    (throw (Exception. "Should be unreachable!"))))


Fix an exception caused by logging a %s

Fix an exception caused by logging a %s

--- src/circle/backend/build.clj
+++ src/circle/backend/build.clj
@@ -127,10 +127,23 @@

 (def ^:dynamic *log-ns* nil) ;; contains the name of the logger for the current build

+(defn- ssh-build-log
+  "This is a different function from the normal build log because 1)
+  ssh/handle-out won't pass format arguments. 2) if the string does happen to
+  contain a %s, we don't want format throwing because we have a %s and
+  no extra args"
+  [s]
+  (when *log-ns*
+    (log *log-ns* :info nil s)))
+
+(defn- ssh-build-log-error [s]
+  (when *log-ns*
+    (log *log-ns* :error nil s)))
+
 (defmacro with-build-log [build & body]
   `(binding [*log-ns* (log-ns ~build)
-             ssh/handle-out build-log
-             ssh/handle-err build-log-error]
+             ssh/handle-out ssh-build-log
+             ssh/handle-err ssh-build-log-error]
      ~@body))

 (defn build-log [message & args]


Minor cleanup of random/weighted-choice

Minor cleanup of random/weighted-choice

--- src/clj/genartlib/random.clj
+++ src/clj/genartlib/random.clj
@@ -71,8 +71,8 @@
   (nth items (int (random (count items)))))

 (defn weighted-choice
-  "Given a sequence of alternating item, weight arguments, chooses one of the
-   items with a probability equal to the weight.  Each weight should be
+  "Given a sequence of alternating item and weight arguments, chooses one of the
+   items with a probability equal to the weight. Each weight should be
    between 0.0 and 1.0, and all weights should sum to 1.0."
   [& items-and-weights]
   (assert (zero? (mod (count items-and-weights) 2)))
@@ -82,10 +82,7 @@
            remaining-items items-and-weights]
       (if (<= (count remaining-items) 2)
         (first remaining-items)
-        (let [; -- (println "remaining items:" remaining-items)
-              ; -- (assert (> (count remaining-items) 2))
-              ; -- (assert (not (nil? weight-seen)))
-              new-weight (second remaining-items)
+        (let [new-weight (second remaining-items)
               end-bound (+ weight-seen new-weight)]
           (if (between? r weight-seen end-bound)
             (first remaining-items)


Reset selected districts when complete

Reset selected districts when complete

--- src/cljs/geoforms/forms.cljs
+++ src/cljs/geoforms/forms.cljs
@@ -38,7 +38,9 @@
 (defn complete! []
   (reset! user-form user-defaults)
   (reset! idea-form idea-defaults)
-  (swap! app-state assoc :completed? true))
+  (swap! app-state assoc
+         :completed? true
+         :selected-districts '()))

 (defn restart! []
   (swap! app-state assoc :completed? false))


Fix error with percent encoded input

Fix error with percent encoded input

--- src/cljs/subman/history.cljs
+++ src/cljs/subman/history.cljs
@@ -2,7 +2,6 @@
   (:require [cljs.reader :refer [read-string]]
             [goog.events :as gevents]
             [goog.history.EventType :as history-event]
-            [goog.string :as string]
             [goog.history.Html5History :as history5]
             [jayq.util :refer [wait]]))

@@ -24,10 +23,10 @@
                    (wait 500 #(when (= new-value @value)
                                 (.setToken history new-value)))))
       (gevents/listen history history-event/NAVIGATE
-                      #(let [token (.-token %)]
+                      #(let [token (-> % .-token js/decodeURIComponent)]
                          (when (and (= (.-isNavigatopn %))
                                     (not= token @value))
                            (reset! value token))))
       (->> (.getToken history)
-           string/urlDecode
+           js/decodeURIComponent
            (reset! value)))))


We don't need the index for the errors to be a hash, can use count

--- src/cljs/tropology/core.cljs
+++ src/cljs/tropology/core.cljs
@@ -28,7 +28,7 @@
 ;

 (defn go-to-top []
-  (.animate (js/jQuery "html,body") (clj->js {:scrollTop (-> (js/jQuery "#top-anchor") .offset .-top )}) "slow"))
+  (.animate (js/jQuery "html,body") (clj->js {:scrollTop (-> (js/jQuery "#top-anchor") .offset .-top)}) "slow"))

 ;
@@ -378,9 +378,7 @@
          [:div {:class "section-inner"}
           [:h2 {:class "heading"} "There seems to have been a problem..."]
           [:div {:class "content"}
-           (for [error @errors]
-             ; We can't do a hash of the message, since we may get the same message more than once.
-             ^{:key (rand-int 999999)} [:div [:label {:class "control-label"} error]])
+           (map-indexed (fn [i error] ^{:key i} [:div [:label {:class "control-label"} error]]) @errors)
            ]
           ]]
         ))))


Remove uxbox.view.router ns.

Remove uxbox.view.router ns.

--- frontend/src/uxbox/view/router.cljs
+++ frontend/src/uxbox/view/router.cljs
@@ -1,77 +0,0 @@
-;; This Source Code Form is subject to the terms of the Mozilla Public
-;; License, v. 2.0. If a copy of the MPL was not distributed with this
-;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
-;;
-;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
-
-(ns uxbox.util.router
-  (:require [bide.core :as r]
-            [beicon.core :as rx]
-            [potok.core :as ptk]
-            [uxbox.main.store :as st]))
-
-(enable-console-print!)
-
-(defonce +router+ nil)
-
-;; --- Update Location (Event)
-
-(deftype UpdateLocation [id params]
-  ptk/UpdateEvent
-  (update [_ state]
-    (let [route (merge {:id id}
-                       (when params
-                         {:params params}))]
-      (assoc state :route route))))
-
-(defn update-location?
-  [v]
-  (instance? UpdateLocation v))
-
-(defn update-location
-  [name params]
-  (UpdateLocation. name params))
-
-;; --- Navigate (Event)
-
-(deftype Navigate [id params]
-  ptk/EffectEvent
-  (effect [_ state stream]
-    (r/navigate! +router+ id params)))
-
-(defn navigate
-  ([id] (navigate id nil))
-  ([id params]
-   {:pre [(keyword? id)]}
-   (Navigate. id params)))
-
-;; --- Public Api
-
-(defn init
-  ([routes]
-   (init routes nil))
-  ([routes {:keys [default] :or {default :auth/login}}]
-   (let [opts {:on-navigate #(st/emit! (update-location %1 %2))
-               :default default}
-         router (-> (r/router routes)
-                    (r/start! opts))]
-     (set! +router+ router)
-     router)))
-
-(defn go
-  "Redirect the user to other url."
-  ([id] (go id nil))
-  ([id params]
-   (st/emit! (navigate id params))))
-
-(defn route-for
-  "Given a location handler and optional parameter map, return the URI
-  for such handler and parameters."
-  ([id]
-   (if +router+
-     (r/resolve +router+ id)
-     ""))
-  ([id params]
-   (if +router+
-     (r/resolve +router+ id params)
-     "")))


Regexes are now applied!

Regexes are now applied!

--- src/espdig/components/youtube_feeds.clj
+++ src/espdig/components/youtube_feeds.clj
@@ -23,7 +23,7 @@
   (try
     (when-let [resp (tagsoup/parse rss)]
       (hash-map :chan-id (-> resp (find-element :channelId) (last))
-                :author  (-> resp (find-element :author) (find-element :name) (last))
+                :author  channel
                 :entries (map #(hash-map :id (-> % (find-element :videoId) (last))
                                          :title (-> % (find-element :title) (last))
                                          :original-link (-> % (find-element :link) (second) :href)
@@ -45,10 +45,14 @@
         (when-let [entries (fetch-feed-entries! db feed)]
           (try
             (let [{:keys [entries chan-id author]} entries
-                  {:keys [feed/channel feed/rss feed/title-rgx]} feed
+                  {:keys [feed/title-rgx]} feed
                   entries' (->> entries
                                 (map #(es/entry->media-item % chan-id author))
-                                (filter #(not (db/get-item-by-id db (:tbl-name config) (:meta/hash %)))))]
+                                (filter
+                                 #(some (fn [p]
+                                          (re-find (re-pattern p) (:media/name %))) title-rgx))
+                                (filter
+                                 #(not (db/get-item-by-id db (:tbl-name config) (:meta/hash %)))))]
               (when-not (zero? (count entries'))
                 (log/info "Found" (count entries') "new entry/entries for" chan-id))
               (run! #(save-entry! config db %) entries'))


Wrap player-pool in an agent as its manipulation contains side effects. Also default size of thread pool to the number of cpus.

--- src/overtone/time_utils.clj
+++ src/overtone/time_utils.clj
@@ -4,7 +4,7 @@
   overtone.time-utils
   (:import (java.util.concurrent ScheduledThreadPoolExecutor TimeUnit
                                  PriorityBlockingQueue))
-  (:use (overtone event)))
+  (:use (overtone event util)))

 ; Time

@@ -34,15 +34,12 @@
 ; it seems that timing isn't accurate enough.

 (defn make-pool
-  "creates a new pool of threads to schedule new events for. Defaults to 10 threads."
-  ([] (make-pool 10))
+  "Creates a new pool of threads to schedule new events for. Pool size defaults to the cpu count"
+  ([] (make-pool (cpu-count)))
   ([num-threads]
      (ScheduledThreadPoolExecutor. num-threads)))

-(def player-pool* (atom (make-pool)))
-
-(defn now []
-  (System/currentTimeMillis))
+(def player-pool* (agent (make-pool)))

 (defn schedule
   "Schedules fun to be executed after ms-delay milliseconds. Pool defaults to the player-pool."
@@ -59,21 +56,31 @@
            ms-period     (long ms-period)]
        (.scheduleAtFixedRate pool fun initial-delay ms-period TimeUnit/MILLISECONDS))))

+(defn- stop-and-reset-pool*
+  [pool now?]
+  (let [num-threads (.getCorePoolSize pool)
+        new-pool (make-pool num-threads)]
+    (if now?
+      (.shutdownNow pool)
+      (.shutdown pool))
+
+    new-pool))
+
 (defn stop-and-reset-pool!
-  "Shuts down a given pool (passed in as an atom) either immediately or not depending on whether the optional now param is used.
-   The pool is then reset to a fresh new pool preserving the original size."
-  [pool-ref & [now]]
-  (let [pool @pool-ref
-        num-threads (.getCorePoolSize pool)]
-    (reset! pool-ref (make-pool num-threads))
-    (if now
-      (.shutdownNow pool)
-      (.shutdown pool))))
-  (on-sync-event :reset ::player-reset #(stop-and-reset-pool! player-pool* true ))
+  "Shuts down a given pool (passed in as an agent) either immediately or not depending on whether the optional now param is
+   used. The pool is then reset to a fresh new pool preserving the original size."
+  ([pool-ag] (stop-and-reset-pool! pool-ag false))
+  ([pool-ag now?]
+     (send-off pool-ag stop-and-reset-pool* now?)))

+(on-sync-event :reset ::player-reset #(stop-and-reset-pool! player-pool* true ))

 (defn stop-player [player & [now]]
   (.cancel player (or now false)))
+
+
+(defn now []
+  (System/currentTimeMillis))

 ; Recursion in Time
 ;   By passing a function using #'foo syntax instead of just foo, when later
@@ -81,13 +88,13 @@
 ; the instance of the function defined earlier.
 ; (apply-at (+ dur (now)) #'my-melody arg1 arg2 [])

-(def *APPLY-AHEAD* 150)
+(def APPLY-AHEAD 150)

 (defn apply-at
-  "Calls (apply f args argseq) as soon after ms-time (timestamp in milliseconds) as possible."
+  "Calls (apply f args argseq) APPLY-AHEAD ms before ms-time."
   {:arglists '([ms-time f args* argseq])}
   [#^clojure.lang.IFn ms-time f & args]
-  (let [delay-time (- ms-time *APPLY-AHEAD* (now))]
+  (let [delay-time (- ms-time APPLY-AHEAD (now))]
     (if (<= delay-time 0)
       (apply f (#'clojure.core/spread args))
       (schedule #(apply f (#'clojure.core/spread args)) delay-time))))


Temporarily "fixing" composition to work.

Until we have the internal server fixed to use more memory by default,
I've changed the harpsichord duration so this doesn't cause allocation
errors.

--- src/examples/composition.clj
+++ src/examples/composition.clj
@@ -8,10 +8,11 @@
      (pluck (* (white-noise) (env-gen (perc 0.001 5) :action FREE))
             1 1 (/ 1 freq) (* duration 2) 0.25))))

+; NOTE: the duration is so short because otherwise we max out the internal
+; server's memory allocator.
 (definst harpsichord [freq 440]
-    (let [duration 0.5
+    (let [duration 0.1
           snd  (string freq duration)
-;          ]
           t1   (* 0.2 (string (* 2/1 freq) duration))
           t2   (* 0.15 (string (* 3/2 freq) duration))
           t3   (* 0.1 (string (* 4/3 freq) duration))
@@ -46,4 +47,4 @@
           (play (after 16 metro) notes)))

 ;(play (metronome 120) melody)
-;;(play-round (metronome 120) melody)
+;(play-round (metronome 120) melody)


Update usage to match new Clojail API

Update usage to match new Clojail API

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -183,11 +183,11 @@
                     ["Empty input is not allowed."]
                     (for [test tests]
                       (try
-                        (when-not (sb sb-tester
-                                      (->> user-forms
+                        (when-not (sb (->> user-forms
                                            (s/replace test "__")
                                            read-string-safely
                                            first)
+                                      sb-tester
                                       {#'*out* devnull
                                        #'*err* devnull})
                           "You failed the unit tests")


Some tidying of problems.clj. Arguably not much of an improvement, but I don't really care for the #(vec ...) pattern

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -64,11 +64,12 @@
      [:div {:id "prob-desc"}
       (problem :description)[:br]
       [:div {:id "testcases"}
-       (map #(vec [:li {:class "testcase"} %]) (problem :tests))]
+       (for [test (:tests problem)]
+         [:li {:class "testcase"} test])]
       (if-let [restricted (problem :restricted)]
         [:div {:id "restrictions"}
          [:u "Special Restrictions"] [:br]
-         (map #(vec [:li %]) restricted)])]
+         (map (partial vector :li) restricted)])]
      [:div
       [:b "Enter your code:" [:br]
        [:span {:class "error"} (session/flash-get :error)]]]
@@ -86,7 +87,8 @@
    [:th "Tags"]
    [:th "Count"]
    [:th "Solved?"]
-   (let [solved (get-solved (session/session-get :user))]
+   (let [solved (get-solved (session/session-get :user))
+         problems (get-problem-list)]
      (map-indexed
       (fn [x p]
         [:tr (row-class x)
@@ -100,4 +102,4 @@
           [:img {:src (if (contains? solved (p :_id))
                         "/checkmark.png"
                         "/empty-sq.png")}]]])
-      (get-problem-list)))])
+      problems))])


fix null pointer

fix null pointer

--- src/graphql_clj/executor.clj
+++ src/graphql_clj/executor.clj
@@ -148,7 +148,9 @@
     (let [type-name (:name field-type)
           tag (:tag field-type)
           inner-type (:inner-type field-type)]
-      (when (or result (= (.toString type-name)  "Boolean"))
+      (when (or result
+                (and type-name
+                     (= (.toString type-name)  "Boolean")))
         (cond
           (#{:scalar-definition :enum-definition} tag) result
           (#{:type-definition :interface-definition} tag) (if (seq selection-set)


Filter out non-Grimoire directories

Filter out non-Grimoire directories

This addresses issue #20.

Solve it in the shortest way possible by just inserting a check whether
a directory at the group level contains a file named meta.edn. If it
doesn't, it either isn't a Grimoire directory or violates the contract
(which I can't find right now), so throw it out.

Not sure if a more complete solution is desired. – Putting the raw
string "meta.edn" in there is not so nice and maybe we should also check
directories below group level? Anyway, this commit does fix the most
common issue.

--- src/grimoire/api/fs/read.clj
+++ src/grimoire/api/fs/read.clj
@@ -23,7 +23,8 @@
     (if (.isDirectory handle)
       (succeed
        (for [d     (.listFiles handle)
-             :when (.isDirectory d)]
+             :when (.isDirectory d)
+             :when (.exists (io/file d "meta.edn"))]
          (t/->Group (url/url-decode (f->name d)))))
       (fail "Could not find store directory"))))


change signature on method

change signature on method

--- src/hivewing_core/worker.clj
+++ src/hivewing_core/worker.clj
@@ -12,7 +12,7 @@
         per-page (if (> (:per-page params) 100) 100 (:per-page params))
         page     (:page params)
         ]
-    (jdbc/query sql-db ["SELECT name, created_at, updated_at, apiary_uuid, hive_uuid FROM workers WHERE hive_uuid = ? LIMIT ? OFFSET ?"
+    (jdbc/query sql-db ["SELECT uuid, created_at, updated_at FROM workers WHERE hive_uuid = ? LIMIT ? OFFSET ?"
                         (ensure-uuid hive-uuid)
                         per-page
                         (* (- page 1) per-page)])))


Fix debug logging after a timeout

Fix debug logging after a timeout

Fixes #35

--- src/io/aviso/rook/server.clj
+++ src/io/aviso/rook/server.clj
@@ -60,7 +60,7 @@
                                         (l/debugf "Response:%n%s" (pretty-print response))
                                         response)
                                       (do
-                                        (l/debugf "Handler for %f closed response channel." (utils/summarize-request request))
+                                        (l/debugf "Handler for %s closed response channel." (utils/summarize-request request))
                                         not-found-response))))))))

 (defn construct-handler


Fixes #34

Fixes #34

--- src/re_com/modal_panel.cljs
+++ src/re_com/modal_panel.cljs
@@ -23,30 +23,29 @@
       :or   {wrap-nicely? true backdrop-color "black" backdrop-opacity 0.6}
       :as   args}]
   {:pre [(validate-args-macro modal-panel-args-desc args "modal-panel")]}
-  (fn []
-    [:div
-     (merge {:class  (str "rc-modal-panel display-flex " class)    ;; Containing div
-             :style (merge {:position "fixed"
-                            :left     "0px"
-                            :top      "0px"
-                            :width    "100%"
-                            :height   "100%"}
-                           style)}
-            attr)
-     [:div
-      {:style    {:position         "fixed"           ;; Backdrop
-                  :width            "100%"
-                  :height           "100%"
-                  :background-color backdrop-color
-                  :opacity          backdrop-opacity
-                  :z-index          1020
-                  :pointer-events   "none"}           ;; TODO: trying to prevent change of focus under the when clicking on backdrop (also with the on-click below). Remove!
-       :on-click #(do (println "stopping propagation") (.preventDefault %) (.stopPropagation %))
-       }]
-     [:div
-      {:style (merge {:margin  "auto"                 ;; Child
-                      :z-index 1020}
-                     (when wrap-nicely? {:background-color "white"
-                                         :padding          "16px"
-                                         :border-radius    "6px"}))}
-      child]]))
+  [:div
+   (merge {:class  (str "rc-modal-panel display-flex " class)    ;; Containing div
+           :style (merge {:position "fixed"
+                          :left     "0px"
+                          :top      "0px"
+                          :width    "100%"
+                          :height   "100%"}
+                         style)}
+          attr)
+   [:div
+    {:style    {:position         "fixed"           ;; Backdrop
+                :width            "100%"
+                :height           "100%"
+                :background-color backdrop-color
+                :opacity          backdrop-opacity
+                :z-index          1020
+                :pointer-events   "none"}           ;; TODO: trying to prevent change of focus under the when clicking on backdrop (also with the on-click below). Remove!
+     :on-click #(do (println "stopping propagation") (.preventDefault %) (.stopPropagation %))
+     }]
+   [:div
+    {:style (merge {:margin  "auto"                 ;; Child
+                    :z-index 1020}
+                   (when wrap-nicely? {:background-color "white"
+                                       :padding          "16px"
+                                       :border-radius    "6px"}))}
+    child]])


remove extra "themselves" entries

remove extra "themselves" entries

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1689,29 +1689,6 @@
               :sem {:human true
                     :reflexive true}
               :subcat '()}}
-    {:note "♀"
-     :synsem {:cat :noun
-              :pronoun true
-              :case :acc
-              :reflexive true
-              :agr {:person :3rd
-                    :number :plur
-                    :gender :fem}
-              :sem {:human false
-                    :reflexive true}
-              :subcat '()}}
-
-    {:note "♂"
-     :synsem {:cat :noun
-              :pronoun true
-              :case :acc
-              :reflexive true
-              :agr {:person :3rd
-                    :number :plur
-                    :gender :masc}
-              :sem {:human false
-                    :reflexive true}
-              :subcat '()}}
     ]

    "they"


added learn pred

added learn pred

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -1307,6 +1307,9 @@

    "learn" [

+           {:synsem {:cat :verb
+                     :sem {:pred :learn}}}
+
            {:english {:note "a-"}
             :synsem  {:cat :verb
                       :sem {:pred :learn-a}}}
@@ -2268,7 +2271,7 @@
               :sem {:pred :turn-down}
               :subcat {:3 {:cat :prep
                            :sem {:pred :down}}}}}
-
+
     ;; "turn the radio off"
     {:phrasal-verb true
      :synsem {:cat :verb
@@ -2282,7 +2285,7 @@
               :sem {:pred :turn-off}
               :subcat {:3 {:cat :prep
                            :sem {:pred :off}}}}}
-
+
     ;; "turn the radio on"
     {:phrasal-verb true
      :synsem {:cat :verb


added cantar

added cantar

--- src/babel/espanol/lexicon.cljc
+++ src/babel/espanol/lexicon.cljc
@@ -190,7 +190,8 @@
                         :sem {:pred :walk}}}
    "cancelar" {:synsem {:cat :verb
                         :sem {:pred :cancel}}}
-   "cantar" {}
+   "cantar" {:synsem {:cat :verb
+                        :sem {:pred :sing}}}
    "casarse" {}

    "cenar" {:synsem {:cat :verb


don't need to make human/nonhuman distinction with "ils" and "elles"

--- src/babel/francais/lexicon.clj
+++ src/babel/francais/lexicon.clj
@@ -177,26 +177,15 @@
                     :pred :lei}
              :subcat '()}}]
    "elles"
-   [{:synsem {:cat :noun
+   {:synsem {:cat :noun
               :pronoun true
               :case :nom
               :agr {:person :3rd
                     :number :plur
                     :gender :fem}
-              :sem {:human true
-                    :gender :fem
+              :sem {:gender :fem
                     :pred :loro}
               :subcat '()}}
-    {:synsem {:cat :noun
-             :pronoun true
-             :case :nom
-             :agr {:person :3rd
-                   :number :plur
-                   :gender :fem}
-             :sem {:human false
-                   :gender :fem
-                   :pred :loro}
-             :subcat '()}}]

    "enseigner" [{:synsem {:cat :verb
                          :sem {:pred :show}}}
@@ -290,28 +279,17 @@
               '()}}]

     "ils"
-    [{:synsem {:cat :noun
-               :pronoun true
-               :case :nom
-               :agr {:person :3rd
-                     :number :plur
-                     :gender :masc}
-               :sem {:human true
-                     :gender :masc
-                     :pred :loro}
+    {:synsem {:cat :noun
+              :pronoun true
+              :case :nom
+              :agr {:person :3rd
+                    :number :plur
+                    :gender :masc}
+              :sem {:gender :masc
+                    :pred :loro}
                :subcat '()}}
-     {:synsem {:cat :noun
-               :pronoun true
-               :case :nom
-               :agr {:person :3rd
-                     :number :plur
-                     :gender :masc}
-               :sem {:human false
-                     :gender :masc
-                     :pred :loro}
-               :subcat '()}}]
-
-  "imaginer" {:synsem {:cat :verb
+
+    "imaginer" {:synsem {:cat :verb
                        :sem {:pred :imagine}}}
   "importer" {:synsem {:cat :verb
                        :sem {:pred :import}}}


Add more comments in litedocx.wpml

Add more comments in litedocx.wpml

--- src/bakyeono/litedocx/wpml.clj
+++ src/bakyeono/litedocx/wpml.clj
@@ -446,42 +446,53 @@

   Parameters:
   - style: <string> style of table
-  - h-align: <string or keyword> horizontal alignment option in each cell.
+  - align: <string or keyword> horizontal alignment option in each cell.
   - widths: <vector of numbers> widths of cells
   - & body: content of table (tr is expected)

   Examples:
   (table \"table-style1\" :center [964 964 8072] ...)"
-  [style h-align widths & body]
+  [style align widths & body]
+  ;; Table
   (node :w:tbl {}
+        ;; Table Properties
         (node :w:tblPr {}
+              ;; Referenced Table Style
               (node :w:tblStyle {:w:val style})
+              Preferred Table Width
               (node :w:tblW {:w:w (reduce + widths)
-                             :w:type "dxa"})
-              (node :w:jc {:w:val (name h-align)}))
+                             :w:type "dxa"}) ; Table Width Units : nil, pct, dxa, auto
+              ;; Table Alignment
+              (node :w:jc {:w:val (name align)}))
+        ;; Table Grid
         (node :w:tblGrid {}
               (for [w widths]
+                ;; Grid Column Width
                 (node :w:gridCol {:w:gridCol w})))
         body))

 (defn tr
-  "Returns XML tag node of table.
+  "Returns XML tag node of table row.

   Parameters:
   - & body: content of row (td is expected)"
   [& body]
+  ;; Table Row
   (node :w:tr {}
         body))

 (defn td
-  "Returns XML tag node of table.
+  "Returns XML tag node of table cell.

   Parameters:
   - width: width of cell
   - & body: content of cell"
   [width & body]
+  ;; Table Cell
   (node :w:tc {}
+        ;; Table Cell Properties
         (node :w:tcPr {}
+              ;; Preferred Table Cell Width
               (node :w:tcW {:w:w width
                             :w:type "dxa"}))
         body))
@@ -493,15 +504,23 @@
   - style: <string or keyword> style of paragraph
   - text: <string> text in paragraph"
   ([text]
+   ;; Paragraph
    (node :w:p {}
+         ;; Text Run
          (node :w:r {}
+               ;; Text
                (node :w:t {}
                      text))))
   ([style text]
+   ;; Paragraph
    (node :w:p {}
+         ;; Paragraph Properties
          (node :w:pPr {}
+               ;; Referenced Paragraph Style
                (node :w:pStyle {:w:val (name style)}))
+         ;; Text Run
          (node :w:r {}
+               ;; Text
                (node :w:t {}
                      text)))))


JC | #27 | wired in POST handler for resetting password

--- src/stonecutter/handler.clj
+++ src/stonecutter/handler.clj
@@ -86,6 +86,7 @@
        :send-forgotten-password-email        (partial forgotten-password/forgotten-password-form-post email-sender user-store forgotten-password-store)
        :show-forgotten-password-confirmation forgotten-password/show-forgotten-password-confirmation
        :show-reset-password-form             (partial forgotten-password/show-reset-password-form forgotten-password-store user-store)
+       :reset-password                       (partial forgotten-password/reset-password-form-post forgotten-password-store user-store token-store)
        :show-authorise-form                  (partial oauth/show-authorise-form client-store)
        :authorise                            (partial oauth/authorise auth-code-store client-store user-store token-store)
        :authorise-client                     (partial oauth/authorise-client auth-code-store client-store user-store token-store)
@@ -104,7 +105,8 @@
                                           :confirmation-sign-in-form :confirmation-sign-in
                                           :show-forgotten-password-form :send-forgotten-password-email
                                           :show-forgotten-password-confirmation
-                                          :show-reset-password-form}))))
+                                          :show-reset-password-form
+                                          :reset-password}))))

 (defn api-handlers [stores-m]
   (let [auth-code-store (storage/get-auth-code-store stores-m)


Moved notes and cleanup domain.

Moved notes and cleanup domain.

--- src/clj/elephantdb/service.clj
+++ src/clj/elephantdb/service.clj
@@ -71,39 +71,69 @@
         (let [{:keys [finished-loaders shard-states]} state]
           (swap! finished-loaders + (count (shard-states domain))))))))

+(defn cleanup-domain!
+  [domain-path]
+  "Destroys all but the most recent version in the versioned store
+  located at `domain-path`."
+  (doto (DomainStore. (local-filesystem) domain-path)
+    (.cleanup 1)))
+
+(defn cleanup-domains!
+  "Destroys every old version for each domain in `domains` located
+  inside of `local-dir`. (Each domain directory contains a versioned
+  store, capable of being 'cleaned up' in this fashion.)
+
+  If any cleanup operation throws an error, `cleanup-domains!` will
+  try to operate on the rest of the domains, and throw a single error
+  on completion."
+  [domains local-dir]
+  (let [error (atom nil)]
+    (dofor [domain domains :let [domain-path (str (path local-dir domain))]]
+           (try (log-message "Purging old versions of domain: " domain)
+                (cleanup-domain! domain-path)
+                (catch Throwable t
+                  (log-error t "Error when purging old versions of domain: " domain)
+                  (reset! error t))))
+    (when-let [e @error]
+      (throw e))))
+
 (defn load-and-sync-status!
   "TODO: Only note success for non-failed domains. check thrift status."
   [edb-config rw-lock domains-info & {:keys [state]}]
-  (let [remote-path-map (:domains edb-config)
-        status (thrift/ready-status :loading? true)
-        loaders (p-dofor [[domain info] domains-info
-                          :let [remote-path (get remote-path-map domain)
-                                loader-state (or state (mk-loader-state
-                                                        {domain (domain/host-shards info)}))]]
-                         (try (domain/set-domain-status! info status)
-                              (when-let [new-data (use-cache-or-update domain
-                                                                       remote-path
-                                                                       edb-config
-                                                                       loader-state)]
-                                (domain/set-domain-data! rw-lock domain info new-data))
-                              (domain/set-domain-status! info (thrift/ready-status))
-                              (catch Throwable t
-                                (log-error t "Error when loading domain " domain)
-                                (domain/set-domain-status! info
-                                                           (thrift/failed-status t)))))]
+  (let [{remote-path-map :domains
+         local-dir :local-dir} edb-config
+         status (thrift/ready-status :loading? true)
+         domain-names (keys domains-info)
+         loaders (p-dofor [[domain info] domains-info
+                           :let [remote-path (get remote-path-map domain)
+                                 loader-state (or state (mk-loader-state
+                                                         {domain (domain/host-shards info)}))]]
+                          (try (domain/set-domain-status! info status)
+                               (when-let [new-data (use-cache-or-update domain
+                                                                        remote-path
+                                                                        edb-config
+                                                                        loader-state)]
+                                 (domain/set-domain-data! rw-lock domain info new-data))
+                               (domain/set-domain-status! info (thrift/ready-status))
+                               (catch Throwable t
+                                 (log-error t "Error when loading domain " domain)
+                                 (domain/set-domain-status! info (thrift/failed-status t)))))]
     (with-ret loaders
-      (log-message "Successfully loaded domains: "
-                   (s/join ", " (keys domains-info))))))
+      (try (log-message "Removing all old versions of updated domains!")
+           (cleanup-domains! domain-names local-dir)
+           (catch Throwable t
+             (log-error t "Error when cleaning old versions.")))
+      (log-message "Successfully loaded domains: " (s/join ", " domain-names)))))

 (defn load-cached-domains!
   [edb-config rw-lock domains-info]
   (let [{:keys [hdfs-conf local-dir local-db-conf]} edb-config
         remote-path-map (:domains edb-config)
         status (thrift/loading-status)
+        domain-names (keys domains-info)
         loaders (p-dofor [[domain info] domains-info]
                          (try (domain/set-domain-status! info status)
-                              (let [host-shards  (domain/host-shards info)
-                                    remote-path  (get remote-path-map domain)
+                              (let [remote-path  (get remote-path-map domain)
                                     local-domain-root (str (path local-dir domain))
                                     local-vs (mk-local-vs (filesystem hdfs-conf)
                                                           remote-path
@@ -111,15 +141,18 @@
                                 (when-let [new-data (and (domain-has-data? local-vs)
                                                          (open-domain local-db-conf
                                                                       local-domain-root
-                                                                      host-shards))]
-                                  (println "LOADING CACHED: " domain)
+                                                                      (domain/host-shards info)))]
                                   (domain/set-domain-data! rw-lock domain info new-data)))
                               (domain/set-domain-status! info (thrift/ready-status))
                               (catch Throwable t
                                 (log-error t "Error when loading domain " domain)
                                 (domain/set-domain-status! info (thrift/failed-status t)))))]
     (with-ret loaders
-      (log-message "Successfully loaded cached domains: " (s/join ", " (keys domains-info))))))
+      (try (log-message "Removing all old versions of updated domains!")
+           (cleanup-domains! domain-names local-dir)
+           (catch Throwable t
+             (log-error t "Error when cleaning old versions.")))
+      (log-message "Successfully loaded cached domains: " (s/join ", " domain-names)))))

 (defn purge-unused-domains!
   "Walks through the supplied local directory, recursively deleting
@@ -135,32 +168,6 @@
            (log-message "Deleting local path of deleted domain: " domain-path)
            (delete lfs (.getPath domain-path) true))))

-(defn cleanup-domain!
-  [domain-path]
-  "Destroys all but the most recent version in the versioned store
-  located at `domain-path`."
-  (doto (DomainStore. (local-filesystem) domain-path)
-    (.cleanup 1)))
-
-(defn cleanup-domains!
-  "Destroys every old version for each domain in `domains` located
-  inside of `local-dir`. (Each domain directory contains a versioned
-  store, capable of being 'cleaned up' in this fashion.)
-
-  If any cleanup operation throws an error, `cleanup-domains!` will
-  try to operate on the rest of the domains, and throw a single error
-  on completion."
-  [domains local-dir]
-  (let [error (atom nil)]
-    (dofor [domain domains :let [domain-path (str (path local-dir domain))]]
-           (try (log-message "Purging old versions of domain: " domain)
-                (cleanup-domain! domain-path)
-                (catch Throwable t
-                  (log-error t "Error when purging old versions of domain: " domain)
-                  (reset! error t))))
-    (when-let [e @error]
-      (throw e))))
-
 (defn prepare-local-domains!
   [domains-info edb-config rw-lock]
   (let [{:keys [local-dir]} edb-config
@@ -170,7 +177,6 @@
         (try (purge-unused-domains! domain-seq local-dir)
              (load-cached-domains! edb-config rw-lock domains-info)
              (load-and-sync-status! edb-config rw-lock domains-info)
-             (cleanup-domains! domain-seq local-dir)
              (log-message "Finished loading all updated domains from remote.")
              (catch Throwable t
                (log-error t "Error when syncing data.")
@@ -205,7 +211,6 @@
             (not (.isDone @download-supervisor))))))

 (defn- update-domains
-  "TODO: Always cleanup after update?"
   [download-supervisor domains-info edb-config rw-lock]
   (let [{max-kbs :max-online-download-rate-kb-s
          local-dir :local-dir} edb-config
@@ -221,10 +226,6 @@
                                   domains-info
                                   :state download-state)
            (log-message "Finished updating all domains from remote.")
-           (log-message "Removing all old versions of updated domains!")
-           (try (cleanup-domains! (keys domains-info) local-dir)
-                (catch Throwable t
-                  (log-error t "Error when cleaning old versions")))
            (catch Throwable t
              (log-error t "Error when syncing data"))))))


deflection working

deflection working

--- src/cljs/dodgeball/combat.cljs
+++ src/cljs/dodgeball/combat.cljs
@@ -9,43 +9,55 @@
 (defn defense-team-without [u]
   (filter #(not= u %) (unit/all-unit-coords-for (unit/defense))))

-(defn ball-deflect [x y]
+(defn out-of-bounds [x y]
+  (or
+   (< x 0)
+   (> x 10)
+   (< y 0)
+   (> y 10)))
+
+(defn reset-ball [id]
+  (case id
+     1 {:x 1 :y 5}
+     2 {:x 3 :y 5}
+     3 {:x 5 :y 5}
+     4 {:x 7 :y 5}
+     5 {:x 9 :y 5}))
+
+(defn deflect [x y]
   (let [magnitude (+ 1 (rand-int 3))
-        dir (case
-              (+ 1 (rand-int 4))
-
-              1
-              (map #(* magnitude %) [0 -1])
-
-              2
-              (map #(* magnitude %) [-1 0])
-
-              3
-              (map #(* magnitude %) [1 0])
-
-              4
-              (map #(* magnitude %) [0 1]))]
-    (map + dir [x y])))
+        dir
+        (case (+ 1 (rand-int 4))
+          1 (map #(* magnitude %) [ 0 -1])
+          2 (map #(* magnitude %) [-1  0])
+          3 (map #(* magnitude %) [ 1  0])
+          4 (map #(* magnitude %) [ 0  1]))]
+    (if (out-of-bounds x y)
+      (reset-ball (get-in (unit/selected-unit) [:ball :id]))
+      (zipmap [:x :y] (map + dir [x y])))))

 (defn miss [updated-unit offense-team defense-team]
   (swap! state/game assoc-in [:units :balls] (conj (get-in @state/game [:units :balls]) (:ball (unit/selected-unit))))
   (swap! state/game assoc-in [:units (:turn @state/game)] (conj offense-team updated-unit)))

-(defn hit [updated-unit offense-team defense-team]
-  (swap! state/game assoc-in [:units :balls] (conj (get-in @state/game [:units :balls]) (:ball (unit/selected-unit))))
-  (swap! state/game assoc-in [:units (:turn @state/game)] (conj offense-team updated-unit))
-  (swap! state/game assoc-in [:units (unit/defense)] defense-team))
+(defn hit [updated-unit offense-team defense-team defense-unit]
+  (let [coords (:coords defense-unit)
+        ball   (assoc (:ball (unit/selected-unit)) :coords (deflect (:x coords) (:y coords)))]
+    (swap! state/game assoc-in [:units :balls] (conj (get-in @state/game [:units :balls]) ball))
+    (swap! state/game assoc-in [:units (:turn @state/game)] (conj offense-team updated-unit))
+    (swap! state/game assoc-in [:units (unit/defense)] defense-team)))

 (defn attack [x y]
   (let [updated-unit   (conj (unit/selected-unit) {:ball nil})
         attack-points  (+ 1 (rand-int 8))
         defense-points (+ 1 (rand-int 8))
         offense-team   (offense-team-without (unit/selected-unit))
-        defense-team   (defense-team-without (unit/unit-by-type x y (unit/defense)))]
+        defense-unit   (unit/unit-by-type x y (unit/defense))
+        defense-team   (defense-team-without defense-unit)]
     (println "attack dice: " attack-points "defense dice: " defense-points)
     (if (<= attack-points defense-points)
       (miss updated-unit offense-team defense-team)
-      (hit  updated-unit offense-team defense-team))))
+      (hit  updated-unit offense-team defense-team defense-unit))))

     ;(println (unit/all-unit-coords-for :balls) (ball-deflect (:x defense-unit)


remove comment

remove comment

--- src/clojure_fabric/orderer.clj
+++ src/clojure_fabric/orderer.clj
@@ -1,15 +1,5 @@
-;; Peer implementation of "Fabric SDK Design Spec"
+;; Orderer implementation of "Fabric SDK Design Spec"
 ;;
-;; The Peer class represents the remote Peer node and its network membership materials,
-;; aka the ECert used to verify signatures. Peer membership represents organizations,
-;; unlike User membership which represents individuals.
-;;
-;; When constructed, a Peer instance can be designated as an event source, in which case
-;; a “eventSourceUrl” attribute should be configured. This allows the SDK to automatically
-;; attach transaction event listeners to the event stream.
-;;
-;; It should be noted that Peer event streams function at the Peer level and not at the chain
-;; and chaincode levels.

 (ns clojure-fabric.orderer
   (:require [clojure-fabric.user :as user]))


cascade delete on a User should include Pulses.

--- src/metabase/models/user.clj
+++ src/metabase/models/user.clj
@@ -49,6 +49,7 @@
     (cascade-delete 'Session :user_id id)
     (cascade-delete 'Dashboard :creator_id id)
     (cascade-delete 'Card :creator_id id)
+    (cascade-delete 'Pulse :creator_id)
     (cascade-delete 'Activity :user_id id)
     (cascade-delete 'ViewLog :user_id id)))


backend database acces now allows for any number of notes requested at once

--- src/note_server/database.clj
+++ src/note_server/database.clj
@@ -8,15 +8,21 @@
                :password ""})

-; returns a hashmap
-(defn query [id]
-  ; TODO support any number of arguments
+(defn query
+  "Returs a JSON list with objects, as a string"
+  [id]
   (sql/query database
-             [(str "select id, header, body
-                   from note_test
-                   where id in (?,?)")
-              (first id)
-              (first (rest id))]))
+             (into []
+                   (cons
+                     (str "select id, header, body
+                          from note_test
+                          where id in ("
+                          (apply str
+                                 (interpose ","
+                                            (repeat (count id)
+                                                    "?")))
+                          ")")
+                     id))))

 ; entry is a hashmap


add DIOTONIC-MODES dict containing the sequences of all the diotonic modes.

--- src/overtone/music/pitch.clj
+++ src/overtone/music/pitch.clj
@@ -105,6 +105,27 @@
               :minor minor
               :major-pentatonic (only major [1 2 3 5 6])
               :minor-pentatonic (only minor [1 3 4 5 7])}))
+
+(def DIOTONIC-MODES
+  ;; offset-order: ionian, dorian, phrygian, lydian, mixolydian, aeolian, lochrian
+  (let [ionian-sequence [2 2 1 2 2 2 1]
+        ionian-offset     0
+        dorian-offset     1
+        phrygian-offset   2
+        lydian-offset     3
+        mixolydian-offset 4
+        aeolian-offset    5
+        lochrian-offset   6
+        rotate-ionian (fn [offset] (drop offset (take (+ 7 offset) (cycle ionian-sequence))))]
+    {:ionian     (rotate-ionian ionian-offset)
+     :major      (rotate-ionian ionian-offset)
+     :dorian     (rotate-ionian dorian-offset)
+     :phrygian   (rotate-ionian phrygian-offset)
+     :lydian     (rotate-ionian lydian-offset)
+     :mixolydian (rotate-ionian mixolydian-offset)
+     :aeolian    (rotate-ionian aeolian-offset)
+     :minor      (rotate-ionian aeolian-offset)
+     :lochrian   (rotate-ionian lochrian-offset)}))

 ; Various scale intervals in terms of steps on a piano, or midi note numbers
 (def SCALES


Don't require cljs-ajax' API wholesale.

Don't require cljs-ajax' API wholesale.

--- src/day8/re_frame/http_fx.cljs
+++ src/day8/re_frame/http_fx.cljs
@@ -2,7 +2,8 @@
   (:require
     [goog.net.ErrorCode :as errors]
     [re-frame.core :refer [reg-fx dispatch console]]
-    [ajax.core :as ajax]
+    [ajax.simple :as ajax]
+    [ajax.xhrio]
     #_[cljs.spec :as s])
   (:import (goog.net XhrIo)))


Rename symbols

Rename symbols

--- src/play_clj/core_basics.clj
+++ src/play_clj/core_basics.clj
@@ -81,20 +81,16 @@
 (defn game
   "Provides quick access to often-used functions.

-    (game :width) ; width of the window
-    (game :height) ; height of the window
-    (game :fps) ; frames per second
-    (game :is-fullscreen?) ; whether the window is fullscreen
-    (game :is-touched?) ; whether the window is being touched/clicked
-    (game :x) ; the x position of the touch/click
-    (game :y) ; the y position of the touch/click"
+    (game :width)"
   [k]
   (case k
     :width (graphics! :get-width)
     :height (graphics! :get-height)
     :fps (graphics! :get-frames-per-second)
-    :is-fullscreen? (graphics! :is-fullscreen)
-    :is-touched? (input! :is-touched)
+    :fullscreen? (graphics! :is-fullscreen)
+    :touched? (input! :is-touched)
+    :is-fullscreen? (graphics! :is-fullscreen) ; deprecated
+    :is-touched? (input! :is-touched) ; deprecated
     :x (input! :get-x)
     :y (input! :get-y)
     (u/throw-key-not-found k)))
@@ -107,13 +103,18 @@
   [k]
   `~(u/gdx-field "Input$Keys" (u/key->upper k)))

-(defmacro is-pressed?
+(defmacro pressed?
   "Returns a boolean indicating if the key cooresponding to `k` is being pressed.

-    (is-pressed? :a)
-    (is-pressed? :page-down)"
+    (pressed? :a)
+    (pressed? :page-down)"
   [k]
   `(input! :is-key-pressed (key-code ~k)))
+
+(defmacro is-pressed?
+  "Deprecated. Please us `pressed?` instead."
+  [k]
+  `(pressed? ~k))

 (defn ^:private add-input!
   [^InputProcessor p]


adding mark

adding mark

--- src/hypervisors/networking.clj
+++ src/hypervisors/networking.clj
@@ -68,11 +68,16 @@
       [s e])
     (catch [:type :celestial.common/missing-conf] e nil)))

-(defm mark-used
-  "Marks used ips, memoized so it will be called once on each boot/usage"
+(defn mark
+   "marks a single ip as used"
+   [ip k]
+   (wcar (car/zadd k 1 ip)) ip)
+
+(defm mark-conf
+  "Marks all used ips in configuration, memoized so it will be called once on each boot/usage"
   [k]
   (doseq [ip (map ip-to-long (get! :hypervisor :proxmox :generators :used-ips))]
-    (wcar (car/zadd k 1 ip))))
+    (mark ip k)))

 (defn initialize-range
   "Initializes ip range zset 0 marks unused 1 marks used (only if missing)."
@@ -82,7 +87,6 @@
       (when-not (= 1 (car/exists k))
         (doseq [ip (range s (+ 1 e))]
           (car/zadd k 0 ip))))))
-

 (defn- fetch-ip
   "Redis ip range fetcher"
@@ -102,7 +106,7 @@
   [ct k]
   (let [k* (ips-key k)]
     (when (= 0 (wcar (car/exists k*))) (initialize-range k*))
-    (mark-used k*) ; in case list was updated
+    (mark-conf k*) ; in case list was updated
     (if-let [ip (fetch-ip k*)]
       (assoc ct :ip_address ip)
       (throw+ {:type ::ip-gen-error} "Failed to obtain ip for container"))))


Fix field type wonkiness :wrench:

Fix field type wonkiness :wrench:

--- src/metabase/db/migrations.clj
+++ src/metabase/db/migrations.clj
@@ -272,4 +272,4 @@
   (db/update-where! 'Field {:base_type [:not-like "type/%"]}
     :base_type "type/*")
   (db/update-where! 'Field {:special_type [:not-like "type/%"]}
-    :special_type "type/*"))
+    :special_type nil))


Change homepage layout

Change homepage layout

Minor change: moved the intro panel with text to the top, and now the
serialized game can be right next to the game. This looks more like a
playground/test zone and will be useful to test the AI.

--- src/obb_demo/views/player.cljs
+++ src/obb_demo/views/player.cljs
@@ -268,8 +268,7 @@
 (defn- game-as-string
   [game-data]
   [:div.row
-    [:textarea {:style {:margin-top "10px"
-                        :height "500px"}
+    [:textarea {:style {:height "500px"}
                 :class "form-control"
                 :on-change (partial game-str-changed game-data)
                 :value (or (:game-str game-data)
@@ -280,27 +279,24 @@
   [state]
   (let [game-data (get-game-data state)
         game (:game game-data)]
-    [:div.row
-      [:div.col-lg-2
-       (challenger-selector game-data)
-       (game-turn game-data)
-       (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"]
-       (unit-quantity-picker game-data)
-       (rotate-panel game-data)
-       [:button.btn.btn-default {:on-click (partial reset-turn game-data)} "Reset turn"]]
-      [:div.col-lg-5
-        [boardground/render {} game-data]
-        (selected-element-info game-data)]
-      [:div.col-lg-5
-       [:div.jumbotron
-        [:h1 "Demo"]
-        [:p "This is a demo that showcases the gameplay of Orion's Belt against a simple AI."]
-        [:p "It's your turn to play. Perform your actions and then click Play turn."]
-        [:p "Would you like to know more?"
-         [:ul
-          [:li [:a {:href "https://twitter.com/orionsbelt"} "Twitter"]
-          [:li [:a {:href "https://github.com/orionsbelt-battlegrounds/obb-rules"} "Github"]]]]]]
-        (game-as-string game-data)]]))
+    [:div
+      [:div.well
+        [:h4 "Demo"]
+        [:p "This is a demo that showcases the gameplay of Orion's Belt against a simple AI.
+            It's your turn to play. Perform your actions and then click Play turn."]]
+      [:div.row
+        [:div.col-lg-2
+         (challenger-selector game-data)
+         (game-turn game-data)
+         (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"]
+         (unit-quantity-picker game-data)
+         (rotate-panel game-data)
+         [:button.btn.btn-default {:on-click (partial reset-turn game-data)} "Reset turn"]]
+        [:div.col-lg-5
+          [boardground/render {} game-data]
+          (selected-element-info game-data)]
+        [:div.col-lg-5
+          (game-as-string game-data)]]]))


Require clojure.set

Require clojure.set

--- src/obb_rules/actions/move.clj
+++ src/obb_rules/actions/move.clj
@@ -1,5 +1,6 @@
 (ns obb-rules.actions.move
-  (:require [obb-rules.actions.move-restrictions :as move-restrictions]
+  (:require [clojure.set]
+            [obb-rules.actions.move-restrictions :as move-restrictions]
             [obb-rules.game :as game]
             [obb-rules.laws :as laws]
             [obb-rules.element :as element]


Remove unused require.

Remove unused require.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -6,7 +6,6 @@
             [taoensso.timbre :as timbre]
             [compojure.core :as compojure :refer (ANY OPTIONS DELETE)]
             [liberator.core :refer (defresource by-method)]
-            [clojure.walk :refer (keywordize-keys)]
             [schema.core :as schema]
             [oc.lib.schema :as lib-schema]
             [oc.lib.db.pool :as pool]


Thread values through play# to making timing handling more graceful.

--- src/overtunes/songs/at_all.clj
+++ src/overtunes/songs/at_all.clj
@@ -47,30 +47,30 @@
     (at (timing 3) (note# (:base chord1)))
     (at (timing 4) (note# (:base chord2)))
     (at (timing 6) (chord# (dissoc chord2 :base)))
-    (if chords
-      (rhythm-n-bass# (from timing 8) chords))))
+    (let [next (from timing 8)]
+      (if chords
+        (rhythm-n-bass# next chords)
+        next))))

 (defn even-melody# [timing [note & notes]]
   (do
     (at (timing 0) (note# note))
-    (if notes
-      (even-melody# (from timing 1) notes))))
+    (let [next (from timing 1)]
+      (if notes
+        (even-melody# next notes)
+        next))))

 (defn intro# [timing]
-    (rhythm-n-bass# timing (take 8 (cycle progression)))
-    (even-melody# timing (take 32 (cycle [9 7]))))
+    (even-melody# timing (take 32 (cycle [9 7])))
+    (rhythm-n-bass# timing (take 8 (cycle progression))))

 (defn first-bit# [timing]
-    (rhythm-n-bass# timing (take 8 (cycle progression)))
     (even-melody# (speed-up (from timing -1) 2) (map ionian [2 4 5 4 4 2 4]))
     (even-melody# (speed-up (from timing 7) 2) (map ionian [-2 1 2 1 1 -2 1]))
     (even-melody# (speed-up (from timing 15) 2) (map ionian [-2 1 2 1 1 -2 1 2 3 4]))
-    (even-melody# (speed-up (from timing 23) 2) (map ionian [-1 -2 -3 0 0 -3 0 1 0 -3])))
+    (even-melody# (speed-up (from timing 23) 2) (map ionian [-1 -2 -3 0 0 -3 0 1 0 -3]))
+    (rhythm-n-bass# timing (take 8 (cycle progression))))

-(defn play# []
-  (let [timing (from (bpm 120) 2)] ; Lead in with two beats so that everything starts at once.
-    (intro# timing)
-    (first-bit# (from timing 32))
-    (first-bit# (from timing 64))))
+(defn play# [] (-> (from (bpm 150) 2) intro# first-bit# first-bit#))

 ; (play#)


remove utils fns metadata

remove utils fns metadata

--- src/io/perun/core.clj
+++ src/io/perun/core.clj
@@ -58,7 +58,6 @@

 (defn map-keys
   "Map the keys of given associative collection using function."
-  {:added "0.2.0"}
   [f coll]
   (reduce-map (fn [xf] (fn [m k v]
                          (xf m (f k) v)))
@@ -66,21 +65,18 @@

 (defn map-vals
   "Map the values of given associative collection using function."
-  {:added "0.2.0"}
   [f coll]
   (reduce-map (fn [xf] (fn [m k v]
                          (xf m k (f v))))
               coll))

 (defn filter-keys
-  {:added "0.2.2"}
   [pred coll]
   (reduce-map (fn [xf] (fn [m k v]
                          (if (pred k) (xf m k v) m)))
               coll))

 (defn filter-vals
-  {:added "0.2.2"}
   [pred coll]
   (reduce-map (fn [xf] (fn [m k v]
                          (if (pred v) (xf m k v) m)))


remove playthrough event after first

remove playthrough event after first

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -317,18 +317,19 @@
    (fn [{:keys [status data]}]
      (if (= status :success)
        (let [video  (.createElement js/document "video")
-             canvas (.createElement js/document "canvas")]
+             canvas (.createElement js/document "canvas")
+             e-key  "oncanplaythrough"]
          (doto canvas
            (aset "width"  capture-size)
            (aset "height" capture-size))
          (doto video
            (aset "autoplay" "autoplay")
            (aset
-            "oncanplaythrough"
+            e-key
             (fn []
               (let [vw (.-videoWidth video)
                     vh (.-videoHeight video)]
-                (js-delete video "onplaying")
+                (js-delete video e-key)
                 (swap!
                  app-state
                  merge


forgot config for element

forgot config for element

--- src/cellf/core.cljs
+++ src/cellf/core.cljs
@@ -297,7 +297,8 @@
                 "You can also export a replay of your moves to an animated gif by "
                 "clicking the 'make gif' button."))

-            (dom/p (dom/a #js {:href "https://github.com/dmotz/cellf"} "open source")
+            (dom/p nil
+              (dom/a #js {:href "https://github.com/dmotz/cellf"} "open source")
               "For more experiments like this, visit "
               (dom/a #js {:href "http://oxism.com"} "oxism.com")
               \.)


Add tests for netty allocations and read/write specs.

--- test/bytebuf/core_tests.clj
+++ test/bytebuf/core_tests.clj
@@ -14,14 +14,80 @@

 (ns bytebuf.core-tests
   (:require [clojure.test :refer :all]
-            [bytebuf.core :as buf]))
+            [bytebuf.core :as buf])
+  (:import java.nio.ByteBuffer
+           io.netty.buffer.ByteBuf))
+

 (deftest allocate
-  (testing "Allocate heap buffer."
+  (testing "Allocate heap nio buffer"
     (let [buffer (buf/allocate 16)]
-      (is (not (.isDirect buffer)))))
+      (is (not (.isDirect buffer)))
+      (is (instance? ByteBuffer buffer))))

-  (testing "Allocate direct buffer"
+  (testing "Allocate direct nio buffer"
     (let [buffer (buf/allocate 16 {:type :direct})]
-      (is (.isDirect buffer))))
+      (is (.isDirect buffer))
+      (is (instance? ByteBuffer buffer))))
+
+  (testing "Allocate heap netty buffer"
+    (let [buffer (buf/allocate 16 {:type :heap :impl :netty})]
+      (is (not (.isDirect buffer)))
+      (is (instance? ByteBuf buffer))))
+
+  (testing "Allocate direct netty buffer"
+    (let [buffer (buf/allocate 16 {:type :direct :impl :netty})]
+      (is (.isDirect buffer))
+      (is (instance? ByteBuf buffer))))
 )
+
+(deftest spec-constructor
+  (testing "creating spec"
+    (let [spec (buf/spec :field1 (buf/int32)
+                         :field2 (buf/int64))]
+      (is (= (count spec) 2))
+      (is (= (buf/size spec) 12))))
+)
+
+(deftest associative-static-specs
+  (testing "write data"
+    (let [spec (buf/spec :field1 (buf/int32)
+                         :field2 (buf/int64))
+          buffer (buf/allocate 12)
+          data {:field1 1 :field2 4}]
+      (is (= (buf/write! buffer data spec) 12))
+      (is (= (.getInt buffer 0) 1))
+      (is (= (.getLong buffer 4) 4))))
+
+  (testing "write data with offset"
+    (let [spec (buf/spec :field1 (buf/int32))
+          buffer (buf/allocate 12)
+          data {:field1 500}]
+      (is (= (buf/write! buffer data spec {:offset 3}) 4))
+      (is (= (.getInt buffer 3) 500))))
+
+  (testing "write data to wrong buffer (less space)"
+    (let [spec (buf/spec :field1 (buf/int32))
+          buffer (buf/allocate 2)
+          data {:field1 1}]
+      (is (thrown? java.lang.IndexOutOfBoundsException
+                   (buf/write! buffer data spec) 12))))
+
+  (testing "read data"
+    (let [spec (buf/spec :field1 (buf/int32)
+                         :field2 (buf/int64))
+          buffer (buf/allocate 12)]
+      (.putInt buffer 0 10)
+      (.putLong buffer 4 100)
+      (let [[readed data] (buf/read* buffer spec)]
+        (is (= readed 12))
+        (is (= data {:field2 100 :field1 10})))))
+
+  (testing "read data with offset"
+    (let [spec (buf/spec :field1 (buf/int32))
+          buffer (buf/allocate 12)]
+      (.putInt buffer 8 1000)
+      (let [[readed data] (buf/read* buffer spec {:offset 8})]
+        (is (= readed 4))
+        (is (= data {:field1 1000})))))
+)


Actually fix the tests, add test to cover fixed bug

--- test/gogolica/core_test.clj
+++ test/gogolica/core_test.clj
@@ -24,10 +24,13 @@

 (deftest generate-args
   (testing "Generation of function arguments."
-    (is (= (g/generate-args parameters ["bar" "fooBar"] nil)
+    (is (= (g/generate-args {:parameters parameters
+                             :parameterOrder ["bar" "fooBar"]})
            '[bar foo-bar {:as optional-params :keys [baz]}])))
   (testing "Generation of function arguments, when request body is present."
-    (is (= (g/generate-args parameters ["bar" "fooBar"] {:$ref "Bucket"})
+    (is (= (g/generate-args {:parameters parameters
+                             :parameterOrder ["bar" "fooBar"]
+                             :request {:$ref "Bucket"}})
            '[bucket bar foo-bar {:as optional-params :keys [baz]}]))))

 (deftest template->path-vector
@@ -36,7 +39,10 @@
            '("b/" foo-bar "/c/" bar))))
   (testing "Uri template conversion with no vars."
     (is (= (g/template->path-vector "b" [])
-           '("b")))))
+           '("b"))))
+  (testing "Uri template conversion with no vars at the end"
+    (is (= (g/template->path-vector "b/{fooBar}/o" ["fooBar"])
+           '("b/" foo-bar "/o")))))

 (deftest generate-path
   (testing "Uri template to path vector conversion, with raw parameters."


undoable is now a middleware factory

undoable is now a middleware factory

--- src/re_frame/middleware.cljs
+++ src/re_frame/middleware.cljs
@@ -11,10 +11,14 @@

 (defn pure
   "Acts as an adaptor, allowing handlers to be writen as pure functions.
-  The re-frame router will pass in an atom as the first parameter. This middleware
-  adapts that to the value within the atom.
-  If you strip away the error/efficiency checks, this middleware is just:
-     (reset! app-db (handler @app-db event-vec))"
+  The re-frame router will pass in an atom as the first parameter. This
+  middleware adapts that atom to be the value within the atom.
+  If you strip away the error/efficiency checks, this middleware is just doing:
+     (reset! app-db (handler @app-db event-vec))
+  You don't have to use this middleare directly. Is supplied by default
+  when you use register-handler.
+  The only way to by-pass use of pure is to use the low level registration function
+  re-frame.handlers/register-handler-base"
   [handler]
   (fn pure-handler
     [app-db event-vec]
@@ -48,14 +52,6 @@
       new-db)))

-(defn undoable
-  "Middleware which stores an undo checkpoint."
-  [handler]
-  (fn undoable-handler
-    [app-db event-vec]
-    (store-now!)
-    (handler app-db event-vec)))
-

 (defn trim-v
   "Middleware which removes the first element of v which allows you to write
@@ -72,7 +68,8 @@

 (defn path
-  "Supplies a sub-tree of `db` to the handler. A narrowed view.
+  "A middleware factory which supplies a sub-tree of `db` to the handler.
+  Supplies a narrowed view.
   Assumes \"pure\" is in the middleware pipeline prior.
   Grafts the result back into db.
   If a get-in of the path results in a nil, then \"default-fn\" will be called to supply a value.
@@ -89,6 +86,26 @@
         (let [val (get-in db p)
               val (if (nil? val) (default-fn) val)]
           (assoc-in db p (handler val v)))))))
+
+
+(defn undoable
+  "A Middleware factory which stores an undo checkpoint.
+  \"explanation\" can be either a string or a function. If it is a
+  function then it must be:  (db event-vec) -> string.
+  \"explanation\" can be nil. in which case no
+  "
+  [explanation]
+  (fn middleware
+    [handler]
+    (fn undoable-handler
+      [db event-vec]
+      (let [explanation (cond
+                          (fn? explanation)     (explanation db event-vec)
+                          (string? explanation) explanation
+                          (nil? explanation)    ""
+                          :else (warn "re-frame: undoable given bad parameter. Got: " explanation))]
+      (store-now! explanation)
+      (handler db event-vec)))))

 (defn enrich


Some web unit tests.

Some web unit tests.

--- test/tyranitar/unit/web.clj
+++ test/tyranitar/unit/web.clj
@@ -1,5 +1,6 @@
 (ns tyranitar.unit.web
-  (:require [cheshire.core :as json])
+  (:require [cheshire.core :as json]
+            [tyranitar.git :as git])
   (:use [tyranitar.web]
         [midje.sweet]))

@@ -17,4 +18,55 @@
 (fact-group :unit
   (fact "Ping returns a pong"
         (:body (request :get "/1.x/ping"))  => "pong" )
-)
+
+  (fact "Status returns ok"
+        (request :get "/1.x/status") => (contains {:status 200}))
+
+  (fact "Healthcheck returns ok"
+        (request :get "/healthcheck") => (contains {:status 200}))
+
+  (fact "Invalid environment name results in not found response"
+        (request :get "/1.x/applications/wrongenv/test") => (contains {:status 404}))
+
+  (fact "Get commits for application and dev environment works"
+        (request :get "/1.x/applications/dev/test") => (contains {:status 200})
+        (provided
+         (git/get-list "dev" "test") => []))
+
+  (fact "Get commits for application and prod environment works"
+        (request :get "/1.x/applications/prod/test") => (contains {:status 200})
+        (provided
+         (git/get-list "prod" "test") => []))
+
+  (fact "Get commits for application that doesn't exist results in not found response"
+        (request :get "/1.x/applications/prod/test") => (contains {:status 404})
+        (provided
+         (git/get-list "prod" "test") => nil))
+
+  (fact "Get head -n commit for application works"
+        (request :get "/1.x/applications/prod/test/head~2/application-properties") => (contains {:status 200})
+        (provided
+         (git/get-data "prod" "test" "head~2" "application-properties") => []))
+
+  (fact "Get head commit for application works"
+        (request :get "/1.x/applications/prod/test/head/application-properties") => (contains {:status 200})
+        (provided
+         (git/get-data "prod" "test" "head" "application-properties") => []))
+
+  (fact "Get specific commit for application works"
+        (request :get "/1.x/applications/prod/test/921f195c98570550e743911bc3f5aca260d73f6f/application-properties") => (contains {:status 200})
+        (provided
+         (git/get-data "prod" "test" "921f195c98570550e743911bc3f5aca260d73f6f" "application-properties") => []))
+
+  (fact "Get for an invalid commit value results in not found response"
+        (request :get "/1.x/applications/prod/test/badcommit/application-properties") => (contains {:status 404}))
+
+  (fact "Getting deployment-params works"
+        (request :get "/1.x/applications/prod/test/head/deployment-params") => (contains {:status 200})
+        (provided
+         (git/get-data "prod" "test" "head" "deployment-params") => []))
+
+    (fact "Getting launch-data works"
+        (request :get "/1.x/applications/prod/test/head/launch-data") => (contains {:status 200})
+        (provided
+         (git/get-data "prod" "test" "head" "launch-data") => [])))


~(defn vocab-entry-to-lexeme): support noun categories other than "noun1" (e.g. "nounsingf")

--- src/babel/english/lexicon.cljc
+++ src/babel/english/lexicon.cljc
@@ -667,7 +667,7 @@
                               vocab-cat :vocab_cat}]
   ;; add some additional constraints that we should not need (should be in compile-lex)
   ;; TODO: remove need to add these constraints.
-  (cond (= vocab-cat "noun1")
+  (cond (clojure.string/starts-with? vocab-cat "noun")
         {surface
          [{:synsem {:sem {:pred (keyword pred)}
                     :propernoun false


fix typo in "conducir"

fix typo in "conducir"

--- src/babel/espanol/lexicon.cljc
+++ src/babel/espanol/lexicon.cljc
@@ -229,11 +229,12 @@
              :synsem {:cat :verb
                       :sem {:pred :confess}}}

-   "conducir" [{:espanol  {:present {:1sing "conduzco"}
-                  {:synsem {:cat :verb
-                       :sem {:pred :lead}}}
-             {:synsem {:cat :verb
-                       :sem {:pred :drive-c}}}]
+   "conducir" [{:espanol  {:present {:1sing "conduzco"}}
+                :synsem {:cat :verb
+                         :sem {:pred :lead}}}
+               {:espanol  {:present {:1sing "conduzco"}}
+                :synsem {:cat :verb
+                         :sem {:pred :drive-c}}}]
    "conocer" {}

    "consentir" {:espanol {:boot-stem "consient"}


Move instructions above textinput.

Move instructions above textinput.

--- src/todo_repl_webapp/views.clj
+++ src/todo_repl_webapp/views.clj
@@ -5,32 +5,34 @@

 (def instructions
   (core/html
-    [:div.alert.alert-info.col-md-7.col-md-offset-2
+    [:div.alert.alert-info
       [:div [:b "Instructions"]]
-      [:br]
-      [:div.col-md-4
-        [:p "To Display Tasks"]
-        [:code "(tasks)"]]
-      [:div.col-md-4
-        [:p "To Reset Tasks"]
-        [:code "(init-tasks)"]]
-      [:div.col-md-4
-        [:p "Tasks look like this"]
-        [:code "{:name name" [:br]
-               ":due date " [:em "(try natural language for the date)"] [:br]
-               ":context context}"]]
-      [:div.col-md-4
-        [:p "To Add a Task"]
-        [:code "(add-new-task" [:br]
-               "{:name \"Build a Rocketship\"" [:br]
-               "               :due \"tomorrow\"" [:br]
-               "               :context \"hobbies\"}"]]
+      [:div.row
+        [:div.col-md-4
+          [:p "To Display Tasks"]
+          [:code "(tasks)"]]
+        [:div.col-md-6
+          [:p "To Reset Tasks"]
+          [:code "(init-tasks)"]]]
+      [:div.row
+        [:div.col-md-4
+          [:p "Tasks look like this"]
+          [:code "{:name name" [:br]
+                 "  :due " [:em "date (try natural language)"] [:br]
+                 "  :context  " [:em "context"] [:br]
+                 "}"]]
+        [:div.col-md-4
+          [:p "To Add a Task"]
+          [:code "(add-new-task" [:br]
+                 "  {:name \"Build a Rocketship\"" [:br]
+                 "   :due \"tomorrow\"" [:br]
+                 "   :context \"hobbies\"})"]]

-      [:div.col-md-4
-        [:p "To Complete a Task"]
-        [:code "(complete-task "
-               [:em "index"]
-               ")"]]]))
+        [:div.col-md-4
+          [:p "To Complete a Task"]
+          [:code "(complete-task "
+                 [:em "index"]
+                 ")"]]]]))

 (defn task-item
   "Given a task (map), return a div representing the task"
@@ -76,6 +78,8 @@
         [:body
           [:div.col-md-7.col-md-offset-2
             [:h1 "todo-repl"]
+            [:div
+              instructions]
             (form/form-to {:id "todoForm"}
                           [:post "/eval"]
                           (form/text-area {:class "form-control"}
@@ -84,7 +88,6 @@
                           [:br]
                           (form/submit-button {:id "todoSubmitButton"}
                                               "Eval"))]
-          instructions
           [:div#display.col-md-7.col-md-offset-2
             (display tasks)]
           (page/include-js "js/eval.js")]))


remove some ??-preds

remove some ??-preds

--- src/babel/francais/lexicon.clj
+++ src/babel/francais/lexicon.clj
@@ -52,6 +52,15 @@
                    :gender :fem
                    :pred :loro}
              :subcat '()}}
+
+   "essayer" {:synsem {:cat :verb
+                      :sem {:pred :try}}}
+
+   "gagner" [{:synsem {:cat :verb
+                      :sem {:pred :earn}}}
+            {:synsem {:cat :verb
+                      :sem {:pred :win}}}]
+
    "il"
    {:synsem {:cat :noun
              :pronoun true
@@ -73,15 +82,27 @@
                    :gender :masc
                    :pred :loro}
              :subcat '()}}
-   "je"
-   {:synsem {:cat :noun
-             :pronoun true
-             :case :nom
-             :agr {:person :1st
-                   :number :sing}
-              :sem {:human true
-                    :pred :io}
-             :subcat '()}}
+
+
+  "imaginer" {:synsem {:cat :verb
+                       :sem {:pred :imagine}}}
+  "importer" {:synsem {:cat :verb
+                       :sem {:pred :import}}}
+
+  "insister" {:synsem {:cat :verb
+                       :sem {:pred :insist}}}
+
+;;  "interessér" {:synsem {:cat :verb
+;;                         :sem {:pred :interest??}}}
+
+  "je" {:synsem {:cat :noun
+                 :pronoun true
+                 :case :nom
+                 :agr {:person :1st
+                       :number :sing}
+                 :sem {:human true
+                       :pred :io}
+                 :subcat '()}}
    "manger"
    {:synsem {:cat :verb
              :sem {:pred :mangiare}}}
@@ -245,29 +266,10 @@
   "marcher" {:synsem {:cat :verb
                       :sem {:pred :work-nonhuman}}}

-  "gagner" [{:synsem {:cat :verb
-                      :sem {:pred :earn}}}
-            {:synsem {:cat :verb
-                      :sem {:pred :win}}}]
-
-  "imaginer" {:synsem {:cat :verb
-                       :sem {:pred :imagine??}}}
-  "importer" {:synsem {:cat :verb
-                       :sem {:pred :import??}}}
-  "commencer" {:synsem {:cat :verb
-                        :sem {:pred :begin??}}}
-  "insister" {:synsem {:cat :verb
-                       :sem {:pred :insist??}}}
-  "essayer" {:synsem {:cat :verb
-                      :sem {:pred :try??}}}
-  "interessér" {:synsem {:cat :verb
-                         :sem {:pred :interest??}}}
   "soulever" {:synsem {:cat :verb
-                       :sem {:pred :lift??}}}
-  "appeler" {:synsem {:cat :verb
-                      :sem {:pred :call??}}}
-  "apporter" {:synsem {:cat :verb
-                       :sem {:pred :take/carry??}}}
+                       :sem {:pred :lift}}}
+
+
   "gérer" {:synsem {:cat :verb
                     :sem {:pred :manage??}}}
   "envoyer" {:synsem {:cat :verb


silly silly buffers

silly silly buffers

--- code/clojure/src/ekade/leemail.clj
+++ code/clojure/src/ekade/leemail.clj
@@ -18,11 +18,11 @@
 (defn prepare-attachment
   [content-type filename filepath file-content]
   (make-parents filepath)
-  (let [in (b64/decode (.getBytes file-content))
-        out (output-stream filepath)]
-    (if (textish? content-type)
-      (spit filepath (apply str (map char (byte-array in)))))
-      (.write out (byte-array in)))
+  (let [in (b64/decode (.getBytes file-content))]
+    (with-open [out (output-stream filepath)]
+      (if (textish? content-type)
+        (spit filepath (apply str (map char (byte-array in))))
+        (.write out (byte-array in)))))
   {:type :inline
    :content-type content-type
    :content-id filename


comparison of two java strings with z3

comparison of two java strings with z3

--- src/be/ac/ua/aspchecker/z3.clj
+++ src/be/ac/ua/aspchecker/z3.clj
@@ -6,14 +6,70 @@
   (:import [com.microsoft.z3 Context Status]))

-(defn init-solver []
+
+(defn z3-merge-formulae [source target]
+  (str
+    "(benchmark tst :formula (and (not "
+    source
+    ")"
+    target
+    "))"))
+
+
+(defn z3-create-sort [ctx type]
+  (case type
+    :uninterpreted (.MkUninterpretedSort ctx "unin")
+    :real (.MkRealSort ctx)
+    :bool (.MkBoolSort ctx)))
+
+
+(defn z3-init []
   (let [cfg (new java.util.HashMap)]
     (do
       (.put cfg "model" "true")
       (new Context cfg))))

-(defn eval-context [ctx]
+(defn z3-create-symbols [ctx symbols]
+  (loop [result (hash-map
+                  :symbols []
+                  :functions [])
+         col symbols]
+    (if
+      (seq col)
+      (let [{id :identifier type :type} (first col)
+            sym (.MkSymbol ctx id)]
+        (recur
+          (assoc
+            result
+            :symbols (conj (:symbols result) sym)
+            :functions (conj (:functions result) (.MkConstDecl ctx sym (z3-create-sort ctx type))))
+          (rest col)))
+      result)))
+
+
+(defn z3-create-info [ctx source target]
+  (let [f1 (transform source)
+        f2 (transform target)
+        jt (z3-merge-formulae f1 f2)
+        s1 (z3-create-symbols ctx (retrieve-sorts (parse-contract source)))
+        s2 (z3-create-symbols ctx (retrieve-sorts (parse-contract target)))]
+    (hash-map
+      :formula jt
+      :symbols (into [] (concat (:symbols s1) (:symbols s2)))
+      :functions (into [] (concat (:functions s1) (:functions s2))))))
+
+
+(defn z3-set-info [ctx info]
+  (let [{form :formula syms :symbols funcs :functions} info
+        symarr (into-array syms)
+        funarr (into-array funcs)]
+    (doto
+      ctx
+      (.ParseSMTLIBString form nil nil symarr funarr))))
+
+
+(defn z3-eval [ctx]
   (let
     [exp (nth (.SMTLIBFormulas ctx) 0)
      solv (.MkSolver ctx)]
@@ -22,11 +78,16 @@
       (= (.Check solv) Status/SATISFIABLE))))

-(defn clean-solver [ctx]
+(defn z3-clean [ctx]
   (.Dispose ctx))

 (defn more-restrictive? [source target]
-  (let [cx (init-solver)]
-    (.ParseSMTLIBString cx (str source target) nil nil nil nil)
-    (eval cx)))+  (let [cx (z3-init)
+        info (z3-create-info cx source target)]
+    (do
+      (z3-set-info cx info)
+      (let [res (z3-eval cx)]
+        (do
+          (z3-clean cx)
+          res)))))


Remove old reference.

Remove old reference.

--- src/workshop/challenge_2_0.clj
+++ src/workshop/challenge_2_0.clj
@@ -26,7 +26,7 @@
      [;; The first catalog entry we'll look at is an :input
       ;; type. :input and :output catalog entries talk to plugins.
       ;; Plugins are the mechanism by which data is moved in and out of
-      ;; Onyx. The important thing to note here is :onyx/ident.
+      ;; Onyx. The important thing to note here is :onyx/plugin.
       ;; This is mapped to a predefined keyword (resolved to a fn in that namespace)
       ;; by the plugin author. You'd typically find this
       ;; catalog entry in the README of the plugin repository.
@@ -52,7 +52,7 @@
        :onyx/doc "Multiplies :n in the segment by 2"}

       ;; The last catalog entry to observe is the :output type.
-      ;; As with the :input type, the critical piece is :onyx/ident.
+      ;; As with the :input type, the critical piece is :onyx/plugin.
       ;; This maps to a predefined keyword in the plugin. Under the
       ;; covers, a multimethod is dispatching and looking for this keyword.
       {:onyx/name :write-segments


document repl testing

document repl testing

--- src/yeller_timbre_appender.clj
+++ src/yeller_timbre_appender.clj
@@ -34,3 +34,7 @@
                  {:environment (:environment with-default "production")
                   :location (:ns args)
                   :custom-data custom-data}))))}))
+
+(comment
+  ;; for repl testing
+  (do (require '[yeller-timbre-appender :reload true]) (timbre/set-config! [:appenders :yeller] (yeller-timbre-appender/make-yeller-appender {:token "YOUR TOKEN HERE" :environment "timebre-test"})) (timbre/error (ex-info "lol" {:foo 1}))))


Trim superflouous comment

Trim superflouous comment

--- src/clinvar_submitter/core.clj
+++ src/clinvar_submitter/core.clj
@@ -51,8 +51,6 @@
   [t loc & preds]
   (first (ld-> t loc preds)))

-
-;;TODO handle case when ld-> returns a collection
 (defn prop=
   "Filter ressults where a specific key (or recursive chain of keys}
   is equal to value"


Only add editorial or recommendation to the ncc if the are not empty

Fixes #47

--- src/clj/catalog/layout/obi.clj
+++ src/clj/catalog/layout/obi.clj
@@ -5,6 +5,7 @@
   later in the tool chain."
   (:require [catalog.layout.common :as layout]
             [clojure.data.xml :as xml]
+            [clojure.string :as string]
             [java-time :as time]))

 (defn- heading-keyword [level]
@@ -61,8 +62,9 @@
                      ;; cannot use select-keys as we need to retain
                      ;; the sorted map.
                      (#(apply dissoc % (remove #{:hörbuch} (keys %))))
-                     (assoc :editorial editorial
-                            :recommendation recommendation))
+                     (cond->
+                         (not (string/blank? editorial)) (assoc :editorial editorial)
+                         (not (string/blank? recommendation)) (assoc :recommendation recommendation)))
         path-to-numbers (layout/path-to-number subitems)]
     [:dtbook {:xmlns "http://www.daisy.org/z3986/2005/dtbook/"
               :version "2005-3" :xml:lang language}


Add the recommendations to the front for :hörbuch also for obi

i.e. for the xml that is produced for recording with obi

--- src/clj/catalog/layout/obi.clj
+++ src/clj/catalog/layout/obi.clj
@@ -40,15 +40,15 @@
               (layout/section-numbers (get path-to-numbers path))
               (layout/translations (last path)))]
      (cond
-       ;; handle the special case where the editorial or the recommendations are passed in the tree
-       (#{:editorial :recommendations} (last path)) (md-to-obi items path path-to-numbers)
+       ;; handle the special case where the editorial or the recommendation is passed in the tree
+       (#{:editorial :recommendation} (last path)) (md-to-obi items path path-to-numbers)
        ;; handle a list of entries
        (vector? items) (map #(entry-sexp (inc level) %) items)
        :else (map #(level-sexp (get items %) (conj path %) path-to-numbers) (keys items)))]))

 (defn document
   "Return a hiccup style sexp of DTBook XML for a catalog"
-  [items year issue editorial recommendations &
+  [items year issue editorial recommendation &
                 {:keys [creator date language]
                  :or {creator "SBS Schweizerische Bibliothek für Blinde, Seh- und Lesebehinderte"
                       date (time/local-date)
@@ -62,7 +62,7 @@
                      ;; the sorted map.
                      (#(apply dissoc % (remove #{:hörbuch} (keys %))))
                      (assoc :editorial editorial
-                            :recommendations recommendations))
+                            :recommendation recommendation))
         path-to-numbers (layout/path-to-number subitems)]
     [:dtbook {:xmlns "http://www.daisy.org/z3986/2005/dtbook/"
               :version "2005-3" :xml:lang language}
@@ -104,7 +104,7 @@
 (defn dtbook
   "Return a catalog in the form of DTBook XML. This will be imported
   into obi so the narrator has a structure when reading the catalog."
-  [items year issue editorial recommendations]
-  (-> (document items year issue editorial recommendations)
+  [items year issue editorial recommendation]
+  (-> (document items year issue editorial recommendation)
       xml/sexp-as-element
       (xml/indent-str :doctype doctype)))


Investigate db returns

Investigate db returns

--- src/clj_crud/data/accounts.clj
+++ src/clj_crud/data/accounts.clj
@@ -68,6 +68,7 @@
                                               :admin admin?
                                               :created_at now
                                               :updated_at now})]
+          (debug "Database res: " res)
           (when-not (contains? (first res) :1)
             (throw (Exception.  "DB Create has not succeeded")))
           (get-account db (:slug account)))))))