documentation, finally

documentation, finally

--- src/engine/server/rope.clj
+++ src/engine/server/rope.clj
@@ -1,24 +1,35 @@
 (ns engine.server.rope
+  "Implementation of Ropes as per \"Ropes: an Alternative to Strings\"
+by Boehm, Hans-J; Atkinson, Russ; and Plass, Michael (December 1995), doi:10.1002/spe.4380251203."
   (:use [clojure.string :only [join]])
   (:require [clojure.zip :as zip])
-  (:import [clojure.lang IPersistentCollection ITransientCollection Seqable Counted Indexed ISeq]
+  (:import [clojure.lang Counted Indexed]
            [java.lang String IndexOutOfBoundsException]))

 (def *fib-seq* (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
 (def *leaf-cutoff-length* 128)

 (defprotocol Measurable
-  (measure [object]))
+  "Trivial protocol for things measurable.
+Default implementations are provided for nil and String; nil measures as 0
+characters, 0 lines. Strings get analyzed accordingly."
+  (measure [object] "Measure object"))

 (defrecord CharSequenceMeasurement [#^int length #^int lines])

-(defn measurement [length lines]
+(defn measurement
+  "CharSequenceMeasurement from length and lines"
+  [length lines]
   (CharSequenceMeasurement. length lines))

-(defn count-matches [char string]
+(defn count-matches
+  "Number of character matches in string"
+  [char string]
   (->> string (filter #(= char %)) count))

-(defn measure-string [string]
+(defn measure-string
+  "CharSequenceMeasurement of number of characters and newlines in string"
+  [string]
   (measurement (count string) (count-matches \newline string)))

 (extend-type nil
@@ -31,14 +42,13 @@

 (defprotocol Treeish-2-3
+  "Protocol describing 2-3-Trees, such as Ropes.
+Default implementations for nil and String exist."
   (split [tree pred])
   (conc [tree1 tree2])
   (left [tree])
   (right [tree])
   (depth [tree]))
-
-(defprotocol Ropey
-  (balanced? [rope]))

 (extend-type nil
   Treeish-2-3
@@ -54,31 +64,45 @@
   (right [_] nil)
   (depth [_] 0))

+(defprotocol Ropey
+  "Rope-specific protocol for things that don't fit into general 2-3-Trees."
+  (balanced? [rope]))
+

 ; necessary forward declaration
 (deftype Rope [#^CharSequence left #^CharSequence right #^CharSequenceMeasurement weight #^int level])
-
-(defn rope? [x]
+
+(defn rope?
+  "Is x a Rope?"
+  [x]
   (instance? Rope x))

-(defn weigh [seq]
-  (if (and (rope? seq) (right seq)) ; no child on the right? not required to weigh again
+(defn weigh
+  "The accumulated measurement of all children to the right, provided that Treeish-2-3 is implemented for seq.
+In other words: What a new Treeish-2-3 node would weigh with seq as its left child."
+  [seq]
+  (if (and (satisfies? Treeish-2-3 seq) (right seq)) ; no child on the right? not required to weigh again
     (->> seq (iterate right) (take-while identity) (map measure) (map vals) (reduce #(map + %1 %2)) (apply measurement))
     (measure seq)))

 (defn rope
+  "New Rope that concatenates the given arguments, if any"
   ([] (Rope. nil nil (measurement 0 0) 0))
   ([seq] (Rope. seq nil (weigh seq) (inc (depth seq))))
   ([seq1 seq2] (Rope. seq1 seq2 (weigh seq1) (inc (max (depth seq1) (depth seq2))))))

-(defn rope-zip [root]
+(defn rope-zip
+  "Creates Zipper structures for Ropes, starting from root"
+  [root]
   (zip/zipper rope?
               (fn [node] (filter identity [(left node) (right node)]))
               (fn [node children] (apply rope children))
               root))

-(defn rope-nth [rope index]
-  (loop [zipper (rope-zip rope) l-index index]
+(defn rope-nth
+  "Evaluates to character at position index in the Rope at root in O(log n) time"
+  [root index]
+  (loop [zipper (rope-zip root) l-index index]
     (let [node (zip/node zipper)]
       (cond (string? node) (nth node l-index)
             node
@@ -88,17 +112,24 @@
                 (recur next l-index)))
             :default (throw (IndexOutOfBoundsException. (str "String index out of range: " index)))))))

-(defn rope-seq [rope]
-  (for [node (iterate zip/next (rope-zip rope)) :while (not (zip/end? node))]
+(defn rope-seq
+  "Lazy sequence of all Rope nodes at root, depth-first order"
+  [root]
+  (for [node (iterate zip/next (rope-zip root)) :while (not (zip/end? node))]
     (zip/node node)))

-(defn rope-str [rope]
-  (->> (rope-seq rope) (filter string?) (reduce str)))
-
-(defn rope-rebalance [coll]
+(defn rope->string
+  "Flat string from Rope at root"
+  [root]
+  (->> (rope-seq root) (filter string?) (reduce str)))
+
+(defn rope-rebalance
+  "Create rebalanced copy of the Rope, using the algorithm described in \"Ropes: an Alternative to Strings\".
+The implementation does not resemble the one from the paper, but is instead
+idiomatic Clojure and optimized for functional languages in general."  [root]
   (let [fold (fn [coll] (reduce rope (reverse coll)))
         fib-border (fn [limit] (->> *fib-seq* (take-while #(>= limit %)) last))]
-    (loop [acc (), coll (->> (rope-seq coll) (filter string?)), max-length nil]
+    (loop [acc (), coll (->> (rope-seq root) (filter string?)), max-length nil]
       (let [current (first coll), length (count current)]
         (if current
           (if (and (seq acc) (>= length max-length))
@@ -107,7 +138,9 @@
             (recur (cons current acc) (next coll) (fib-border length)))
           (fold acc))))))

-(defmulti rope-concat (fn [rope1 rope2] [(type rope1) (type rope2)]))
+(defmulti rope-concat
+  "Concatenation of two Ropes, including Strings which are treated as leafes"
+  (fn [rope1 rope2] [(type rope1) (type rope2)]))
 (defmethod rope-concat [String String] [string1 string2] (str string1 string2))
 (defmethod rope-concat :default [coll1 coll2]
   (let [new-rope (rope coll1 coll2)]
@@ -116,13 +149,19 @@
       (rope-rebalance new-rope))))

 (defn rope-split
-  ([coll pred] (rope-split coll pred :length))
-  ([coll pred measure-key]
+  "Split Rope at root by calling pred against the accumulated weights and nodes traversed so far.
+Pred should evaluate to a truthy value if the weight or node should be traversed
+to the right, i.e. towards higher weights.
+The vector retuned is composed of the re-evaluated tree to the left of the
+split, the actual split leaf and a reassembled tree of the nodes cut off to the
+right of the traversal."
+  ([root pred] (rope-split root pred :length))
+  ([root pred measure-key]
      (let [reassemble (fn [coll]
                         (if (empty? coll)
                           (rope)
                           (->> coll (reduce rope-concat) rope)))]
-       (loop [acc (), zipper (rope-zip coll), total-weight 0]
+       (loop [acc (), zipper (rope-zip root), total-weight 0]
          (let [node (zip/node zipper), node-weight (-> node measure measure-key), new-weight (+ node-weight total-weight)]
            (if (string? node)
              (if (pred new-weight node)
@@ -138,38 +177,45 @@

 ;; Presumably faster than iterating till zip/end?
 (defn rope-conj
-  ([coll x]
-     (loop [zipper (rope-zip coll)]
+  "Conjoin for Ropes. x is concatenated to the depth-first end, i.e. rightmost node of the Rope.
+Additional xs will be concatenated first."
+  ([root x]
+     (loop [zipper (rope-zip root)]
        (let [left-child (zip/down zipper) right-child (zip/right left-child)]
          (cond (and right-child (rope? (zip/node right-child))) (recur right-child)
                (and left-child (rope? (zip/node left-child))) (recur left-child)
                :default (-> zipper (zip/edit #(rope-concat %1 %2) x) zip/root)))))
-  ([coll x & xs]
-     (rope-conj coll (reduce rope-concat x xs))))
-
-(defn- rope-split-at [coll index]
-  (let [[left-rope string right-rope] (rope-split coll (fn [weight _] (>= index weight)))
+  ([root x & xs]
+     (rope-conj root (reduce rope-concat x xs))))
+
+(defn- rope-split-at
+  "Split Rope at index, with the additional remaining string index as fourth vector element"
+  [root index]
+  (let [[left-rope string right-rope] (rope-split root (fn [weight _] (>= index weight)))
         position (- index (count left-rope))]
     [left-rope string right-rope position]))

-(defn rope-insert [coll index string]
-  (if (= index (count coll))
-    (rope-conj coll string)
-    (let [[left-rope target right-rope position] (rope-split-at coll index)]
+(defn rope-insert
+  "Insert string in Rope at index"
+  [root index string]
+  (if (= index (count root))
+    (rope-conj root string)
+    (let [[left-rope target right-rope position] (rope-split-at root index)]
       (rope-concat (rope-conj left-rope (subs target 0 position) string (subs target position))
                    right-rope))))

 (defn rope-subs
-  ([coll start]
-     (if (= start (count coll))
+  "Report in O(log n) time for Ropes, the equivalent of string subs"
+  ([root start]
+     (if (= start (count root))
        "" ; For consistency with "normal" subs
-       (let [[_ string right-rope position] (rope-split-at coll start)]
+       (let [[_ string right-rope position] (rope-split-at root start)]
          (str (subs string position) right-rope))))
-  ([coll start end]
+  ([root start end]
      {:pre [(>= (- end start) 0)]}
-     (if (= start (count coll))
+     (if (= start (count root))
        ""
-       (let [[_ part1 right-rope position1] (rope-split-at coll start)
+       (let [[_ part1 right-rope position1] (rope-split-at root start)
              length (- end start)
              rest (- (count part1) position1)]
          (if (> length rest)
@@ -177,13 +223,15 @@
              (str (subs part1 position1) middle-rope (subs part2 0 position2)))
            (subs part1 position1 (+ position1 length)))))))

-(defn rope-delete [coll start end]
+(defn rope-delete
+  "Delete the characters at interval [start..end] in the Rope"
+  [root start end]
   {:pre [(>= (- end start) 0)]}
-  (if (= end (count coll))
-    (let [[left-rope part _ position] (rope-split-at coll start)]
+  (if (= end (count root))
+    (let [[left-rope part _ position] (rope-split-at root start)]
       (rope-conj left-rope (subs part 0 position)))
-    (let [[left-rope part1 _ position1] (rope-split-at coll start)
-          [_ part2 right-rope position2] (rope-split-at coll end)]
+    (let [[left-rope part1 _ position1] (rope-split-at root start)
+          [_ part2 right-rope position2] (rope-split-at root end)]
       (rope-concat (rope-conj left-rope (subs part1 0 position1) (subs part2 position2))
                    right-rope))))

@@ -211,25 +259,7 @@
   (charAt [this index] (nth this index))
   (length [this] (count this))
   (subSequence [this start end] (rope-subs this start end))
-  (toString [this] (rope-str this))
-
-  ;; ISeq
-  ;; (first [_] left)
-  ;; (more [this] (or (next this) (empty this)))
-  ;; (next [this] (seq right))
-
-  ;; Seqable
-  ;; (seq [this] (when left this))
-
-  ;; IPersistentCollection
-  ;; (cons [this x] (rope x this))
-  ;; (empty [_] (rope))
-  ;; (equiv [this x] (= (str this) (str x)))
-
-  ;; ITransientCollection
-  ;; (conj [this x] (println "called") (rope-conj this x))
-  ;; (persistent [this] this)
-  )
+  (toString [this] (rope->string this)))

 (defmethod print-method Rope [rope writer]
   (print-simple (format "#<Rope %s>" (->> (measure rope) vals (join "/"))) writer))
@@ -242,5 +272,9 @@
       (rope (left coll) (str right-child string))
       (rope-concat coll (rope string)))))

-(defn string->rope [string]
+(defn string->rope
+  "Create a fresh Rope from flat string.
+The resulting leafes will carry at most *leaf-cutoff-length* characters of the
+input string."
+  [string]
   (->> (partition-all *leaf-cutoff-length* string) (map #(apply str %)) (reduce rope) rope-rebalance rope))


Add support for definition of projections

--- src/eventstore/streams.clj
+++ src/eventstore/streams.clj
@@ -1,7 +1,10 @@
 (ns eventstore.streams
-  (:require [clojure.core.async :refer [go-loop go <! >! chan buffer
-                                        sliding-buffer mult tap close!]]
+  (:require [clojure.core.async :refer [go-loop go <!! <! >! chan buffer
+                                        sliding-buffer mult tap close!]
+             :as async]
             [clojure.tools.logging :as log]
+            [somnium.congomongo :as m]
+            [clj-time.coerce :as cc]
             [eventstore.riak :as riak]))

 (def cold-latency 5000)
@@ -13,19 +16,141 @@
         (>! ch event)))
     ch))

-(defn cold-stream [a-stream date-string & args]
-  (let [m-args (apply hash-map args)
-        s (riak/lazy-events (:db a-stream) date-string)]
-    (if (true? (:channel m-args))
-      (seq->channel s)
-      s)))
-
-(defmulti m-stream (fn [params _] (get params "stream-type" "hot")))
-
-(defmethod m-stream "cold" [params a-stream]
+(defprotocol ColdStream
+  (clean! [this])
+  (data-from [this date-string]))
+
+(defprotocol HotStream
+  (next! [this]))
+
+(defprotocol EventProcessor
+  (register-query! [this query-name f init])
+  (current-query-value [this query-name])
+  (process-event! [this ev]))
+
+(defn parse-old-date [date-string]
+  (cc/to-long
+    (clj-time.format/parse
+      (clj-time.format/formatter
+        "EEE MMM dd yyyy HH:mm:ss zZ '(GMT)'")
+      (clojure.string/replace date-string #"BST|UTC" "GMT"))))
+
+
+
+(defmulti stream (fn [_ params]
+                   (log/info (pr-str params))
+                   (get params "stream-type" "hot")))
+
+(def queries (ref {}))
+
+(defrecord DummyStream [db channel mult-channel]
+  ColdStream
+  (clean! [this]
+    (m/with-mongo db
+      (m/destroy! :events {})))
+  (data-from [this date]
+    (let [records (m/with-mongo db
+                    (m/fetch :events :where {}))
+          query-date (if (string? date) (read-string date) date)]
+      (filter #(and
+                 (not (nil? (:server_timestamp %)))
+                 (not (empty? (:server_timestamp %)))
+                 (let [db-date (parse-old-date (:server_timestamp %))]
+                   (>= db-date query-date)))
+              records)))
+  HotStream
+  (next! [this] (go (<! channel)))
+  EventProcessor
+  (register-query! [this query-name f init]
+    (let [s (stream this {"from" "0" "stream-type" "hot-cold"})
+          running-query (ref {:query-name query-name
+                              :fn f
+                              :current-value init
+                              :processed 0
+                              :last-event nil
+                              :last-error nil
+                              :status :running})]
+      (dosync (alter queries assoc query-name running-query))
+      (go
+        (loop [current-value init current-event (<! s)]
+          (if (nil? current-event)
+            (dosync (alter running-query assoc :status :finished))
+            (let [new-value (try
+                              (f current-value current-event)
+                              (catch Exception e e))]
+              (if (instance? Exception new-value)
+                (dosync
+                  (alter running-query
+                         merge {:last-event current-event
+                                :processed (inc (:processed @running-query))
+                                :last-error new-value
+                                :status :failed}))
+                (do
+                  (dosync
+                    (alter running-query
+                           merge {:last-event current-event
+                                  :current-value new-value
+                                  :processed (inc (:processed @running-query))}))
+                  (recur new-value (<! s))))))))))
+  (process-event! [this ev]
+    (go (>! channel ev))
+    (m/with-mongo db
+      (m/insert! :events ev))))
+
+(defrecord AsyncStream [db channel mult-channel]
+  ColdStream
+  (clean! [this] (riak/delete-all! db))
+  (data-from [this date-string]
+    (riak/lazy-events db date-string))
+  HotStream
+  (next! [this] (go (<! channel)))
+  EventProcessor
+  (register-query! [this query-name f init]
+    (let [s (stream this {"from" "0" "stream-type" "hot-cold"})
+          running-query (ref {:query-name query-name
+                              :fn f
+                              :current-value init
+                              :processed 0
+                              :last-event nil
+                              :last-error nil
+                              :status :running})]
+      (dosync (alter queries assoc query-name running-query))
+      (go
+        (loop [current-value init current-event (<! s)]
+          (if (nil? current-event)
+            (dosync (alter running-query assoc :status :finished))
+            (let [new-value (try
+                              (f current-value current-event)
+                              (catch Exception e e))]
+              (if (instance? Exception new-value)
+                (dosync
+                  (alter running-query
+                         merge {:last-event current-event
+                                :processed (inc (:processed @running-query))
+                                :last-error new-value
+                                :status :failed}))
+                (do
+                  (dosync
+                    (alter running-query
+                           merge {:last-event current-event
+                                  :current-value new-value
+                                  :processed (inc (:processed @running-query))}))
+                  (recur new-value (<! s))))))))))
+  (process-event! [this ev]
+    (go (>! channel ev))
+    (riak/store db "events" (riak/uuid) ev)))
+
+(defn async-stream [db]
+  (let [tube (chan 1)
+        tube-m (mult tube)]
+    (->AsyncStream db tube tube-m)))
+
+
+(defmethod stream "cold" [a-stream params]
   (let [ch (chan (buffer 1))
-        full-s (cold-stream a-stream (get params "from" 0))]
+        full-s (data-from a-stream (get params "from" 0))]
     (go
+      (log/info "Opening stream...")
       (loop [e (first full-s) s (rest full-s) closed? false]
         (if (nil? e)
           (do
@@ -38,54 +163,33 @@
                 (recur (first s) (rest s) closed?)))))))
     ch))

-(defmethod m-stream "hot-cold" [params a-stream]
+(defmethod stream "hot-cold" [a-stream params]
   (let [ch (chan (buffer 1))
-        full-s (cold-stream a-stream (get params "from" 0))]
+        full-s (data-from a-stream (get params "from" 0))]
     (go
       (loop [e (first full-s)
              s (rest full-s)
              closed? false
              last-t (System/currentTimeMillis)]
         (let [rest-s (rest s)
-              new-s (if (empty? rest-s) (cold-stream a-stream last-t) s)
+              new-s (if (empty? rest-s) (data-from a-stream last-t) s)
               last-t (if (empty? rest-s) (System/currentTimeMillis) last-t)]
           (if (nil? e)
-            (do
-              #_(close! ch)
-              (log/info ":::::::::::::::::::: Stream depleted, switching to hot stream"))
+            (log/info ":::::::::::::::::::: Stream depleted, switching to hot stream")
             (if closed?
               (log/info ":::::::::::::::::::: Stream closed by peer, switching to hot stream")
-              (do
-                (let [closed? (not (>! ch e))]
-                  (recur (first new-s) (rest new-s) closed? last-t)))))))
+              (let [closed? (not (>! ch e))]
+                (recur (first new-s) (rest new-s) closed? last-t))))))
       (tap (:mult-channel a-stream) ch))
     ch))

-(defmethod m-stream "hot" [params a-stream]
+(defmethod stream "hot" [a-stream params]
   (let [ch (chan 1)]
-    (tap (:tube-m a-stream) ch)
-    ch))
-
-(defprotocol Stream
-  (clean! [this])
-  (stream [this params]))
-
-(defprotocol EventProcessor
-  (process-event! [this ev]))
-
-(defrecord AsyncStream [db channel mult-channel]
-  Stream
-  (clean! [this] (riak/delete-all! db))
-  (stream [this params] (m-stream params this))
-  EventProcessor
-  (process-event! [this ev]
-    (go (>! channel ev))
-    (riak/store db "events" (riak/uuid) ev)))
-
-(defn async-stream [db]
-  (let [tube (chan 1)
-        tube-m (mult tube)]
-    (->AsyncStream db tube tube-m)))
+    (tap (:mult-channel a-stream) ch)
+    ch))
+
+#_(def test-ch (chan))
+#_(def test-ds (->DummyStream (m/make-connection "eventstore") test-ch (mult test-ch)))

 #_(def test-s (stream {"stream-type" "cold"}))


OO: Re-calculate table viewport if window is resized

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -318,6 +318,17 @@
        (+ main-navigation-height
           tab-navigation-height))))

+(defn set-window-resize-handler
+  [owner]
+  (let [resize-handler (fn [event]
+                         (om/set-state! owner
+                                        :table-view-height
+                                        (get-table-view-height)))]
+    (.addEventListener js/window
+                       "resize"
+                       resize-handler)
+    (om/set-state! owner :resize-handler resize-handler)))
+
 (defmethod table-page :default
   [app-state owner {:keys [slick-grid-event-handlers] :as opts}]
   "Om component for the table grid.
@@ -348,10 +359,17 @@
   (reify
     om/IDidMount
     (did-mount [_]
+      (set-window-resize-handler owner)
       (let [data (get-in app-state [:data])]
         (when-let [[grid dataview]
                    (init-grid! data owner slick-grid-event-handlers)]
           (handle-table-events app-state grid dataview))))
+
+    om/IWillUnmount
+    (will-unmount [_]
+      (.removeEventListener js/window
+                            "resize"
+                            (om/get-state owner :resize-handler)))

     om/IWillReceiveProps
     (will-receive-props [_ next-props]
@@ -369,8 +387,8 @@
               (.setItems dataview (clj->js new-data) _id)
               (.render grid))))))

-    om/IRender
-    (render [_]
+    om/IRenderState
+    (render-state [_ {:keys [table-view-height]}]
       (let [{:keys [data dataset-info]
              {:keys [prevent-scrolling-in-table-view? submission-clicked]}
              :table-page}
@@ -381,7 +399,8 @@
         (html
          [:div {:class "table-view"
                 :style (when prevent-scrolling-in-table-view?
-                         {:height (get-table-view-height)
+                         {:height (or table-view-height
+                                      (get-table-view-height))
                           :overflow "hidden"})}
           (when (:data submission-clicked)
             (om/build submission-view


CMR-8143: Fixed build.

CMR-8143: Fixed build.

--- common-lib/project.clj
+++ common-lib/project.clj
@@ -19,7 +19,6 @@
                  [clojusc/ltest "0.3.0"]
                  [com.dadrox/quiet-slf4j "0.1"]
                  [com.fasterxml.jackson.core/jackson-core "2.13.2"]
-                 [com.fasterxml.jackson.core/jackson-databind "2.13.2.1"]
                  [com.fasterxml.jackson.dataformat/jackson-dataformat-cbor "2.13.2"]
                  [com.gfredericks/test.chuck "0.2.9"]
                  [com.taoensso/timbre "5.1.0"]


formatting

formatting

--- test/clj/com/rpl/specter/core_test.clj
+++ test/clj/com/rpl/specter/core_test.clj
@@ -3,7 +3,7 @@
         [clojure.test.check.clojure-test]
         [com.rpl specter]
         [com.rpl.specter test-helpers])
-  (:require [clojure.test.check
+  (:require [clojure.test.check
              [generators :as gen]
              [properties :as prop]]
             [clojure.test.check :as qc]))
@@ -24,7 +24,7 @@
 (defspec select-all-keyword-filter
   (for-all+
     [kw gen/keyword
-     v (gen/vector (max-size 5
+     v (gen/vector (max-size 5
                      (gen-map-with-keys gen/keyword gen/int kw)))
      pred (gen/elements [odd? even?])]
     (= (select [ALL kw pred] v)
@@ -33,12 +33,12 @@

 (defspec select-pos-extreme-pred
   (for-all+
-    [v (gen/vector gen/int)
-     pred (gen/elements [odd? even?])
-     pos (gen/elements [[FIRST first] [LAST last]])]
-    (= (select-one [(filterer pred) (first pos)] v)
-       (->> v (filter pred) ((last pos)))
-       )))
+   [v (gen/vector gen/int)
+    pred (gen/elements [odd? even?])
+    pos (gen/elements [[FIRST first] [LAST last]])]
+   (= (select-one [(filterer pred) (first pos)] v)
+      (->> v (filter pred) ((last pos)))
+      )))

 (defspec select-all-on-map
   (for-all+
@@ -157,7 +157,7 @@
      )))

 (defspec replace-in-test
-  (for-all+
+  (for-all+
     [v (gen/vector gen/int)]
     (let [res (->> v (map (fn [v] (if (even? v) (inc v) v))))
           user-ret (->> v
@@ -170,7 +170,7 @@
          ))))

 (defspec replace-in-custom-merge
-  (for-all+
+  (for-all+
     [v (gen/vector gen/int)]
     (let [res (->> v (map (fn [v] (if (even? v) (inc v) v))))
           last-even (->> v (filter even?) last)


Test for NPE in uri->job-name

Test for NPE in uri->job-name

--- test/emender_jenkins/rest_api_test.clj
+++ test/emender_jenkins/rest_api_test.clj
@@ -368,6 +368,11 @@
             "test-Product_Name-Product_Version-Book_Name-en-US (prod)"
             (uri->job-name "http://jenkins.server.com:8080/test-Product_Name-Product_Version-Book_Name-en-US%20(prod)" "http://jenkins.server.com:8080/")
             )))
+
+(deftest test-uri->job-name-NPE
+    "Check the function emender-jenkins.rest-api/uri->job-name."
+    (testing "the function emender-jenkins.rest-api/uri->job-name."
+        (is (thrown? NullPointerException (uri->job-name nil "prefix")))))

 (deftest test-body->results
     "Check the function emender-jenkins.rest-api/body->results."


small fix

small fix

--- src/cljs/salava/extra/socialuser/ui/connections.cljs
+++ src/cljs/salava/extra/socialuser/ui/connections.cljs
@@ -157,23 +157,27 @@
     (fn []
       [:div
        [:div.info-block
-        [:a {:href (path-for "/connections/user")}
+        ;[:a {:href (path-for "/connections/user")}
          [:div.info
           ;[:i.fa.fa-user.icon]
           [:div.text
            [:p.num (->> (:following-users @state) count)]
            [:p.desc (t :social/Followedusers)]
-           ]]]]
+           ]]
+         ;]
+        ]

        [:div.info-block
-        [:a {:href (path-for "/connections/user")}
+        ;[:a {:href (path-for "/connections/user")}
          [:div.info
           (when (pos? (count (:pending @state))) [:span.badge (count (:pending @state))])
           ;[:i.fa.fa-user.icon]
           [:div.text
            [:p.num (->> (:followers-users @state) count)]
            [:p.desc (t :social/Followersusers)]
-           ]]]]])))
+           ]
+          ;]
+        ]]])))

 (defn handler [site-navi]
   (let [state (atom {:visible-area  nil


Fix bug in Implementation of Uwes algorithm

The computation of singleton proper premises was not correct.

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

--- src/conexp/contrib/experimental/ryssel_algorithm.clj
+++ src/conexp/contrib/experimental/ryssel_algorithm.clj
@@ -26,15 +26,19 @@
 (defn ryssel-base
   "Returns the implications computed by Ryssels Algorithm, as a lazy sequence."
   [ctx]
-  (let [gens (reduce! (fn [map x]     ;generating elements of attribute extents
-                        (let [extent (aprime ctx #{x})]
-                          (assoc! map extent
-                            (conj (get map extent #{}) x))))
-                      {}
-                      (attributes ctx)),
-        M    (set (keys gens))]       ;all attribute extents
+  (let [gens        (reduce! (fn [map x]     ;generating elements of attribute extents
+                               (let [extent (aprime ctx #{x})]
+                                 (assoc! map extent
+                                         (conj (get map extent #{}) x))))
+                             {}
+                             (attributes ctx)),
+        M           (set (keys gens)),       ;all attribute extents
+        empty-prime (adprime ctx #{})]
     (->> (reduce into
-                 ()
+                 (for [m (attributes ctx)
+                       :when (not= (adprime ctx #{m})
+                                   (conj empty-prime m))]
+                   #{m})
                  (pmap (fn [A]
                          (let [candidates (set-of U | U (disj M A),
                                                       :let [U-cap-A (intersection U A)]
@@ -46,16 +50,11 @@
                                                                                :when (and (not (subset? X Y))
                                                                                (not (subset? Y X))))),
                                covers     (cover (objects ctx) candidates A)]
-                           (concat (for [m (gens A)
-                                         :when (exists [N M]
-                                                 (and (subset? A N)
-                                                      (not= (gens N) #{m})))]
-                                     #{m})
-                                   (for [X covers]
-                                     (set-of m | Y X, m (gens Y))))))
+                           (for [X covers]
+                             (set-of m | Y X, m (gens Y)))))
                        M))
          distinct
-         (map #(make-implication % (context-attribute-closure ctx %))))))
+         (map #(make-implication % (adprime ctx %))))))

 ;;;


* benchmark/cljs/benchmark_runner.cljs: add nth / -nth benchmark. empty PHM benchmark

--- benchmark/cljs/benchmark_runner.cljs
+++ benchmark/cljs/benchmark_runner.cljs
@@ -40,6 +40,8 @@
 (simple-benchmark [] [] 1000000)
 (simple-benchmark [] [1 2 3] 1000000)
 (simple-benchmark [coll [1 2 3]] (transient coll) 100000)
+(simple-benchmark [coll [1 2 3]] (nth coll 0) 1000000)
+(simple-benchmark [coll [1 2 3]] (-nth coll 0) 1000000)
 (simple-benchmark [coll [1 2 3]] (conj coll 4) 1000000)
 (simple-benchmark [coll [1 2 3]] (-conj coll 4) 1000000)
 (simple-benchmark [coll [1 2 3]] (seq coll) 1000000)
@@ -98,6 +100,7 @@
 (simple-benchmark [coll pmap] (get coll :f0) 1000000)
 (simple-benchmark [coll pmap] (-lookup coll :f0 nil) 1000000)
 (simple-benchmark [coll pmap] (assoc coll :g0 32) 1000000)
+(simple-benchmark [coll cljs.core.PersistentHashMap/EMPTY] (assoc coll :f0 1) 1000000)
 (println)

 (println ";;; seq ops")


A better docstring

A better docstring

--- umm-spec-lib/src/cmr/umm_spec/util.clj
+++ umm-spec-lib/src/cmr/umm_spec/util.clj
@@ -133,7 +133,7 @@
      value)))

 (defn default-value?
-  "Does the given value match umm-spec-lib default?"
+  "Returns true if value is the umm-spec-lib default/placeholder"
   [value]
   (= value not-provided))


Adjust test to actually do what it says.

--- messaging/test/immutant/messaging_test.clj
+++ messaging/test/immutant/messaging_test.clj
@@ -194,10 +194,10 @@

 (deftest publish-from-a-listener-should-work
   (let [q (queue "pub-listener" :durable false)
-        p (promise)
-        l (listen q #(deliver p %))]
+        q2 (queue "pub-response" :durable false)
+        l (listen q #(publish q2 %))]
     (try
       (publish q :ham)
-      (is (= :ham (deref p 1000 :failure)))
+      (is (= :ham (receive q2 :timeout 1000 :timeout-val :failure)))
       (finally
         (.close l)))))


rm redundancy in action phrase.

rm redundancy in action phrase.

--- clojure/beer-song/beer.clj
+++ clojure/beer-song/beer.clj
@@ -10,8 +10,9 @@
 (defn- action-phrase [n]
   (cond
    (= n 0) "go to the store and buy some more, "
-   (= n 1) "take it down and pass it around, "
-   :else "take one down and pass it around, "))
+   :else (str "take "
+              (if (= n 1) "it" "one")
+              " down and pass it around, ")))

 (defn- next-count-phrase [n]
   (cond


Fix typo.

Fix typo.

--- dev/migrate.clj
+++ dev/migrate.clj
@@ -58,7 +58,7 @@
                                                                    (hayt/order-by [:type :desc])
                                                                    (hayt/limit 1)))))]
           (db/execute session (hayt/update :sensor_metadata
-                                           (hayt/set-columns :upper_ts first-ts
-                                                             :lower_ts last-ts)
+                                           (hayt/set-columns :upper_ts last-ts
+                                                             :lower_ts first-ts)
                                            (hayt/where where)))))))
   (log/info "Finished populating sensor bounds."))


Disable template caching in dev mode

Disable template caching in dev mode

When the layout is changed during development, the pages are still
served from the cache. Turning caching off works much better during
development.

--- dev/src/dev.clj
+++ dev/src/dev.clj
@@ -6,6 +6,7 @@
             [clojure.java.io :as io]
             [duct.core :as duct]
             [eftest.runner :as eftest]
+            [selmer.parser :as templates]
             [integrant.core :as ig]
             [integrant.repl :refer [clear halt go init prep reset]]
             [integrant.repl.state :refer [config system]]))
@@ -24,4 +25,6 @@

 (integrant.repl/set-prep! (comp duct/prep read-config))

+(templates/cache-off!)
+
 (go)


Modified markov code to accomodate new json.

The new json is slightly different - map holds strings mapped to counts,
instead of containers of strings. Code changed to match.

--- wysitutwyg/src-cljs/wysitutwyg/markov.cljs
+++ wysitutwyg/src-cljs/wysitutwyg/markov.cljs
@@ -47,7 +47,7 @@
   "Given a starting state, returns a lazy sequence of generated words until it
   reaches an end state."
   [start-state counts]
-  (if-let [next-word (pick-word (counts start-state))]
+  (if-let [next-word (pick-word (counts (map #(apply str %) start-state)))]
     (cons (apply str next-word)
           (lazy-seq (lazy-chain (conj (vec (rest start-state))
                                       next-word)


debugger: fix signal highlighting

debugger: fix signal highlighting

--- examples/_common/middleware/devtools.cljs
+++ examples/_common/middleware/devtools.cljs
@@ -105,17 +105,14 @@
 (defn -signal-id->parent-id
   "Returns a map."
   [signal-events]
-  (let [result (atom {})]
-    (doseq [{:keys [id parent-id]} signal-events]
-      (swap! result assoc id parent-id))
-
-    @result))
+  (into {} (map #(-> [(:id %) (:parent-id %)]) signal-events)))

 (defn -signal-parent-ids
   "Returns a set containing: id of parent, parent of parent, etc.
   Non-existent parent ids are ignored."
   [id->parent-id id]
   {:pre [(map? id->parent-id)]}
+  (println "id->parent-id =" id->parent-id)
   (let [existing-ids (keys id->parent-id)
         result (atom #{})]
     (loop [child-id id]
@@ -341,8 +338,8 @@
         signal-events (reaction (-> @debugger :signal-events))
         signal-id->parent-id (reaction (-signal-id->parent-id @signal-events))
         highlighted-signal-id (reaction (-> @debugger :highlighted-signal-id))
-        highlighted-signal-ids (reaction #(into #{@highlighted-signal-id}
-                                                (-signal-parent-ids @signal-id->parent-id @highlighted-signal-id)))]
+        highlighted-signal-ids (reaction (into #{@highlighted-signal-id}
+                                               (-signal-parent-ids @signal-id->parent-id @highlighted-signal-id)))]
     (-> (mvsa/track-keys debugger
                          [:initial-model :replay-mode? :visible? :toggle-visibility-shortcut :action-events])
         (assoc :signal-events (reaction


reflexive morphology

reflexive morphology

--- src/babel/francais/morphology/verbs.clj
+++ src/babel/francais/morphology/verbs.clj
@@ -12,8 +12,12 @@

 (def suppress-incomplete-morphology-errors true)

+(defn reflexive-to-infinitive [reflexive-infinitive]
+  "e.g.: se amuser -> amuser"
+  (string/replace reflexive-infinitive #"^se " ""))
+
 (defn conditional [word]
-  (let [infinitive (get-in word '(:français))
+  (let [infinitive (reflexive-to-infinitive (get-in word [:français]))
         ar-type (try (re-find #"ar$" infinitive)
                      (catch Exception e
                        (throw (Exception. (str "Can't regex-find on non-string: " infinitive " from word: " word)))))
@@ -90,7 +94,7 @@
          (throw (Exception. message)))))))

 (defn future [word]
-  (let [infinitive (get-in word '(:français))
+  (let [infinitive (reflexive-to-infinitive (get-in word '(:français)))
         ar-type (try (re-find #"ar$" infinitive)
                      (catch Exception e
                        (throw (Exception. (str "Can't regex-find on non-string: " infinitive " from word: " word)))))
@@ -164,7 +168,7 @@
      (throw (Exception. (str "get-string: futuro regular inflection: don't know what to do with input argument: " (strip-refs word)))))))

 (defn imperfect [word]
-  (let [infinitive (get-in word '(:français))
+  (let [infinitive (reflexive-to-infinitive (get-in word [:français]))
         ar-type (try (re-find #"ar$" infinitive)
                      (catch Exception e
                        (throw (Exception. (str "Can't regex-find on non-string: " infinitive " from word: " word)))))
@@ -233,7 +237,7 @@
          (throw (Exception. message)))))))

 (defn present [word]
-  (let [infinitive (get-in word '(:français))
+  (let [infinitive (reflexive-to-infinitive (get-in word [:français]))
         ar-type (try (re-find #"ar$" infinitive)
                      (catch Exception e
                        (throw (Exception. (str "Can't regex-find on non-string: " infinitive " from word: " word)))))
@@ -331,7 +335,7 @@
      (throw (Exception. (str "get-string: present regular inflection: don't know what to do with input argument: " (strip-refs word) " (er-type: " er-type "; ir-type: " ir-type "; re-type: " re-type))))))

 (defn passe-compose [word]
-  (let [infinitive (get-in word '(:français))]
+  (let [infinitive (reflexive-to-infinitive (get-in word '(:français)))]
     (if-let [irregular (get-in word [:past-participle])]
       irregular


add present-tense analysis rules

add present-tense analysis rules

--- src/babel/italiano/morphology/verbs.clj
+++ src/babel/italiano/morphology/verbs.clj
@@ -1,85 +1,201 @@
 (ns babel.italiano.morphology.verbs)

+(def replace-patterns-present-tense
+  [
+   {:p [#"^([^' ]+)o$"         "$1are"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)o$"         "$1ere"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)isco$"      "$1ire"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)o$"         "$1ire"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)o$"         "$1arsi"] ;; alzo -> alzarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)o$"         "$1irsi"] ;; diverto -> divertirso
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ico$"       "$1ire"] ;; dico -> dire
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :1st}}}
+                 :infl :present}}}
+   ;; 2nd sing
+   {:p [#"^([^' ]+)i$"         "$1are"] ;; lavi -> lavare
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)i$"         "$1iare"] ;; studi -> studiare
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)i$"         "$1arsi"] ;; lavi -> lavarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)cci$"       "$1cciare"] ;; abbracci -> abbracciare
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)i$"         "$1ere"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)i$"         "$1ire"] ;; senti -> sentire
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+c)hi$"       "$1are"] ;; cerchi -> cercare
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+
+   {:p [#"^([^' ]+)i$"         "$1iarsi"] ;; arrabi -> arrabiarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)sci$"       "$1re"] ;; finisci -> finire
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)i$"         "$1irsi"] ;; diverti -> divertirsi
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ici$"       "$1ire"] ;; dici -> dire
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)hi$"        "$1are"] ;; pieghi -> piegare
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :2nd}}}
+                 :infl :present}}}
+
+   {:p [#"^([^' ]+)a$"         "$1are"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)e$"         "$1ere"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)e$"         "$1ire"]
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)a$"         "$1arsi"] ;; prepara -> preperarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)sce$"       "$1re"] ;; finisce -> finire
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)te$"        "$1tirsi"] ;; diverte -> divertirsi
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ice$"      "$1ire"] ;; dice -> dire
+    :u {:synsem {:subcat {:1 {:agr {:number :sing
+                                    :person :3rd}}}
+                 :infl :present}}}
+
+   {:p [#"^([^' ]+)iamo$"      "$1are"]  ;; parliamo -> parlare
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+
+   {:p [#"^([^' ]+)iamo$"      "$1iare"] ;; mangiamo -> mangiare
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)iamo$"      "$1ere"]
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)iamo$"      "$1ire"]
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+c)hiamo$"    "$1are"] ;; sprechiamo -> sprecare
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)iamo$"      "$1iarsi"] ;; arrabiamo -> arrabiarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)iamo$"      "$1arsi"] ;; chiamiamo -> chiamarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)iamo$"      "$1irsi"] ;; divertiamo -> divertirsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ciamo$"     "$1re"] ;; diciamo -> dire
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)hiamo$"     "$1are"] ;; pieghiamo -> piegare
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   ;; 2nd plur
+   {:p [#"^([^' ]+)([aei])te$" "$1$2re"] ;; parlate -> parlare; leggere -> leggere
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :2nd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)([aei])te$" "$1$2rsi"] ;; chiamate -> chiamarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :2nd}}}
+                 :infl :present}}}
+
+   {:p [#"^([^' ]+)ano$"       "$1are"]
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ono$"       "$1ere"]
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ono$"       "$1ire"]
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+
+   {:p [#"^([^' ]+)ano$"       "$1arsi"] ;; alzano -> alzarsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)scono$"     "$1re"] ;; finiscono -> finire
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ono$"       "$1irsi"] ;; divertono -> divertirsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :1st}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)cono$"      "$1re"] ;; dicono -> dire
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+   {:p [#"^([^' ]+)ono$"       "$1irsi"] ;; vestono -> vestirsi
+    :u {:synsem {:subcat {:1 {:agr {:number :plur
+                                    :person :3rd}}}
+                 :infl :present}}}
+   ])
+
 (def replace-patterns
-  [
-   {:p [#"^([^' ]+)o$" "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)o$" "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)o$" "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)i$" "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$" "$1iare"] ;; "studi" => "studiare"
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}}}}
-
-   {:p [#"^([^' ]+)ci$" "$1ciare"] ;; e.g. "abbracci" => "abbracciare"
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$" "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)i$" "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)a$" "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)e$" "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)e$" "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :sing
-                                    :person :3rd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)iamo$" "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$" "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)iamo$" "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :1st}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)([aei])te$" "$1$2re"] ;; parlate => parlare; leggere => leggere
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :2nd}}}
-                 :infl :present}}}
-
-   {:p [#"^([^' ]+)ano$" "$1are"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ono$" "$1ere"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   {:p [#"^([^' ]+)ono$" "$1ire"]
-    :u {:synsem {:subcat {:1 {:agr {:number :plur
-                                    :person :3rd}}}
-                 :infl :present}}}
-   ])
-
-
-
+  (concat
+   replace-patterns-present-tense))


[EN] Bump kehaar version and include schema.

Also bump Clojure to 1.7.0.

--- resources/leiningen/new/kraken/project.clj
+++ resources/leiningen/new/kraken/project.clj
@@ -3,14 +3,15 @@
   :url "http://example.com/FIXME"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
-  :dependencies [[org.clojure/clojure "1.7.0-alpha5"]
+  :dependencies [[org.clojure/clojure "1.7.0"]
                  [org.clojure/tools.logging "0.3.1"]
                  [turbovote.resource-config "0.1.4"]
                  [com.novemberain/langohr "3.2.0"]
                  [democracyworks/datomic-toolbox "1.0.0" :exclusions [com.datomic/datomic-pro]]
                  [com.datomic/datomic-pro "0.9.5153" :exclusions [joda-time]]
                  [org.immutant/core "2.0.0"]
-                 [democracyworks/kehaar "0.2.1"]]
+                 [democracyworks/kehaar "0.3.1"]
+                 [prismatic/schema "0.4.3"]]
   :plugins [[lein-immutant "2.0.0"]]
   :main ^:skip-aot {{name}}.core
   :target-path "target/%s"


fix a bug on the results page when there are ties

--- cljs-client/tourneybot_client/core.cljs
+++ cljs-client/tourneybot_client/core.cljs
@@ -176,8 +176,7 @@
     [:tr
       [:td.place (when-not no-games-played? (str "#" (:place result)))]
       [:td.team-name (TeamNameCell (:team-name result) (:team-captain result))]
-      (if (and (zero? (:games-won result))
-               (zero? (:games-lost result)))
+      (if no-games-played?
         [:td.record-cell.no-games "-"]
         (RecordCell ties-allowed? result))]))


Updated Hiccup to 1.3.0-friendly version 0.3.6

--- ring-devel/project.clj
+++ ring-devel/project.clj
@@ -2,5 +2,5 @@
   :description "Ring development and debugging libraries."
   :url "http://github.com/mmcgrana/ring"
   :dependencies [[ring/ring-core "0.3.9"]
-                 [hiccup "0.3.5"]
+                 [hiccup "0.3.6"]
                  [clj-stacktrace "0.2.2"]])


loading progress delay

loading progress delay

--- src/cljs/daveconservatoire/site/ui.cljs
+++ src/cljs/daveconservatoire/site/ui.cljs
@@ -15,9 +15,10 @@
 (om/defui ^:once Button
   Object
   (render [this]
-    (let [{:keys [color]} (om/props this)]
+    (let [{:keys [color]
+           :or {color "orange"}} (om/props this)]
       (dom/a #js {:href      "#"
-                  :className (str "btn dc-btn-" (or color "orange"))}
+                  :className (str "btn dc-btn-" color)}
         (om/children this)))))

 (def button (om/factory Button))
@@ -130,6 +131,23 @@

 (defn route->factory [route] (om/factory (r/route->component route)))

+(om/defui ^:once Loading
+  Object
+  (initLocalState [_] {:show? false})
+
+  (componentDidMount [this]
+    (js/setTimeout
+      (fn [] (if (om/mounted? this) (om/set-state! this {:show? true})))
+      100))
+
+  (render [this]
+    (let [show? (om/get-state this :show?)]
+      (if show?
+        (dom/div nil "Loading page data...")
+        (dom/noscript nil)))))
+
+(def loading (om/factory Loading))
+
 (om/defui ^:once Root
   static uc/InitialAppState
   (initial-state [_ _]
@@ -162,5 +180,5 @@
           (dom/li nil (link {:to ::r/about} "About"))
           (dom/li nil (link {:to ::r/topic :params {::r/slug "getting-started"}} "Topic Getting Started")))
         (if (= :loading (get-in data [:ui/fetch-state ::df/type]))
-          "Loading page data..."
+          (loading nil)
           ((route->factory route) (assoc data :ref :page)))))))


make request animation frame

make request animation frame

--- src/cljs/infinitelives/pixi/events.cljs
+++ src/cljs/infinitelives/pixi/events.cljs
@@ -1,6 +1,34 @@
 (ns infinitelives.pixi.events
   (:require [cljs.core.async :refer [put! chan close!]])
   (:require-macros [cljs.core.async.macros :refer [go]]))
+
+;;
+;; Animation handler
+;;
+(def fallback-fps 60)
+
+(defn make-request-animation-frame
+  "compose a function that is the r-a-f func. returns a function. This returned function takes a callback and ensures
+  its called next frame"
+  []
+  (cond
+   (.-requestAnimationFrame js/window)
+   #(.requestAnimationFrame js/window %)
+
+   (.-webkitRequestAnimationFrame js/window)
+   #(.webkitRequestAnimationFrame js/window %)
+
+   (.-mozRequestAnimationFrame js/window)
+   #(.mozRequestAnimationFrame js/window %)
+
+   (.-oRequestAnimationFrame js/window)
+   #(.oRequestAnimationFrame js/window %)
+
+   (.-msRequestAnimationFrame js/window)
+   #(.msRequestAnimationFrame js/window %)
+
+   :else
+   #(.setTimeout js/window % (/ 1000 fallback-fps))))

 ;;


protect existing long values as gui height/width

--- src/clojure/zensols/cisql/db_access.clj
+++ src/clojure/zensols/cisql/db_access.clj
@@ -200,8 +200,8 @@
 (defn- display-height-width-fudge
   "Return the pixels to add to the gui as `[height width]`."
   []
-  [(Integer/parseInt (or (conf/config :guiheight) "0"))
-   (Integer/parseInt (or (conf/config :guiwidth) "0"))])
+  [(Integer/parseInt (str (or (conf/config :guiheight) "0")))
+   (Integer/parseInt (str (or (conf/config :guiwidth) "0")))])

 (defn display-results
   "Display results either in text or as a graphical swing table.


Increase probability of hitting a unique ident

--- src/com/wsscode/pathom/specs/query.cljc
+++ src/com/wsscode/pathom/specs/query.cljc
@@ -19,7 +19,9 @@
    (fn gen-ident-key [_] gen/keyword)

    ::gen-ident-value
-   (fn gen-ident-value [_] gen/simple-type-printable)
+   (fn gen-ident-value [_]
+     (gen/frequency [[15 gen/simple-type-printable]
+                     [1 (gen/return '_)]]))

    ::gen-ident
    (fn gen-ident [{::keys [gen-ident-key gen-ident-value] :as env}]


[#2877] Fix: Add java.time.Instant encoder to production code too

--- backend/src/akvo/lumen/db/dataset_version.clj
+++ backend/src/akvo/lumen/db/dataset_version.clj
@@ -1,5 +1,9 @@
 (ns akvo.lumen.db.dataset-version
-  (:require [hugsql.core :as hugsql]))
+  (:require [hugsql.core :as hugsql]
+            [cheshire.generate :as ches.generate])
+  (:import [java.time Instant]))
+
+(ches.generate/add-encoder Instant (fn [obj jsonGenerator] (.writeString jsonGenerator (str obj))))

 (hugsql/def-db-fns "akvo/lumen/lib/dataset_version.sql")


Uncommet clj-stacktrace injection.

Uncommet clj-stacktrace injection.

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -4,14 +4,14 @@
                   [clj-stacktrace "0.2.4"]
                   [lein-pprint "1.1.1"]
                   [slamhound "1.2.0"]
-                  [lein-cljsbuild "0.1.8"]
+                  [lein-cljsbuild "0.1.9"]
                   ;[lein-autodoc "0.9.0"]
                   [lein-marginalia "0.7.0"]
                   [lein-noir "1.2.0"]]
-        ;:injections [(let [orig (ns-resolve (doto 'clojure.stacktrace require)
-                                            ;'print-cause-trace)
-                           ;new (ns-resolve (doto 'clj-stacktrace.repl require)
-                                           ;'pst)]
-                       ;(alter-var-root orig (constantly @new)))]
+        :injections [(let [orig (ns-resolve (doto 'clojure.stacktrace require)
+                                            'print-cause-trace)
+                           new (ns-resolve (doto 'clj-stacktrace.repl require)
+                                           'pst)]
+                       (alter-var-root orig (constantly @new)))]
         :vimclojure-opts {:repl true
                           :port 2113}}}


Lein: add a clojars mirror

Lein: add a clojars mirror

--- .lein/profiles.clj
+++ .lein/profiles.clj
@@ -46,7 +46,7 @@
 ;;                  [lein-ritz "0.7.0"]   		; for nrepl-inspect
 ;;                  [lein-marginalia "0.8.0"]
                     [lein-ancient "0.6.7"]
-;;                  [lein-try "0.4.3"]
+;;                    [lein-try "1.4.3"]
 ;;                  ;;[lein-alembic "0.1.0"]     ; make alembic available -> reload prj deps w/o restarting repl: (alembic.still/load-project)
 ;;                  [lein-clojuredocs "1.0.2"] ; Create clojuredocs-style doc
 ;;                  ;;[quickie "0.2.6"] ; autotest for clojure.test
@@ -66,4 +66,5 @@
  ;;                      ritz.nrepl.middleware.simple-complete/wrap-simple-complete
  ;;                      io.aviso.nrepl/pretty-middleware ;; pretty-print exceptions in repl
                        ]}
+       :mirrors {#"clojars" {:name "clojars mirror" :url "https://clojars-mirror.tcrawley.org/repo/"}}
  }}


Created UI "X" button that allows user to close tabs when clicked.

--- src/lt/objs/tabs.cljs
+++ src/lt/objs/tabs.cljs
@@ -33,6 +33,7 @@
           (set! (.-scrollLeft gp) (+ (- right pwidth) 50)))
         ))))

+
 (behavior ::on-destroy-remove
           :triggers #{:destroy :closed}
           :reaction (fn [this]
@@ -104,6 +105,10 @@
 (defn dirty? [c e]
   (str c (when (:dirty @e)
            " dirty")))
+
+(defui close-tab [obj] ;; TODO: Create x button
+  [:button "x"]
+  :click (fn [] (object/raise obj :close)))

 (defui item [multi e pos]
   [:li {:class (-> " "
@@ -113,7 +118,8 @@
         :title (->path e)
         :obj-id (object/->id e)
         :pos pos}
-   (->name e)]
+   (close-tab e)
+   (->name e)]    ;; TODO: Add 'x' button next to file name
   :click (fn []
            (active! e))
   :contextmenu (fn [ev]
@@ -363,7 +369,7 @@
    [:div.list
     (bound this #(objs-list this (:objs %)))]
    [:div.items
-    (map-bound (partial tabbed-item (subatom this :active-obj)) this {:path [:objs]})]
+    (map-bound (partial tabbed-item (subatom this :active-obj)) this {:path [:objs]})]    ;; TODO: Try putting x here
    (vertical-grip this)]
   :click (fn []
            (object/raise this :active)))


[fix] include order.

[fix] include order.

--- src/ombs/db/admin.clj
+++ src/ombs/db/admin.clj
@@ -3,11 +3,11 @@
             [korma.db :as kdb]
             [ombs.db.payment :as dbpay]
             [ombs.db.partial :as partial-event]
-            [korma.core :as sql]
-            [noir.session :as sess]
             [ombs.db.old :refer :all] ; for entity
             [ombs.validate :as isvalid]
             [ombs.funcs :as fns]
+            [noir.session :as sess]
+            [korma.core :as sql]
             ))

 (declare rm-fee)


Only transact :seqs if supplied.

Only transact :seqs if supplied.

--- src-cljs/pepa/api.cljs
+++ src-cljs/pepa/api.cljs
@@ -255,7 +255,8 @@
       (prn response)
       (when (:successful? response)
         (let [data (:response/transit response)]
-          (om/transact! state :seqs #(merge % (:seqs data))))))))
+          (when-let [seqs (:seqs data)]
+            (om/transact! state :seqs #(merge % seqs))))))))

 (go-loop []
   (<! (async/timeout 1000))


list interface

list interface

--- src/ontrail/pages.clj
+++ src/ontrail/pages.clj
@@ -9,18 +9,32 @@
    [ontrail.webutil :as webutil]
    [ontrail.auth :as auth]
    [ontrail.formats :as formats]
+   [ontrail.mongerfilter :as mongerfilter]

    [clj-time.core :as time]
    [hiccup.form :as form]
    [hiccup.core :as hiccup]
    [stencil.core :as stencil]
-   [clojure.string :as string]
-   ))
+   [clojure.string :as string])
+  (:import [java.net URLEncoder]))

 (def #^{:private true} logger (org.slf4j.LoggerFactory/getLogger (str *ns*)))

-(defn url[& parts]
-  (apply (partial str "/sp") parts))
+(defn urlp [params]
+  (if (empty? params)
+    ""
+    (str "?"
+         (apply str
+                (interpose "&"
+                 (map (fn [param] (str (-> param first name) "=" (-> param second URLEncoder/encode)))
+                   params))))))
+
+;; (url {:a "b" :c "d"} "/list/" page) = /list/page?a=b&c=d
+(defn url[maybe-params & parts]
+  (if (map? maybe-params)
+    (let [params (urlp maybe-params)]
+      (apply (partial str "/sp") (concat parts [params])))
+    (apply (partial str "/sp" maybe-params) parts)))

 (defmacro render-with [render-fn data & [status]]
   `(try
@@ -79,9 +93,12 @@
    (row (:avghr ex))])

 (defn action [ex]
-  (str (:user ex) " " (:did ex) " "  (:duration ex)
+  (str (:user ex) " " (:did ex)
        (if (and (:distance ex) (not= (:distance ex) ""))
-         (str (:distance ex) " vauhdilla " (:pace ex)) "")))
+         (str " " (:distance ex) " ajassa " (:duration ex) " vauhdilla " (:pace ex))
+         (if (= "0 min" (:duration ex))
+           ""
+           (:duration ex)))))

 (defn latest-list-entry [ex]
   [:article.listEntry
@@ -97,17 +114,17 @@
      [:div.shortEx (-> ex :body utils/strip-html truncate)]]]
    ])

-(defn as-link [name page]
-  [:a.naviLink {:href (url "/latest/" page)} (str name)])
-
-(defn latest-paging [page current-count]
+(defn as-link [url-fn name page]
+  [:a.naviLink {:href (url-fn page)} (str name)])
+
+(defn latest-paging [url-fn page current-count]
   (let [pages 1
         next-pages (if (> current-count 0) (range (inc page) (+ page (inc pages))) [])
         start-page (- page pages)
         prev-pages (if (> start-page 0) (range start-page page) (range 1 page))
-        navigation  (vec (conj (concat (map (partial as-link "edellinen") prev-pages)
+        navigation  (vec (conj (concat (map (partial as-link url-fn "edellinen") prev-pages)
                                        [[:span.currentPage (str " " page " ")]]
-                                       (map (partial as-link "seuraava") next-pages)) :div.pageNavi))]
+                                       (map (partial as-link url-fn "seuraava") next-pages)) :div.pageNavi))]
     navigation))

 (defn header [user]
@@ -184,14 +201,14 @@
      ]]]])

 ;; renders /sp/latest/1
-(defn latest [page {res :exs user :user}]
+(defn latest [url-fn page {res :exs user :user}]
    [:html
     (head (str "ontrail.net :: " page))
     [:body [:div.main
      (header user)
-     (latest-paging page (count res))
+     (latest-paging url-fn page (count res))
      (for [entry res] (latest-list-entry entry))
-     (latest-paging page (count res))
+     (latest-paging url-fn page (count res))
      ]]])

 (defroutes templates
@@ -199,13 +216,23 @@
   (GET "/sp/latest/:page" {params :params cookies :cookies}
        (let [page (Integer/parseInt ^String (webutil/get-page params))
              user (auth/user-from-cookie cookies)]
-         (render-with (partial latest page)
+         (render-with (partial latest (partial url "/latest/") page)
                       {:exs (ex/get-latest-ex-list-default-order
                              user
                              {}
                              page)
                        :user user})))

+  (GET "/sp/list/:page" {params :params cookies :cookies}
+       (let [page (Integer/parseInt ^String (webutil/get-page params))
+             user (auth/user-from-cookie cookies)]
+         (render-with (partial latest (partial url (dissoc params :page) "/list/") page)
+                      {:exs  (ex/get-latest-ex-list user
+                                                    (mongerfilter/make-query-from params)
+                                                    (webutil/get-page params)
+                                           (mongerfilter/sortby params))
+                       :user user})))
+
   (GET "/sp/ex/:id" {params :params cookies :cookies}
        (let [user (auth/user-from-cookie cookies)]
          (render-with single-exercise
@@ -216,7 +243,7 @@
           (let [user (auth/user-from-cookie cookies)
                 comment (mutate/comment-ex user params)]
             (redirect (url "/ex/" (:id params))))
-          (redirect "/sp/login.html")))
+          (redirect "/s/login.html")))

   (GET "/sp/addex" {params :params cookies :cookies} ;;addex
        (let [user (auth/user-from-cookie cookies)]
@@ -233,7 +260,5 @@
   (GET "/sp" {cookies :cookies}
        (if (not= "nobody" (auth/user-from-cookie cookies))
          (redirect "/sp/latest/1")
-         (redirect "/s/login.html")))
+         (redirect "/s/login.html"))))

-  )
-


endpoint for counts

endpoint for counts

--- src/ophion/server.clj
+++ src/ophion/server.clj
@@ -49,6 +49,21 @@
    :headers {"content-type" "application/json"}
    :body (json/generate-string schema)})

+(defn count-all-handler
+  [db protograph request]
+  (let [labels (keys (:vertexes protograph))]
+    {:status 200
+     :headers {"content-type" "application/json"}
+     :body (json/generate-string (mongo/counts db))}))
+
+(defn count-label-handler
+  [db request]
+  (let [label (get-in request [:params :label])
+        number (mongo/number db label)]
+    {:status 200
+     :headers {"content-type" "application/json"}
+     :body (json/generate-string {label number})}))
+
 (defn aggregate-query-handler
   [mongo protograph request]
   (let [query (mapv identity (read-json (:body request)))
@@ -64,6 +79,18 @@
   (fn [request]
     (log/info "--> fetch schema")
     (#'fetch-schema-handler schema request)))
+
+(defn count-all
+  [db protograph]
+  (fn [request]
+    (log/info "--> count all")
+    (#'count-all-handler db protograph request)))
+
+(defn count-label
+  [db]
+  (fn [request]
+    (log/info "--> count label" (get-in request [:params :label]))
+    (#'count-label-handler db request)))

 (defn aggregate-query
   [mongo protograph]
@@ -81,6 +108,8 @@
   [graph protograph]
   [["/" :home #'home]
    ["/schema/protograph" :schema (fetch-schema protograph)]
+   ["/count" :count-all (count-all graph protograph)
+    [["/:label" :count-label (count-label graph)]]]
    ["/query/:label" :aggregate-query (aggregate-query graph protograph)]])

 (def parse-args


Make promesa work with thenable objects (see issue #66).

--- src/promesa/impl.cljc
+++ src/promesa/impl.cljc
@@ -56,12 +56,19 @@
        pt/IPromise
        (-map [it cb]
          (.then it #(cb %)))
-       (-bind [it cb]
-         (.then it #(cb %)))
        (-catch [it cb]
          (.catch it #(cb %))))))

-#?(:cljs (extend-promise! js/Promise))
+#?(:cljs
+   (extend-promise! js/Promise))
+
+#?(:cljs
+   (extend-type object
+     pt/IPromise
+     (-map [it cb]
+       (pt/-map (pt/-promise it) cb))
+     (-catch [it cb]
+       (pt/-catch (pt/-promise it) cb))))

 #?(:clj
    (extend-type CompletableFuture


Debug kc cypress dark-lumenci build problem

--- backend/src/akvo/lumen/endpoint/user.clj
+++ backend/src/akvo/lumen/endpoint/user.clj
@@ -31,7 +31,8 @@
     ["/profile" {:get {:handler (fn [{tenant :tenant
                                     query-params :query-params}]
                                 (let [u (user/user authorizer tenant (get query-params "email"))]
-                                  (lib/ok (select-keys u [:admin :email :firstName :id :lastName]))))}}]]
+                                    (log/error :email (get query-params "email") :profile u)
+                                    (lib/ok (select-keys u [:admin :email :firstName :id :lastName])))))}}]]
    ["/admin/users"
     ["" {:get {:handler (fn [{tenant :tenant}]
                           (user/users authorizer tenant))}}]


Fixed comment in time demo.

Fixed comment in time demo.

--- src/re_demo/time.cljs
+++ src/re_demo/time.cljs
@@ -31,7 +31,7 @@
                   [:li "maximum - max time as an integer e.g. 1400 - will not allow input more than this time - default 2359."]
                   [:li "on-change - function to call upon change."]
                   [:li "disabled - true if the component should be disabled - default false"]
-                  [:li "show-time-icon - true if the clock icon should be disabled - default false"]
+                  [:li "show-time-icon - true if the clock icon should be displayed - default false"]
                   [:li "style - css style"]]
                 [label :label "Examples" :style {:font-weight "bold"}]
                 [label :label "Basic time input, empty model"]


Init sink proxies with a small buffer - absence of buffer made app hang on reload! Added shutdown channel logic.

--- cljx/plongeur-cljs/src/kierros/core.cljs
+++ cljx/plongeur-cljs/src/kierros/core.cljs
@@ -1,6 +1,7 @@
 (ns kierros.core
   "Cycle-flavoured core functions."
-  (:require [cljs.core.async :as a :refer [<! chan]]))
+  (:require [cljs.core.async :as a :refer [<! chan close!]])
+  (:require-macros [cljs.core.async.macros :refer [go]]))

 (defn sink-proxies
   "Accepts a map of drivers. Returns a map of the equivalent of Rx.ReplaySubject instance
@@ -8,7 +9,7 @@
   [drivers]
   (->> drivers
        keys
-       (map (fn [name] [name (chan)]))
+       (map (fn [name] [name (chan 10)]))
        (into {})))

 (defn call-drivers
@@ -25,11 +26,19 @@
 (defn weld-cycle!
   "Closes the cycle between the sinks and sink-proxies."
   [sink-chans sink-proxy-chans]
-  (->> sink-chans
-       (map (fn [[key sink-chan]]
-              (when sink-chan
-                (a/pipe sink-chan (key sink-proxy-chans)))))
-       (dorun)))
+  (doseq [[key sink-chan] sink-chans]
+    (when sink-chan
+      (a/pipe sink-chan (key sink-proxy-chans)))))
+
+(defn shutdown-channel
+  "Accepts a colletion of channels. Returns the shutdown channel.
+  When a signal is taken from the shutdown channel, all specified channels are closed."
+  [chans]
+  (let [shutdown-chan (chan 1)]
+    (go
+      (<! shutdown-chan)              ;; wait for the shutdown signal
+      (doseq [ch chans] (close! ch))) ;; close all driver channels
+    shutdown-chan))

 (defn run
   "Cycle.run equivalent. Accepts a main function and a map of drivers."
@@ -38,4 +47,5 @@
         source-chans     (call-drivers drivers sink-proxy-chans)
         sink-chans       (main source-chans)
         _                (weld-cycle! sink-chans sink-proxy-chans)]
-    (println "cycle running")))
+    (println "cycle running")
+    (->> sink-proxy-chans vals shutdown-channel)))


Do not calculate the time for every message in clojure-http-kit

--- clojure-http-kit/src/sse_server/core.clj
+++ clojure-http-kit/src/sse_server/core.clj
@@ -35,8 +35,9 @@
     (handle-404)))

 (defn notify-channels []
-  (doseq [channel (keys @channel-hub)]
-    (send! channel (str "data: " (System/currentTimeMillis) "\n\n") false)))
+  (let [time (System/currentTimeMillis)]
+    (doseq [channel (keys @channel-hub)]
+      (send! channel (str "data: " time "\n\n") false))))

 (defn start-timer []
   (schedule-task 1000


Don't delete orphaned files for any of our users

--- common/clojure/nightweb/torrents_dht.clj
+++ common/clojure/nightweb/torrents_dht.clj
@@ -157,7 +157,7 @@
       (on-recv-meta-file user-hash-bytes
                          (io/read-meta-file parent-dir path-leaves)))
     ; remove any files that the torrent no longer contains
-    (when-not (c/is-me? user-hash-bytes)
+    (when-not (c/is-me? user-hash-bytes true)
       (io/delete-orphaned-files user-hash-bytes paths))))

 ; receiving meta links


Multiple asteroids. Asteroid variance

Multiple asteroids. Asteroid variance

--- src/asteroids/core.clj
+++ src/asteroids/core.clj
@@ -19,8 +19,12 @@
 (def turn-speed 4)
 (def shot-size (/ ship-size 10))
 (def shot-speed 1.5)
-(def shot-millis 200)
-(def asteroid-max-speed 1)
+(def shot-millis 400)
+(def asteroids-start-number 6)
+(def asteroid-start-size 4)
+(def asteroid-size-variance 0.1)
+(def asteroid-jaggedness 0.3)
+(def asteroid-max-speed 0.6)
 (def asteroid-max-rotation-speed 5)
 (def turn-millis 20)
 (def actions {
@@ -32,6 +36,15 @@

 ; END: constants

+(defn random [from to]
+  (let [range (- to from)]
+    (+ from (rand range))))
+
+(defn vary [variance n]
+  (let [from (* n (- 1 variance))
+        to (* n (+ 1 variance))]
+    (random from to)))
+
 ; transformation math:

 (defn invert [mat]
@@ -99,7 +112,7 @@
   )

 (defn polygon-to-screen [pol mat]
-  (let [f (fn [v] (->> (conj v 1)
+  (let [f (fn [v] (->> (conj (vec v) 1)
                        (mat*vec mat)
                        (take 2)
                        (round)))]
@@ -155,11 +168,17 @@
   ([size pos]
    (let [direction (rand (* 2 (Math/PI)))
          speed (num*vec (rand asteroid-max-speed) (rotate-vec direction [0 1]))
-         rotation-speed (rand asteroid-max-rotation-speed)]
+         rotation-speed (rand asteroid-max-rotation-speed)
+         num-points (Math/round (+ size 3.0))
+         make-point (fn [n]
+                      (let [angle (* 2 (Math/PI) (/ n num-points))
+                            length (random (- 1 asteroid-jaggedness) (+ 1 (/ asteroid-jaggedness 2)))]
+                        (rotate-vec angle [0 length])))
+         shape (map make-point (range num-points))]
      {:type           :asteroid

-      :size           size
-      :shape          [[-1.0 -1.0] [1.0 -1.0] [1.0 1.0] [-1.0 1.0]]
+      :size           (vary asteroid-size-variance size)
+      :shape          shape
       :color          (Color. 250 240 20)

       :position       pos
@@ -173,6 +192,10 @@
    (let [x (rand width)
          y (rand height)]
      (create-asteroid size [x y]))))
+
+(defn create-asteroids [num size]
+  (map create-asteroid (repeat num size))
+  #_(repeat num (create-asteroid size)))

 (defn out-of-bounds? [{[x y] :position size :size}]
   (or
@@ -205,7 +228,8 @@
 (defmethod move :ship [{:keys [direction rotation-speed position speed acceleration shots] :as ship}]
   (let [direction (+ direction (* rotation-speed turn-millis 0.001))
         speed (vec+vec speed (rotate-vec direction [0 (* acceleration turn-millis 0.001)]))
-        position (vec+vec speed position)
+        [x y] (vec+vec speed position)
+        position [(mod x width) (mod y height)]
         shots (->> shots
                    (filter #(not (out-of-bounds? %)))
                    (map move))]
@@ -246,12 +270,12 @@
 ; ----------------------------------------------------------
 ; mutable model
 ; ----------------------------------------------------------
-(defn update-positions! [ship asteroid]
+(defn update-positions! [ship asteroids]
   (dosync
     (alter ship shoot)
     (alter ship move)
-    (alter asteroid move))
-  nil)
+    (alter asteroids (partial map move))
+    nil))

 (defn do-action!
   ([ship {:keys [rotation acceleration shoot] :as action} modifier]
@@ -263,10 +287,10 @@
    (do-action! ship action 1))
   )

-(defn reset-game! [ship asteroid]
+(defn reset-game! [ship asteroids]
   (dosync
     (ref-set ship (create-ship))
-    (ref-set asteroid (create-asteroid 2)))
+    (ref-set asteroids (create-asteroids asteroids-start-number asteroid-start-size)))
   nil)

 ; ----------------------------------------------------------
@@ -314,19 +338,20 @@
 ; game
 ; ----------------------------------------------------------

-(defn game-panel [frame ship asteroid]
+(defn game-panel [frame ship asteroids]
   (proxy [JPanel ActionListener KeyListener] []
     (paintComponent [g]                                     ; <label id="code.game-panel.paintComponent"/>
       (proxy-super paintComponent g)
       (paint g @ship)
-      (paint g @asteroid))
+      (doseq [asteroid @asteroids]
+        (paint g asteroid)))
     (actionPerformed [e]                                    ; <label id="code.game-panel.actionPerformed"/>
-      (update-positions! ship asteroid)
+      (update-positions! ship asteroids)
       (when (lose? @ship)
-        (reset-game! ship asteroid)
+        (reset-game! ship asteroids)
         (JOptionPane/showMessageDialog frame "You lose!"))
       (when (win? @ship)
-        (reset-game! ship asteroid)
+        (reset-game! ship asteroids)
         (JOptionPane/showMessageDialog frame "You win!"))
       (.repaint this))
     (keyPressed [e]
@@ -340,9 +365,9 @@

 (defn game []
   (let [ship (ref (create-ship))
-        asteroid (ref (create-asteroid 2))
+        asteroids (ref (create-asteroids asteroids-start-number asteroid-start-size))
         frame (JFrame. "Asteroids")
-        panel (game-panel frame ship asteroid)
+        panel (game-panel frame ship asteroids)
         timer (Timer. turn-millis panel)]
     (doto panel                                             ; <label id="code.game.panel"/>
       (.setFocusable true)


A proof of concept test spec added to system/core_test ns

--- test/clj/hellhound/system/core_test.clj
+++ test/clj/hellhound/system/core_test.clj
@@ -13,3 +13,7 @@

 ;; (t/deftest something
 ;;   (assert (stest/check 'hellhound.system.core/get-components)))
+(t/deftest get-components
+  (let [check-results (stest/check `hellhound.system.core/get-components)
+        passed       (every? nil? (map :failure check-results))]
+    (t/is passed (first check-results))))


PLATFORM-2818: fixing tests

PLATFORM-2818: fixing tests

--- test/vignette/http/integration_test.clj
+++ test/vignette/http/integration_test.clj
@@ -160,7 +160,7 @@
       (:status response) => 200
       (get (:headers response) "Surrogate-Key") => "e77cd6979116303a6d50610962fa9790469574c2"
       (get (:headers response) "Content-Disposition") => "inline; filename=\"baboon.webp\"; filename*=UTF-8''baboon.webp"
-      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 10030 50)
+      (Integer/parseInt (get (:headers response) "Content-Length")) => (roughly 18000 50)
       (get (:headers response) "Connection") => "close"
       (get (:headers response) "Cache-Control") => "public, max-age=31536000"
       (get (:headers response) "Content-Type") => "image/webp"


Upgrade reitit to last version

Upgrade reitit to last version

--- backend/project.clj
+++ backend/project.clj
@@ -23,7 +23,7 @@
                  [funcool/cuerdas "2.0.5"]
                  [honeysql "0.9.3"]
                  [meta-merge "1.0.0"]
-                 [metosin/reitit "0.2.12" :exclusions [org.clojure/spec.alpha org.ow2.asm/asm ring/ring-core mvxcvi/puget ring/ring-codec org.clojure/core.rrb-vector fipp r com.fasterxml.jackson.core/jackson-databind com.fasterxml.jackson.core/jackson-core]]
+                 [metosin/reitit "0.2.13" :exclusions [org.clojure/spec.alpha org.ow2.asm/asm ring/ring-core mvxcvi/puget ring/ring-codec org.clojure/core.rrb-vector fipp r com.fasterxml.jackson.core/jackson-databind com.fasterxml.jackson.core/jackson-core]]
                  [org.akvo/commons "0.4.5" :exclusions [org.postgresql/postgresql org.clojure/java.jdbc]]
                  [org.akvo/resumed "1.46.266acfa5bb52c9b484af19f0bcfbfacb60b97319"]
                  [org.apache.tika/tika-core "1.18"]


[#346] Update backend deps (#353)

[#346] Update backend deps (#353)

--- backend/project.clj
+++ backend/project.clj
@@ -5,7 +5,7 @@
             :url  "https://www.gnu.org/licenses/agpl-3.0.html"}
   :min-lein-version "2.0.0"
   :dependencies [[cheshire "5.6.3"]
-                 [clj-http "3.1.0"]
+                 [clj-http "3.2.0"]
                  [clj-time "0.12.0"]
                  [com.ibm.icu/icu4j "57.1"]
                  [com.layerware/hugsql "0.4.7"]
@@ -13,7 +13,7 @@
                  [compojure "1.5.1"]
                  [duct "0.8.0"]
                  [duct/hikaricp-component "0.1.0"]
-                 [environ "1.0.3"]
+                 [environ "1.1.0"]
                  [meta-merge "1.0.0"]
                  [org.akvo/commons "0.4.4-SNAPSHOT"
                   :exclusions [org.postgresql/postgresql org.clojure/java.jdbc]]
@@ -23,9 +23,9 @@
                  [org.clojure/data.csv "0.1.3"]
                  [org.immutant/scheduling "2.1.5" :exclusions [ch.qos.logback/logback-classic]]
                  [org.immutant/web "2.1.5"]
-                 [org.postgresql/postgresql "9.4.1209"]
+                 [org.postgresql/postgresql "9.4.1210"]
                  [org.slf4j/slf4j-nop "1.7.21"]
-                 [ragtime/ragtime.jdbc "0.6.1"]
+                 [ragtime/ragtime.jdbc "0.6.3"]
                  [ring "1.5.0"]
                  [ring/ring-defaults "0.2.1"]
                  [ring/ring-json "0.4.0"]]
@@ -50,12 +50,12 @@
    :profiles/dev  {}
    :profiles/test {}
    :project/dev   {:dependencies   [[duct/generate "0.8.0"]
-                                    [reloaded.repl "0.2.2"]
+                                    [reloaded.repl "0.2.3"]
                                     [org.clojure/tools.namespace "0.2.11"]
                                     [org.clojure/tools.nrepl "0.2.12"]
                                     [eftest "0.1.1"]
-                                    [com.gearswithingears/shrubbery "0.3.1"]
-                                    [kerodon "0.7.0"]]
+                                    [com.gearswithingears/shrubbery "0.4.1"]
+                                    [kerodon "0.8.0"]]
                    :source-paths   ["dev/src"]
                    :resource-paths ["dev/resources" "test/resources"]
                    :repl-options   {:init-ns user}


Absolutize file-deps on file-params reading

--- daemon/src/inlein/daemon/read_script.clj
+++ daemon/src/inlein/daemon/read_script.clj
@@ -40,11 +40,19 @@
     {:jvm-opts (concat (:jvm-opts params ["-XX:+TieredCompilation" "-XX:TieredStopAtLevel=1"])
                        ["-cp" cp-string])}))

+(defn- absolutize-file-deps [params fname]
+  (if-not (:file-deps params)
+    params
+    (assoc params
+           :file-deps (into #{} (map #(utils/resolve-sibling fname %)
+                                     (:file-deps params))))))
+
 (defn- file-params [fname]
   (let [contents (slurp* fname)
         raw-params (read-string* contents fname)]
     (validate-params raw-params fname)
     (-> (second raw-params)
+        (absolutize-file-deps fname)
         deps/add-global-exclusions)))

@@ -58,7 +66,7 @@
        (reduce
         all-file-params
         (assoc already-fetched fname params)
-        (map #(utils/resolve-sibling fname %) (:file-deps params)))))))
+        (:file-deps params))))))

 (defn- os-peek [^OrderedSet stack]
   (peek (.i->k stack)))
@@ -73,14 +81,13 @@
   [fmap ^OrderedSet stack]
   (let [fname (os-peek stack)
         params (get fmap fname)]
-    (doseq [dep (:file-deps params)]
-      (let [dep-fname (utils/resolve-sibling fname dep)]
-        (when (contains? stack dep-fname)
-          (throw (ex-info "Cyclic :file-dep detected"
-                          {:error (str "Cyclic :file-dep detected: "
-                                       (c.str/join " -> " (os-member stack dep-fname))
-                                       " -> " dep-fname)})))
-        (detect-cycles fmap (conj stack dep-fname))))))
+    (doseq [dep-fname (:file-deps params)]
+      (when (contains? stack dep-fname)
+        (throw (ex-info "Cyclic :file-dep detected"
+                        {:error (str "Cyclic :file-dep detected: "
+                                     (c.str/join " -> " (os-member stack dep-fname))
+                                     " -> " dep-fname)})))
+      (detect-cycles fmap (conj stack dep-fname)))))

 (defn read-script-params
   ([fname]


Added simple ring middleware to always redirect to https.

--- src/cadence/server.clj
+++ src/cadence/server.clj
@@ -3,11 +3,25 @@

 (server/load-views "src/cadence/views/")

+(defn https-url [request-url]
+  (str "https://"
+       (:server-name request-url)
+       (let [port (:server-port request-url)]
+         (if (nil?  port) (str ":" port)))
+       (:uri request-url)))
+
+(defn require-https [handler]
+  (fn [request]
+    (if (= (:scheme request) :http)
+      (ring.util.response/redirect (https-url request))
+      (handler request))))
+
+
 (defn -main [& m]
   (let [mode (keyword (or (first m) :dev))
-        port (Integer. (get (System/getenv) "PORT" "5010"))
-        url "cadence.ryanmcg.com"]
+        port (Integer. (get (System/getenv) "PORT" "5000"))
+        url "cadence.herokuapp.com"]
+    (if (not= mode :dev) (server/add-middleware require-https))
     (server/start port {:mode mode
                         ;:base-url (if (= mode :dev) (str "test" url))
                         :ns 'cadence})))
-


Private key and known-hosts now in code. Easier to work with.


Put comments at start of each test.

Put comments at start of each test.

--- src/cbfg/net-test.cljs
+++ src/cbfg/net-test.cljs
@@ -12,77 +12,78 @@
 (defn test-net [actx]
   (ago tn actx
        (let [n (atom 0)]
-         (if (and (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)]
-                    ; Closing listen-ch should shutdown net.
-                    (aclose tn listen-ch)
-                    (e n (atake tn net) :done (atake tn net)))
-                  (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)]
-                    ; Closing connect-ch should shutdown net.
-                    (aclose tn connect-ch)
-                    (e n (atake tn net) :done (atake tn net)))
-                  (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)
-                        listen-result-ch (achan tn)]
-                    ; Closing listen-ch should shutdown net and accept-ch's.
-                    (aput tn listen-ch [:addr-a 1000 listen-result-ch])
-                    (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
-                      (aclose tn listen-ch)
-                      (and (e n (atake tn accept-ch) nil nil)
-                           (e n (atake tn net) :done (atake tn net)))))
-                  (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)
-                        listen-result-ch (achan tn)]
-                    ; Closing connect-ch should shutdown net and accept-ch's.
-                    (aput tn listen-ch [:addr-a 1000 listen-result-ch])
-                    (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
-                      (aclose tn connect-ch)
-                      (and (e n (atake tn accept-ch) nil nil)
-                           (e n (atake tn net) :done (atake tn net)))))
-                  (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)
-                        listen-result-ch (achan tn)
-                        listen-result-ch2 (achan tn)]
-                    ; 2nd listen on same addr/port should fail.
-                    (aput tn listen-ch [:addr-a 1000 listen-result-ch])
-                    (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
-                      (aput tn listen-ch [:addr-a 1000 listen-result-ch2])
-                      (and (e n (atake tn listen-result-ch2) nil nil)
-                           (do (aclose tn listen-ch)
-                               (aclose tn connect-ch)
-                               (and (e n (atake tn accept-ch) nil nil)
-                                    (e n (atake tn net) :done (atake tn net)))))))
-                  (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)
-                        connect-result-ch (achan tn)]
-                    ; Connecting to unlistened to port should fail.
-                    (aput tn connect-ch [:addr-a 1000 :addr-x connect-result-ch])
-                    (and (e n (atake tn connect-result-ch) nil nil)
-                         (do (aclose tn listen-ch)
-                             (aclose tn connect-ch)
-                             (e n (atake tn net) :done (atake tn net)))))
-                  (let [listen-ch (achan tn)
-                        connect-ch (achan tn)
-                        net (make-net tn listen-ch connect-ch)
-                        listen-result-ch (achan tn)]
-                    ; Close of close-accept-ch should close accept-ch and fail new connects.
-                    (aput tn listen-ch [:addr-a 1000 listen-result-ch])
-                    (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
-                      (aclose tn close-accept-ch)
-                      (and (e n (atake tn accept-ch) nil nil)
-                           (let [connect-result-ch (achan tn)]
-                             (aput tn connect-ch [:addr-a 1000 :addr-x connect-result-ch])
-                             (and (e n (atake tn connect-result-ch) nil nil)
-                                  (do (aclose tn listen-ch)
-                                      (aclose tn connect-ch)
-                                      (e n (atake tn net) :done (atake tn net)))))))))
+         (if (and
+              ; Closing listen-ch should shutdown net.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)]
+                (aclose tn listen-ch)
+                (e n (atake tn net) :done (atake tn net)))
+              ; Closing connect-ch should shutdown net.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)]
+                (aclose tn connect-ch)
+                (e n (atake tn net) :done (atake tn net)))
+              ; Closing listen-ch should shutdown net and accept-ch's.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)
+                    listen-result-ch (achan tn)]
+                (aput tn listen-ch [:addr-a 1000 listen-result-ch])
+                (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
+                  (aclose tn listen-ch)
+                  (and (e n (atake tn accept-ch) nil nil)
+                       (e n (atake tn net) :done (atake tn net)))))
+              ; Closing connect-ch should shutdown net and accept-ch's.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)
+                    listen-result-ch (achan tn)]
+                (aput tn listen-ch [:addr-a 1000 listen-result-ch])
+                (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
+                  (aclose tn connect-ch)
+                  (and (e n (atake tn accept-ch) nil nil)
+                       (e n (atake tn net) :done (atake tn net)))))
+              ; 2nd listen on same addr/port should fail.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)
+                    listen-result-ch (achan tn)
+                    listen-result-ch2 (achan tn)]
+                (aput tn listen-ch [:addr-a 1000 listen-result-ch])
+                (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
+                  (aput tn listen-ch [:addr-a 1000 listen-result-ch2])
+                  (and (e n (atake tn listen-result-ch2) nil nil)
+                       (do (aclose tn listen-ch)
+                           (aclose tn connect-ch)
+                           (and (e n (atake tn accept-ch) nil nil)
+                                (e n (atake tn net) :done (atake tn net)))))))
+              ; Connecting to unlistened to port should fail.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)
+                    connect-result-ch (achan tn)]
+                (aput tn connect-ch [:addr-a 1000 :addr-x connect-result-ch])
+                (and (e n (atake tn connect-result-ch) nil nil)
+                     (do (aclose tn listen-ch)
+                         (aclose tn connect-ch)
+                         (e n (atake tn net) :done (atake tn net)))))
+              ; Close of close-accept-ch should close accept-ch and fail new connects.
+              (let [listen-ch (achan tn)
+                    connect-ch (achan tn)
+                    net (make-net tn listen-ch connect-ch)
+                    listen-result-ch (achan tn)]
+                (aput tn listen-ch [:addr-a 1000 listen-result-ch])
+                (let [[close-accept-ch accept-ch] (atake tn listen-result-ch)]
+                  (aclose tn close-accept-ch)
+                  (and (e n (atake tn accept-ch) nil nil)
+                       (let [connect-result-ch (achan tn)]
+                         (aput tn connect-ch [:addr-a 1000 :addr-x connect-result-ch])
+                         (and (e n (atake tn connect-result-ch) nil nil)
+                              (do (aclose tn listen-ch)
+                                  (aclose tn connect-ch)
+                                  (e n (atake tn net) :done (atake tn net)))))))))
            "pass"
            (str "FAIL: on test-net #" @n)))))


made aliases available in the defined function but just like defblock they don't have to be available within

--- src/util/funxions.clj
+++ src/util/funxions.clj
@@ -19,8 +19,9 @@

 ;you need not bind this though, unless you really want to name it something
 ;but it won't clash with others, supposedly - there may be some case when it could clash let within a let
-(def ^:dynamic *fxn_defBlock_symbol* (gensym 'fxn_defBlock))
-(def ^:dynamic *fxn_defBlockRaw_symbol* (gensym 'fxn_defBlockRaw))
+(def ^:dynamic *fxn_defBlock_symbol* (gensym 'fxn_defBlock_))
+(def ^:dynamic *fxn_defBlockRaw_symbol* (gensym 'fxn_defBlockRaw_))
+(def ^:dynamic *fxn_defBlock_Aliases* (gensym 'fxn_defBlock_Aliases_))

 (defmacro get_fxn
@@ -46,6 +47,7 @@

 (get_fxn *fxn_defBlock_symbol* defBlock) ;(defmacro get_fxn_defBlock ...)
 (get_fxn *fxn_defBlockRaw_symbol* defBlockRaw) ;(defmacro get_fxn_defBlockRaw ...)
+(get_fxn *fxn_defBlock_Aliases* defBlock_Aliases);(defmacro get_fxn_defBlock_Aliases ...)
 ;(defmacro get_fxn_defBlock2
 ;  []
 ;  ;like get the value of <the symbol returned by *fxn_defBlock_symbol*>
@@ -68,18 +70,6 @@
   (q/is (= nil (second nil)))
   )

-;(defn x []
-;  (println)
-;  (q/assumedTrue [1 "fail"])
-;  (println)
-;)
-;(defn y []
-;  (println)
-;  (x)
-;  (println)
-;  )
-;(eval '(y))
-

 (defmacro defxn ;def funxion
   [fname ;funxion name
@@ -96,11 +86,12 @@
     ; evaDefBlock == `'~evaDefBlock = `~*fxn_defBlock_symbol*
     `(defn ~fname [& allParamsInAMap#]
 "
-this function takes only one parameter: a map with the parameters
-"
-       {:pre [(q/assumedTruthy [(let [f# (first allParamsInAMap#)
-                                      s# (second allParamsInAMap#)
-                                      ]
+this function takes only one parameter: a map with the parameters;
+or no parameters at all.
+"
+     {:pre [(q/assumedTruthy [(let [f# (first allParamsInAMap#)
+                                    s# (second allParamsInAMap#)
+                                    ]
                                 (or
                                   (nil? f#);means 0 params
                                   (and ;if the above isn't true we're here, so there is a first params
@@ -113,11 +104,13 @@
 for function `" '~fname "` you passed `" allParamsInAMap# "`"])]}
        (let [~*fxn_defBlock_symbol* '~evaDefBlock
              ~*fxn_defBlockRaw_symbol* '~passedDefBlock
+             ~*fxn_defBlock_Aliases* '~aliases
              ;~'fxn_evalled ~e
              ]
          ;(clojure.pprint/pprint (list ~'*fxn_defBlockRaw_symbol* ~*fxn_defBlockRaw_symbol*))
          ;(clojure.pprint/pprint (list ~'*fxn_defBlock_symbol* ~*fxn_defBlock_symbol*));symbol and its value
-         (clojure.pprint/pprint  '~aliases)
+         ;(clojure.pprint/pprint  '~aliases)
+         (clojure.pprint/pprint (list ~'*fxn_defBlock_Aliases* ~*fxn_defBlock_Aliases*))
          ~@codeblocks
          #_(= (~(:c x) ~(:d x))
            (~(:e x) ~(:d x)))
@@ -219,7 +212,7 @@
   ;TODO: allow invariants functions for each param and throw when any of them fail(obviously)
   ;TODO: ignore optional params that weren't passed on call
   ;TODO: throw when required params aren't passed on call
-  (clojure.pprint/pprint (list "foocode" (get_fxn_defBlock)));firsta)
+  (clojure.pprint/pprint (list "infoocode" (get_fxn_defBlock)));firsta)
   )

 (q/deftest test_fxn1
@@ -274,6 +267,7 @@

 (def a 0)
+
 (defxn noes {:a
              ~(inc (+ 1 2)) ;this will resolve at compile time?
              :b firsta
@@ -281,17 +275,21 @@
              :d a ;"a" has to be resolvable in current ns where defxn is called and it will point to the same a, thus will not be relative to *ns* once defxn executed
              :e ~(list partial > 1)
              }
-  (println "!!!" (get_fxn_defBlock))
+  (println "!!!" (get_fxn_defBlock))
+  (println "!!!" (get_fxn_defBlock_Aliases))
 ;  (:b fxn_defBlock)
 ;  (:c fxn_defBlock)
   )
+
 (println (noes))
 (def a 1)
 (println (noes))
+
 (binding [*fxn_defBlock_symbol* 'abc]
   (println *fxn_defBlock_symbol*)
-  (noes))
-
-
+  (noes)
+  )
+
+;last lines:
 (q/show_state2)
 (q/gotests)