Implicit conversions.

Implicit conversions.

--- src/angelic/hierarchy/angelic.clj
+++ src/angelic/hierarchy/angelic.clj
@@ -99,11 +99,40 @@
 ; and not the other.

 (defn explode-implicit-pair [[implicit-set reward]]
-  (into {} (for [s (state-set/explicit-map implicit-set)])))
+  (into {} (for [s (when implicit-set (state-set/explicit-set implicit-set))] [s reward])))

 (def explicit-from-implicit
-  {:optimistic-map- (fn implicit-optimistic-map [a s] )})
+     {:optimistic-map-  (fn o-m- [a s]
+                          (explode-implicit-pair
+                           (optimistic-set-and-reward- a (state-set/make-logging-factored-state-set [s]))))
+      :pessimistic-map- (fn p-m- [a s]
+                          (explode-implicit-pair
+                           (optimistic-set-and-reward- a (state-set/make-logging-factored-state-set [s]))))})
+
+(defn implode-explicit-map [reward-combiner m]
+  (when-let [rel-pairs (seq (filter #(> (val %) Double/NEGATIVE_INFINITY) (seq m)))]
+    [(state-set/make-logging-factored-state-set (map key rel-pairs))
+     (apply reward-combiner (map val rel-pairs))]))
+
+; Note: assumes no constraints on refinements, can be wrong...
+(def implicit-from-explicit
+     {:can-refine-from-set?        (constantly true)
+      :immediate-refinements-set-  (fn immediate-refinements-set- [a ss]
+                                     (when-not (state-set/empty? ss)
+                                       (for [ref (hierarchy/immediate-refinements a (state-set/some-element ss))]
+                                         [{} ref])))
+      :optimistic-set-and-reward-  (fn optimistic-set-and-reward- [a ss]
+                                     (implode-explicit-map max
+                                      (apply merge-with max (map (partial optimistic-map- a) (state-set/explicit-set ss)))))
+      :pessimistic-set-and-reward- (fn pessimistic-set-and-reward- [a ss]
+                                     (implode-explicit-map min
+                                      (apply merge-with max (map (partial pessimistic-map- a) (state-set/explicit-set ss)))))})

+(defprotocol ImplicitAngelicAction
+  (can-refine-from-set? [a ss] "Return true if set has enough information to refine.")
+  (immediate-refinements-set- [a ss] "Return seq of [constraint ref] pairs from this set")
+  (optimistic-set-and-reward- [a ss] "Return pair of implicit outcome set and reward, or nil")
+  (pessimistic-set-and-reward- [a ss] "Return pair of implicit outcome set and reward, or nil"))


Add a secretbox-easy for byte buffers

Add a secretbox-easy for byte buffers

--- src/caesium/crypto/secretbox.clj
+++ src/caesium/crypto/secretbox.clj
@@ -10,8 +10,17 @@

   You only want this to manage the output byte array yourself. Otherwise,
   you want [[secretbox-easy]]."
-  [out msg nonce key]
-  (let [mlen (alength ^bytes msg)]
+  [^bytes out ^bytes msg ^bytes nonce ^bytes key]
+  (let [mlen (long (alength ^bytes msg))]
+    (.crypto_secretbox_easy sodium out msg mlen nonce key)))
+
+(defn secretbox-easy-to-byte-buf!
+  "Like [[secertbox-easy-to-buf!]], but with a ByteBuffer output.
+
+  Like [[secertbox-easy-to-buf!]], this is only useful if you want to manage
+  the output byte buffer yourself. Otherwise, you want [[secretbox-easy]]."
+  [^java.nio.ByteBuffer out ^bytes msg ^bytes nonce ^bytes key]
+  (let [mlen (long (alength ^bytes msg))]
     (.crypto_secretbox_easy sodium out msg mlen nonce key)))

 (defn secretbox-easy


detecting -ér and -re verbs for future and conditional

--- src/babel/francais/morphology.clj
+++ src/babel/francais/morphology.clj
@@ -231,9 +231,10 @@
                  ar-type (try (re-find #"ar$" infinitive)
                               (catch Exception e
                                 (throw (Exception. (str "Can't regex-find on non-string: " infinitive " from word: " word)))))
-                 er-type (re-find #"er$" infinitive)
+                 er-type (re-find #"[eé]r$" infinitive)
                  ir-type (re-find #"ir$" infinitive)
-                 stem (string/replace infinitive #"[iae]r$" "")
+                 re-type (re-find #"re$" infinitive)
+                 stem (string/replace infinitive #"[iaeé]r$" "")
                  last-stem-char-is-i (re-find #"ir$" infinitive)
                  last-stem-char-is-e (re-find #"er$" infinitive)
                  person (get-in word '(:agr :person))
@@ -295,7 +296,8 @@
                                 (throw (Exception. (str "Can't regex-find on non-string: " infinitive " from word: " word)))))
                  er-type (re-find #"er$" infinitive)
                  ir-type (re-find #"ir$" infinitive)
-                 stem (string/replace infinitive #"[iae]r$" "")
+                 re-type (re-find #"re$" infinitive)
+                 stem (string/replace infinitive #"[iaeé]r$" "")
                  last-stem-char-is-i (re-find #"ir$" infinitive)
                  last-stem-char-is-e (re-find #"er$" infinitive)
                  is-care-or-gare? (re-find #"[cg]ar$" infinitive)


Re-disable debugging code.

Re-disable debugging code.

--- src/circleci/web/views/index.clj
+++ src/circleci/web/views/index.clj
@@ -92,7 +92,7 @@

 (defpartial youre-done [& content]
   (do
-    (session/remove! :signed-up) ; For debugging
+;    (session/remove! :signed-up) ; For debugging
     [:div.move-right
       [:h2.blue-box "Thanks!" [:br] "We'll be in touch soon!"]]))


Add top link to quickref

Add top link to quickref

--- src/clj/clojuredocs/quickref.clj
+++ src/clj/clojuredocs/quickref.clj
@@ -62,6 +62,7 @@
   (let [toc-groups (partition-all 2 quickref-data)]
     [:div.toc.clearfix
      [:h5 "Table of Contents"]
+     [:h6 [:a {:href "#" :data-animate-scroll "true" :data-animate-buffer "10"} "Top"]]
      (for [tg toc-groups]
        [:div.col-sm-4.col-md-12
         (map $toc-sphere tg)])]))


Remove clojurescript log statements

Remove clojurescript log statements

--- src/cljs/dashboard_clj/core.cljs
+++ src/cljs/dashboard_clj/core.cljs
@@ -13,7 +13,7 @@
  :initialize
  (fn
    [db _]
-     (merge db {:data-sources {}})))
+   (merge db {:data-sources {}})))

 (rf/register-handler
@@ -37,22 +37,19 @@
   (let [{:keys  [chsk ch-recv send-fn state]} (sente/make-channel-socket! "/chsk" {:type :auto})]
     (asyncm/go-loop []
       (let [{:keys [event id ?data send-fn]} (async/<! ch-recv)]
-        (.log js/console "received event "(str id))
         (when (= (get ?data 0) :data-source/event)
-          (.log js/console (str "got event:" event))
           (let [[_ [ds-name ds-data]] ?data]
             (rf/dispatch [:update-data-source ds-name ds-data])))
         (when (and
                (= id :chsk/state)
                (= (:first-open? ?data) true))
-          (.log js/console (str "channel ready"))
           (send-fn [:dashboard-clj.core/sync])))
-        (recur))))
+      (recur))))

 (defn start-dashboard[dashboard element_id]
-  (rf/dispatch-sync [:initialize])
+  (rf/dispatch-sync [:initialize])
   (register-global-app-state-subscription)
-  (connect-to-data-sources)
+  (connect-to-data-sources)
   (let [new-layout (layout/create-layout dashboard)]
     (r/render new-layout (.getElementById js/document element_id))))


Active field is last, board has padding, abbreviation is displayed for active fields

--- src/cljs/db_quiz/layout/svg.cljs
+++ src/cljs/db_quiz/layout/svg.cljs
@@ -3,6 +3,8 @@
             [db-quiz.logic :as logic]
             [db-quiz.state :refer [app-state]]
             [db-quiz.util :refer [join-by-space shade-colour]]
+            [db-quiz.i18n :refer [t]]
+            [cljs-http.client :refer [generate-query-string]]
             [clojure.string :as string]))

 (defn get-gradients
@@ -45,26 +47,32 @@
         [x y] center]
     (fn []
       (let [{:keys [board current-field loading?]} @app-state
-            ownership (name (get-in board [id :ownership]))
+            {:keys [abbreviation ownership]} (board id)
             disabled? (not (nil? current-field))
-            availability (if (or loading? disabled? (not (#{"default" "missed"} ownership)))
+            availability (if (or loading? disabled? (not (#{:default :missed} ownership)))
                              "unavailable"
                              (case ownership
-                                   "default" "available"
-                                   "missed" "missed"))]
-        [:g {:class (join-by-space "hexagon" availability (when (= ownership "active") "active"))
-             :on-click (partial logic/pick-field id)}
-         [:polygon.hex-outer {:fill (str "url(#" ownership "-outer)")
+                                   :default "available"
+                                   :missed "missed"))
+            ownership-name (name ownership)
+            {:keys [font-size-ratio label]} (if (= ownership :active)
+                                                 {:font-size-ratio (max (dec (count abbreviation)) 2.5)
+                                                  :label abbreviation}
+                                                 {:font-size-ratio 2
+                                                  :label text})]
+        [:g {:class (join-by-space "hexagon" availability (when (= ownership :active) "active"))
+             :on-click (partial logic/pick-field id)}
+         [:polygon.hex-outer {:fill (str "url(#" ownership-name "-outer)")
                               :points (hex-coords center size)}]
-         [:polygon.hex-inner {:fill (str "url(#" ownership "-inner)")
+         [:polygon.hex-inner {:fill (str "url(#" ownership-name "-inner)")
                               :points (hex-coords (map #(- % absolute-offset) center)
                                                   (- size (* 2 absolute-offset)))
                               :transform (str "translate(" absolute-offset "," absolute-offset ")")}]
-         [:text {:x x
-                 :y (+ y (/ size 5))
-                 :font-size (/ size 2)
+         [:text {:x x
+                 :y (+ y (/ size (* 2.5 font-size-ratio)))
+                 :font-size (/ size font-size-ratio)
                  :text-anchor "middle"}
-          text]]))))
+          label]]))))

 (def hex-triangle
   "Component that generates triangular board of hexagons."
@@ -72,27 +80,31 @@
           r :hex-radius} :layout
          n :board-size} config
         size (* 2 r)
+        padding (/ r 2)
         y-space (* size (/ space 100))
         x-space (* y-space (/ (.sqrt js/Math 3) 2))
         w (* (.sqrt js/Math 3) r)
         grid-width (+ (* n w)
                       (* 2 border-width) ; Account for hexagon's border
-                      (* (dec n) x-space))
+                      (* (dec n) x-space)
+                      padding)
         grid-height (+ (* (/ 3 2) r n) (/ r 2)
                        (* (dec n) y-space) ; Add height for spaces
-                       (* 2 border-width)) ; Account for hexagon's border
+                       (* 2 border-width) ; Account for hexagon's border
+                       padding)
         x-offset (fn [x y] (+ (* (- n (inc y)) (/ w 2))
                               (* x w)
                               (when-not (= x 1) (* (dec x) x-space)) ; Account for spaces
                               (when-not (= y n) (* (- n y) (/ x-space 2)))
-                              border-width)) ; Account for hexagon's border
+                              border-width ; Account for hexagon's border
+                              (/ padding 2)))
         y-offset (fn [y] (+ r
                             border-width ; Account for hexagon's border
                             (* (/ 3 2) r (dec y))
-                            (when-not (= y 1) (* (dec y) y-space))))] ; Account for spaces
+                            (when-not (= y 1) (* (dec y) y-space)) ; Account for spaces
+                            (/ padding 2)))]
     (fn []
-      [:svg#hex-triangle {:x 0
-                          :y 0
+      [:svg#hex-triangle {:x 0 :y 0
                           :width grid-width
                           :height grid-height}
        [:defs (mapcat (fn [[status colour]]
@@ -105,7 +117,9 @@
                                        (y-offset y)]
                               :id [x y]
                               :size size)])
-          (:board @app-state))])))
+            (sort-by (comp :ownership second)
+                     (fn [a b] (if (= a :active) 1 -1))
+                     (:board @app-state)))])))

 (defn winners-cup
   "Winner's cup coloured with the colour of the winning player."
@@ -123,13 +137,13 @@
        [:stop {:offset 1
                :style {:stop-color colour
                        :stop-opacity 1}}]]]
-   [:g
+   [:g
     [:path {:d "m 23.094464,-2e-5 23.522065,57.01846 -12.801831,22.16903 45.725784,79.20482 8.89883,0 9.488616,23.019 15.351792,0 0,35.95961 0.0694,0 -33.773938,16.3058 0.50306,16.3233 90.688298,0 0.15613,-16.3233 -33.75659,-16.3058 0.0693,0 0,-35.95961 15.21301,0 9.50598,-23.019 9.03761,0 L 216.70041,79.18747 203.88122,56.9664 227.42063,-2e-5 l -56.42865,0 -91.451568,0 -56.446015,0 z m 175.981796,68.58867 6.12336,10.59882 -36.9657,64.04383 30.84234,-74.64265 z m -147.654708,0.0694 30.44338,73.81003 -36.532055,-63.28059 6.088675,-10.52944 z"
             :id "cup"
             :style {:fill "url(#cup-gradient)"}}]
     [:path {:d "M 34.526818,-51.55751 52.996969,21.61337 -3.3828659,-29.67722 47.907724,26.68531 -25.263158,8.21516 47.336482,28.79717 -25.263158,51.97574 49.223311,35.73862 -3.3828669,89.86811 50.746623,37.26193 34.526818,111.7484 57.688076,39.14876 78.270092,111.7484 59.79994,38.56021 116.17977,89.86811 64.889185,33.48828 138.04275,51.97574 65.443117,31.39373 138.04275,8.21516 63.573598,24.43496 116.17977,-29.67722 62.050286,22.91165 78.270092,-51.55751 55.091523,21.04213 34.526818,-51.55751 z"
             :id "shine"
-            :style {:fill "#ffffff"}}]]])
+            :style {:fill "#fff"}}]]])

 (defn not-found
   "Not found hexagon"


Move shared strings into a let

Move shared strings into a let

--- src/cljs/hyphen_keeper/core.cljs
+++ src/cljs/hyphen_keeper/core.cljs
@@ -100,17 +100,18 @@
        (re-find #"\S-\S" s)))

 (defn hyphenation-field []
-  [:div
-   {:class (if (or (string/blank? @hyphenation)
-                   (hyphenation-valid? @hyphenation))
-             "form-group" "form-group has-error")}
-   [:label {:for "hyphenationInput"} "Corrected Hyphenation"]
-   [:input.form-control
-    {:type "text"
-     :placeholder "Hyphenation"
-     :value @hyphenation
-     :on-change #(reset! hyphenation (-> % .-target .-value))}]
-   #_[:p.help-block "If the hyphenation is as you would expect it then the problem lies with the liblouis tables. Please contact Christian or Mischa."]])
+  (let [label "Corrected Hyphenation"
+        valid? (or (string/blank? @hyphenation) (hyphenation-valid? @hyphenation))
+        klass (if valid? "form-group" "form-group has-error")]
+    [:div
+     {:class klass}
+     [:label {:for "hyphenationInput"} label]
+     [:input.form-control
+      {:type "text"
+       :placeholder label
+       :value @hyphenation
+       :on-change #(reset! hyphenation (-> % .-target .-value))}]
+     #_[:p.help-block "If the hyphenation is as you would expect it then the problem lies with the liblouis tables. Please contact Christian or Mischa."]]))

 (defn- hyphenation-add-button []
   [:button.btn.btn-default


Add the feedback component again

Add the feedback component again

--- src/cljs/hyphen_keeper/core.cljs
+++ src/cljs/hyphen_keeper/core.cljs
@@ -13,19 +13,25 @@
     :spelling 1
     :word ""
     :hyphenation ""
-    :suggested-hyphenation ""}))
+    :suggested-hyphenation ""
+    :feedback {:message "" :kind :none}}))

 (def spelling (reagent/cursor app-state [:spelling]))
 (def word (reagent/cursor app-state [:word]))
 (def hyphenations (reagent/cursor app-state [:hyphenations]))
 (def hyphenation (reagent/cursor app-state [:hyphenation]))
 (def suggested-hyphenation (reagent/cursor app-state [:suggested-hyphenation]))
+(def feedback (reagent/cursor app-state [:feedback]))

 (defn update-hyphenations! [f & args]
   (apply swap! app-state update-in [:hyphenations] f args))

 (defn remove-hyphenation! [{:keys [word]}]
   (update-hyphenations! dissoc word))
+
+(defn set-feedback! [message kind]
+  (reset! feedback {:message message :kind kind})
+  (.setTimeout js/window #(reset! feedback {:message "" :kind :none}) 5000))

 (defn load-hyphenation-patterns!
   [spelling word]
@@ -46,7 +52,9 @@
   [pattern]
   (ajax/POST "/api/words"
    :params pattern
-   :handler (fn [] (load-hyphenation-patterns! @spelling @word))
+   :handler (fn []
+              (set-feedback! "Word has been added" :success)
+              (load-hyphenation-patterns! @spelling @word))
    :error-handler (fn [details]
                     (.warn js/console
                            (str "Failed to add hyphenation pattern: " details)))
@@ -198,6 +206,12 @@
                  "disabled")}
     "Add"]])

+(defn feedback-ui [feedback]
+  (let [{:keys [kind message]} @feedback
+        klass (when-not (= kind :none) (str "alert-" (name kind)))]
+    (when-not (= kind :none)
+      [:div.alert {:class klass :role "alert"} message])))
+
 (defn spelling-ui []
   [:div.form-group
    [:select {:value @spelling
@@ -277,7 +291,8 @@
       [word-ui]
       [suggested-hyphenation-ui]
       [hyphenation-ui]
-      [hyphenation-add-ui]]]]
+      [hyphenation-add-ui]
+      [feedback-ui feedback]]]]
    [hyphenation-lookup-ui spelling @word]
    [:h2 "Similar words"]
    [:div.row


comment out a few sections

comment out a few sections

--- src/cljs/just_married/views.cljs
+++ src/cljs/just_married/views.cljs
@@ -16,10 +16,11 @@
 (def SECTIONS
   {:story story
    :find-us find-us
-   :rvsp rvsp
-   :gifts gifts
-   :accomodation accommodation
-   :contacts contacts})
+   ;; :rvsp rvsp
+   ;; :gifts gifts
+   ;;:accomodation accommodation
+   ;;:contacts contacts
+   })

 (defn get-browser-language
   "Return the language set in the browser, assuming that


renaming

renaming

--- src/cljs/triboard/game_loop.cljs
+++ src/cljs/triboard/game_loop.cljs
@@ -22,8 +22,7 @@
       (<! (async/timeout ai-move-delay))
       (<! ai-chan))))

-(defn- handle-menu-event!
-  "Handle the menu event"
+(defn- handle-game-event!
   [msg]
   (store/swap-game!
     (case msg
@@ -42,7 +41,7 @@
                           (ai-computation @store/game)
                           play-events)]
           (alt!
-            game-events ([msg] (handle-menu-event! msg))
+            game-events ([msg] (handle-game-event! msg))
             play-chan ([coord] (store/swap-game! game/play-at coord))
             ))))
     {:play-events play-events


refactor game loop

refactor game loop

--- src/cljs/triboard/game_loop.cljs
+++ src/cljs/triboard/game_loop.cljs
@@ -7,10 +7,6 @@
     [cljs.core.async.macros :refer [go go-loop alt!]]
     ))

-
-;; -----------------------------------------
-;; GAME LOOP
-;; -----------------------------------------

 (def animation-delay 500)
 (def ai-move-delay 1000)
@@ -26,18 +22,17 @@
       (<! (async/timeout ai-move-delay))
       (<! ai-chan))))

-(defn player-moves-chan
-  []
-  (chan 1 (filter #(not @store/ai-player?))))

 (defn start-game-loop
   "Manage transitions between player moves, ai moves, and generic game events"
   []
-  (let [player-moves (player-moves-chan)
+  (let [player-moves (chan 1 (filter #(not @store/ai-player?)))
         menu-events (chan 1)]
     (go
       (while true
-        (let [play-chan (if @store/ai-player? (ai-computation @store/game) player-moves)]
+        (let [play-chan (if @store/ai-player?
+                          (ai-computation @store/game)
+                          player-moves)]
           (alt!
             menu-events ([msg] (store/send-event! msg))
             play-chan ([coord] (store/send-event! [:play-at coord]))


Fix typo

Fix typo

--- src/cljs/whatishistory/core.cljs
+++ src/cljs/whatishistory/core.cljs
@@ -86,7 +86,7 @@
         frm-mode (get @app-atom :defn-form-mode)
         new-defn (Definition.)]
     (.setACL new-defn (js/Parse.ACL. (.current js/Parse.User)))
-    (def defn-data {:definedby (get @app-atom :curr-user)
+    (def defn-data {:definedBy (get @app-atom :curr-user)
                     :definition (get @app-atom :definition)
                     :author (condp = (get @app-atom :author)
                               nil "Anonymous"


Add gtm_erase

Add gtm_erase

--- src/clojush/instructions/gtm.clj
+++ src/clojush/instructions/gtm.clj
@@ -172,6 +172,20 @@
                             true)
                           :boolean
                           state)))
+      state)))
+
+(define-registered ;; make primary tape is blank at current position
+  gtm_erase
+  ^{:stack-types [:gtm]}
+  (fn [state]
+    (if (:gtm state)
+      (let [primary (:primary (:gtm state))
+            primary-tape (get (:tapes (:gtm state)) primary)
+            primary-position (:position primary-tape)]
+        (trace 'gtm_erase
+               (assoc-in state
+                         [:gtm :tapes primary :contents]
+                         (dissoc (:contents primary-tape) primary-position))))
       state)))

 (define-registered ;; push primary tape's instruction to code stack


Handle empty TermsEnum.

Handle empty TermsEnum.

--- src/clucy/positions_searcher.clj
+++ src/clucy/positions_searcher.clj
@@ -147,7 +147,7 @@
 (defn- find-phrase [^clojure.lang.PersistentVector phrase
                     ^TermsEnum te]
   "Phrase position searching."
-  (let [first-positions (if (.seekExact te (first phrase))
+  (let [first-positions (if (and te (.seekExact te (first phrase)))
                           (get-positions te))]
     (if first-positions
       (loop [words (next phrase)
@@ -179,15 +179,15 @@
         ^Terms terms (.getTermVector reader
                                      docID
                                      (as-str *field-name*))
-        terms-lenght (.size terms)
-        ^TermsEnum te (.iterator terms)]
+        terms-lenght (if terms (.size terms) 0)
+        ^TermsEnum te (if terms (.iterator terms))]
     [te terms-lenght]))

 (defn get-term-iter [^TermsEnum terms-enum]
   "TermsEnum => [term-as-BytesRef [[beg end]... ]] iterator."
   (letfn
       [(next-term []
-         (if (.next terms-enum)
+         (if (and terms-enum (.next terms-enum))
            (get-positions terms-enum :get-term true)))
        (it [] (let [term (next-term)]
                 (when term


Omni Complete now also completes imported classes

--- src/de/kotka/gorilla/backend.clj
+++ src/de/kotka/gorilla/backend.clj
@@ -70,14 +70,16 @@
    :children (map #(-> % second var-info) (ns-interns the-namespace))})

 ; Omni Completion
-(defn type-of-var
-  [the-var]
-  (let [the-val (var-get the-var)]
-    (cond
-      (:macro (meta the-var)) "m"
-      (fn? the-val)           "f"
-      (instance? clojure.lang.MultiFn the-val) "f"
-      :else                   "v")))
+(defn type-of
+  [thing]
+  (cond
+    (class? thing)        "c"
+    (:macro (meta thing)) "m"
+    :else                 (let [value (var-get thing)]
+                            (cond
+                              (instance? clojure.lang.MultiFn value) "f"
+                              (fn? value) "f"
+                              :else       "v"))))

 (defn complete-in-namespace
   "Complete the given symbol name in the given namespace."
@@ -91,8 +93,8 @@
                          (every? identity (map #(.startsWith %1 %2)
                                                sym-parts name-parts)))
                   (let [sym-var  (ns-resolve (symbol the-space) (symbol sym))
-                        sym-meta (meta sym-var)
-                        sym-type (type-of-var sym-var)
+                        sym-meta (when (var? sym-var) (meta sym-var))
+                        sym-type (type-of sym-var)
                         arglists (:arglists sym-meta)
                         info     (map #(str "  "
                                             (prn-str (cons (symbol sym) %)))


Mapped out the column names.

Mapped out the column names.

--- src/blutwurst/tuple_formatter.clj
+++ src/blutwurst/tuple_formatter.clj
@@ -4,7 +4,10 @@

 ; TODO: handle file output
 (defn- csv-formatter [spec rows]
- (csv/write-csv *out* rows))
+ (trace rows)
+ (let [values-only (map (fn [r] (map (fn [r2] (second r2)) r)) rows)]
+     (csv/write-csv *out* values-only)
+))

 (def formatters
   {
@@ -12,6 +15,6 @@
   })

 (defn format-rows [spec rows]
-  (let [formatter (get formatters (:format spec))]
-   (formatter spec rows)
+  (let [formatter (partial (get formatters (:format spec)) spec)]
+   (map formatter rows)
     ))


The base-url should have been taken from the dynamic params Also using the right charset to produce the qrcode

--- src/freecoin/handlers/qrcode.clj
+++ src/freecoin/handlers/qrcode.clj
@@ -3,11 +3,11 @@
 ;; part of Decentralized Citizen Engagement Technologies (D-CENT)
 ;; R&D funded by the European Commission (FP7/CAPS 610349)

-;; Copyright (C) 2015 Dyne.org foundation
-;; Copyright (C) 2015 Thoughtworks, Inc.
+;; Copyright (C) 2017 Dyne.org foundation

 ;; Sourcecode designed, written and maintained by
 ;; Denis Roio <jaromil@dyne.org>
+;; Aspasia Beneti <aspra@dyne.org>

 ;; This program is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU Affero General Public License as published by
@@ -24,16 +24,16 @@

 (ns freecoin.handlers.qrcode
   (:require [liberator.core :as lc]
-            [freecoin.params :as param]
+            [freecoin.config :as config]
             [freecoin.auth :as auth]
             [freecoin.db.wallet :as wallet]
             [freecoin.context-helpers :as ch]
             [clj.qrgen :as qr]
             [taoensso.timbre :as log]))

-
 (lc/defresource qr-participant-sendto [wallet-store]
   :allowed-methods [:get]
+
   :available-media-types ["image/png"]

   :authorized? #(auth/is-signed-in %)
@@ -44,7 +44,7 @@
   :handle-ok
   (fn [ctx]
     (if-let [email (get-in ctx [:request :params :email])]
-      (qr/as-input-stream
-       (qr/from (format "http://%s:%d/send/to/%s"
-                        (:address param/host)
-                        (:port param/host) email))))))
+      (let [base-url (-> (config/create-config) config/base-url)]
+        (qr/as-input-stream
+         (qr/from (str base-url "/send/to/" email)
+                  :charset "ISO-8859-1"))))))


Change sort order of Belletristik subgenres

Fixes #46

--- src/clj/catalog/layout/common.clj
+++ src/clj/catalog/layout/common.clj
@@ -22,9 +22,10 @@
    :bücher-über-spiel])
 (def subgenres [;; Belletristik
                 :action-und-thriller :beziehungsromane :fantasy-science-fiction
-                :gesellschaftsromane :historische-romane :hörspiele :krimis
+                :gesellschaftsromane :glaube-und-philosophie
+                :historische-romane :hörspiele :krimis
                 :lebensgeschichten-und-schicksale :literarische-gattungen
-                :mundart-heimat-natur :glaube-und-philosophie
+                :mundart-heimat-natur
                 ;; Sachbücher
                 :biografien :freizeit-haus-garten
                 :geschichte-und-gegenwart :kunst-kultur-medien


Remove some nav from dev section

Remove some nav from dev section

--- src/clj/clojuredocs/pages/dev.clj
+++ src/clj/clojuredocs/pages/dev.clj
@@ -40,12 +40,12 @@
      [:div.row
       [:div.col-sm-2
        [:div.sidenav
-        [:section
-         [:h5 "Dev"]
-         [:ul
-          [:li [:a {:href "/dev/api"} "API Docs"]]
-          [:li [:a {:href "/dev/search-perf"} "Search Perf"]]
-          [:li [:a {:href "/dev/canary"} "Canary Tests"]]]]
+        #_[:section
+           [:h5 "Dev"]
+           [:ul
+            [:li [:a {:href "/dev/api"} "API Docs"]]
+            [:li [:a {:href "/dev/search-perf"} "Search Perf"]]
+            [:li [:a {:href "/dev/canary"} "Canary Tests"]]]]
         [:section
          [:h5 "Styleguide"]
          [:ul


extend ALL to records (for walker reimplementation)

--- src/clj/com/rpl/specter/navs.cljc
+++ src/clj/com/rpl/specter/navs.cljc
@@ -129,6 +129,13 @@
   (all-transform [structure next-fn]
     (non-transient-map-all-transform structure next-fn (empty structure)))

+  clojure.lang.IRecord
+  (all-transform [structure next-fn]
+    (reduce
+      (fn [res kv] (conj res (next-fn kv)))
+      structure
+      structure
+      ))

   #?(:clj clojure.lang.PersistentHashMap :cljs cljs.core/PersistentHashMap)
   (all-transform [structure next-fn]


Updated language list

Updated language list

--- src/cljc/salava/user/schemas.cljc
+++ src/cljc/salava/user/schemas.cljc
@@ -27,7 +27,7 @@
                    :last_name  (s/constrained s/Str #(and (>= (count %) 1)
                                                           (<= (count %) 255)))
                    :country    (apply s/enum (keys all-countries))
-                   :language   (s/enum "fi" "en" "fr" "es" "pl")
+                   :language   (s/enum "fi" "en" "fr" "es" "pl" "pt")
                    :password   (s/constrained s/Str #(and (>= (count %) 6)
                                                           (<= (count %) 50)))
                    :password_verify (s/constrained s/Str #(and (>= (count %) 6)


Minor UI changes. Only show latest 100 log entries

--- src/cljs/onyx_dashboard/core.cljs
+++ src/cljs/onyx_dashboard/core.cljs
@@ -64,8 +64,8 @@

 (defcomponent deployment-entries [{:keys [selected-job entries]} owner]
   (render [_]
-          (let [filtered-entries (filter (partial entry-for-job? selected-job)
-                                         entries)]
+          ;(println "ENTRY INFO:" (count (map :message-id entries))  (count (set (map :message-id entries))))
+          (let [filtered-entries nil #_(filter (partial entry-for-job? selected-job) entries)]
             (table {:striped? true :bordered? true :condensed? true :hover? true}
                    (dom/thead
                      (dom/tr
@@ -73,8 +73,9 @@
                        (dom/th "Time")
                        (dom/th "fn")))
                    (dom/tbody ;{:height "500px" :position "absolute" :overflow-y "scroll"}
-                              (for [entry (reverse (sort-by :created-at entries))]
-                                (dom/tr {:title (str (om/value entry))}
+                              (for [entry (take 100 (reverse (sort-by :message-id entries)))]
+                                (dom/tr {:key (str "entry-" (:message-id entry))
+                                         :title (str (om/value entry))}
                                         (dom/td (str (:id (:args entry))))
                                         (dom/td (str (js/Date. (:created-at entry))))
                                         (dom/td (str (:fn entry))))))))))
@@ -91,7 +92,7 @@
                      (dom/th "ID")
                      (dom/th "Time")))
                  (dom/tbody
-                   (for [job (reverse (sort-by :created-at (vals jobs)))]
+                   (for [job (reverse (time (sort-by :created-at (vals jobs))))]
                      (let [job-id (:id job)]
                        (dom/tr {; make this a class
                                 :style {:background-color (if (= job-id selected-job)
@@ -107,12 +108,12 @@

 (defcomponent job-info [{:keys [selected-job jobs]} owner]
   (render [_]
-          ; Maybe only pass in job
-          (let [job (jobs selected-job)]
-            (dom/div
-              (dom/div (str (om/value job)))
-              (if-let [catalog (:catalog job)]
-                (om/build catalog-view catalog {}))))))
+          (if (and selected-job jobs)
+            (let [job (jobs selected-job)]
+              (dom/div
+                (dom/div (str (om/value job)))
+                (if-let [catalog (:catalog job)]
+                  (om/build catalog-view catalog {})))))))

 (defn event-handler [{:keys [event]}]
   (let [[msg-type msg] event]
@@ -140,7 +141,7 @@
 (sente/start-chsk-router! ch-chsk event-handler)

 (defn main []
-  (om/root
+  #_(om/root
     ankha/inspector
     app-state
     {:target (js/document.getElementById "ankha")})


Make names more consistent

Make names more consistent

--- src/clojure/nightcode/editors.clj
+++ src/clojure/nightcode/editors.clj
@@ -206,9 +206,10 @@
 (defn focus-on-field!
   [id]
   (when-let [editor (get-selected-editor)]
-    (doto (s/select editor [id])
-      s/request-focus!
-      .selectAll)))
+    (when-let [widget (s/select editor [id])]
+      (doto widget
+        s/request-focus!
+        .selectAll))))

 (defn focus-on-find!
   [_]
@@ -454,10 +455,10 @@
          (or (contains? styles (get-extension path))
              (utils/is-text-file? pathfile)))))

-(def ^:dynamic editor-controls [:save :undo :redo :font-dec :font-inc
-                                :doc :paredit :paredit-help :find :replace])
-
-(defn create-control
+(def ^:dynamic editor-widgets [:save :undo :redo :font-dec :font-inc
+                               :doc :paredit :paredit-help :find :replace])
+
+(defn create-widget
   [k]
   (case k
     :save (ui/button :id :save-button
@@ -509,20 +510,20 @@
           extension (get-extension path)
           is-clojure? (contains? clojure-exts extension)
           completer (create-completer text-area extension)
-          editor-controls (remove (fn [k]
-                                    (-> (concat []
-                                                (if-not is-clojure?
-                                                  [:paredit :paredit-help])
-                                                (if-not completer
-                                                  [:doc]))
-                                        set
-                                        (contains? k)))
-                                  editor-controls)
-          ; create the buttons with their actions attached
-          btn-group (ui/wrap-panel :items (map create-control editor-controls))
+          editor-widgets (remove (fn [k]
+                                   (-> (concat []
+                                               (if-not is-clojure?
+                                                 [:paredit :paredit-help])
+                                               (if-not completer
+                                                 [:doc]))
+                                       set
+                                       (contains? k)))
+                                 editor-widgets)
+          ; create the widgets
+          widget-group (ui/wrap-panel :items (map create-widget editor-widgets))
           ; create the main panel
           text-group (s/border-panel
-                       :north btn-group
+                       :north widget-group
                        :center (RTextScrollPane. text-area))]
       ; create shortcuts
       (doto text-group
@@ -540,8 +541,8 @@
       ; add prompt text to the fields
       (doseq [[id text] {:#find-field (utils/get-string :find)
                          :#replace-field (utils/get-string :replace)}]
-        (when-let [control (s/select text-group [id])]
-          (doto (TextPrompt. text control)
+        (when-let [widget (s/select text-group [id])]
+          (doto (TextPrompt. text widget)
             (.changeAlpha 0.5))))
       ; update buttons every time a key is typed
       (s/listen text-area
@@ -581,7 +582,7 @@
           toggle-btn (s/button :id :toggle-logcat-button
                                :text (utils/get-string :start))
           ; create the main panel
-          btn-group (ui/wrap-panel :items [toggle-btn])
+          widget-group (ui/wrap-panel :items [toggle-btn])
           ; create the toggle action
           parent-path (-> path io/file .getParentFile .getCanonicalPath)
           start! (fn []
@@ -598,11 +599,11 @@
       ; add the toggle action to the button
       (s/listen toggle-btn :action toggle!)
       ; create shortcuts
-      (doto btn-group
+      (doto widget-group
         (shortcuts/create-mappings! {:toggle-logcat-button toggle!})
         shortcuts/create-hints!)
       ; return a map describing the logcat view
-      {:view (s/border-panel :north btn-group :center console)
+      {:view (s/border-panel :north widget-group :center console)
        :close-fn! #(stop!)
        :should-remove-fn #(not (lein/is-android-project? parent-path))
        :italicize-fn (fn [] @is-running?)})))


send-event dont care about chat rooms!

send-event dont care about chat rooms!

--- src/grooming/chat/web_socket.clj
+++ src/grooming/chat/web_socket.clj
@@ -26,11 +26,12 @@
     (httpkit/send! channel (json-response data))))

 (defn send-event
-  [room-name data]
-  (let [ids (chatroom/members room-name)
-        data (assoc data :chat-room room-name)]
-    (doseq [[id channel] (select-keys @open-channels ids)]
-      (httpkit/send! channel (json-response data)))))
+  [ids data]
+  (let [send-to #(doseq [channel (vals %)]
+                  (httpkit/send! channel (json-response data)))]
+    (case ids
+      :all (send-to @open-channels)
+      (send-to (select-keys @open-channels ids)))))

 (defmulti handle-event
   (fn [session data]
@@ -38,7 +39,8 @@

 (defmethod handle-event :message
   [{u :username} {:keys [chat-room contents] :as data}]
-    (send-event (keyword chat-room) (assoc data :username u)))
+  (let [ids (chatroom/members (keyword chat-room))]
+    (send-event ids (assoc data :username u))))

 (defmethod handle-event :default
   [session data]


Add support for :apply-middleware-fn in compile-dispatch-table

--- src/io/aviso/rook/dispatcher.clj
+++ src/io/aviso/rook/dispatcher.clj
@@ -2,8 +2,9 @@
   (:require [clojure.core.match :refer [match]]
             [clojure.string :as string]
             [clojure.pprint :as pp]
+            [io.aviso.rook :as rook]
+            [io.aviso.rook.async :as async]
             [io.aviso.rook.internals :as internals]
-            [io.aviso.rook :as rook]
             [io.aviso.rook.schema-validation :as sv]))

 (def ^:private default-mappings
@@ -118,6 +119,15 @@
                   (-> ~request-sym :rook :arg-resolvers)))])
     arglist))

+(defn apply-middleware-sync [middleware sync? handler]
+  (middleware handler))
+
+(defn apply-middleware-async [middleware sync? handler]
+  (middleware
+    (if sync?
+      (async/ring-handler->async-handler handler)
+      handler)))
+
 (defn compile-dispatch-table
   "Compiles the dispatch table into a Ring handler.

@@ -128,13 +138,16 @@
   ([options dispatch-table]
      (let [dt  (unnest-dispatch-table dispatch-table)
            req (gensym "request__")
-           emit-fn (or (:emit-fn options) eval)]
+           emit-fn (:emit-fn options eval)
+           apply-middleware (:apply-middleware-fn options
+                                                  `apply-middleware-sync)]
        (emit-fn
          `(fn rook-dispatcher# [~req]
             (match (preparse-request ~req)
               ~@(mapcat
                   (fn [[method pathvec verb-fn-sym middleware]]
                     (let [metadata         (meta (resolve verb-fn-sym))
+                          sync?            (:sync metadata)
                           pathvec          (keywords->symbols pathvec)
                           route-params     (set (filter symbol? pathvec))
                           arglist          (first (:arglists metadata))
@@ -150,7 +163,7 @@
                                                    route-params
                                                    non-route-params)]
                                            (~verb-fn-sym ~@arglist)))]
-                          ((~middleware handler#)
+                          ((~apply-middleware ~middleware ~sync? handler#)
                            (assoc ~req
                              :route-params route-params#)))]))
                   dt)


fix docset to use new syntax display names (close #129)

--- src/main/cljs_api_gen/docset.clj
+++ src/main/cljs_api_gen/docset.clj
@@ -51,32 +51,14 @@
    "special symbol"      "Constant"
    "special namespace"   "Namespace"
    "binding"             "Builtin"
+   "convention"          "Builtin"
+   "special character"   "Builtin"
    })

 (defn dash-name
   [item]
-  (if (= "syntax" (:ns item))
-    (let [name- (:name item)
-          type- (:type item)
-          form (:syntax-form item)
-          forms (if (vector? form) (join " " form) form)
-          name+forms (str name- " " forms)]
-      (cond
-
-        ;; display the conceptual name and its forms (e.g. "vector []")
-        (#{"syntax"
-           "binding"} type-) name+forms
-
-        ;; just display Infinity, not all the sign variations
-        (= name- "Infinity") name-
-
-        ;; just display the forms (e.g. "#js" "js/" "NaN")
-        (#{"tagged literal"
-           "special symbol"
-           "special namespace"} type-) forms
-
-        :else (:name item)))
-    (:name item)))
+  (or (:display item)
+      (:name item)))

 (defn assert-reqs!
   []
@@ -150,7 +132,7 @@
     (println "Adding sections to index database...")
     (j/insert! sqlite-db :searchIndex
        ;; insert categories
-       {:name "Syntax API" :type "Category" :path (resolve-path "README.html#syntax-api")}
+       {:name "Syntax" :type "Category" :path (resolve-path "README.html#syntax")}
        {:name "Library API"  :type "Category" :path (resolve-path "README.html#library-api")}
        {:name "Compiler API" :type "Category" :path (resolve-path "README.html#compiler-api")}


cassandra: coerce KWs to strings in spy session mutated table cleanup

--- src/er_cassandra/session/alia.clj
+++ src/er_cassandra/session/alia.clj
@@ -178,6 +178,7 @@
                                :truncate]))
          (mapcat vals)
          (filter identity)
+         (map name) ;; coerce kw to string
          distinct
          sort
          vec)))


chain thing seems to run properly.

chain thing seems to run properly.

--- src/exp/simple_tree_hierarchy.clj
+++ src/exp/simple_tree_hierarchy.clj
@@ -82,7 +82,7 @@
         (if (= cur-val dst-val)
             [[]]
           (for [as (vals (get dtg cur-val)), action as]
-            [(make-action-hla action) this]))))
+            [(make-action-hla hierarchy action) this]))))
     (cycle-level-           [s] cycle-level))

 (defn- make-precond-hla [hierarchy var dst-val]
@@ -103,7 +103,7 @@
   env/ContextualAction
     (precondition-context [s] precond-var-set)
   hierarchy/HighLevelAction
-    (immediate-refinements- [s] (concat precond-hlas [action]))
+    (immediate-refinements- [s] [(concat precond-hlas [action])])
     (cycle-level-           [s] nil))

 (defn- make-action-hla [hierarchy action]
@@ -116,3 +116,6 @@
                     ((:ancestor-var-set hierarchy) effect-var))))

+
+
+; (run-counted #(sahucs-inverted (make-simple-tree-hierarchy (make-sas-problem-from-pddl (prln (write-infinite-taxi-strips2 (make-random-infinite-taxi-env 2 2 1 6)))))))


Directly call through to after-batch.

Directly call through to after-batch.

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -294,13 +294,6 @@
                                    (count (:onyx.core/results rets))))
     rets))

-(defn close-batch-resources [event]
-  (let [rets (lc/invoke-after-batch event)]
-    (taoensso.timbre/trace (format "[%s / %s] Closed batch plugin resources"
-                                   (:onyx.core/id rets)
-                                   (:onyx.core/lifecycle-id rets)))
-    rets))
-
 (defn launch-aux-threads!
   [messenger {:keys [onyx.core/pipeline
                      onyx.core/compiled-after-ack-segment-fn
@@ -424,7 +417,7 @@
              (assign-windows compiled)
              (write-batch pipeline)
              (flow-retry-segments peer-replica-view state messenger monitoring)
-             (close-batch-resources)
+             (lc/invoke-after-batch)
              (ack-segments task-map peer-replica-view state messenger monitoring)))
       (catch Throwable e
         (ex-f e)))))


Move some computation outside of map for perf

--- src/onyx/peer/task_lifecycle.clj
+++ src/onyx/peer/task_lifecycle.clj
@@ -38,17 +38,12 @@
 (defn munge-start-lifecycle [event]
   ((:onyx.core/compiled-start-task-fn event) event))

-(defn add-acker-id [{:keys [onyx.core/id onyx.core/max-acker-links] :as event} m]
-  (let [peers (get-in @(:onyx.core/replica event) [:ackers (:onyx.core/job-id event)])]
-    (if-not (seq peers)
-      (do (warn (format "[%s] This job no longer has peers capable of acking. This job will now pause execution." (:onyx.core/id event)))
-          (throw (ex-info "Not enough acker peers" {:peers peers})))
-      (let [candidates (operation/select-n-peers id peers max-acker-links)
-            n (mod (hash (:message m)) (count candidates))]
-        (assoc m :acker-id (nth candidates n))))))
-
-(defn add-completion-id [event m]
-  (assoc m :completion-id (:onyx.core/id event)))
+(defn add-acker-id [id peers m]
+  (let [n (mod (hash (:message m)) (count peers))]
+    (assoc m :acker-id (nth peers n))))
+
+(defn add-completion-id [id m]
+  (assoc m :completion-id id))

 (defn sentinel-found? [event]
   (seq (filter (partial = :done) (map :message (:onyx.core/batch event)))))
@@ -204,13 +199,19 @@
   (merge
    event
    (when (= (:onyx/type (:onyx.core/task-map event)) :input)
-     (update-in
-      event
-      [:onyx.core/batch]
-      (fn [batch]
-        (map (comp (partial add-completion-id event)
-                   (partial add-acker-id event))
-             batch))))))
+     (let [{:keys [onyx.core/id onyx.core/max-acker-links]} event
+           peers (get (:ackers @(:onyx.core/replica event)) (:onyx.core/job-id event))
+           candidates (operation/select-n-peers id peers max-acker-links)]
+       (when-not (seq peers)
+         (do (warn (format "[%s] This job no longer has peers capable of acking. This job will now pause execution." (:onyx.core/id event)))
+             (throw (ex-info "Not enough acker peers" {:peers peers}))))
+       (update-in
+         event
+         [:onyx.core/batch]
+         (fn [batch]
+           (map (comp (partial add-completion-id id)
+                      (partial add-acker-id id candidates))
+                batch)))))))

 (defn add-messages-to-timeout-pool [{:keys [onyx.core/state] :as event}]
   (when (= (:onyx/type (:onyx.core/task-map event)) :input)


code formatting.

code formatting.

--- src/kixi/eventlog/application.clj
+++ src/kixi/eventlog/application.clj
@@ -19,7 +19,7 @@
     (component/stop-system this (keys this))))

 (defn new-system
-  ([] (let [zookeeper-connect     (or (System/getenv "ZK_CONNECT") "localhost:2181")
+  ([] (let [zookeeper-connect  (or (System/getenv "ZK_CONNECT") "localhost:2181")
             topic              (or (System/getenv "TOPIC") "events")
             num-partitions     (Integer/parseInt (or (System/getenv "TOPIC_NUM_PARTITIONS") "3"))
             replication-factor (Integer/parseInt (or (System/getenv "TOPIC_REPLICATION_FACTOR") "3"))


根据clojure 编程这书的勘误做的修改

根据clojure 编程这书的勘误做的修改

--- src/learnclojure/chapt1/core5.clj
+++ src/learnclojure/chapt1/core5.clj
@@ -28,11 +28,13 @@
 (strange-adder 1 2)
 ;;letfn可以定义同时定义多个具名函数，并且这些函数可以互相引用
 (letfn [(odd? [n]
-              (even? (- n 2)))
+              (if (zero? n)
+                false
+                (even? (dec n))))
         (even? [n]
                (or (zero? n)
-                   (odd? (- n 2))))]
-  (even? 4))
+                   (odd? (dec n))))]
+  (odd? 12))
 ;;可变参函数，下面函数中的rest被称为剩余参数
 (defn concat-rest
   [_ & rest]


fixing obj syntax

fixing obj syntax

--- src/purnam_crafty_game/core.cljs
+++ src/purnam_crafty_game/core.cljs
@@ -18,7 +18,6 @@
        (js/Crafty.init (G.width) (G.height))
        (js/Crafty.background "rgb(20, 75, 40)")
        (js/Crafty.scene "Game")))})
-

 (do*n
  (js/Crafty.c


Refactor populate-projects!

Refactor populate-projects!

--- test/time_tracker/projects/test_helpers.clj
+++ test/time_tracker/projects/test_helpers.clj
@@ -4,6 +4,39 @@
             [yesql.core :refer [defqueries]]))

 (defqueries "time_tracker/projects/sql/db.sql")
+
+(defn- create-project-as-user!
+  "Creates a project and gives the user admin permissions.
+  Returns the project id."
+  [connection user-id project-name]
+  (let [{project-id :id} (first (jdbc/insert!
+                                 connection "project"
+                                 {"name" project-name}))]
+    (create-admin-permission-query! {:project_id project-id
+                                     :user_id    user-id}
+                                    {:connection connection})
+    project-id))
+
+(defn- create-user!
+  "Creates a user and returns the user id."
+  [connection google-id]
+  ;; Not using time-tracker.users.test-helpers.create-users!
+  ;; because that doesn't return the user id.
+  (:id (first
+        (jdbc/insert! connection "app_user"
+                      {"google_id" google-id
+                       "name" "Agent Smith"}))))
+
+(defn- populate-projects!
+  "Given a user, creates projects for the user
+  and grants admin permissions on those projects.
+  Returns {project-name project-id}"
+  [connection user-id project-names]
+  (->> (for [project-name project-names]
+         (let [project-id (create-project-as-user!
+                           connection user-id project-name)]
+           [project-name project-id]))
+       (into {})))

 (defn populate-data!
   "In: {google-id [list of owned projects]}
@@ -12,17 +45,8 @@
   [test-data]
   (jdbc/with-db-transaction [conn (db/connection)]
     (reduce (fn [project-name-ids [google-id project-names]]
-              (let [{user-id :id} (first (jdbc/insert! conn "app_user"
-                                                       {"google_id" google-id
-                                                        "name" "Agent Smith"}))]
+              (let [user-id (create-user! conn google-id)]
                 (merge project-name-ids
-                       (->> (for [project-name project-names]
-                              (let [{project-id :id} (first (jdbc/insert! conn "project"
-                                                                          {"name" project-name}))]
-                                (create-admin-permission-query! {:project_id project-id
-                                                                 :user_id    user-id}
-                                                                {:connection conn})
-                                [project-name project-id]))
-                            (into {})))))
+                       (populate-projects! conn user-id project-names))))
             {}
             test-data)))


Add missing CLJS refer for clojure.test/are

--- test/clojure/contrib/humanize_test.cljc
+++ test/clojure/contrib/humanize_test.cljc
@@ -1,6 +1,6 @@
 (ns clojure.contrib.humanize-test
   (:require #?(:clj  [clojure.test :refer :all]
-               :cljs [cljs.test :refer-macros [deftest testing is]])
+               :cljs [cljs.test :refer-macros [deftest testing is are]])
             [clojure.contrib.humanize :refer [intcomma ordinal intword numberword
                                               filesize truncate oxford datetime
                                               duration-terms duration]]


Small changes for Uwe's Algorithm

Small changes for Uwe's Algorithm

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

--- src/conexp/contrib/experimental/ryssel_algorithm.clj
+++ src/conexp/contrib/experimental/ryssel_algorithm.clj
@@ -70,11 +70,7 @@
 ;;; The actual algorithm

 (defn- cover [base-set candidates A]
-  (let [candidates    (difference candidates
-                                  (set-of (intersection X Y) | X candidates, Y candidates
-                                                               :when (and (not (subset? X Y))
-                                                                          (not (subset? Y X))))),
-        object-covers (minimum-covers (difference base-set A)
+  (let [object-covers (minimum-covers (difference base-set A)
                                       (set-of (difference base-set N) | N candidates))]
     (map (fn [cover]
            (map #(difference base-set %) cover))
@@ -104,17 +100,19 @@
                                           n (gens N),
                                           :when (not= m n)])),
               candidates   (set-of U
-                                   [U M,
+                                   [U (disj M A),
                                     :when (not (exists [V M]
                                                  (and (subset? (intersection U A) V)
                                                       (proper-subset? V A))))]),
-              candidates   (disj candidates A),
+              candidates   (difference candidates
+                                       (set-of (intersection X Y) | X candidates, Y candidates
+                                                                    :when (and (not (subset? X Y))
+                                                                               (not (subset? Y X))))),
               covers       (cover (objects ctx) candidates A),
               B            (oprime A),
               implications (union implications
-                                  (set-of (make-implication premise B)
-                                          [X covers,
-                                           :let [premise (set-of m | Y X, m (gens Y))]]))]
+                                  (set-of (make-implication (set-of m | Y X, m (gens Y)) B)
+                                          | X covers))]
           (recur implications (rest extents)))))))

 ;;;


Fixed #126

Fixed #126

--- src/server/client-interface.cljs
+++ src/server/client-interface.cljs
@@ -209,7 +209,7 @@
     (println "Socket id " (.-id socket) " is unmuted!")
     (rooms/unmute-user user-id
       (fn []
-        (.emit (.to io room-id) "user-unmuted" (.-id socket)))))
+        (.emit (.to io room-id) "user-unmuted" user-id))))

   (s/defevent "track-complete" [] [user-id room-id]


Fix handler.cljs :require typo

Fix handler.cljs :require typo

--- lein-light-nrepl/src/lighttable/nrepl/handler.clj
+++ lein-light-nrepl/src/lighttable/nrepl/handler.clj
@@ -9,7 +9,7 @@
             [lighttable.nrepl.eval :as eval]
             [lighttable.nrepl.cljs :as cljs]
             [lighttable.nrepl.doc :as doc]
-            lighttable.nrepl.auto-complete
+            [lighttable.nrepl.auto-complete :as auto-complete]
             [clojure.repl :as repl]))

 (defn with-lt-data [msg]


WIP - add cache busting to local resources.

--- metlog-vault/src-server/metlog_vault/core.clj
+++ metlog-vault/src-server/metlog_vault/core.clj
@@ -56,8 +56,11 @@
     (data/store-data-samples (edn/read-string (slurp (:body req))))
     "Incoming data accepted.")

+  (GET "/dashboard" [] (render-dashboard))
+
+  (route/resources "/resources/public")
+
   (GET "/" [] (ring/redirect "/dashboard"))
-  (GET "/dashboard" [] (render-dashboard))
   (route/not-found "Resource Not Found"))

 (defn wrap-request-logging [ app ]
@@ -71,7 +74,6 @@

 (def handler (-> all-routes
                  (data/wrap-db-connection)
-                 (wrap-resource "public")
                  (wrap-content-type)
                  (wrap-browser-caching {"text/javascript" 360000
                                         "text/css" 360000})


Add lots of pattern matching tests

Add lots of pattern matching tests

The main match function doesn't pass all its tests yet

--- src/chapter3/match.cljs
+++ src/chapter3/match.cljs
@@ -22,7 +22,21 @@
   (is (not (match '(1 (2 nope) 3) '(1 (2 not really) 3)))))
 (defn basic-pattern-match-test [match]
   (is (match '(1 (? x) 2) '(1 not-really 2)))
-  (is (= 'not-really ('x (match '(1 (? x) 2) '(1 not-really 2))))))
+  (is (= 'not-really ('x (match '(1 (? x) 2) '(1 not-really 2)))))
+  (is (= nil ('y (match '(1 (? x) 2) '(1 caught 2)))))
+  (is (= {} (match '(1 2 3) '(1 2 3))))
+  (is (= {'x 1 'y 2} (match '((? x) (? y) 3) '(1 2 3))))
+  (is (not (match '(1 3) '(1 2))))
+  (is (= {} (match '(1 (2) 3) '(1 (2) 3))))
+  (is (not (match '(1 (?) 3) '(1 (2) 3))))
+  (is (not (match '(1 (? x y) 3) '(1 (2) 3))))
+  (is (not (match '(1 (! x) 3) '(1 (2) 3))))
+  (is (not (match '((? x) 3) '(1 2)))))
+(defn =1? [x] (= x 1))
+(defn function-pattern-match-test [match]
+  (is (= {'x 1 'y 2} (match '((chapter3.match/=1? x) (? y) 3) '(1 2 3))))
+  (is (not (match '((chapter3.match/=1? x) 2 3) '(2 2 3)))))
+
 (with-test
   (defn match2 [p s]
     (cond
@@ -87,6 +101,7 @@
          (not (atom? (first p)))
          (= (count (first p)) 2)
          (not (= (first (first p)) '?))
+         (resolve (first (first p)))
          ((resolve (first (first p))) (first s))
          (match5 (rest p) (rest s)))
         (do
@@ -95,52 +110,58 @@
         :else false))
     (if (match-helper p s) @variables false))
   (basic-match-test match5)
-  (basic-pattern-match-test match5))
-(defn match
+  (basic-pattern-match-test match5)
+  (function-pattern-match-test match5))
+(with-test
+  (defn match
   "Note: ClojureScript doesn't have resolve so arbitrary predicates won't work there."
-  [p s]
-  (def variables (atom {}))
-  (defn match-helper [p s]
-    (cond
-      ; (or (atom? p) (atom? s)) false
-      (empty? p) (empty? s)
-      (atom? (first p))
-      (and (not (empty? s))
-           (= (first p) (first s))
-           (match-helper (rest p) (rest s)))
-      ; complex patterns
-      (and (not (empty? s))
-           (= (first (first p)) '?))
-      (when (match-helper (rest p) (rest s))
-        (swap! variables (fn [vs] (assoc vs (second (first p)) (first s))))
-        true)
-      (= (first (first p)) '*)
-      (cond
-        (and (not (empty? s))
+    [p s]
+    (def variables (atom {}))
+    (defn match-helper [p s]
+      (cond
+        ; (or (atom? p) (atom? s)) false
+        (empty? p) (empty? s)
+        (atom? (first p))
+        (and (not (empty? s))
+             (= (first p) (first s))
              (match-helper (rest p) (rest s)))
-        (do
-          (swap! variables (fn [vs] (assoc vs (second (first p)) (list (first s)))))
-          true)
-        (match-helper (rest p) s)
-        (do
-          (swap! variables (fn [vs] (assoc vs (second (first p)) (list))))
-          true)
-        (and (not (empty? s))
-             (match-helper p (rest s)))
-        (do
-          (swap! variables (fn [vs] (assoc vs
-                                           (second (first p))
-                                           (cons (first s) (vs (second (first p)))))))
-          true))
-      (and
-       (not (empty? s))
-       ((resolve (first (first p))) (first s))
-       (match-helper (rest p) (rest s)))
-      (do
-        (swap! variables (fn [vs] (assoc vs (second (first p)) (first s))))
-        true)
-      :else false))
-  (if (match-helper p s) @variables false))
+        ; complex patterns
+        (and (not (empty? s))
+             (= (first (first p)) '?))
+        (when (match-helper (rest p) (rest s))
+          (swap! variables (fn [vs] (assoc vs (second (first p)) (first s))))
+          true)
+        (= (first (first p)) '*)
+        (cond
+          (and (not (empty? s))
+               (match-helper (rest p) (rest s)))
+          (do
+            (swap! variables (fn [vs] (assoc vs (second (first p)) (list (first s)))))
+            true)
+          (match-helper (rest p) s)
+          (do
+            (swap! variables (fn [vs] (assoc vs (second (first p)) (list))))
+            true)
+          (and (not (empty? s))
+               (match-helper p (rest s)))
+          (do
+            (swap! variables (fn [vs] (assoc vs
+                                             (second (first p))
+                                             (cons (first s) (vs (second (first p)))))))
+            true))
+        (and
+         (not (empty? s))
+         (resolve (first (first p)))
+         ((resolve (first (first p))) (first s))
+         (match-helper (rest p) (rest s)))
+        (do
+          (swap! variables (fn [vs] (assoc vs (second (first p)) (first s))))
+          true)
+        :else false))
+    (if (match-helper p s) @variables false))
+  (basic-match-test match)
+  (basic-pattern-match-test match)
+  (function-pattern-match-test match))
 (defn match-state
   "Note: ClojureScript doesn't have resolve so arbitrary predicates won't work there."
   [p s]


Check unit of selected sensor.

Check unit of selected sensor.

--- src-cljs/kixi/hecuba/tabs/sensors.cljs
+++ src-cljs/kixi/hecuba/tabs/sensors.cljs
@@ -152,6 +152,26 @@
                      :defaultChecked (get row :actual_annual "")
                      :on-change #(om/set-state! owner [:sensor :actual_annual] (.-checked (.-target %)))}]]]]])))))

+(defn update-sensor-selection [selected-sensors unit chart sensors history]
+  (om/update! sensors :selected selected-sensors)
+  (om/update! chart :sensor selected-sensors)
+  (om/update! chart :unit unit)
+  (om/update! chart :message "")
+  (history/update-token-ids! history :sensors (if (seq selected-sensors)
+                                                (string/join ";" selected-sensors)
+                                                nil)))
+
+(defn sensor-click [selected? sensors chart history id unit]
+
+  (let [selected-sensors ((if selected? disj conj) (:selected @sensors) id)]
+    (if-not selected?
+      (let [current-unit (:unit @chart)]
+        (if (or (empty? current-unit)
+                (= current-unit unit))
+          (update-sensor-selection selected-sensors unit chart sensors history)
+          (om/update! chart :message "Sensors must be of the same unit.")))
+      (update-sensor-selection selected-sensors unit chart sensors history))))
+
 (defn form-row [data chart history table-id editing-chan]
   (fn [cursor owner]
     (reify
@@ -166,16 +186,10 @@
                        selected? (contains? (:selected sensors) id)]
            [:tr {:onClick (fn [e] (let [div-id (.-id (.-target e))]
                                     (when-not (= "edit" div-id)
-                                      (let [selected-sensors ((if selected? disj conj) (:selected @sensors) id)]
-                                        (om/update! sensors :selected selected-sensors)
-                                        (om/update! chart :sensor selected-sensors)
-                                        (om/update! chart :unit unit) ;; TODO sensors should be of the same unit (?)
-                                        (when (and lower_ts upper_ts)
-                                          (om/update! chart :range {:start-date (common/unparse-date lower_ts "yyyy-MM-dd HH:MM:SS")
-                                                                    :end-date (common/unparse-date upper_ts "yyyy-MM-dd HH:MM:SS")}))
-                                        (history/update-token-ids! history :sensors (if (seq selected-sensors)
-                                                                                (string/join ";" selected-sensors)
-                                                                                nil))))))
+                                      (sensor-click selected? sensors chart history id unit)
+                                      (when (and lower_ts upper_ts)
+                                        (om/update! chart :range {:start-date (common/unparse-date lower_ts "yyyy-MM-dd HH:MM:SS")
+                                                                  :end-date (common/unparse-date upper_ts "yyyy-MM-dd HH:MM:SS")})))))
                  :class (when selected? "success")
                  :id (str table-id "-selected")}
             (when editable


Moving Culture record at the top of civs.model.core

--- src/civs/model/core.clj
+++ src/civs/model/core.clj
@@ -6,6 +6,8 @@

 (defrecord PoliticalEntity [id name society groups culture])
 (defrecord Game [world settlements groups political-entities next_id])
+(defrecord Culture [nomadism knowledge language])
+
 (declare culture)
 (declare society)
 (declare update-political-entity)
@@ -58,8 +60,6 @@
    :post [(instance? Game %)]}
   (let [pe (to-political-entity game x)]
     (update-political-entity game (.id pe) (fn [pe _] (assoc-in pe [:culture :nomadism] nomadism)))))
-
-(defrecord Culture [nomadism knowledge language])

 (def initial-culture (Culture. :nomadic [] nil))


remove old comment :sad:

remove old comment :sad:

--- test/metabase/test/data/generic_sql.clj
+++ test/metabase/test/data/generic_sql.clj
@@ -47,7 +47,7 @@

 (defn drop-physical-table! [dataset-loader database-definition {:keys [table-name]}]
   (execute-sql! dataset-loader database-definition
-    (format "DROP TABLE IF EXISTS %s;" (quote-name dataset-loader table-name)))) ; don't quote table name because MySQL doesn't like it
+    (format "DROP TABLE IF EXISTS %s;" (quote-name dataset-loader table-name))))

 (defn create-physical-db! [dataset-loader {:keys [table-definitions], :as database-definition}]


port to dev-local

port to dev-local

--- tutorial/component_attributes.clj
+++ tutorial/component_attributes.clj
@@ -6,34 +6,30 @@
 ;   the terms of this license.
 ;   You must not remove this notice, or any other, from this software.

-(require '[datomic.client.api :as d]
-         '[datomic.samples.repl :as repl])
-(import '(java.util UUID))
+(require '[datomic.client.api :as d])

-(def client-cfg (read-string (slurp "config.edn")))
-(def client (d/client client-cfg))
-(def db-name (str "scratch-" (UUID/randomUUID)))
-(d/create-database client {:db-name db-name})
-(def conn (d/connect client {:db-name db-name}))
-
-(repl/transact-all conn (repl/resource "day-of-datomic-cloud/social-news.edn"))
+(def client (d/client {:server-type :dev-local :system "datomic-samples"}))
+(def conn (d/connect client {:db-name "social-news"}))
+(def db (d/with-db conn))

 ;; create a story and some comments
-(let [[story comment-1 comment-2] (map str (repeat "tempid-") (range))
-      {:keys [tempids db-after]}
-      (d/transact conn {:tx-data [{:db/id story
-                                   :story/title "Getting Started"
-                                   :story/url "http://docs.datomic.com/getting-started.html"}
-                                  {:db/id comment-1
-                                   :comment/body "It woud be great to learn about component attributes."
-                                   :_comments story}
-                                  {:db/id comment-2
-                                   :comment/body "I agree."
-                                   :_comments comment-1}]})]
-  (def story (get tempids story))
-  (def comment-1 (get tempids comment-1))
-  (def comment-2 (get tempids comment-2))
-  (def db db-after))
+(def tx-result
+  (d/with db {:tx-data [{:db/id "story"
+                         :story/title "Getting Started"
+                         :story/url "http://docs.datomic.com/getting-started.html"}
+                        {:db/id "comment-1"
+                         :comment/body "It would be great to learn about component attributes."
+                         :_comments "story"}
+                        {:db/id "comment-2"
+                         :comment/body "I agree."
+                         :_comments "comment-1"}]}))
+
+(def tempids (:tempids tx-result))
+(def story (get tempids "story"))
+(def comment-1 (get tempids "comment-1"))
+(def comment-2 (get tempids "comment-2"))
+
+(def db (:db-after tx-result))

 ;; component attributes are automatically pulled when you pull the parent
 (d/pull db '[*] story)
@@ -42,13 +38,11 @@
 (:db/doc (d/pull db '[:db/doc] :db/retractEntity))

 ;; retract the story
-(def retracted-es (->> (d/transact conn {:tx-data [[:db/retractEntity story]]})
+(def retracted-es (->> (d/with db {:tx-data [[:db/retractEntity story]]})
                        :tx-data
                        (remove :added)
                        (map :e)
                        (into #{})))

 ;; retraction recursively retracts component comments
-(assert (= retracted-es #{story comment-1 comment-2}))
-
-(d/delete-database client {:db-name db-name})
+(assert (= retracted-es #{story comment-1 comment-2}))


Update usage example.

Update usage example.

--- src/cli4clj/example.clj
+++ src/cli4clj/example.clj
@@ -14,8 +14,9 @@
   (:use cli4clj.cli)
   (:gen-class))

-(defn multiply [x y]
-  (* x y))
+;;; This function is just used for providing an example below.
+(defn divide [x y]
+  (/ x y))

 (defn -main [& args]
 ;;; In the simplest scenario only the commands have to be defined.
@@ -38,11 +39,14 @@
 ;;;                      All Clojure data types are supported as arguments.
 ;;;                      However, no sanity checks, e.g., with respect to the number of arguments or the argument type(s), are performed.
 ;;;                      If things go wrong, exceptions will be thrown and printed.
-                         :add  {:fn (fn [a b] (+ a b))}
+                         :add  {:fn (fn [a b] (+ a b))
+                                :short-info "Add two values."}
                          :a :add
 ;;;                      The following example shows the use of a named function.
-                         :multiply {:fn multiply}
-                         :m :multiply
+                         :divide {:fn divide
+                                  :short-info "Divide two values."
+                                  :long-info "The first argument will be divided by the second argument."}
+                         :d :divide
 ;;;                      "h" is already a pre-defined command but it can be overridden.
 ;;;                      This is shown by using the definition of an alias for test as example.
                          :h :test


Fix NPE for `unexceptional-status-for-request?` (#474)

Fixes `(unexceptional-status-for-request? {:unexceptional-status nil}
200) => NPE`. I.e. if you have no `:unexceptional-status` key, this
will work fine, but if this key is present then `nil` will be used as fn

--- src/clj_http/client.clj
+++ src/clj_http/client.clj
@@ -206,7 +206,8 @@

 (defn unexceptional-status-for-request?
   [req status]
-  ((:unexceptional-status req unexceptional-status?) status))
+  ((or (:unexceptional-status req) unexceptional-status?)
+   status))

 ;; helper methods to determine realm of a response
 (defn success?


be more disciplined about ints in murmur3 code

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -466,22 +466,22 @@

 ;; http://smhasher.googlecode.com/svn/trunk/MurmurHash3.cpp
 (def m3-seed 0)
-(def m3-C1 0xcc9e2d51)
-(def m3-C2 0x1b873593)
+(def m3-C1 (int 0xcc9e2d51))
+(def m3-C2 (int 0x1b873593))

 (defn ^number m3-mix-K1 [k1]
-  (-> k1 (imul m3-C1) (int-rotate-left 15) (imul m3-C2)))
+  (-> (int k1) (imul m3-C1) (int-rotate-left 15) (imul m3-C2)))

 (defn ^number m3-mix-H1 [h1 k1]
-  (-> h1 (bit-xor k1) (int-rotate-left 13) (imul 5) (+ 0xe6546b64)))
+  (int (-> (int h1) (bit-xor (int k1)) (int-rotate-left 13) (imul 5) (+ (int 0xe6546b64)))))

 (defn ^number m3-fmix [h1 len]
-  (as-> h1 h1
+  (as-> (int h1) h1
     (bit-xor h1 len)
     (bit-xor h1 (unsigned-bit-shift-right h1 16))
-    (imul h1 0x85ebca6b)
+    (imul h1 (int 0x85ebca6b))
     (bit-xor h1 (unsigned-bit-shift-right h1 13))
-    (imul h1 0xc2b2ae35)
+    (imul h1 (int 0xc2b2ae35))
     (bit-xor h1 (unsigned-bit-shift-right h1 16))))

 (defn ^number m3-hash-int [in]


Improved conditional compilation for 1.2.x.

Use a macro to conditionally compile, rather than Class/forName at runtime.

--- src/cheshire/custom.clj
+++ src/cheshire/custom.clj
@@ -191,13 +191,14 @@

 ;; This is lame, thanks for changing all the BigIntegers to BigInts
 ;; in 1.3 clojure/core :-/
-(when (not= {:major 1 :minor 2} (select-keys *clojure-version* [:major :minor]))
-  ;; Use Class/forName so it only resolves if it's running on clojure 1.3
-  (extend (Class/forName "clojure.lang.BigInt")
-    JSONable
-    {:to-json (fn encode-bigint
-                [^java.lang.Number n ^JsonGenerator jg]
-                (.writeNumber jg ^java.math.BigInteger (.toBigInteger n)))}))
+(defmacro handle-bigint []
+  (when (not= {:major 1 :minor 2} (select-keys *clojure-version* [:major :minor]))
+    `(extend clojure.lang.BigInt
+       JSONable
+       {:to-json ~'(fn encode-bigint
+                     [^clojure.lang.BigInt n ^JsonGenerator jg]
+                     (.writeNumber jg (.toBigInteger n)))})))
+(handle-bigint)

 (extend clojure.lang.Ratio
   JSONable


CLJS-346: fix CLJ-319 regression for println when given no arguments.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -6177,12 +6177,15 @@
   "Prints a sequence of objects using string-print, observing all
   the options given in opts"
   [objs opts]
-  (doseq [string (pr-seq (first objs) opts)]
-    (string-print string))
-  (doseq [obj (next objs)]
-    (string-print " ")
-    (doseq [string (pr-seq obj opts)]
-      (string-print string))))
+  (if (empty? objs)
+    (string-print "")
+    (do
+     (doseq [string (pr-seq (first objs) opts)]
+       (string-print string))
+     (doseq [obj (next objs)]
+       (string-print " ")
+       (doseq [string (pr-seq obj opts)]
+         (string-print string))))))

 (defn newline [opts]
   (string-print "\n")


chabot: put his twitter

chabot: put his twitter

--- src/cljs/type/core.cljs
+++ src/cljs/type/core.cljs
@@ -134,10 +134,15 @@
        "")]
     [:div.footer
      [:span.social-btn.left [twitter-button]]
-     [:span.instructions-and-link.right
+     [:span.instructions-and-link.right {:style {:font-size "14px"
+                                                 :position "relative"
+                                                 :top "6px"}}
       [:span {:style {:color "#fff"}} "Made by "]
       [:a {:target "_blank"
-           :href "https://twitter.com/teawaterwire"} "@teawaterwire"]]]]
+           :href "https://twitter.com/teawaterwire"} "@teawaterwire"]
+      [:span {:style {:color "#fff"}} " & Designed by "]
+      [:a {:target "_blank"
+           :href "https://twitter.com/guillaumechabot"} "@guillaumechabot"]]]]
    ])

 ;; -------------------------


Add math constants.

Add math constants.

--- src/cljx/quil/core.cljx
+++ src/cljx/quil/core.cljx
@@ -190,13 +190,14 @@

 ;;; Useful trig constants
 #+clj (def PI  (float Math/PI))
-#+clj (def HALF-PI    (/ PI (float 2.0)))
-#+clj (def THIRD-PI   (/ PI (float 3.0)))
-#+clj (def QUARTER-PI (/ PI (float 4.0)))
-#+clj (def TWO-PI     (* PI (float 2.0)))
-
-#+clj (def DEG-TO-RAD (/ PI (float 180.0)))
-#+clj (def RAD-TO-DEG (/ (float 180.0) PI))
+#+cljs (def PI  (.-PI js/Math))
+(def HALF-PI    (/ PI (float 2.0)))
+(def THIRD-PI   (/ PI (float 3.0)))
+(def QUARTER-PI (/ PI (float 4.0)))
+(def TWO-PI     (* PI (float 2.0)))
+
+(def DEG-TO-RAD (/ PI (float 180.0)))
+(def RAD-TO-DEG (/ (float 180.0) PI))

 #+clj
 (def  ^{:private true}


Fix crash for missing autocomplete.

Fix crash for missing autocomplete.

This hangs for a couple of seconds, but doesn't crash.

--- src/clojupyter/core.clj
+++ src/clojupyter/core.clj
@@ -330,9 +330,16 @@

 (defn is-complete-reply
   "Returns whether or not what the user has typed is complete (ready for execution).
-   Not yet implemented. May be  that it is just used by jupyter-console."
+   Not yet implemented. May be that it is just used by jupyter-console."
   [message signer]
-  true)
+  {:status "unknown"})
+
+(defn complete-reply
+  [message signer]
+  {:matches nil
+   :cursor_start (:cursor_pos message)
+   :cursor_end (:cursor_pos message)
+   :status "ok"})

 (defn configure-shell-handler [shell-socket iopub-socket signer nrepl-transport]
   (let [execute-request (execute-request-handler shell-socket iopub-socket nrepl-transport)]
@@ -345,6 +352,7 @@
           "shutdown_request" (shutdown-reply message signer)
           "comm_open" (immediately-close-comm message shell-socket signer)
           "is_complete_request" (is-complete-reply message signer)
+          "complete_request" (complete-reply message signer)
           (do
             (println "Message type" msg-type "not handled yet. Exiting.")
             (println "Message dump:" message)


removed unused dot-product function

removed unused dot-product function

--- src/clj/forma/utils.clj
+++ src/clj/forma/utils.clj
@@ -54,11 +54,6 @@
   the supplied number `fact`."
   [factor coll]
   (for [x coll] (* x factor)))
-
-(defn dot-product
-  "returns the dot product of two vectors"
-  [x y]
-  (reduce + (map * x y)))

 (defn multiply-rows
   "multiply matrix rows (in place) by a collection"


Fix error introduced in redirect patch.  wrap-url must be called prior to wrap-user-info and wrap-query-params

--- src/clj_http/client.clj
+++ src/clj_http/client.clj
@@ -173,15 +173,15 @@
    core client. See client/client."
   [request]
   (-> request
+      wrap-query-params
+      wrap-user-info
       wrap-url
       wrap-redirects
       wrap-exceptions
       wrap-decompression
       wrap-input-coercion
       wrap-output-coercion
-      wrap-query-params
       wrap-basic-auth
-      wrap-user-info
       wrap-accept
       wrap-accept-encoding
       wrap-content-type


Ring returns lower case header parameters, added a lower-case "content-encoding" to fix wrap-decompression

--- src/clj_http/client.clj
+++ src/clj_http/client.clj
@@ -60,7 +60,8 @@
       (client req)
       (let [req-c (update req :headers assoc "Accept-Encoding" "gzip, deflate")
             resp-c (client req-c)]
-        (case (get-in resp-c [:headers "Content-Encoding"])
+        (case (or (get-in resp-c [:headers "Content-Encoding"])
+                  (get-in resp-c [:headers "content-encoding"]))
           "gzip"
           (update resp-c :body util/gunzip)
           "deflate"


At Stuart Sierra's suggestion, use condp instead of clojure.contrib.fcase/re-case since c.c.fcase is sort of deprecated.

--- src/clj_record/util.clj
+++ src/clj_record/util.clj
@@ -1,10 +1,9 @@
 (ns clj-record.util
-  (:use (clojure.contrib str-utils
-                         fcase)))
+  (:use (clojure.contrib str-utils)))

 (defn singularize [plural]
   (let [lc (.toLowerCase plural)]
-    (re-case lc
+    (condp re-find lc
       #"ies$" (re-sub #"ies$" "y" lc)
       #"(s|z|ch|sh|x)es$" (re-sub #"(s|z|ch|sh|x)es$" "$1" lc)
       #"s$" (re-sub #"s$" "" lc)


Add scroll to top on brand

Add scroll to top on brand

--- src/cljs/auto/core.cljs
+++ src/cljs/auto/core.cljs
@@ -49,6 +49,7 @@
                        {:target (. js/document (getElementById "app-content"))})))

 (defroute "/brand/:brand-id" {:as params}
+          (js/scroll 0 0)
           (app params))

 (defroute "/brand/:brand-id/model/:model-id" {:as params}


* src/cljs/cljs/reader.cljs: semi-fix. Breaks browser REPL

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -981,6 +981,8 @@
   one arg, returns the concatenation of the str values of the args."
   ([] "")
   ([x] (cond
+        (symbol? x) (. x (substring 2 (.length x)))
+        (keyword? x) (str ":" (. x (substring 2 (.length x))))
         (nil? x) ""
         :else (. x (toString))))
   ([x & ys]


Remove Seq protocol from array and string.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -358,15 +358,6 @@

   goog.global.Array
   (-nth [array n] (aget array n)))
-
-(extend-protocol ISeq
-  goog.global.String
-  (-first [string] (-first (-seq string)))
-  (-rest [string] (-rest (-seq string)))
-
-  goog.global.Array
-  (-first [array] (-first (-seq array)))
-  (-rest [array] (-rest (-seq array))))

 (defn cons
   "Returns a new seq where x is the first element and seq is the rest."


Apply patch from Arthur Ulfeldt to fix #CLJS-6. Add tests to test-stuff.

--- src/cljs/cljs/core.cljs
+++ src/cljs/cljs/core.cljs
@@ -2335,6 +2335,18 @@
    (when-let [s (seq coll)]
      (when (pred (first s))
        (cons (first s) (take-while pred (rest s)))))))
+
+(defn range
+  "Returns a lazy seq of nums from start (inclusive) to end
+  (exclusive), by step, where start defaults to 0, step to 1, and end
+  to infinity."
+  ([] (iterate inc 0))
+  ([end] (range 0 end 1))
+  ([start end] (range start end 1))
+  ([start end step]
+    (take-while
+      (fn [n] (< n end))
+      (iterate (fn [x] (+ x step)) start))))

 (defn take-nth
   "Returns a lazy seq of every nth item in coll."
@@ -3416,6 +3428,12 @@
   (assert (= (rem 2 -5) 2))
   (assert (= (rem 0 3) 0))

+  ;; range
+  (assert (= (range 10) (list 0 1 2 3 4 5 6 7 8 9)))
+  (assert (= (range 10 20) (list 10 11 12 13 14 15 16 17 18 19)))
+  (assert (= (range 10 20 2) (list 10 12 14 16 18)))
+  (assert (= (take 20 (range)) (list 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)))
+
   ;; group-by
   (let [d (group-by second {:a 1 :b 2 :c 1 :d 4 :e 1 :f 2})]
     (assert (= 3 (count (get d 1))))


cues on main page

cues on main page

--- src/cljs/spcr/core.cljs
+++ src/cljs/spcr/core.cljs
@@ -9,6 +9,7 @@

 (defn home []
-  [:h1 "Hello World from Reagent"])
+  [:h1 "Hello World from Reagent"]
+  [:p "put your grid here"])

 (reagent/render-component [home] (.getElementById js/document "app"))


cache seconds route

cache seconds route

--- src/cljsbin/routes.cljs
+++ src/cljsbin/routes.cljs
@@ -2,6 +2,7 @@
   (:require
     [bidi.bidi :as bidi]
     [hiccups.runtime]
+    [clojure.string]
     [macchiato.util.response :as r]
     [macchiato.util.request :refer [request-url body-string]]
     [camel-snake-kebab.core :refer [->HTTP-Header-Case]])
@@ -131,6 +132,18 @@
           (get-in req [:headers "if-none-match"]))
     (res (r/not-modified))
     (get_ req res raise)))
+
+(defn cache-seconds
+  "Sets a Cache-Control header for n seconds."
+  [req res raise]
+  (let [seconds (js/parseInt (get-in req [:route-params :n]))
+        header-value (str "public, max-age=" seconds)
+        respond #(-> %
+                     (r/header "Cache-Control" header-value)
+                     (res))]
+    (if (integer? seconds)
+      (get_ req respond raise)
+      (raise (js/Error "Not a valid cache age.")))))

 (defn status
   "Returns given HTTP Status code."
@@ -249,6 +262,7 @@
        "/robots.txt" {:get robots}
        "/deny" {:get deny}
        "/cache" {:get cache}
+       ["/cache/" :n] {:get cache-seconds}
        ["/status/" :status] {:get status}
        ["/delay/" :n] {:get delay_}
        "/response-headers" {:get response-headers}


wip on adding participants to a class

wip on adding participants to a class

--- src/tango/cljs/runtime/core.cljs
+++ src/tango/cljs/runtime/core.cljs
@@ -183,7 +183,7 @@
 (defui CreateClassView
   static om/IQuery
   (query [_]
-    [:class/name :class/id])
+    [:class/name :class/id {:class/starting [:participant/number]}])
   Object
   (render
     [this]
@@ -213,12 +213,27 @@

             ;; Adjudicator Panel

+            ;; Dances
+
             ;; Participants
             (dom/div #js {:className "form-group"}
               (dom/label #js {:className "col-sm-2 control-label"} "Participants")
               (dom/div #js {:className "col-sm-8"}
-                (dom/ul nil
-                  (dom/li nil "A"))))
+                (dom/div nil
+                  (dom/button #js {:className "btn btn-default"
+                                   :onClick   (fn [e]
+                                                (let [new-id (random-uuid)]
+                                                  (om/transact!
+                                                    reconciler
+                                                    `[(app/select-page {:selected-page :edit-class-participants})
+
+                                                      :app/selected-page])))}
+                              (dom/span #js {:className "glyphicon glyphicon-plus"}))
+                  (dom/p nil (str "Starting : " (count (:class/starting selected-class)))))
+                ;(dom/ul nil)
+                (map #(dom/button #js {:className "col-sm-6 btn btn-default"}
+                                  (str (:participant/number %) " - " (:participant/name %)))
+                     (:class/starting selected-class))))

             ;; Create
             (dom/div #js {:className "form-group"}
@@ -269,7 +284,9 @@
 (defui ClassRow
   static om/IQuery
   (query [_]
-    '[:class/position :class/name :class/remaining :class/starting :class/id
+    '[:class/position :class/name :class/remaining :class/id
+      ;; TODO - in a normalized view only participant/id should be good
+      {:class/starting [:participant/number :participant/name :participant/id]}
       {:class/rounds
        [{:round/status [*]}
        {:round/type [*]}]}
@@ -366,6 +383,43 @@
                                                                    false)})) classes))
           )))))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; SelectClassParticipantsView
+(defui SelectClassParticipantsView
+  static om/IQuery
+  (query [_]
+    [])
+  Object
+  (render
+    [this]
+    (let [participants (sort-by :participant/number (:participants (om/props this)))
+          selected-class (:selected-class (om/props this))
+          starting (:class/starting selected-class)
+          selected? (fn [participant]
+                      (if (seq (filter
+                                 #(= (:participant/id %) (:participant/id participant))
+                                 starting))
+                        true
+                        false))]
+      (log "SelectedClassParticipantsView")
+      (log selected-class)
+      (dom/div #js {:className "col-sm-12"}
+        (dom/h2 {:className "sub-header"} (str "Select Participants for Class "
+                                               (:class/name selected-class)))
+        (dom/div nil
+          (dom/button nil "Back")
+          (dom/button nil "Done"))
+        (map #(dom/button #js {:className (str "col-sm-6 btn" (if (selected? %)
+                                                                " btn-primary"
+                                                                " btn-default"))
+                               :onClick (fn [e]
+                                          (om/transact!
+                                            reconciler
+                                            `[(class/update
+                                                {:class/starting ~(conj starting %)})
+                                              :app/selected-class]))}
+                          (str (:participant/number %) " - " (:participant/name %)))
+             participants)))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Import/Export Component
@@ -615,6 +669,10 @@
                      )

           :create-class ((om/factory CreateClassView) (:app/selected-class p))
+
+          :edit-class-participants ((om/factory SelectClassParticipantsView)
+                                     {:participants participants
+                                      :selected-class (:app/selected-class p)})

           :time-schedule ((om/factory ScheduleView) {:competition/activities
                                                      (:competition/activities selected-competition)


Fix errors.

Fix errors.

--- src/org/spootnik/cyanite/es_path.clj
+++ src/org/spootnik/cyanite/es_path.clj
@@ -178,12 +178,14 @@
 (defn es-native
   [{:keys [index host port cluster_name]
     :or {index "cyanite" host "localhost" port 9300 cluster_name "elasticsearch"}}]
-  (let [hosts (map #([% port]) (if (sequential? host) host [host]))
+  (let [hosts (map #(vector % port) (if (sequential? host) host [host]))
         conn (esn/connect hosts {"cluster.name" cluster_name})
         existsfn (partial esnd/present? conn index ES_DEF_TYPE)
         updatefn (partial esnd/async-put conn index ES_DEF_TYPE)
         scrollfn (partial esnd/scroll-seq conn)
         queryfn (partial esnd/search conn index ES_DEF_TYPE)]
+    (info (format "creating elasticsearch path store: %s"
+                  (str/join ", " (map #(str/join ":" %) hosts))))
     (if (not (esni/exists? conn index))
       (esni/create conn index :mappings ES_TYPE_MAP))
     (reify Pathstore


views: only display the first line of a multi-line shell script

The full script is only displayed when we have enough space for that.

--- src/org/spootnik/om_fleet/views.cljs
+++ src/org/spootnik/om_fleet/views.cljs
@@ -135,7 +135,8 @@
         (string? script) (when (not= script "ping") (dom/code nil script))
         (script "service") (script "service")
         (script "sleep") (script "sleep")
-        (script "shell") (dom/code nil (script "shell"))))))
+        (script "shell") (dom/code nil (first (clojure.string/split-lines
+                                               (script "shell"))))))))

 (defcomponent scenario-history
   [history owner]
@@ -259,7 +260,9 @@
                                            (script "action") " "))

         (and (map? script) (script "shell"))
-        (dom/span nil "Script " (dom/code nil (script "shell") " "))
+        (dom/span nil "Script " (dom/code nil (first
+                                               (clojure.string/split-lines
+                                                (script "shell"))) " "))

         :else
         (dom/span nil "Script " (dom/code nil script) " "))


Documented :mailing-list and :license in sample.project.clj.

Also mentioned :mailing-lists, :licenses, :licence(s) in the comments.

--- sample.project.clj
+++ sample.project.clj
@@ -11,6 +11,26 @@
   :description "A sample project"
   ;; The URL is also metadata that Clojars uses.
   :url "http://example.org/sample-clojure-project"
+  ;; The mailing list of the project. If the project has multiple mailing
+  ;; lists, use the :mailing-lists key (bound to a seq of mailing list
+  ;; descriptions as below).
+  :mailing-list {:name "sample mailing list"
+                 :archive "http://example.org/sample-mailing-list-archives"
+                 :other-archives ["http://example.org/sample-mailing-list-another-archive-url"
+                                  "http://example.org/sample-mailing-list-yet-another-archive-url"]
+                 :post "list@example.org"
+                 :subscribe "list-subscribe@example.org"
+                 :unsubscribe "list-unsubscribe@example.org"}
+  ;; The project's license. :distribution should be :repo or :manual;
+  ;; :repo means it is ok for public repositories to host this project's
+  ;; artifacts. :licence can be used in place of :license, and for projects
+  ;; which allow their users to choose among several licenses, :licenses
+  ;; and :licences keys are supported. NB. all licenses mentioned in
+  ;; project.clj under any of the supported keys will be put in pom.xml.
+  :license {:name "Eclipse Public License - v 1.0"
+            :url "http://www.eclipse.org/legal/epl-v10.html"
+            :distribution :repo
+            :comments "same as Clojure"}
   ;; Dependencies are listed as [group-id/name version].
   :dependencies [[org.clojure/clojure "1.1.0"]
                  [org.clojure/clojure-contrib "1.1.0"]


Update examples

Update examples

--- modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc
+++ modules/reitit-swagger-ui/src/reitit/swagger_ui.cljc
@@ -15,19 +15,17 @@
      | :config          | parameters passed to swaggger-ui as-is.

      See https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md
-     for all available :config options
+     for all available :config options.

      Examples:
+     ```
+     (swagger-ui/create-swagger-ui-handler)

-        ;; with defaults
-        (create-swagger-ui-handler)
-
-        ;; with path and url set, swagger validator disabled, jsonEditor enabled
-        (swagger-ui/create-swagger-ui-handler
-          {:path \"/\"
-           :url \"/api/swagger.json\"
-           :config {:validatorUrl nil
-                    :jsonEditor true})"
+     (swagger-ui/create-swagger-ui-handler
+       {:path \"/swagger-ui\"
+        :url \"/api/swagger.json\"
+        :config {:validatorUrl nil}})
+     ```"
      ([]
       (create-swagger-ui-handler nil))
      ([options]


oops, that was only changed in newest closure release

--- src/main/shadow/build/closure.clj
+++ src/main/shadow/build/closure.clj
@@ -532,7 +532,10 @@
 (defn js-error-xf [state ^com.google.javascript.jscomp.Compiler cc]
   (map (fn [^JSError err]
          (let [source-name
-               (.getSourceName err)
+               (.-sourceName err)
+
+               description
+               (.-description err)

                line
                (.getLineNumber err)
@@ -559,7 +562,7 @@
               :source-name source-name
               :line line
               :column column
-              :msg (.getDescription err)}
+              :msg description}

              (let [{:keys [resource-id resource-name file url]} src

@@ -586,7 +589,7 @@
                 :file file
                 :line line
                 :column column
-                :msg (.getDescription err)
+                :msg description
                 :source-excerpt source-excerpt}
                ))))))


prevent name collision on PrintWriter-on with clj 1.10 alphas

fixes #389

--- src/main/shadow/cljs/devtools/server/repl_system.clj
+++ src/main/shadow/cljs/devtools/server/repl_system.clj
@@ -149,9 +149,10 @@
         s))))

-;; taken from clojure/core/server.clj 1.10 alphas
-
-(defn ^java.io.PrintWriter PrintWriter-on
+;; taken from clojure/core/server.clj 1.10 alphas PrintWriter_on
+;; renamed to prevent name collision
+
+(defn ^java.io.PrintWriter writer->fn
   "implements java.io.PrintWriter given flush-fn, which will be called
   when .flush() is called, with a string built up since the last call to .flush().
   if not nil, close-fn will be called with no arguments when .close is called"
@@ -186,7 +187,6 @@
             (InputStreamReader.)
             (LineNumberingPushbackReader.))

-
         send-msg
         (fn [msg]
           (let [msg (assoc msg
@@ -197,14 +197,14 @@
               (log/warn ::clj-session-overload msg))))

         session-out
-        (PrintWriter-on
+        (writer->fn
           (fn [text]
             (send-msg {::m/op ::m/session-out
                        ::m/session-out text}))
           nil)

         session-err
-        (PrintWriter-on
+        (writer->fn
           (fn [text]
             (send-msg {::m/op ::m/session-err
                        ::m/session-err text}))


Tundra disk store fix: don't recur endlessly when failing to create output dir

--- src/taoensso/carmine/tundra/disk.clj
+++ src/taoensso/carmine/tundra/disk.clj
@@ -45,7 +45,7 @@
       (cond
        (instance? Path result) true
        (instance? NoSuchFileException result)
-       (do (mkdirs path) (recur k v))
+       (if (mkdirs path) (recur k v) result)

        (instance? Exception result) result
        :else (ex-info (format "Unexpected result: %s" result) {:result result})))))


replace memoize with delay

replace memoize with delay

--- src/vip/data_processor/queue.clj
+++ src/vip/data_processor/queue.clj
@@ -14,16 +14,11 @@
                             {:access-key-id     access-key
                              :secret-access-key secret-key})}))

-(def sns-client-memo (memoize sns-client))
-
-(defn default-sns-client
-  []
-   ;; memoize the default sns-client construction, so that
-   ;; we can avoid creating extra thread pools over time.
-   ;; see https://github.com/cognitect-labs/aws-api/issues/80
-   (memoize (sns-client (config [:aws :creds :access-key])
-                        (config [:aws :creds :secret-key])
-                        (config [:aws :region]))))
+(def default-sns-client
+  "SNS Client configured by runtime environment"
+  (delay (sns-client (config [:aws :creds :access-key])
+                     (config [:aws :creds :secret-key])
+                     (config [:aws :region]))))

 (defn- publish
   [sns-client topic payload]
@@ -34,7 +29,7 @@
 (defn publish-success
   "Publish a successful feed processing message to the topic."
   ([payload]
-   (publish-success (default-sns-client)
+   (publish-success @default-sns-client
                     (config [:aws :sns :success-topic-arn])
                     payload))
   ([sns-client topic payload]
@@ -45,7 +40,7 @@
 (defn publish-failure
   "Publish a failed feed processing message to the topic."
   ([payload]
-   (publish-failure (default-sns-client)
+   (publish-failure @default-sns-client
                     (config [:aws :sns :failure-topic-arn])
                     payload))
   ([sns-client topic payload]


fix application route

fix application route

--- src/cljs/salava/extra/application/ui/routes.cljs
+++ src/cljs/salava/extra/application/ui/routes.cljs
@@ -10,8 +10,8 @@
     #(layout/default site-navi content)))

 (defn ^:export routes [context]
-  {} #_{(str (base-path context) "/gallery") [["/application" a/handler]]})
+  {(str (base-path context) "/badge") [["/application" a/handler]]})

 (defn ^:export navi [context]
-  {} #_{(str (base-path context) "/gallery/application")         {:weight 45 :title (t :extra-application/Application)  :site-navi true :breadcrumb (t :gallery/Gallery " / " :extra-application/Application)}})
+  {(str (base-path context) "/badge/application") {:weight 45 :title (t :extra-application/Application)  :site-navi true :breadcrumb (t :gallery/Gallery " / " :extra-application/Application)}})


Too many secondary indexes!

Too many secondary indexes!

--- src/compound2/core.cljc
+++ src/compound2/core.cljc
@@ -255,7 +255,7 @@

 (defn compound* [indexes]
   (let [pi (indexer (merge primary-defaults (first indexes)))
-        sis (map (fn [opts] (indexer (merge secondary-defaults opts))) indexes)]
+        sis (map (fn [opts] (indexer (merge secondary-defaults opts))) (rest indexes))]
     (assert (satisfies? PrimaryIndex pi) "First index must be a primary index")
     (with-meta {}
       {`items (fn [c]
@@ -316,24 +316,3 @@
                                               sixs)
                                    ks)
                             (recur px sixs ks)))))})))
-(def fruit
-  (-> (compound [{:kfn :name}
-                 {:kfn :colour}])
-
-      (add-items #{{:name :strawberry
-                    :colour :red}
-
-                   {:name :raspberry
-                    :colour :red}
-
-                   {:name :banana
-                    :colour :yellow}})))
-
-{:name
- {:banana {:name :banana, :colour :yellow},
-  :raspberry {:name :raspberry, :colour :red},
-  :strawberry {:name :strawberry, :colour :red}},
- :colour
- {:yellow #{{:name :banana, :colour :yellow}},
-  :red #{{:name :raspberry, :colour :red}
-         {:name :strawberry, :colour :red}}}}


Moved event hook to after the event handling

--- src/ctia/flows/crud.clj
+++ src/ctia/flows/crud.clj
@@ -56,10 +56,10 @@
                                    :login login
                                    :entity realized
                                    :prev-entity prev-entity}))))
-        _ (h/apply-event-hooks event)
         result (if (= :delete flow-type)
                  (store-fn entity-id)
                  (store-fn realized))]
+    (h/apply-event-hooks event)
     (h/apply-hooks :entity realized
                    :prev-entity prev-entity
                    :hook-type (case flow-type