no need to store `data_atom` in local state

--- src/main/devcards_om_next/core.cljs
+++ src/main/devcards_om_next/core.cljs
@@ -23,18 +23,6 @@
                              (= (dc/get-state this :state_change_count)
                                 (.-state_change_count next-state)))]
              update?)))
-       :componentWillMount
-       (if (html-env?)
-         (fn []
-           (this-as
-            this
-            (let [card (dc/get-props this :card)
-                  data_atom (get-in card [:main-obj :data_atom])
-                  unique-id (dc/get-state this :omnext$unique-id)]
-              ;; when the component mounts, we can get the data_atom that the
-              ;; macro passes in (the Om Next app-state)
-              (.setState this #js {:data_atom data_atom}))))
-         (fn []))
        :componentDidMount
        (if (html-env?)
          (fn []
@@ -44,11 +32,10 @@
                   main-obj (:main-obj card)
                   mount-fn (:mount-fn main-obj)
                   unique-id (dc/get-state this :omnext$unique-id)
-                  target (js/document.getElementById unique-id)
-                  data_atom (dc/get-state this :data_atom)]
+                  target (js/document.getElementById unique-id)]
               ;; actually mount the Om Next root into our element
               (mount-fn target)
-              (when-let [data_atom (dc/get-state this :data_atom)]
+              (when-let [data_atom (:data_atom main-obj)]
                   (add-watch data_atom unique-id
                              (fn [_ _ _ _]
                                (.setState this #js {:state_change_count
@@ -75,7 +62,8 @@
         (fn []
           (this-as
            this
-           (let [data_atom (dc/get-state this :data_atom)
+           (let [card (dc/get-props this :card)
+                 data_atom (get-in card [:main-obj :data_atom])
                  id        (dc/get-state this :omnext$unique-id)]
              (when (and data_atom id)
                (remove-watch data_atom id)))))
@@ -86,7 +74,7 @@
            (let [card (dc/get-props this :card)
                  options (:options card)
                  unique-id (dc/get-state this :omnext$unique-id)
-                 data_atom (dc/get-state this :data_atom)
+                 data_atom (get-in card [:main-obj :data_atom])
                  main (cond->> (js/React.createElement "div" #js {:id unique-id})
                         (false? (:watch-atom options)) (dc/dont-update (dc/get-state this :state_change_count)))]
              (dc/render-all-card-elements main data_atom card))))})


fixed docstring on add-kafka-to-task

fixed docstring on add-kafka-to-task

--- src/lib_onyx/plugins/kafka.clj
+++ src/lib_onyx/plugins/kafka.clj
@@ -56,27 +56,29 @@
   opts are of the following form for Kafka consumers AND producers

   :kafka/topic               - Name of a topic
-  :kafka/partition           -- Optional: partition to read from if
+  :kafka/partition           - Optional: partition to read from if
                                  auto-assignment is not used
-  :kafka/group-id            -- The consumer identity to store in ZooKeeper
+  :kafka/group-id            - The consumer identity to store in ZooKeeper
   :kafka/zookeeper           - The ZooKeeper connection string
-  :kafka/offset-reset        -- Offset bound to seek to when not found
+  :kafka/offset-reset        - Offset bound to seek to when not found
                                  - :smallest or :largest
-  :kafka/force-reset?        -- Force to read from the beginning or end of the
+  :kafka/force-reset?        - Force to read from the beginning or end of the
                                  log, as specified by :kafka/offset-reset.
                                  If false, reads from the last acknowledged
                                  messsage if it exists
   :kafka/serializer-fn       - :json or :edn for default serializers, a
-                                custom fn can also be supplied
-  :kafka/deserializer-fn     -- :json or :edn for default deserializers, a
-                                custom fn can also be supplied
+                                custom fn can also be supplied. Only for
+                                :output tasks
+  :kafka/deserializer-fn     - :json or :edn for default deserializers, a
+                                custom fn can also be supplied. Only for
+                                :input tasks

   ========================== Optional Settings =================================
   :kafka/chan-capacity
   :kafka/fetch-size
   :kafka/empty-read-back-off
   :kafka/commit-interval
-  :kafka/request-size        -
+  :kafka/request-size
   "
   [job task opts] ;; TODO: Catch this assertion error
   (if-let [entry (view-single job (*> (module-lens [:catalog] :onyx/name task)


Upped the number of generations.

Upped the number of generations.

--- src/simple_symbolic_regression_clojure/core.clj
+++ src/simple_symbolic_regression_clojure/core.clj
@@ -33,7 +33,7 @@
   [& args]
   (dorun
    (map print-generation-report
-        (take 10 (future-history initial-sine-population 0.05 sine-rubrics))))
+        (take 100 (future-history initial-sine-population 0.05 sine-rubrics))))
   ; The shutdown-agents call is necessary to make sure that things like "lein run"
   ; terminate when they're done. Otherwise they can hang around waiting for other
   ; threads to finish.


Node.js REPL should work even if :output-dir not supplied

--- src/clj/cljs/repl/node.clj
+++ src/clj/cljs/repl/node.clj
@@ -80,7 +80,7 @@
 (defn setup
   ([repl-env] (setup repl-env nil))
   ([repl-env opts]
-    (let [output-dir (io/file (:output-dir opts))
+    (let [output-dir (io/file (util/output-directory opts))
           _    (.mkdirs output-dir)
           of   (io/file output-dir "node_repl.js")
           _   (spit of


Refactors Morph ICE.

Refactors Morph ICE.

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -99,6 +99,24 @@
         rezzed-next? #(and (rezzed? %) (has-subtype? % "NEXT"))]
     (reduce (fn [c server] (+ c (count (filter rezzed-next? (:ices server))))) 0 servers)))

+
+;;; For Morph ICE
+(defn morph-effect
+  "Creates morph effect for ICE. Morphs from base type to other type"
+  [base other]
+  (req (if (odd? (get (get-card state card) :advance-counter 0))
+         (morph state side card other base)
+         (morph state side card base other))))
+
+(defn morph-ice
+  "Creates the data for morph ICE with specified types and ability."
+  [base other ability]
+  (let [ab {:req (req (= (:cid card) (:cid target)))
+            :effect (morph-effect base other)}]
+    {:advanceable :always
+     :effect (morph-effect base other)
+     :abilities [ability]
+     :events {:advance ab :advancement-placed ab}}))

 ;;;; Card definitions
 (def cards-ice
@@ -204,17 +222,8 @@
                  :effect (req (swap! state assoc-in [:run :position] 0) (derez state side card))}]}

    "Changeling"
-   (let [ab {:req (req (= (:cid card) (:cid target)))
-             :effect (req (if (odd? (:advance-counter (get-card state card)))
-                            (morph state side card "Sentry" "Barrier")
-                            (morph state side card "Barrier" "Sentry")))}]
-     {:advanceable :always
-      :effect (req (if (odd? (get card :advance-counter 0))
-                     (morph state side card "Sentry" "Barrier")
-                     (morph state side card "Barrier" "Sentry")))
-      :abilities [end-the-run]
-      :events {:advance ab :advancement-placed ab}})
-
+   (morph-ice "Barrier" "Sentry" end-the-run)
+
    "Checkpoint"
    {:effect (effect (gain :bad-publicity 1) (system-msg "takes 1 bad publicity"))
     :abilities [(trace-ability 5 {:label "Do 3 meat damage when this run is successful"
@@ -544,16 +553,7 @@
     :flags {:cannot-lower-strength true}}

    "Lycan"
-   (let [ab {:req (req (= (:cid card) (:cid target)))
-             :effect (req (if (odd? (:advance-counter (get-card state card)))
-                            (morph state side card "Code Gate" "Sentry")
-                            (morph state side card "Sentry" "Code Gate")))}]
-     {:advanceable :always
-      :effect (req (if (odd? (get card :advance-counter 0))
-                     (morph state side card "Code Gate" "Sentry")
-                     (morph state side card "Sentry" "Code Gate")))
-      :abilities [trash-program]
-      :events {:advance ab :advancement-placed ab}})
+   (morph-ice "Sentry" "Code Gate" trash-program)

    "Mamba"
    {:abilities [(do-net-damage 1)
@@ -880,16 +880,7 @@
                 (do-net-damage 2)]}

    "Wendigo"
-   (let [ab {:req (req (= (:cid card) (:cid target)))
-             :effect (req (if (odd? (:advance-counter (get-card state card)))
-                            (morph state side card "Barrier" "Code Gate")
-                            (morph state side card "Code Gate" "Barrier")))}]
-     {:advanceable :always
-      :effect (req (if (odd? (get card :advance-counter 0))
-                     (morph state side card "Barrier" "Code Gate")
-                     (morph state side card "Code Gate" "Barrier")))
-      :abilities [{:msg "prevent the Runner from using a chosen program for the remainder of this run"}]
-      :events {:advance ab :advancement-placed ab}})
+   (morph-ice "Code Gate" "Barrier" {:msg "prevent the Runner from using a chosen program for the remainder of this run"})

    "Whirlpool"
    {:abilities [{:msg "prevent the Runner from jacking out"


Refactors gain-credits.

Refactors gain-credits.

--- src/clj/game/cards-ice.clj
+++ src/clj/game/cards-ice.clj
@@ -25,6 +25,13 @@
   {:label (str "Do " dmg " net damage")
    :msg (str "do " dmg " net damage")
    :effect (effect (damage :net dmg {:card card}))})
+
+(defn gain-credits
+  "Gain specified amount of credits"
+  [credits]
+  {:label (str "Gain " credits " [Credits]")
+   :msg (str "gain " credits " [Credits]")
+   :effect (effect (gain :credit credits))})

 ;;; For Grail ICE
 (def reveal-grail
@@ -106,7 +113,7 @@

    "Assassin"
    {:abilities [{:label "Trace 5 - Do 3 net damage"
-                 :trace {:base 5 :msg "do 3 net damage" :effect (effect (damage :net 3 {:card card}))}}
+                 :trace (assoc (do-net-damage 3) :base 5)}
                 {:label "Trace 4 - Trash a program"
                  :trace (assoc trash-program :base 4 :msg "trash a program")}]}

@@ -158,9 +165,9 @@

    "Caduceus"
    {:abilities [{:label "Trace 3 - Gain 3 [Credits]"
-                 :trace {:base 3 :msg "gain 3 [Credits]" :effect (effect (gain :credit 3))}}
+                 :trace (assoc (gain-credits 3) :base 3)}
                 {:label "Trace 2 - End the run"
-                 :trace {:base 2 :msg "end the run" :effect (effect (end-run))}}]}
+                 :trace (assoc end-the-run :base 2)}]}

    "Cell Portal"
    {:abilities [{:msg "make the Runner approach the outermost ICE"
@@ -188,19 +195,20 @@
                                       (swap! state assoc-in [:run :run-effect :card] card))}}]}

    "Chimera"
-   {:prompt "Choose one subtype" :choices ["Barrier" "Code Gate" "Sentry"]
-    :msg (msg "make it gain " target " until the end of the turn")
-    :effect (effect (update! (assoc card :subtype
-                                         (->> (vec (.split (:subtype card) " - "))
-                                              (concat [target])
-                                              (join " - "))))
-                    (update-ice-strength card))
-    :events {:runner-turn-ends {:effect (effect (derez :corp card)
-                                                (update! (assoc (get-card state card) :subtype "Mythic")))}
-             :corp-turn-ends {:effect (effect (derez :corp card)
-                                              (update! (assoc (get-card state card) :subtype "Mythic")))}}
-    :abilities [end-the-run]}
-
+   (let [ab {:effect (effect (derez :corp card)
+                             (update! (assoc (get-card state card) :subtype "Mythic")))}]
+     {:prompt "Choose one subtype"
+      :choices ["Barrier" "Code Gate" "Sentry"]
+      :msg (msg "make it gain " target " until the end of the turn")
+      :effect (effect (update! (assoc card :subtype
+                                      (->> (vec (.split (:subtype card) " - "))
+                                           (concat [target])
+                                           (join " - "))))
+                      (update-ice-strength card))
+      :events {:runner-turn-ends ab
+               :corp-turn-ends ab}
+      :abilities [end-the-run]})
+
    "Clairvoyant Monitor"
    {:abilities [{:msg "start a Psi game"
                  :psi {:not-equal {:player :corp
@@ -294,7 +302,7 @@
                 end-the-run]}

    "Errand Boy"
-   {:abilities [{:msg "gain 1 [Credits]" :effect (effect (gain :credit 1))}
+   {:abilities [(gain-credits 1)
                 {:msg "draw 1 card" :effect (effect (draw))}]}

    "Excalibur"
@@ -306,7 +314,8 @@
     :abilities [{:msg "do 1 brain damage" :effect (effect (damage :brain 1 {:card card}))} end-the-run]}

    "Fire Wall"
-   {:advanceable :always :abilities [end-the-run]
+   {:advanceable :always
+    :abilities [end-the-run]
     :strength-bonus (req (or (:advance-counter card) 0))}

    "Flare"
@@ -557,7 +566,8 @@
     :rez-cost-bonus (req (* -3 (or (:advance-counter card) 0)))}

    "Negotiator"
-   {:abilities [{:msg "gain 2 [Credits]" :effect (effect (gain :credit 2))} trash-program]}
+   {:abilities [(gain-credits 2)
+                trash-program]}

    "Neural Katana"
    {:abilities [(do-net-damage 3)]}
@@ -598,7 +608,8 @@
    {:abilities [end-the-run]}

    "Pop-up Window"
-   {:abilities [{:msg "gain 1 [Credits]" :effect (effect (gain :credit 1))} end-the-run]}
+   {:abilities [(gain-credits 1)
+                end-the-run]}

    "Pup"
    {:abilities [(do-net-damage 1)]}
@@ -646,7 +657,7 @@

    "Shadow"
    {:advanceable :always
-    :abilities [{:msg "gain 2 [Credits]" :effect (effect (gain :credit 2))}
+    :abilities [(gain-credits 2)
                 (tag-trace 3)]
     :strength-bonus (req (or (:advance-counter card) 0))}


Support for joining multiple IRC channels

--- src/clj_mrazik/irc_bot.clj
+++ src/clj_mrazik/irc_bot.clj
@@ -208,16 +208,19 @@

 (defn start-irc-bot
     [configuration]
-    (let [server  (:name configuration)
-          port    (:port configuration)
-          channel (:channel configuration)
-          nick    (:nick configuration)]
+    (let [server   (:name configuration)
+          port     (:port configuration)
+          channels (:channels configuration)
+          chanlist (clojure.string/split channels #" ")
+          nick     (:nick configuration)]
         (println "Connecting to" server "on port" port)
         (let [conn (irc/connect server port nick
                                 :callbacks {:privmsg on-incoming-message})]
-            (println "Connected, joining to channel" channel)
+            (println "Connected, joining to channels" channels)
             (reset! dyncfg/connection conn)
             (reset! dyncfg/bot-nick nick)
-            (irc/join @dyncfg/connection channel)
+            (doseq [channel chanlist]
+                (println channel)
+                (irc/join @dyncfg/connection (clojure.string/trim channel)))
             (println "Connected..."))))


Simply available-unit-type-eids track -Remove filter -Expand queries instead

--- src/cljs/zetawar/subs.cljs
+++ src/cljs/zetawar/subs.cljs
@@ -508,21 +508,20 @@

 (deftrack available-unit-type-eids [conn]
   (when-let [[sel-q sel-r] @(selected-hex conn)]
-    (let [selected-base-name (-> @(terrain-at conn sel-q sel-r)
-                                 (get-in [:terrain/type :terrain-type/id])
-                                 name)]
-      (->> @(posh/q '[:find ?ut ?i
-                      :in $ ?g
+    (let [selected-base (e @(terrain-at conn sel-q sel-r))]
+      (->> @(posh/q '[:find ?ut
+                      :in $ ?g ?t
                       :where
                       [_   :app/game ?g]
                       [?g  :game/current-faction ?f]
                       [?f  :faction/credits ?credits]
                       [?ut :unit-type/cost ?cost]
                       [?ut :unit-type/id ?unit-type-id]
-                      [?ut :unit-type/buildable-at ?i]]
-                    conn @(game-eid conn)
+                      [?t  :terrain/type ?tt]
+                      [?tt :terrain-type/can-build ?cb]
+                      [?cb :terrain-build/unit-type ?ut]]
+                    conn @(game-eid conn) selected-base
                     {:cache :forever})
-           (filter #(= selected-base-name (name (second %))))
            (map first)
            (into [])))))


Update the github links to the current URL style.

--- src/clojars/web/common.clj
+++ src/clojars/web/common.clj
@@ -52,8 +52,8 @@
       body]]
     [:footer
      (link-to "https://github.com/ato/clojars-web/wiki/Contact" "contact")
-     (link-to "http://github.com/ato/clojars-web" "code")
-     (link-to "http://wiki.github.com/ato/clojars-web" "help")]]))
+     (link-to "https://github.com/ato/clojars-web" "code")
+     (link-to "https://github.com/ato/clojars-web/wiki/" "help")]]))

 (defn error-list [errors]
   (when errors


render with more comments and a few simplifications

--- src/clojure/yaw/render.clj
+++ src/clojure/yaw/render.clj
@@ -24,18 +24,17 @@
 ;; just reuse its previous value.
 ;;}

-;; CONTROLLER
-;; ----------
-;; Will be inside the the universe
-
-;; (defn make-controller []
-;;   (atom {:components {}}))
-
-;; XXX: nested #(...) are not allowed ...
-;; (defn register-component! [controller component]
-;;   (swap! controller #(update % :components #(assoc % component {}))))
-
-(defn register-component! [controller component]
+;;{
+;; Inside the controller map, the components are all listed under
+;; the key `:components`. If is a map with the component references
+;; as keys and an information map as value. Initially the map is empty.
+;; if it is not empty, then it corresponds to save values of arguments
+;; so that we can check if something has changed or not...
+;;}
+
+(defn register-component!
+  "Register the specified scene `component` into the `controller` atom."
+  [controller component]
   (swap! controller #(update % :components (fn [comps] (assoc comps component {})))))

 (defn unregister-component! [controller component]
@@ -47,8 +46,9 @@
                        (dissoc comps component)
                        (throw (ex-info "No such component in controller" {:controller ctrl
                                                                           :component component}))))))))
-;;{
-;;
+
+
+;;{
 ;; ## Renderer
 ;;
 ;; The component renderer takes a possibly partially
@@ -56,23 +56,20 @@
 ;; and produces a complete scene and an updated controller
 ;;}

-(defn register-ratoms-map [ratoms-map ratoms component]
-  (reduce (fn [rmap ratom]
-            (when (contains? ratoms-map ratom)
-              (throw (ex-info "Reactive atom has already a dependent parent component" {:ratom ratom
-                                                                                :parent-component (get ratoms-map ratom)
-                                                                                :child-component component})))
-            (assoc rmap ratom component)) ratoms-map ratoms))
-
-(defn unregister-ratoms-map [ratoms-map component]
-  (reduce (fn [rmap [ratom comp]]
-            (if (= comp component)
-              rmap
-              (assoc rmap ratom comp))) {} ratoms-map))
+;; auxiliary functions to maintain the `ratoms-map` in the component renderer
+(declare register-ratoms-map
+         unregister-ratoms-map)

 (defn render-component
+  "Renders the scene `component` in the context of the controller `ctrl`."
   [ctrl component]
-  (loop [elements (list component), ratoms-map {}, rendering [], rendered #{}, seen #{}, ctrl ctrl]
+  (loop [elements (list component)
+         , ratoms-map {}  ; we build a map associating each referenced ratom to the components that depend on it
+         , rendering []   ; this is finally the items to effectively render
+         , rendered #{}   ; we are careful note to render twice the same item
+         , seen #{}       ; we also track all the items we encountered
+         , ctrl ctrl]     ; the controller state is optionally updated at each step
+    ;; the loop proceeds for the component and all its subcomponents (if any)
     (if (seq elements)
       (cond
         ;; if the first element is a scene, splice it into the rest
@@ -87,59 +84,69 @@
         (= (ffirst elements) ::return)
         (let [component (second (first elements))]
           (recur (rest elements)
-                 (unregister-ratoms-map ratoms-map component)
+                 (unregister-ratoms-map ratoms-map component) ; the dependency is removed after the return
                  rendering
                  rendered
                  seen
                  ctrl))
-        ;; if it's a component call
+        ;; if it's a component call, i.e.  [component args ...]  with component a function
         (fn? (ffirst elements))
         (let [component (ffirst elements)
               args (rest (first elements))
-              ratoms (filter reactive-atom? args)
-              new-ratoms (filter #(not (contains? ratoms-map %)) ratoms)
-              ratom-args (mapv deref ratoms)]
+              ratoms (filter reactive-atom? args) ; we analyze all reactive atoms referenced in the arguments
+              new-ratoms (filter #(not (contains? ratoms-map %)) ratoms) ; some ratoms are already tracked
+              ratom-args (mapv deref ratoms)] ; we take all the current values of the referenced ratoms
           ;;(println "[render-component] component=" component)
           ;;(println "  => args=" args)
           ;;(println "  => ratom-args=" ratom-args)
+          ;; We check if there is some available component information (values of a previous call)
           (if-let [comp-infos (get (:components ctrl) component)]
             (do #_(when (:previous-available comp-infos)
                   (println " => previous args= " (:previous-args comp-infos))
                   (println " => previous ratom args= " (:previous-ratom-args comp-infos)))
+                ;; In the component infos do we have the values from a previous call?
+                ;; moreover, are these previous values the same as the current values
                 (if (and (:previous-available comp-infos)
-                         (= (:previous-args comp-infos) args)
+                         (= (:previous-args comp-infos) args) ;
                          (= (:previous-ratom-args comp-infos) ratom-args))
-                  ;; no need for a new rendering
+                  ;; if it is the case there is no need for a new rendering of the whole component
                   (do
                     ;; (println "  ---> No need for new rendering <---")
                     (recur (cons (:previous-render comp-infos) (cons [::return component] (rest elements)))
-                           (register-ratoms-map ratoms-map new-ratoms component)
+                           ;; XXX: old code does not work since the component returns directly (?)
+                           ;; (register-ratoms-map ratoms-map new-ratoms component) ; the dependencies are still listed
+                           ratoms-map ;; unchanged is ok (guessing ...)
                            rendering
                            rendered
-                           (conj seen component)
+                           (conj seen component) ; we saw this component already
                            ctrl))
-                  ;; need to update the component
+                  ;; otherwise, we need to update the component hence we make an explicit call
                   (let [invoked (apply component args)]
                     ;;(println "  ---> Rendering required <---")
-                    (recur (cons invoked (cons [::return component] (rest elements)))
-                           (register-ratoms-map ratoms-map new-ratoms component)
+                    (recur (cons invoked (cons [::return component] (rest elements))) ; we will return after handling the subcomponents
+                           (register-ratoms-map ratoms-map new-ratoms component) ; we register the new dependencies
                            rendering
-                           (conj rendered component)
-                           (conj seen component)
+                           (conj rendered component) ; the component was asked to be rendered
+                           (conj seen component)     ; we saw it
+                           ;; we update the controller with the new argument values
                            (assoc-in ctrl [:components component]
                                      (assoc comp-infos
                                             :previous-available true
                                             :previous-args (vec args)
                                             :previous-ratom-args ratom-args
                                             :previous-render invoked))))))
-            ;; the component is unknown
-            (let [ratoms (filter reactive-atom? args)
-                  new-ratoms (filter #(not (contains? ratoms-map %)) ratoms)
+            ;; the component is unknown, there is no previous information available
+            (let [;; ratoms (filter reactive-atom? args) ; XXX old code : already done above !
+                  ;; new-ratoms (filter #(not (contains? ratoms-map %)) ratoms) ; XXX: same
+                  ;; We add the component as depending on all the newly discovered ratoms
                   _ (doseq [new-ratom new-ratoms]
                       (ratom/depend-component! new-ratom component))
+                  ;; we then perform the call explicitly
                   invoked (apply component args)
-                  ratom-args (mapv deref ratoms)]
+                  ;; ratom-args (mapv deref ratoms)
+                  ]
               ;;(println "  ---> Registering unknown component <---")
+              ;; this is exactly the same continuation as the previous case (re-invokation)
               (recur (cons invoked (cons [::return component] (rest elements)))
                      (register-ratoms-map ratoms-map new-ratoms component)
                      rendering
@@ -150,7 +157,7 @@
                                 :previous-args (vec args)
                                 :previous-render invoked
                                 :previous-ratom-args ratom-args})))))
-        ;; otherwise it is an item, already rendering
+        ;; otherwise it is an item that must be rendered anyway (except that a diff will be computed)
         :else
         (recur (rest elements)
                ratoms-map
@@ -160,6 +167,24 @@
                ctrl))
       ;; no more elements to render
       [rendering rendered seen ctrl])))
+
+
+(defn register-ratoms-map [ratoms-map ratoms component]
+  (reduce (fn [rmap ratom]
+            (when (contains? ratoms-map ratom)
+              (throw (ex-info "Reactive atom has already a dependent parent component" {:ratom ratom
+                                                                                :parent-component (get ratoms-map ratom)
+                                                                                :child-component component})))
+            (assoc rmap ratom component)) ratoms-map ratoms))
+
+(defn unregister-ratoms-map [ratoms-map component]
+  (reduce (fn [rmap [ratom comp]]
+            (if (= comp component)
+              rmap
+              (assoc rmap ratom comp))) {} ratoms-map))
+
+
+
 ;;{
 ;; The main rendering function follows.
 ;;}


Use "*/parse*" instead of "read-string"

Use "*/parse*" instead of "read-string"

--- src/core/clj/virt/core.clj
+++ src/core/clj/virt/core.clj
@@ -40,8 +40,8 @@
 (defn channels-handler [request]
   (edn-response
     (let [params (:params request)
-          lon (read-string (:lon params))
-          lat (read-string (:lat params))]
+          lon (Double/parseDouble (:lon params))
+          lat (Double/parseDouble (:lat params))]
       (get-channels lon lat))))

 (defn new-channel [channel-name lon lat]
@@ -63,7 +63,7 @@
 (defn chat-threads-handler [request]
   (edn-response
     (let [params (:route-params request)
-          channel-id (read-string (:channel-id params))]
+          channel-id (Integer/parseInt (:channel-id params))]
       (get-threads channel-id))))

 (defn new-chat-thread [channel-id thread-descr]
@@ -83,7 +83,7 @@
 (defn chat-messages-handler [request]
   (edn-response
     (let [params (:route-params request)
-          thread-id (read-string (:thread-id params))]
+          thread-id (Integer/parseInt (:thread-id params))]
       (get-messages thread-id))))

 (defn add-msg [thread-id msg]


CLJSDevtoolsFormatter should survive :advanced compilation

--- src/devtools/core.cljs
+++ src/devtools/core.cljs
@@ -7,7 +7,7 @@

 (def formatter-key "devtoolsFormatters")

-(deftype CLJSDevtoolsFormatter [header hasBody body])
+(deftype CLJSDevtoolsFormatter [])

 ; devtools.debug namespace may not be present => no debugging
 (defn find-fn-in-debug-ns [fn-name]
@@ -47,11 +47,15 @@
   (let [wrap (fn [name api-call]
                (let [monitor (partial monitor-api-calls name)
                      sanitizer (partial sanitize name)]
-                 ((comp monitor sanitizer) api-call)))]
-    (CLJSDevtoolsFormatter.
-      (wrap "header" format/header-api-call)
-      (wrap "hasBody" format/has-body-api-call)
-      (wrap "body" format/body-api-call))))
+                 ((comp monitor sanitizer) api-call)
+                 api-call))
+        formatter (CLJSDevtoolsFormatter.)
+        define! (fn [name fn]
+                  (aset formatter name (wrap name fn)))]
+    (define! "header" format/header-api-call)
+    (define! "hasBody" format/has-body-api-call)
+    (define! "body" format/body-api-call)
+    formatter))

 (defn- is-ours? [o]
   (instance? CLJSDevtoolsFormatter o))


better handling of replacements surrounded by text

--- src/chat/client/views/helpers.cljs
+++ src/chat/client/views/helpers.cljs
@@ -50,16 +50,28 @@
                  match))}
    })

+(defn re-replace
+  [re s replace-fn]
+  (if-let [match (second (re-find re s))]
+    ; TODO: recurse, incease the rest has more matches?
+    ; using Javascript split beacuse we don't want the match to be in the last
+    ; component
+    (let [[pre _ post] (seq (.split s re 3))]
+      (if (and (or (string/blank? pre) (re-matches #".*\s$" pre))
+            (or (string/blank? post) (re-matches #"^\s.*" post)))
+      ; XXX: find a way to use return a seq & use mapcat instead of this hack
+      (dom/span #js {:className "dummy"} pre (replace-fn match) post)
+      s))
+    s))
+
 (defn make-text-replacer
   "Make a new function to perform a simple stateless replacement of a single element"
   [match-type]
   (fn [text-or-node]
     (if (string? text-or-node)
       (let [text text-or-node
-            pattern (get-in replacements [match-type :pattern])]
-        (if-let [match (second (re-find pattern text))]
-          ((get-in replacements [match-type :replace]) match)
-          text))
+            type-info (get replacements match-type)]
+        (re-replace (type-info :pattern) text (type-info :replace)))
       text-or-node)))

 (defn make-delimited-processor


seem to have misplaced a )

seem to have misplaced a )

--- src/clj/shadow/devtools/server.clj
+++ src/clj/shadow/devtools/server.clj
@@ -471,5 +471,5 @@
       (async/close! repl-input)
       (async/close! repl-output)
       (prn [:repl-quit])
-      ))
-
+      )))
+


Fix bug in enclosing rectangle function (my view of the world was too simplistic..)

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -31,21 +31,27 @@
 (defn enclosing-rectangle
   "Calculates an enclosing rectangle which contains the given
   one centered on the screen (would you believe that working
-  this out was the hardest thing in this project?)"
+  this out was the hardest thing in this project?)
+
+  The metric to use is whether the aspect ratio of the desired
+  rectangle is greater than the aspect ratio of the screen or not.
+  This lets us determine whether to pad the rectangle out in
+  the x-dimension or the y-dimension"
   [x0 y0 width height screen-width screen-height]
-  (let [portrait?    (>= height width)
-
-        aspect-ratio (/ width height)
-
-        padding      (if portrait?
-                       (- screen-width (* screen-height aspect-ratio))
-                       (- screen-height (/ screen-width aspect-ratio)))
-
-        scale        (if portrait?
-                       (/ screen-height height)
-                       (/ screen-width width))]
-
-    (if portrait?
+  (let [aspect-ratio        (/ width height)
+        screen-aspect-ratio (/ screen-width screen-height)
+
+        pad-x?              (<= aspect-ratio screen-aspect-ratio)
+
+        padding             (if pad-x?
+                              (- screen-width (* screen-height aspect-ratio))
+                              (- screen-height (/ screen-width aspect-ratio)))
+
+        scale               (if pad-x?
+                              (/ screen-height height)
+                              (/ screen-width width))]
+
+    (if pad-x?
       {:x0     (- x0 (* 0.5 (/ padding scale)))
        :y0     y0
        :width  (+ width (/ padding scale))


Minor: update docstring

Minor: update docstring

--- src/cljs/mandelbrot_cljs/core.cljs
+++ src/cljs/mandelbrot_cljs/core.cljs
@@ -199,7 +199,7 @@
     (recur)))

 (defn init!
-  "Initialise event handlers, add atom watches, do the first rendering"
+  "Start the message processing thread, set JS event handlers and do the first rendering"
   []
   (let [messages (chan)]


experiment with the idea of a deftype

experiment with the idea of a deftype

--- src/cljs/triboard/logic/board.cljs
+++ src/cljs/triboard/logic/board.cljs
@@ -27,6 +27,37 @@
   (algo/zip
     positions
     (mapcat #(repeat n %) (conj player/all :wall))))
+
+#_(deftype Board
+  [grid]
+
+  ILookup
+  (-lookup
+    [board coord not-found] (get-in (.-grid board) coord not-found))
+  (-lookup
+    [board coord] (-lookup board coord :wall))
+
+  IAssociative
+  (-contains-key? [board coord]
+    (-lookup board coord nil))
+  (-assoc [board coord owner]
+    (Board. (assoc-in (.-grid board) coord owner)))
+
+  ISeqable
+  (-seq [board]
+    (for [coord coordinates]
+      [coord (get-in (.-grid board) coord)]))
+  )
+
+#_(defn test-board-type
+  []
+  (let [b (Board. empty-board)]
+    (println b)
+    (println (get b [0 0]))
+    (println (contains? b [0 0]))
+    (println (get (assoc b [0 0] :wall) [0 0]))
+    (println (seq b))
+    ))

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


weka bug

weka bug

--- src/clojure/zensols/model/weka.clj
+++ src/clojure/zensols/model/weka.clj
@@ -489,7 +489,9 @@
   (let [res (clone-instances src)]
     (->> (.enumerateInstances dst)
          enumeration-seq
-         (map #(.add res %)))))
+         (map #(.add res %))
+         doall)
+    res))

 (defn- index-for-attribute
   "Return an `weka.core.Attribute` in **inst** (`weka.core.Instances`)


master: Added draft and history functions.

--- src/gmail_clj/core.clj
+++ src/gmail_clj/core.clj
@@ -51,6 +51,11 @@

 (defmethod send-http :post [method url params headers]
   (http/post (prepend-url url) {:timeout 2000
+                                 :headers headers
+                                 :form-params params}))
+
+(defmethod send-http :delete [method url params headers]
+  (http/delete (prepend-url url) {:timeout 2000
                                  :headers headers
                                  :form-params params}))

@@ -172,13 +177,49 @@

 ; Users.drafts

+(defn draft-create
+  "Create a draft with the DRAFT label."
+  []
+  (throw (Exception. "Not yet implemented.")))
+
+(defn draft-delete
+  "Create a draft with the DRAFT label."
+  [message-id]
+  (api-request :delete (str "/users/me/drafts/" message-id) {} :auth (get-token)))
+
+(defn draft-get
+  "Returns the record for a given draft message id."
+  [message-id & {:keys [format]
+                 :or {format :full}}]
+  (api-request :get (str "/users/me/drafts/" message-id) {:format (name format)} :auth (get-token)))
+
+(defn draft-list
+  "Returns all draft messages."
+  [& {:keys [maxResults pageToken] :or {maxResults 10}}]
+  (api-request :get "/users/me/drafts/" {:maxResults maxResults :pageToken pageToken} :auth (get-token)))
+
+(defn draft-create
+  "Create a draft with the DRAFT label."
+  []
+  (throw (Exception. "Not yet implemented.")))
+
 ; Users.history

+(defn history-list
+  "Create a draft with the DRAFT label."
+  [& {:keys [maxResults pageToken labelId startHistoryId]
+      :or {maxResults 10}}]
+  (let [params {:maxResults maxResults
+                :pageToken pageToken
+                :startHistoryId startHistoryId
+                :labelId labelId}]
+    (api-request :get "/users/me/history" params :auth (get-token))))
+
 ; Users.labels

 ; Users.messages

-(defn messages-list
+(defn message-list
   "Returns a list of messages based on a given query."
   [query & {:keys [labels max-results page] :or {max-results 10}}]
   (let [params {:includeSpamTrash false
@@ -188,18 +229,18 @@
                 :q query}]
     (api-request :get "/users/me/messages/" params :auth (get-token))))

-(defn messages-trash
+(defn message-trash
   "Moves a specific message to the trash can."
   [message-id]
   (api-request :post (str "/users/me/messages/" message-id "/trash") {} :auth (get-token)))

-(defn messages-get
+(defn message-get
   "Returns the record for a given message id."
   [message-id & {:keys [format]
                  :or {format :full}}]
   (api-request :get (str "/users/me/messages/" message-id) {:format (name format)} :auth (get-token)))

-(defn messages-send
+(defn message-send
   "Sends an email to a specified user."
   [message & {:keys [thread-id]}]
   (let [message (if (map? message) (map->mime message) message)


Additional work on schema compilation and running proces.

Changed the way that schema compilation process runs. Now the
result of the schema compilation is a ready to execute sqlvec's.

--- src/continuo/postgresql/schema.clj
+++ src/continuo/postgresql/schema.clj
@@ -14,6 +14,7 @@

 (ns continuo.postgresql.schema
   (:require [suricatta.core :as sc]
+            [taoensso.nippy :as nippy]
             [continuo.util.template :as tmpl]
             [continuo.executor :as exec]))

@@ -63,38 +64,50 @@

 (defmethod compile-op :db/add
   [[_ attrname props]]
-  (let [attr (normalize-attrname attrname)
-        sql (generate-create-sql (assoc props :attr attr))]
-    (fn [execute]
-      (execute sql))))
+  (let [attr (normalize-attrname attrname)]
+    (generate-create-sql (assoc props :attr attr))))

 (defmethod compile-op :db/drop
   [[_ attrname]]
-  (let [attr (normalize-attrname attrname)
-        sql (generate-drop-sql attr)]
-    (fn [execute]
-      (execute sql))))
+  (let [attr (normalize-attrname attrname)]
+    (generate-drop-sql attr)))

 (defmethod compile-op :default
   [[op]]
   (throw (ex-info (format "The schema operation %s is not supported." op) {})))

-(defn compile-schema
+(defn- compile-schema
   "Compile a schema entries."
   [schema]
-  (reduce (fn [acc v]
-            (fn [execute]
-              (let [callable (compile-op v)]
-                (acc execute)
-                (callable execute))))
-          identity
-          schema))
+  (reduce #(conj %1 [(compile-op %2)]) [] schema))
+
+(defn- schema->facts
+  "Normalize the schema values into facts like data."
+  [schema]
+  (letfn [(reducer [acc v]
+            (conj acc (case (count v)
+                        3 v
+                        2 (conj v nil))))]
+    (reduce func [] schema))
+
+;; (defn get-transact-sql
+;;   [schema]
+;;   (let [data (nippy/freeze schemas)]
+;;     [["INSERT INTO txlog VALUES (?,?,?,?,?);"]]))

 ;; (defn execute-schema
 ;;   [schema ]
-;;   {:pre [(seq schema)]}
 ;;   (csch (fn [sql]
 ;;             (println "EXECUTING:" sql)))))
+
+(defn run-schema
+  [conn schema]
+  {:pre [(seq schema)]}
+  (let [ctx (:context conn)]
+        locksql (get-lock-sql)
+        txsql (get-transact-sql schema)
+        opsql (compile-schema schema)]
+    ))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Utils


Only show instarepl button for clojure files

--- src/net/sekao/nightcode/editors.clj
+++ src/net/sekao/nightcode/editors.clj
@@ -16,6 +16,7 @@
            [java.io File]))

 (def ^:const clojure-exts #{"boot" "clj" "cljc" "cljs" "cljx" "edn" "pxi"})
+(def ^:const instarepl-exts #{"clj" "cljc"})
 (def ^:const wrap-exts #{"md" "txt"})
 (def ^:const max-file-size (* 1024 1024 2))

@@ -98,9 +99,10 @@
     (let [pane (FXMLLoader/load (io/resource "editor.fxml"))
           webview (-> pane .getChildren (.get 1))
           engine (.getEngine webview)
-          clojure? (-> file .getName u/get-extension clojure-exts some?)]
+          clojure? (-> file .getName u/get-extension clojure-exts some?)
+          instarepl? (-> file .getName u/get-extension instarepl-exts some?)]
       (.setContextMenuEnabled webview false)
-      (-> pane (.lookup "#instarepl") (.setManaged clojure?))
+      (-> pane (.lookup "#instarepl") (.setManaged instarepl?))
       (shortcuts/add-tooltips! pane ids)
       (-> engine
           (.executeScript "window")


Six tests for get-exception-message function

--- test/emender_jenkins/utils_test.clj
+++ test/emender_jenkins/utils_test.clj
@@ -72,3 +72,57 @@
 ; Tests for behaviour of all functions
 ;

+(deftest test-get-exception-message-1
+    "Check the function clouseau.utils/get-exception-message."
+    (testing "the function clouseau.utils/get-exception-message."
+        (try
+            (throw (new java.lang.Exception "Message text"))
+            (is nil "Exception not thrown as expected!")
+            (catch Exception e
+                (is (= "Message text" (get-exception-message e)))))))
+
+(deftest test-get-exception-message-2
+    "Check the function clouseau.utils/get-exception-message."
+    (testing "the function clouseau.utils/get-exception-message."
+        (try
+            (/ 1 0)
+            (is nil "Exception not thrown as expected!")
+            (catch Exception e
+                (is (= "Divide by zero" (get-exception-message e)))))))
+
+(deftest test-get-exception-message-3
+    "Check the function clouseau.utils/get-exception-message."
+    (testing "the function clouseau.utils/get-exception-message."
+        (try
+            (Integer/parseInt "unparseable")
+            (is nil "Exception not thrown as expected!")
+            (catch Exception e
+                (is (.startsWith (get-exception-message e) "For input string:"))))))
+
+(deftest test-get-exception-message-4
+    "Check the function clouseau.utils/get-exception-message."
+    (testing "the function clouseau.utils/get-exception-message."
+        (try
+            (throw (new java.lang.Exception ""))
+            (is nil "Exception not thrown as expected!")
+            (catch Exception e
+                (is (= "" (get-exception-message e)))))))
+
+(deftest test-get-exception-message-5
+    "Check the function clouseau.utils/get-exception-message."
+    (testing "the function clouseau.utils/get-exception-message."
+        (try
+            (throw (new java.lang.Exception))
+            (is nil "Exception not thrown as expected!")
+            (catch Exception e
+                (is (nil? (get-exception-message e)))))))
+
+(deftest test-get-exception-message-6
+    "Check the function clouseau.utils/get-exception-message."
+    (testing "the function clouseau.utils/get-exception-message."
+        (try
+            (println (nth [] 10)) ; realize the sequence and getter
+            (is nil "Exception not thrown as expected!")
+            (catch Exception e
+                (is (nil? (get-exception-message e)))))))
+


Fix util/extract-params test

Fix util/extract-params test

--- test/github_changelog/util_test.clj
+++ test/github_changelog/util_test.clj
@@ -7,5 +7,5 @@
   (is (= "foobar" (util/strip-trailing "foobar" "!!"))))

 (deftest extract-params
-  (is (= {}) (util/extract-params ""))
-  (is (= {:a 1 :b 2}) (util/extract-params "a=1&b=2")))
+  (is (= {} (util/extract-params "")))
+  (is (= {:a "1" :b "2"} (util/extract-params "a=1&b=2"))))


Better cleaning of required namespaces in require_test

--- test/node/replumb/require_test.cljs
+++ test/node/replumb/require_test.cljs
@@ -36,7 +36,7 @@
       (is (success? res) "(require ...) and (doc clojure.string/trim) should succeed.")
       (is (valid-eval-result? docstring) "(require ...) and (doc clojure.string/trim) should be a valid result")
       (is (re-find #"Removes whitespace from both ends of string" docstring) "(require ...) and (doc clojure.string/trim) should return valid docstring")
-      (repl/reset-env! ['clojure.set])))
+      (repl/reset-env! '[clojure.string goog.string goog.string.StringBuffer])))

   (deftest process-require
     ;; AR - Test for "No *load-fn* when requiring a namespace in browser #35"
@@ -96,7 +96,7 @@
       (is (valid-eval-result? out) "(require 'clojure.string) should be a valid result")
       (is (= 'cljs.user (repl/current-ns)) "(require 'clojure.string) should not change namespace")
       (is (= "nil" out) "(require 'clojure.string) should return \"nil\"")
-      (repl/reset-env! ['clojure.string]))
+      (repl/reset-env! '[clojure.string goog.string goog.string.StringBuffer]))

     (let [res (do (read-eval-call "(require 'clojure.string)")
                   (read-eval-call "(clojure.string/reverse \"clojurescript\")"))
@@ -105,7 +105,7 @@
       (is (valid-eval-result? out) "(require 'clojure.string) and clojure.string/reverse should be a valid result")
       (is (= 'cljs.user (repl/current-ns)) "(require 'clojure.string) and clojure.string/reverse should not change namespace")
       (is (= "\"tpircserujolc\"" out) "(require 'clojure.string) and clojure.string/reverse should return \"tpircserujolc\"")
-      (repl/reset-env! ['clojure.string]))
+      (repl/reset-env! '[clojure.string goog.string goog.string.StringBuffer]))

     (let [res (do (read-eval-call "(import 'goog.string.StringBuffer)")
                   (read-eval-call "(let [sb (StringBuffer. \"clojure\")]
@@ -116,7 +116,7 @@
       (is (valid-eval-result? out) "(import 'goog.string.StringBuffer) and .toString should be a valid result")
       (is (= 'cljs.user (repl/current-ns)) "(import 'goog.string.StringBuffer) and .toString should not change namespace")
       (is (= "\"clojurescript\"" out) "(import 'goog.string.StringBuffer) and .toString should return \"clojurescript\"")
-      (repl/reset-env! ['goog.string.StringBuffer])))
+      (repl/reset-env! '[goog.string goog.string.StringBuffer])))

   (deftest process-reload
     (let [alterable-core-path "dev-resources/private/test/src/cljs/alterable/core.cljs"
@@ -130,7 +130,8 @@
         (is (success? res) "(require 'alterable.core) and alterable.core/b should succeed")
         (is (valid-eval-result? out) "(require 'alterable.core) and alterable.core/b should be a valid result")
         (is (= 'cljs.user (repl/current-ns)) "(require 'alterable.core) and alterable.core/b should not change namespace")
-        (is (= "\"pre\"" out) "(require 'alterable.core) and alterable.core/b should return \"pre\""))
+        (is (= "\"pre\"" out) "(require 'alterable.core) and alterable.core/b should return \"pre\"")
+        (repl/reset-env! ['alterable.core]))

       ;; Writing "post" version of alterable.core
       (io/write-file! alterable-core-path post-content)
@@ -140,8 +141,9 @@
         (is (success? res) "(require 'alterable.core :reload) and alterable.core/b should succeed")
         (is (valid-eval-result? out) "(require 'alterable.core :reload) and alterable.core/b should be a valid result")
         (is (= 'cljs.user (repl/current-ns)) "(require 'alterable.core :reload) and alterable.core/b should not change namespace")
-        (is (= "\"post\"" out) "(require 'alterable.core :reload) and alterable.core/b should return \"post\""))
-      (repl/reset-env! ['alterable.core])
+        (is (= "\"post\"" out) "(require 'alterable.core :reload) and alterable.core/b should return \"post\"")
+        (repl/reset-env! ['alterable.core]))
+
       (io/delete-file! alterable-core-path)))

   (deftest process-reload-all


Take advantage of anyargs in async demo

Take advantage of anyargs in async demo

--- demo/reagentdemo/news/async.cljs
+++ demo/reagentdemo/news/async.cljs
@@ -8,7 +8,7 @@
 (def funmap (-> "reagentdemo/news/async.cljs" get-source common/fun-map))
 (def src-for (partial common/src-for funmap))

-(defn timing-wrapper [{f :component-fn}]
+(defn timing-wrapper [f]
   (let [start-time (atom nil)
         render-time (atom nil)
         now #(.now js/Date)
@@ -19,10 +19,10 @@
                    :component-will-update start
                    :component-did-mount stop
                    :component-did-update stop})]
-    (fn [props children]
+    (fn []
       [:div
        [:p [:em "render time: " @render-time "ms"]]
-       (into [timed-f props] children)])))
+       [timed-f]])))

 (def base-color (atom {:red 130 :green 160 :blue 120}))
 (def ncolors (atom 20))
@@ -42,7 +42,7 @@
   (reset! random-colors
           (repeatedly #(-> color tweak-color to-rgb))))

-(defn color-choose [{color-part :color-part}]
+(defn color-choose [color-part]
   [:div.color-slider
    (name color-part) " " (color-part @base-color)
    [:input {:type "range" :min 0 :max 255
@@ -81,11 +81,11 @@
   (fn []
     [:div
      [:h2 "Matching colors"]
-     [color-choose {:color-part :red}]
-     [color-choose {:color-part :green}]
-     [color-choose {:color-part :blue}]
+     [color-choose :red]
+     [color-choose :green]
+     [color-choose :blue]
      [ncolors-choose]
-     [timing-wrapper {:component-fn palette}]]))
+     [timing-wrapper palette]]))

 (defn main [{:keys [summary]}]
   (let [om-article {:href "http://swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/"}]


fix loading bug

fix loading bug

--- dev/snippets/button/loading.cljs
+++ dev/snippets/button/loading.cljs
@@ -10,9 +10,13 @@
   (render-state
    [_ {:keys [loading?]}]
    (let [toggle #(swap! state update-in [:loading?] not)
+
+         ;; This is required to get around
+         ;; https://github.com/Prismatic/om-tools/issues/29.
+         set-timeout (aget owner "set_timeout")
          handle-click (fn [e]
                         (toggle)
-                        ((aget owner "set-timeout") toggle 2000))]
+                        (set-timeout toggle 2000))]
      (b/button {:bs-style "primary"
                 :disabled? loading?
                 :on-click (when-not loading?


format & add parse function

format & add parse function

--- src/graphql_clj/parser.clj
+++ src/graphql_clj/parser.clj
@@ -6,17 +6,23 @@
   (insta/parser
     "whitespace = #'\\s+'"))

-(comment
-  ((insta/parser (io/resource "graphql.bnf")) "query {
+(defn parse
+  [stmt]
+  (let [parser (insta/parser (io/resource "graphql.bnf"))]
+    (parser stmt)))
+
+(def statements
+  [
+   "query {
   user(id: 4) {
     id
     name
     profilePic(width: 100, height: 50)
   }
 }
-")
-
-  "query {
+"
+
+   "query {
   user(id: 4) {
     id
     name
@@ -24,13 +30,13 @@
   }
 }"

-  "{
-  user(id: 4) {
-    name
-  }
-}"
-
-  "mutation {
+   "{
+  user(id: 4) {
+    name
+  }
+}"
+
+   "mutation {
   likeStory(storyID: 12345) {
     story {
       likeCount
@@ -38,7 +44,7 @@
   }
 }"

-  "{
+   "{
   me {
     id
     firstName
@@ -53,7 +59,7 @@
   }
 }"

-  "# `me` could represent the currently logged in viewer.
+   "# `me` could represent the currently logged in viewer.
 {
   me {
     name
@@ -61,7 +67,7 @@
 }
 "

-  "# `me` could represent the currently logged in viewer.
+   "# `me` could represent the currently logged in viewer.
 {
   me {
     name
@@ -76,7 +82,7 @@
   }
 }"

-  "{
+   "{
   user(id: 4) {
     id
     name
@@ -84,7 +90,7 @@
   }
 }
 "
-  "{
+   "{
   user(id: 4) {
     id
     name
@@ -93,8 +99,8 @@
 }
 "

-  ;; In this example, we can fetch two profile pictures of different sizes and ensure the resulting object will not have duplicate keys:
-  "{
+   ;; In this example, we can fetch two profile pictures of different sizes and ensure the resulting object will not have duplicate keys:
+   "{
   user(id: 4) {
     id
     name
@@ -104,8 +110,8 @@
 }
 "

-  ;; Since the top level of a query is a field, it also can be given an alias:
-  "{
+   ;; Since the top level of a query is a field, it also can be given an alias:
+   "{
   zuck: user(id: 4) {
     id
     name
@@ -113,10 +119,10 @@
 }
 "

-  ;; Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document. Inline Fragments can be used directly within a selection to condition upon a type condition when querying against an interface or union.
-
-  ;; For example, if we wanted to fetch some common information about mutual friends as well as friends of some user:
-  "query noFragments {
+   ;; Fragments allow for the reuse of common repeated selections of fields, reducing duplicated text in the document. Inline Fragments can be used directly within a selection to condition upon a type condition when querying against an interface or union.
+
+   ;; For example, if we wanted to fetch some common information about mutual friends as well as friends of some user:
+   "query noFragments {
   user(id: 4) {
     friends(first: 10) {
       id
@@ -131,8 +137,8 @@
   }
 }"

-  ;; The repeated fields could be extracted into a fragment and composed by a parent fragment or query.
-  "query withFragments {
+   ;; The repeated fields could be extracted into a fragment and composed by a parent fragment or query.
+   "query withFragments {
   user(id: 4) {
     friends(first: 10) {
       ...friendFields
@@ -150,10 +156,10 @@
 }
 "

-  ;; Fragments are consumed by using the spread operator (...). All fields selected by the fragment will be added to the query field selection at the same level as the fragment invocation. This happens through multiple levels of fragment spreads.
-
-  ;; For example:
-  "query withNestedFragments {
+   ;; Fragments are consumed by using the spread operator (...). All fields selected by the fragment will be added to the query field selection at the same level as the fragment invocation. This happens through multiple levels of fragment spreads.
+
+   ;; For example:
+   "query withNestedFragments {
   user(id: 4) {
     friends(first: 10) {
       ...friendFields
@@ -175,7 +181,7 @@
 }
 "

-  "query FragmentTyping {
+   "query FragmentTyping {
   profiles(handles: [\"zuck\", \"cocacola\"]) {
     handle
     ...userFragment
@@ -195,7 +201,7 @@
   }
 }"

-  "query inlineFragmentTyping {
+   "query inlineFragmentTyping {
   profiles(handles: [\"zuck\", \"cocacola\"]) {
     handle
     ... on User {
@@ -211,7 +217,7 @@
   }
 }"

-  "query inlineFragmentNoType($expandedInfo: Boolean) {
+   "query inlineFragmentNoType($expandedInfo: Boolean) {
   user(handle: \"zuck\") {
     id
     name
@@ -223,7 +229,7 @@
   }
 }"

-  "query getZuckProfile($devicePicSize: Int) {
+   "query getZuckProfile($devicePicSize: Int) {
   user(id: 4) {
     id
     name
@@ -231,7 +237,7 @@
   }
 }"

-  "query hasConditionalFragment($condition: Boolean) {
+   "query hasConditionalFragment($condition: Boolean) {
   ...maybeFragment @include(if: $condition)
 }

@@ -240,4 +246,25 @@
     name
   }
 }"
-  )
+
+   "query hasConditionalFragment($condition: Boolean) {
+  ...maybeFragment
+}
+
+fragment maybeFragment on Query @include(if: $condition) {
+  me {
+    name
+  }
+}"
+
+   "query myQuery($someTest: Boolean) {
+  experimentalField @skip(if: $someTest)
+}"
+
+   "mutation setName {
+  setName(name: \"Zuck\") {
+    newName
+  }
+}"
+
+])


Update table-height function and add table-height to app-state

--- src/hatti/views/table.cljs
+++ src/hatti/views/table.cljs
@@ -506,7 +506,7 @@
   (- (-> "body"
          js/document.querySelector
          .-clientHeight)
-     (-> ".tab-page"
+     (-> ".table-page"
          js/document.querySelector
          .getBoundingClientRect
          .-top)))
@@ -556,21 +556,21 @@
       om/IRenderState
       (render-state [_ {:keys [table-view-height]}]
         (let [{:keys [data dataset-info]
-               {:keys [prevent-scrolling-in-table-view? submission-clicked]}
+               {:keys [submission-clicked]}
                :table-page}
               cursor
               {:keys [num_of_submissions]} dataset-info
               no-data? (empty? data)
               with-info #(merge cursor %)]
+          (swap! shared/app-state
+                 assoc-in
+                 [:table-page :table-view-height]
+                 (when-not (nil? (js/document.querySelector ".table-page"))
+                   (get-table-view-height)))
           (when active?
             (html
              [:div.table-view
-             ;; Check if prevent-scrolling-in-table-view? value is equal to true
-             ;; since it can also be null
-              {:style (when (= true prevent-scrolling-in-table-view?)
-                        {:height (or table-view-height
-                                     (get-table-view-height))
-                         :overflow "hidden"})}
+              {:style {:overflow "initial"}}
               (when (:data submission-clicked)
                 (om/build submission-view
                           (with-info submission-clicked)


Add printing of JSON

Add printing of JSON

--- src/hydrofoil/core.clj
+++ src/hydrofoil/core.clj
@@ -1,5 +1,6 @@
 (ns hydrofoil.core
-  (:require [hydrofoil.evolution :refer :all]
+  (:require [clojure.data.json :as json]
+            [hydrofoil.evolution :refer :all]
             [hydrofoil.model :refer :all]
             [hydrofoil.utils :refer :all]))

@@ -12,7 +13,7 @@

 (defn print-content [list]
     (doseq [item list]
-    (println item)))
+    (println (json/write-str item))))

 (defn hill-climber [max-tries run-constants]
@@ -50,7 +51,6 @@
 (defn -main [& args]
   (hill-climber 100 (run-constants 1 50 -10)))

-(lift-function (NACA-design 5 5 12) (run-constants 1 1 5))


add some asserts and eval dependency information

--- support/src/figwheel/client/file_reloading.cljs
+++ support/src/figwheel/client/file_reloading.cljs
@@ -1,6 +1,6 @@
 (ns figwheel.client.file-reloading
   (:require
-   [figwheel.client.utils :as utils]
+   [figwheel.client.utils :as utils :refer-macros [dev-assert]]
    [goog.Uri :as guri]
    [goog.string]
    [goog.net.jsloader :as loader]
@@ -14,11 +14,16 @@
 (defonce ns-meta-data (atom {}))

 ;; this assumes no query string on url
-(defn add-cache-buster [url] (.makeUnique (guri/parse url)))
-
-(defn ns-to-js-file [ns] (str (string/replace ns "." "/") ".js"))
+(defn add-cache-buster [url]
+  (dev-assert (string? url))
+  (.makeUnique (guri/parse url)))
+
+(defn ns-to-js-file [ns]
+  (dev-assert (string? ns))
+  (str (string/replace ns "." "/") ".js"))

 (defn resolve-ns [ns]
+  (dev-assert (string? ns))
   (str (string/replace (.-basePath js/goog) #"(.*)goog/" #(str %2))
        (ns-to-js-file ns)))

@@ -41,51 +46,18 @@
   (set! (.-provide js/goog) (.-exportPath_ js/goog))
   (set! (.-CLOSURE_IMPORT_SCRIPT (.-global js/goog)) reload-file*))

-;; may not need to load these deps as we may not be using them
-#_(def goog-deps-path (str (.-basePath js/goog) "deps.js"))
-
-#_(defn get-main-file-path
-  "Very unreliable way to get the main js file for reloading.
-   Fortunately its not the end of the world if this file doesn't
-   get reloaded."
-  []
-  (when (utils/html-env?)
-    (let [sel  (str "script[src='" goog-deps-path "']")]
-      (when-let [el (.querySelector js/document sel)]
-        (when-let [el (.-nextElementSibling el)]
-          (.getAttribute el "src"))))))
-
-#_(let [main-file-path (get-main-file-path)]
-  (defn resolve-deps-path [file]
-    (cond
-      (re-matches #".*goog/deps\.js" file) goog-deps-path
-      (and main-file-path
-           (apply = (mapv #(last (string/split % "/")) [main-file-path file])))
-      main-file-path
-      :else (do
-              (utils/debug-prn (str "No deps match:" file))
-              file))))
-
-;; server should add a type to each file
-(defn file-type [{:keys [type dependency-file namespace]}]
-    (cond
-      (= type :css)   :css
-      ;; dependency-file :dependency-file
-      namespace       :namespace))
-
-(defmulti resolve-url file-type)
+(defmulti resolve-url :type)

 (defmethod resolve-url :default [{:keys [file]}] file)

-#_(defmethod resolve-url :dependency-file [{:keys [file]}]
-    (resolve-deps-path file))
-
 (defmethod resolve-url :namespace [{:keys [namespace]}]
+  (dev-assert (string? namespace))
   (resolve-ns namespace))

 (defmulti reload-base utils/host-env?)

 (defmethod reload-base :node [request-url callback]
+  (dev-assert (string? request-url) (not (nil? callback)))
   (let [root (string/join "/" (reverse (drop 2 (reverse (string/split js/__dirname "/")))))
         path (str root "/" request-url)]
     (aset (.-cache js/require) path nil)
@@ -95,6 +67,7 @@
                   false)))))

 (defmethod reload-base :html [request-url callback]
+  (dev-assert (string? request-url) (not (nil? callback)))
   (let [deferred (loader/load (add-cache-buster request-url)
                               #js { :cleanupWhenDone true })]
     (.addCallback deferred #(apply callback [true]))
@@ -105,6 +78,9 @@
   ([request-url] (reload-file* request-url identity)))

 (defn reload-file [{:keys [request-url] :as file-msg} callback]
+  (dev-assert (string? request-url)
+              (map? file-msg)
+              (not (nil? callback)))
   (utils/debug-prn (str "FigWheel: Attempting to load " request-url))
   (reload-file* request-url
                 (fn [success?]
@@ -121,7 +97,8 @@
    (or dependency-file
        (and meta-data (:figwheel-load meta-data))
        ;; IMPORTANT make sure this file is currently provided
-       (contains? *loaded-libs* namespace) #_(.isProvided_ js/goog (name namespace)))
+       (contains? *loaded-libs* namespace)
+       #_(.isProvided_ js/goog (name namespace)))
    (not (:figwheel-no-load (or meta-data {})))))

 (defn js-reload [{:keys [request-url namespace meta-data] :as file-msg} callback]
@@ -154,10 +131,22 @@
 (defn add-request-urls [opts files]
   (map (partial add-request-url opts) files))

+(defn eval-body [{:keys [eval-body file]}]
+  (when (and eval-body (string? eval-body))
+    (let [code eval-body]
+      (try
+        (utils/debug-prn (str "Evaling file " file))
+        (js* "eval(~{code})")
+        (catch :default e
+          (utils/log :error (str "Unable to evaluate " file)))))))
+
 (defn reload-js-files [{:keys [before-jsload on-jsload load-from-figwheel] :as opts} {:keys [files] :as msg}]
   (go
     (before-jsload files)
-    (let [files'  (add-request-urls opts (filter #(not (:dependency-file %)) files))
+    ;; evaluate the eval bodies first
+    (doseq [eval-body-file (filter #(:eval-body %) files)]
+      (eval-body eval-body-file))
+    (let [files'  (add-request-urls opts (filter #(not (:eval-body %)) files))
           res'    (<! (load-all-js-files files'))
           res     (filter :loaded-file res')
           files-not-loaded  (filter #(not (:loaded-file %)) res')]


Fixed dumb ordering bug

Fixed dumb ordering bug

--- src/leiningen/ring/war.clj
+++ src/leiningen/ring/war.clj
@@ -217,8 +217,8 @@
   ([project war-name]
      (ensure-handler-set! project)
       (let [project (-> project
-                        add-servlet-dep
-                        unmerge-profiles)
+                        unmerge-profiles
+                        add-servlet-dep)
            result  (compile/compile project)]
        (when-not (and (number? result) (pos? result))
          (let [war-path (war-file-path project war-name)]


add ajax error handler (resolves #3)

add ajax error handler (resolves #3)

--- src/deathrow/core.cljs
+++ src/deathrow/core.cljs
@@ -8,7 +8,7 @@
 (enable-console-print!)

-(defpartial lastQuote
+(defpartial last-quote
 	[offender]
 	[:blockquote
 		[:p (crate/raw (.-lastStmt offender))]
@@ -18,18 +18,32 @@
 				(str ", executed " (.-dateExecuted offender))]])

+(defpartial error-quote
+	[]
+	[:h2 "There was an error loading your request. "
+		[:small "Try again!"]])
+
+
 (defn render-quote
 	[offender]
 	(-> ($ ".quote")
 		(.empty)
-		(.append (lastQuote offender))))
+		(.append (last-quote offender))))
+
+(defn render-quote-error
+	[]
+	(-> ($ ".quote")
+ 		.empty
+ 		(.append error-quote)
+ 		))

 (defn fetch-random-offender
 	[]
 	(jayq/ajax "http://deathrow.herokuapp.com/offenders/random"
 	                {:dataType "json"
-	                 :success  (fn [data] (render-quote data))}))
+	                 :success  (fn [data] (render-quote data))
+	                 :error render-quote-error}))

 (defn init-random-btn-event


:pencil2: Fix 'tooken' typo

:pencil2: Fix 'tooken' typo

--- backend/src/app/http/auth/google.clj
+++ backend/src/app/http/auth/google.clj
@@ -56,7 +56,7 @@
       (let [data (json/read-str (:body res))]
         (get data "access_token"))
       (catch Throwable e
-        (log/error "unexpected error on parsing response body from google access tooken request" e)
+        (log/error "unexpected error on parsing response body from google access token request" e)
         nil))))

@@ -79,7 +79,7 @@
         {:email (get data "email")
          :fullname (get data "name")})
       (catch Throwable e
-        (log/error "unexpected error on parsing response body from google access tooken request" e)
+        (log/error "unexpected error on parsing response body from google access token request" e)
         nil))))

 (defn auth


Why do you keep exiting

Why do you keep exiting

--- src/lazubot/worker.clj
+++ src/lazubot/worker.clj
@@ -11,7 +11,8 @@
     (register-socket! {:in reply-in :out reply-out :socket-type :rep
                        :configurator (fn [socket] (.bind socket addr))})
     (go-loop []
-             (when-let [message (<! reply-out)]
+             (let [message (<! reply-out)]
+               (println (str "got " message))
                (>! reply-in message)
                (recur)))
     (println "Worker initialized")))


Rewrite adj-path to Paths/normalize instead of File/getCanonicalPath.

.getCanonicalPath resolves links, which we don't want.

Also used 'elems instead of the misleading 'path local variable.

--- src/leiningen/voom.clj
+++ src/leiningen/voom.clj
@@ -642,21 +642,20 @@
     (File. ^String p)))

 (defn ^File adj-path
-  [^File f & path]
-  (-> f
-      to-file
-      .getCanonicalPath
-      (str "/" (s/join "/" path))
-      File.))
+  "Adjusts current File object with subsequent elements."
+  [^File f & elems]
+  (reduce #(-> (File. ^File %1 ^String %2) .toPath .normalize .toFile)
+          f
+          elems))

 (defn ^File adj-dir
-  [p & path]
+  [p & elems]
   ;; TODO Should this be made an isDirectory check?
   (let [^File f (to-file p)
         d (if (.isFile f)
             (.getParentFile f)
             f)]
-    (apply adj-path d path)))
+    (apply adj-path d elems)))

 (defn ^File find-box
   "Locates voom-box root starting from current working directory."


Don't need this

Don't need this

--- src/exploud/asgard.clj
+++ src/exploud/asgard.clj
@@ -18,7 +18,6 @@
             [clojure
              [set :as set]
              [string :as str]]
-            [clojure.repl :only pst]
             [clojure.tools.logging :as log]
             [dire.core :refer [with-handler!
                                with-post-hook!


changing constant to uppercase

changing constant to uppercase

--- src/overtone/sc/buffer.clj
+++ src/overtone/sc/buffer.clj
@@ -353,29 +353,7 @@
   [buf]
   (:size  buf))

-(defn data->wavetable
-  "Convert a sequence of floats into wavetable format. Result will be twice the
-  size of source data. Length of source data must be a power of 2 for SC
-  compatability."
-  [data]
-  (let [v   (vec data)
-        cnt (count v)
-        res (float-array (* 2 cnt))]
-    (dorun
-     (map (fn [idx]
-           (let [a (get v idx)
-                 b (get v (inc idx))
-                 r-idx (* 2 idx)]
-             (aset-float res r-idx (-  (* 2 a) b))
-             (aset-float res (inc r-idx) (- b a))))
-         (range (dec cnt))))
-    (let [a (get v (dec cnt))
-          b (get v 0)]
-      (aset-float res (* 2 (dec cnt)) (- (* 2 a) b))
-      (aset-float res (inc (* 2 (dec cnt))) (- b a)))
-    (seq res)))
-
-(def two-pi (* 2 Math/PI))
+(def TWO-PI (* 2 Math/PI))

 (defn create-buffer-data
   "Create a sequence of floats for use as a buffer.  Result will contain
@@ -389,7 +367,7 @@
     (create-buffer-data 32 identity -1 1)

    Sine-wave for (osc) ugen:
-    (create-buffer-data 512 #(Math/sin %) 0 two-pi)
+    (create-buffer-data 512 #(Math/sin %) 0 TWO-PI)

    Chebyshev polynomial for wave-shaping:
     (create-buffer-data 1024 #(- (* 2 % %) 1) -1 1)"


fix merge conflict

fix merge conflict

--- src/babel/francais/morphology/verbs.cljc
+++ src/babel/francais/morphology/verbs.cljc
@@ -370,13 +370,8 @@
     {:comment "past participle non-reflexive -re"
      :p [#"^(\S+)u$"            "$1re"]
      :g [#"^([^' ]+)re$"        "$1u"]
-<<<<<<< HEAD
-     :u {}}
-
-=======
      :u {:synsem {:français {:past-p {:regular true}}}}}

->>>>>>> origin/master
     {:comment "past participle non-reflexive -ir"
      :p [#"^(\S+)i$"            "$1ir"]
      :g [#"^([^' ]+)ir$"        "$1i"]


fix lookup from cached node+port hashmap

--- src/clj/backtype/storm/daemon/worker.clj
+++ src/clj/backtype/storm/daemon/worker.clj
@@ -221,7 +221,7 @@
                 (reset! (:cached-task->node+port worker)
                         (HashMap. my-assignment)))
               (doseq [endpoint remove-connections]
-                (.close (@(:cached-node+port->socket worker) endpoint)))
+                (.close (get @(:cached-node+port->socket worker) endpoint)))
               (apply swap!
                      (:cached-node+port->socket worker)
                      #(HashMap. (dissoc (into {} %1) %&))


Enable snippet for cljs for `begin-contour` and `end-contour`. Issue #255.

These functions are supported by p5js.

--- src/cljc/quil/snippets/shape/vertex.cljc
+++ src/cljc/quil/snippets/shape/vertex.cljc
@@ -5,22 +5,21 @@
   #?(:cljs
      (:use-macros [quil.snippets.macro :only [defsnippet]])))

-#?(:clj
-   (defsnippet begin-contour-end-contour
-     ["begin-contour" "end-contour"]
-     {:renderer :p2d}
-
-     (q/stroke 255 0 0)
-     (q/begin-shape)
-     (q/vertex 250 20)
-     (q/vertex 400 400)
-     (q/vertex 50 400)
-     (q/begin-contour)
-     (q/vertex 200 200)
-     (q/vertex 300 200)
-     (q/vertex 250 380)
-     (q/end-contour)
-     (q/end-shape :close)))
+(defsnippet begin-contour-end-contour
+  ["begin-contour" "end-contour"]
+  {:renderer :p2d}
+
+  (q/stroke 255 0 0)
+  (q/begin-shape)
+  (q/vertex 250 20)
+  (q/vertex 400 400)
+  (q/vertex 50 400)
+  (q/begin-contour)
+  (q/vertex 200 200)
+  (q/vertex 300 200)
+  (q/vertex 250 380)
+  (q/end-contour)
+  (q/end-shape :close))

 (defsnippet begin-shape-end-shape
   ["begin-shape" "end-shape"]


correct traceback message

correct traceback message

--- src/cljs/infinitelives/pixi/texture.cljs
+++ src/cljs/infinitelives/pixi/texture.cljs
@@ -25,7 +25,7 @@
   [key]
   (or
    (@!texture-store key)
-   (throw (js/Error. (str "Texture " texture " not loaded")))))
+   (throw (js/Error. (str "Texture " key " not loaded")))))

 (defn sub-texture [texture [x y] [w h]]
   (js/PIXI.Texture. texture (js/PIXI.Rectangle. x y w h)))


Ensure direct entry retrieval, share response, and secure uuid retrieval response have favorite reactions where needed.

--- src/oc/storage/api/entries.clj
+++ src/oc/storage/api/entries.clj
@@ -23,7 +23,8 @@
             [oc.storage.resources.common :as common-res]
             [oc.storage.resources.org :as org-res]
             [oc.storage.resources.board :as board-res]
-            [oc.storage.resources.entry :as entry-res]))
+            [oc.storage.resources.entry :as entry-res]
+            [oc.storage.resources.reaction :as reaction-res]))

 ;; ----- Utility functions -----

@@ -225,22 +226,26 @@

   ;; Responses
   :handle-ok (by-method {
-    :get (fn [ctx] (entry-rep/render-entry
-                      (:existing-org ctx)
-                      (:existing-board ctx)
-                      (:existing-entry ctx)
-                      (:existing-comments ctx)
-                      (:existing-reactions ctx)
-                      (:access-level ctx)
-                      (-> ctx :user :user-id)))
-    :patch (fn [ctx] (entry-rep/render-entry
+    :get (fn [ctx] (let [user-id (-> ctx :user :user-id)
+                         org-id (-> ctx :existing-org :uuid)]
+                      (entry-rep/render-entry
                         (:existing-org ctx)
                         (:existing-board ctx)
-                        (:updated-entry ctx)
+                        (:existing-entry ctx)
                         (:existing-comments ctx)
-                        (:existing-reactions ctx)
+                        (reaction-res/reactions-with-favorites conn org-id user-id (:existing-reactions ctx))
                         (:access-level ctx)
-                        (-> ctx :user :user-id)))})
+                        user-id)))
+    :patch (fn [ctx] (let [user-id (-> ctx :user :user-id)
+                         org-id (-> ctx :existing-org :uuid)]
+                        (entry-rep/render-entry
+                          (:existing-org ctx)
+                          (:existing-board ctx)
+                          (:updated-entry ctx)
+                          (:existing-comments ctx)
+                          (reaction-res/reactions-with-favorites conn org-id user-id (:existing-reactions ctx))
+                          (:access-level ctx)
+                          user-id)))})
   :handle-unprocessable-entity (fn [ctx]
     (api-common/unprocessable-entity-response (schema/check common-res/Entry (:updated-entry ctx)))))

@@ -424,7 +429,10 @@
                                                (:existing-board ctx)
                                                (:updated-entry ctx)
                                                (:existing-comments ctx)
-                                               (:existing-reactions ctx)
+                                               (reaction-res/reactions-with-favorites conn
+                                                                                (-> ctx :existing-org :uuid)
+                                                                                (-> ctx :user :user-id)
+                                                                                (:existing-reactions ctx))
                                                (:access-level ctx)
                                                (-> ctx :user :user-id)))
   :handle-unprocessable-entity (fn [ctx]
@@ -469,14 +477,22 @@
                         false))

   ;; Responses
-  :handle-ok (fn [ctx] (entry-rep/render-entry (:existing-org ctx)
-                                               (:existing-board ctx)
-                                               (:existing-entry ctx)
-                                               (:existing-comments ctx)
-                                               (:existing-reactions ctx)
-                                               (:access-level ctx)
-                                               (-> ctx :user :user-id)
-                                               :secure)))
+  :handle-ok (fn [ctx] (let [access-level (:access-level ctx)
+                             user-id (-> ctx :user :user-id)
+                             org-id (-> ctx :existing-org :uuid)]
+                          (entry-rep/render-entry (:existing-org ctx)
+                                                  (:existing-board ctx)
+                                                  (:existing-entry ctx)
+                                                  (:existing-comments ctx)
+                                                  (if (or (= :author access-level) (= :viewer access-level))
+                                                    (reaction-res/reactions-with-favorites conn
+                                                                                org-id
+                                                                                user-id
+                                                                                (:existing-reactions ctx))
+                                                    [])
+                                                  access-level
+                                                  user-id
+                                                  :secure))))

 ;; ----- Routes -----


Add new diversification tests based on reproductive traces

--- src/clojush/pushgp/genetic_operators.clj
+++ src/clojush/pushgp/genetic_operators.clj
@@ -1287,6 +1287,56 @@
                  (sequence-similarity c-made-by gc-made-by)
                  (sequence-similarity gc-made-by ggc-made-by)))))

+(defn symbolic-reproductive-change-changes-diversifying?
+  [ind argmap]
+  (let [symbolic #(filter (comp not number?) %)
+        g (:genome ind)
+        c (produce-child-genome-by-autoconstruction g g argmap)
+        c-made-by (symbolic (flatten (:made-by (meta c))))
+        gc (produce-child-genome-by-autoconstruction c g g argmap)
+        gc-made-by (symbolic (flatten (:made-by (meta gc))))
+        ggc (produce-child-genome-by-autoconstruction gc g g argmap)
+        ggc-made-by (symbolic (flatten (:made-by (meta ggc))))]
+    (assoc ind :diversifying
+      (distinct? 1
+                 (sequence-similarity c-made-by gc-made-by)
+                 (sequence-similarity gc-made-by ggc-made-by)))))
+
+(defn symbolic-reproductive-change-diversifying?
+  [ind argmap]
+  (let [symbolic #(filter (comp not number?) %)
+        g (:genome ind)
+        c (produce-child-genome-by-autoconstruction g g argmap)
+        c-made-by (symbolic (flatten (:made-by (meta c))))
+        gc (produce-child-genome-by-autoconstruction c g g argmap)
+        gc-made-by (symbolic (flatten (:made-by (meta gc))))]
+    (assoc ind :diversifying
+      (not= c-made-by gc-made-by))))
+
+(defn reproductive-change-changes-differently-diversifying?
+  [ind argmap]
+  (let [g (:genome ind)
+        c (produce-child-genome-by-autoconstruction g g argmap)
+        c2 (produce-child-genome-by-autoconstruction g g argmap)
+        c-made-by (flatten (:made-by (meta c)))
+        c2-made-by (flatten (:made-by (meta c2)))
+        gc (produce-child-genome-by-autoconstruction c g g argmap)
+        gc2 (produce-child-genome-by-autoconstruction c2 g g argmap)
+        gc-made-by (flatten (:made-by (meta gc)))
+        gc2-made-by (flatten (:made-by (meta gc2)))
+        ggc (produce-child-genome-by-autoconstruction gc g g argmap)
+        ggc2 (produce-child-genome-by-autoconstruction gc2 g g argmap)
+        ggc-made-by (flatten (:made-by (meta ggc)))
+        ggc2-made-by (flatten (:made-by (meta ggc2)))
+        mbsim-c-gc (sequence-similarity c-made-by gc-made-by)
+        mbsim-c2-gc2 (sequence-similarity c2-made-by gc2-made-by)
+        mbsim-gc-ggc (sequence-similarity gc-made-by ggc-made-by)
+        mbsim-gc2-ggc2 (sequence-similarity gc2-made-by ggc2-made-by)]
+    (assoc ind :diversifying
+      (and (distinct? 1 mbsim-c-gc mbsim-gc-ggc)
+           (distinct? 1 mbsim-c2-gc2 mbsim-gc2-ggc2)
+           (distinct? mbsim-gc-ggc mbsim-gc2-ggc2)))))
+
 (defn use-mate-diversifying?
   [ind argmap]
   (let [g (:genome ind)
@@ -1447,7 +1497,9 @@
                 :makes-three-children-differently makes-three-children-differently-diversifying?
                 :children-make-children-differently children-make-children-differently-diversifying?
                 :three-children-make-children-differently three-children-make-children-differently-diversifying?
+                :symbolic-reproductive-change-changes symbolic-reproductive-change-changes-diversifying?
                 :reproductive-change-changes reproductive-change-changes-diversifying?
+                :reproductive-change-changes-differently reproductive-change-changes-differently-diversifying?
                 :use-mate use-mate-diversifying?
                 :use-mate-differently use-mate-differently-diversifying?
                 :si-and-mate-use si-and-mate-use-diversifying?


Added advent calendar to zonemap

Added advent calendar to zonemap

--- src/demogorgon/nh.clj
+++ src/demogorgon/nh.clj
@@ -59,7 +59,8 @@
       "in Fort Ludios"
       "in the Black Market"
       "in Vlad's Tower"
-      "on The Elemental Planes"])
+      "on The Elemental Planes"
+      "in the Advent Calendar"])

 (def achievements
      ["obtained the Bell of Opening"


Added shape validation for conversations just before export

--- src/polismath/conv_man.clj
+++ src/polismath/conv_man.clj
@@ -6,6 +6,7 @@
             [polismath.db :as db]
             [polismath.utils :refer :all]
             [plumbing.core :as pc]
+            [schema.core :as s]
             [clojure.core.matrix.impl.ndarray]
             [clojure.core.async
              :as as
@@ -143,6 +144,15 @@
           (.printStackTrace e)))
       (log/debug "Profile data for zid" (:zid conv) ": " prof))))

+;; XXX WIP; need to flesh out and think about all the ins and outs
+;; Also, should place this in conversation, but for now...
+(def Conversation
+  "A schema for what valid conversations should look like (WIP)"
+  {:zid               s/Int
+   :lastVoteTimestamp s/Int
+   :group-votes       s/Any
+   ;; Note: we let all other key-value pairs pass through
+   s/Keyword          s/Any})

 (defn update-fn
   "This function is what actually gets sent to the conv-actor. In addition to the conversation and vote batches
@@ -160,6 +170,8 @@
                              :finish-time finish-time
                              :recompute recompute
                              :n-votes (count votes))
+        ;; Make sure our data has the right shape
+        (s/validate Conversation updated-conv)
         ; Format and upload main results
         (doseq [[col-name prep-fn] [["main" prep-main] ; main math results, for client
                                     ["bidtopid" prep-bidToPid]]] ; bidtopid mapping, for server


Autoload main function on load

Autoload main function on load

--- src/discuss/core.cljs
+++ src/discuss/core.cljs
@@ -17,7 +17,7 @@
 ;; Initialization
 (defn main []
   (com/init-with-references!))
-;(main)
+(main)

 ;; Register
 (om/root views/main-view lib/app-state


Use new tooltip view

Use new tooltip view

--- src/discuss/core.cljs
+++ src/discuss/core.cljs
@@ -4,6 +4,7 @@
             [discuss.debug :as debug]
             [discuss.extensions]
             [discuss.lib :as lib]
+            [discuss.tooltip :as tooltip]
             [discuss.views :as views]))

 (enable-console-print!)
@@ -21,7 +22,7 @@
 (om/root views/sidebar-view lib/app-state
          {:target (.getElementById js/document (lib/prefix-name "sidebar"))})

-(om/root views/tooltip-view {}
+(om/root tooltip/view {}
          {:target (.getElementById js/document (lib/prefix-name "tooltip"))})

 (om/root debug/debug-view lib/app-state


Create function to prepare received search results

--- src/discuss/find.cljs
+++ src/discuss/find.cljs
@@ -9,6 +9,13 @@
 ;(def data (atom {}))
 (def counter (atom 0))

+(defn prepare-search-results
+  "Extract values and create a list of maps."
+  []
+  (let [vals (get-in @lib/app-state [:discussion :search :values])
+        vals-dict (for [[k v] vals] {k v})]
+    (vec vals-dict)))
+
 (defn statement-handler
   "Called when received a response in the search."
   [response]
@@ -19,7 +26,10 @@
       (lib/error-msg! error)
       (do
         (lib/no-error!)
-        (lib/update-state-item! :discussion :search (fn [_] res))))))
+        (lib/update-state-item! :discussion :search (fn [_] res))
+        #_(let [foo (prepare-search-results)]
+          (println foo)
+          (println (count foo)))))))

 (defn statement
   "Find related statements to given keywords."
@@ -33,10 +43,14 @@
 (defn item-view [data owner]
   (reify om/IRender
     (render [_]
-      (println data)
-      (dom/div #js {:id (str (lib/prefix-name "search-item-") (swap! counter inc))}
-               (dom/div nil data)
-               (println data)))))
+      (let [bubble-class nil]
+        (dom/li #js {:className bubble-class}
+                (dom/div #js {:className "avatar"})
+                (dom/p #js {:className "messages"}
+                       (vlib/safe-html "foo"))))
+      #_(dom/div #js {:id (str (lib/prefix-name "search-item-") (swap! counter inc))}
+                 (dom/div nil data)
+                 (println data)))))

 (defn view []
   (reify om/IRender
@@ -48,10 +62,10 @@
                         (dom/input #js {:className   "form-control"
                                         :onChange    #(statement (.. % -target -value))
                                         :placeholder "Find Statement"}))
-               (let [vals (get-in @lib/app-state [:discussion :search :values])
-                     vals-dict (for [[k v] vals] {k v})]
-                 (println vals-dict)
-                 (apply dom/div nil
+               (println (prepare-search-results))
+               #_(apply dom/ol #js {:className "foobar"}
+                        (om/build-all item-view (lib/get-bubbles)))
+               #_(apply dom/div nil
                         (om/build-all item-view vals-dict
-                                      )))
+                                      ))
                ))))


improved the query

improved the query

--- src/elliot/search.clj
+++ src/elliot/search.clj
@@ -25,6 +25,7 @@

 (defn extract-data-from-block-query-response
   [highlights block-query-response]
+  ;;(println (get highlights (keyword (:id block-query-response))))
   {:highlight
    (first
     (field-to-display-and-highlight
@@ -43,14 +44,23 @@
                     (:highlights query-response))
            (:docs query-response)))))

+(defn print-n-return [thing]
+  (println thing)
+  thing)
+
 (defn improve-query [stock-query]
   (assoc stock-query
          :q
-         (str
-          "title_t:\""
-          (:q stock-query)
-          "\""
-          (:q stock-query))))
+         (print-n-return
+          (str
+           "title_t:\""
+           (:q stock-query)
+           "\"^10 "
+           (:q stock-query)
+           " \""
+           (:q stock-query)
+           "\"~10000^5"
+           ))))

 (defn go [query-struct]
   (if (nil? (query-struct :q))


Add ability to (dispatch [:flush-reagent])

--- src/re_frame/handlers.cljs
+++ src/re_frame/handlers.cljs
@@ -1,13 +1,34 @@
 (ns re-frame.handlers
-  (:require-macros [cljs.core.async.macros :refer [go-loop]])
-  (:require [re-frame.db :refer [app-db]]
+  (:refer-clojure :exclude [flush])
+  (:require-macros [cljs.core.async.macros :refer [go-loop go]])
+  (:require [reagent.core :refer [flush]]
+            [re-frame.db :refer [app-db]]
             [re-frame.utils :refer [first-in-vector]]
             [cljs.core.async :refer [chan put! <! timeout]]))

+;; -- special handlers ----------------------------------------------------------------------------
+
+;; if true then pause the dispatch loop, generally to give the GUI a chance to sync
+(def wait-one-annimation-frame (atom false))
+
+(defn flush-reagent-handler
+  "Will force reagent to render any pending changes.
+  Useful when a handler is about to hog the CPU for a while and
+  there are pending GUI changes telling the user about progress.
+  Flushes any GUI changes through into the DOM."
+  [_ _]
+  (flush)
+  (reset! wait-one-annimation-frame true))
+
+(def special-handlers {
+     :flush-reagent flush-reagent-handler})
+
+
 ;; -- register of handlers ------------------------------------------------------------------------

-(def ^:private id->fn  (atom {}))
+
+(def ^:private id->fn  (atom special-handlers))

 (defn register
@@ -44,12 +65,18 @@
   "route an event, arriving on the dispatch channel, to the right handler"
   []
   (go-loop []
-      (let [event-v     (<! dispatch-chan)]
+      (let [         ;; if a small pause is required   (dispatch [:flush-reagent])
+            _        (if @wait-one-annimation-frame
+                       (do
+                         (reset! wait-one-annimation-frame false)
+                         (<! (timeout 16)))  ;; Wait one annimation frame, which will make sure any pending GUI work is done.
+                       (<! (timeout 0)))   ;; just in case we are handling one dispatch after an other, give the GUI a chance to do its stuff.
+            event-v  (<! dispatch-chan)]
         (dispatch-sync event-v)
-        (<! (timeout 0))     ;; just in case we are handling one dispatch after an other, give the GU a chance to do its stuff.
         (recur))))

-(router)  ;; run the router loop it
+;; run the router loop - sending event after event to the handlers
+(router)

 ;; -- helper --------------------------------------------------------------------------------------


timeout increased

timeout increased

--- src/etaoin/client.clj
+++ src/etaoin/client.clj
@@ -9,12 +9,14 @@
 ;; defaults
 ;;

+(def timeout 20)
+
 (def default-api-params
   {:as :json
    :accept :json
    :content-type :json
-   :socket-timeout (* 1000 5)
-   :conn-timeout (* 1000 5)
+   :socket-timeout (* 1000 timeout)
+   :conn-timeout (* 1000 timeout)
    :form-params {}
    :debug false})


Handle 404 when getting Numel registrations

--- src/exploud/numel.clj
+++ src/exploud/numel.clj
@@ -26,6 +26,6 @@
   [environment application]
   (let [url (application-registrations-url environment application)
         {:keys [body status] :as response} (http/simple-get url {:socket-timeout timeout})]
-    (if (= 200 status)
-      (json/parse-string body true)
-      (throw (ex-info "Unexpected response" {:type ::unexpected-response :response response})))))
+    (cond (= 200 status) (json/parse-string body true)
+          (= 404 status) nil
+          :else (throw (ex-info "Unexpected response" {:type ::unexpected-response :response response})))))


updated for handler

updated for handler

--- src/selmer/test_parser.clj
+++ src/selmer/test_parser.clj
@@ -75,18 +75,22 @@
 #_(render (tag-content "endfor" (java.io.StringReader. "foo {{name.first}} bar {% endfor %}")) {:name {:first "Bob"}})
 ;"foo Bob bar "

+(defn for-hanlder [[id _ ids] rdr]
+  (let [content (tag-content "endfor" rdr)
+        id (map keyword (.split id "\\."))
+        ids (keyword ids)]
+    (fn [args]
+      (for [value (get args ids)]
+        (render content (assoc args id value))))))
+
 (def expr-tags
-  {:for {:handler
-         (fn [args rdr]
-           (let [content (tag-content "endfor" rdr)]
-             (fn [args] (render content args))))}
+  {:for {:handler for-hanlder}
    :block {:handler
            (fn [args rdr]
              (let [content (tag-content "endblock" rdr)]
                (fn [args] (render content args))))}})

-(defn expr-tag [{:keys [tag-name args]} rdr]
-  (println tag-name args (get-in expr-tags [(keyword tag-name) :handler]))
+(defn expr-tag [{:keys [tag-name args]} rdr]
   ((get-in expr-tags [(keyword tag-name) :handler]) args rdr))

 (defn handle-tag [rdr]


CMR-348: Fixed formatting.

CMR-348: Fixed formatting.

--- src/cmr/search/services/parameter_converters/orbit_number.clj
+++ src/cmr/search/services/parameter_converters/orbit_number.clj
@@ -23,14 +23,14 @@
   [values]
   (let [{:keys [min-orbit-number max-orbit-number]} values
         start-range-condition (qm/map->NumericRangeCondition {:field :start-orbit-number
-                                                          :min-value min-orbit-number
-                                                          :max-value max-orbit-number})
+                                                              :min-value min-orbit-number
+                                                              :max-value max-orbit-number})
         orbit-number-range-condition (qm/map->NumericRangeCondition {:field :orbit-number
-                                                          :min-value min-orbit-number
-                                                          :max-value max-orbit-number})
+                                                                     :min-value min-orbit-number
+                                                                     :max-value max-orbit-number})
         stop-range-condition (qm/map->NumericRangeCondition {:field :stop-orbit-number
-                                                          :min-value min-orbit-number
-                                                          :max-value max-orbit-number})]
+                                                             :min-value min-orbit-number
+                                                             :max-value max-orbit-number})]
     (qm/map->OrbitNumberRangeCondition {:start-orbit-number-range-condition start-range-condition
                                         :orbit-number-range-condition orbit-number-range-condition
                                         :stop-orbit-number-range-condition stop-range-condition})))


stage success add host

stage success add host

--- src/hooks/dnsmasq.clj
+++ src/hooks/dnsmasq.clj
@@ -66,7 +66,9 @@

 (def actions {:reload {:success add-host} :create {:success add-host}
               :start {:success add-host} :stop {:success remove-host}
-              :destroy {:success remove-host :error remove-host}})
+              :destroy {:success remove-host :error remove-host}
+              :stage {:success add-host}
+              })

 (defn update-dns [{:keys [event workflow] :as args}]
   (send-off hosts (get-in actions [workflow event] (fn [hosts-file _] hosts-file)) args))


Remove hackety notes

Remove hackety notes

--- src/icecap/schema.clj
+++ src/icecap/schema.clj
@@ -11,9 +11,7 @@

   An step is a small, atomic part of a capability. It includes things
   like HTTP requests or delays."
-  (s/conditional ;; HACK: this implementation is quite unfortunate,
-   ;; but I can't figure out how to make it any better; see also:
-   ;; https://github.com/Prismatic/schema/issues/140
+  (s/conditional
    #(= (:type %) :http) (get-schema {:type :http})
    #(= (:type %) :delay) (get-schema {:type :delay})))


Add in-dir and out-dir to default config.

--- src/incise/config.clj
+++ src/incise/config.clj
@@ -5,7 +5,8 @@
   (:import [java.io PushbackReader])
   (:refer-clojure :exclude [merge load assoc get]))

-(defonce config (atom {}))
+(defonce config (atom {:in-dir "content"
+                       :out-dir "public"}))

 (defn get [& more]
   (if (empty? more)


No arguments necessary to asset-pipeline.

--- src/incise/server.clj
+++ src/incise/server.clj
@@ -37,9 +37,7 @@
              (wrap-incise)
              (wrap-log-exceptions)
              (wrap-stacktrace-web)
-             (asset-pipeline {:cache-mode :development
-                              :engine :v8
-                              :compress false})))
+             (asset-pipeline)))

 (defn getenv
   "A nice wrapper around System/getenv that allows a second argument to be
@@ -59,6 +57,7 @@
 (defn defserver
   "Start a server and bind the result to a var, 'server'."
   [& args]
+  (conf/load)
   (reset! server (apply serve args)))

 (defn stop-server []


Use 'major' instead of 'ionian'. No need to bring up modes for this song.

--- src/overtunes/songs/at_all.clj
+++ src/overtunes/songs/at_all.clj
@@ -9,14 +9,14 @@
     #(+ start (* ms-per-beat %))))

-(def ionian #(let [interval (mod % 7)
+(def major #(let [interval (mod % 7)
                   note ([0 2 4 5 7 9 11] interval)
                   octave (quot (- % interval) 7)]
                (+ (* 12 octave) note)))

 (defn after [timing offset] #(timing (+ offset %)))
 (defn tempo [timing factor] #(timing (/ % factor)))
-(defn ground [note] (+ 60 (ionian note)))
+(defn ground [note] (+ 60 (major note)))

 (def note# (comp sampled-piano ground))
 (defn chord# [chord] (doseq [note (vals chord)] (note# note)))


Only include :resources-path in jar if it exists.

--- src/leiningen/jar.clj
+++ src/leiningen/jar.clj
@@ -40,6 +40,9 @@
   (.putNextEntry jar-os (JarEntry. (:path spec)))
   (copy (ByteArrayInputStream. (:bytes spec)) jar-os))

+;; TODO: hacky; needed for conditional :resources-path below
+(defmethod copy-to-jar nil [project jar-os spec])
+
 (defn write-jar [project out-filename filespecs]
   (with-open [jar-os (JarOutputStream. (BufferedOutputStream.
                                         (FileOutputStream. out-filename))
@@ -64,7 +67,9 @@
                                      (:group project)
                                      (:name project))
                        :bytes (make-pom-properties project)}
-                      {:type :path :path (:resources-path project)}
+                      (when (and (:resources-path project)
+                                 (.exists (file (:resources-path project))))
+                        {:type :path :path (:resources-path project)})
                       {:type :path :path (:compile-path project)}
                       {:type :path :path (:source-path project)}
                       {:type :path :path (str (:root project) "/project.clj")}]]


Fix test file for generated projects.

Fix test file for generated projects.

--- src/leiningen/new.clj
+++ src/leiningen/new.clj
@@ -18,19 +18,18 @@
              (str "(defproject " project-name " \"1.0.0-SNAPSHOT\"\n"
                   "  :description \"FIXME: write\"\n"
                   "  :dependencies [[org.clojure/clojure \"1.1.0\"]\n"
-                  "                 [org.clojure/clojure-contrib "
-                  "\"1.1.0-SNAPSHOT\"]])"))
+                  "                 [org.clojure/clojure-contrib \"1.1.0\"]])"))
        (let [project-ns  (.replace (str project-name) "/" ".")
              project-clj (str (apply str (replace {\- \_, \. \/} project-ns))
                               ".clj")
-             test-clj (.replace project-clj ".clj" "-test.clj")]
+             test-clj (.replace project-clj ".clj" "_test.clj")]
          (.mkdirs (file project-dir "test"))
          (.mkdirs (.getParentFile (file project-dir "src" project-clj)))
          (spit (file project-dir "src" project-clj)
                (str "(ns " project-ns ")\n"))
-         (.mkdirs (.getParentFile (file project-dir "test" project-clj)))
+         (.mkdirs (.getParentFile (file project-dir "test" test-clj)))
          (spit (file project-dir "test" test-clj)
-               (str "(ns " (.replace test-clj "\\." "/")
+               (str "(ns " (str project-ns "-test")
                     "\n  (:use [" project-ns "] :reload-all)"
                     "\n  (:use [clojure.test]))\n\n"
                     "(deftest replace-me ;; FIXME: write\n  (is false))\n"))