Form is cleared and UI goes to Show after submission.

--- src/cljs/post_to_screen/core.cljs
+++ src/cljs/post_to_screen/core.cljs
@@ -61,18 +61,19 @@
             [:pre#codeview
              [:code (get posts (dec selected))]]])]))))

-(defn submit-code [posts e]
+(defn submit-code [owner e]
   (let [code (-> js/document
-                 (.getElementById "code")
-                 .-value)]
+                 (.getElementById "code"))]
     #_(print "Sent: " [:post-to-screen/code code])
-    (chsk-send! [:post-to-screen/code code])
+    (chsk-send! [:post-to-screen/code (.-value code)])
+    (set! (.-value code) "")
+    (om/set-state! owner [:selected] 1)
     (.preventDefault e)))

-(defn post-form [posts]
+(defn post-form [owner]
   (html
     [:form.form-horizontal {:role "form"
-                            :on-submit (partial submit-code posts)}
+                            :on-submit (partial submit-code owner)}
      [:div.form-group
       [:label.control-label.col-xs-1 {:for "code"} "Code:"]
       [:div.col-xs-10
@@ -100,7 +101,7 @@
                        tabs)]
          [:hr]
          (case (get tabs selected)
-           "Post" (post-form (:posts cursor))
+           "Post" (post-form owner)
            "Show" (om/build code-view cursor))]))
     om/IDidUpdate
     (did-update [_ _ _]


fix the started time

fix the started time

--- frontend/components/build_head.cljs
+++ frontend/components/build_head.cljs
@@ -201,7 +201,8 @@
                        (build-model/author build)])]
                [:th "Started"]
                [:td (when (:start_time build)
-                      (om/build common/updating-duration {:start (:start_time build)} {:opts {:formatter datetime/time-ago}}) " ago")]]
+                      (list
+                       (om/build common/updating-duration {:start (:start_time build)} {:opts {:formatter datetime/time-ago}}) " ago"))]]
               [:tr
                [:th "Trigger"]
                [:td (build-model/why-in-words build)]


:sparkles: Clean code on router ns.

:sparkles: Clean code on router ns.

--- frontend/src/uxbox/util/router.cljs
+++ frontend/src/uxbox/util/router.cljs
@@ -5,6 +5,7 @@
 ;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>

 (ns uxbox.util.router
+  (:refer-clojure :exclude [resolve])
   (:require
    [reitit.core :as r]
    [cuerdas.core :as str]
@@ -14,8 +15,6 @@
   (:import
    goog.Uri
    goog.Uri.QueryData))
-
-(defonce +router+ nil)

 ;; --- API

@@ -37,9 +36,9 @@
            (transient {})
            (.getKeys qdata))))

-(defn- resolve-url
-  ([router id] (resolve-url router id {} {}))
-  ([router id params] (resolve-url router id params {}))
+(defn resolve
+  ([router id] (resolve router id {} {}))
+  ([router id params] (resolve router id params {}))
   ([router id params qparams]
    (when-let [match (r/match-by-name router id params)]
      (if (empty? qparams)
@@ -68,7 +67,7 @@
   ([router id] (navigate! router id {} {}))
   ([router id params] (navigate! router id params {}))
   ([router id params qparams]
-   (-> (resolve-url router id params qparams)
+   (-> (resolve router id params qparams)
        (html-history/set-path!))))

 (defn match
@@ -83,20 +82,12 @@
                :params params
                :query-params qparams)))))

-(defn route-for
-  "Given a location handler and optional parameter map, return the URI
-  for such handler and parameters."
-  ([id] (route-for id {}))
-  ([id params]
-   (str (some-> +router+ (resolve-url id params)))))
-
 ;; --- Navigate (Event)

 (deftype Navigate [id params qparams]
   ptk/EffectEvent
   (effect [_ state stream]
     (let [router (:router state)]
-      ;; (prn "Navigate:" id params qparams "| Match:" (resolve-url router id params qparams))
       (navigate! router id params qparams))))

 (defn nav


Fuzzy sets now implement clojure.lang.Associative

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

--- src/conexp/contrib/fuzzy/sets.clj
+++ src/conexp/contrib/fuzzy/sets.clj
@@ -42,10 +42,12 @@
     (if-let [n (next hashmap)]
       n
       ()))
-  (cons [this o]
-    (if (zero? (second o))
-      this
-      (Fuzzy-Set. (conj hashmap o))))
+  (cons [this [k v]]
+    (when-not (and (number? v)
+                   (< 0 v)
+                   (<= v 1))
+      (illegal-argument "Fuzzy sets only support real values in (0,1]"))
+    (Fuzzy-Set. (conj hashmap [k v])))
   (seq [this]
     (seq hashmap))
   (count [this]
@@ -62,7 +64,15 @@
   (applyTo [this seq]
     (if (= 1 (count seq))
       (.applyTo hashmap seq)
-      (illegal-argument "Cannot apply fuzzy sets to non-singleton sequences."))))
+      (illegal-argument "Cannot apply fuzzy sets to non-singleton sequences.")))
+  ;;
+  clojure.lang.Associative
+  (containsKey [this o]
+    (unsupported-operation "Fuzzy sets do not support the contains? operation."))
+  (entryAt [this o]
+    (.entryAt hashmap o))
+  (assoc [this k v]
+    (.cons this [k v])))

 (defn make-fuzzy-set
   "Constructs a fuzzy set from a given hashmap. The values must be


Fix bug in size selection of org avatars

We want ?v=2&s=25 rather than ?v=225

--- frontend/components/account.cljs
+++ frontend/components/account.cljs
@@ -41,7 +41,7 @@
                (let [org-url    (routes/v1-org-settings-subpage {:org     (:login org)
                                                                  :subpage "plan"})
                      avatar-url (if-let [avatar-url (:avatar_url org)]
-                                  (str avatar-url "25")
+                                  (str avatar-url "&s=25")
                                   (gh-utils/gravatar-url {:gravatar_id (:gravatar_id org)
                                                           :login       (:login org)
                                                           :size        25}))]


Make helper functions private.

Make helper functions private.

--- src/dsbdp/data_processing_dsl.clj
+++ src/dsbdp/data_processing_dsl.clj
@@ -56,7 +56,7 @@
               ~(name (first rule#))
               ~(create-proc-sub-fn (second rule#) ~'input)))))

-(defn create-proc-fn-body-java-map-out
+(defn- create-proc-fn-body-java-map-out
   "Create a data processing function body for emitting data into a Java map."
   [input rules]
   (reduce
@@ -70,14 +70,14 @@
                 ~(name (first rule#))
                 ~(create-proc-sub-fn (second rule#) ~'input)))))

-(defn create-proc-fn-body-clj-map-out
+(defn- create-proc-fn-body-clj-map-out
   "Create a data processing function body for emitting data into a Clojure map."
   [input rules]
   (reduce
     (reduce-fn-clojure-map-out)
     '[-> {}] rules))

-(defn create-proc-fn-body-csv-str-out
+(defn- create-proc-fn-body-csv-str-out
   "Create a data processing function body for emitting data into a CSV string."
   [input rules]
   (let [extracted-strings (reduce
@@ -91,7 +91,7 @@
         commas (reduce into [] ["." (repeat (- (count rules) 1) ",") "."])]
     (vec (filter #(not= \. %) (interleave extracted-strings commas)))))

-(defn create-proc-fn-body-json-str-out
+(defn- create-proc-fn-body-json-str-out
   "Create a data processing function body for emitting data into a JSON string."
   [input rules]
   (let [extracted-strings (conj


add signature extraction and add parser for rare 'def fn' forms

--- get-symbol-metadata/src/core.clj
+++ get-symbol-metadata/src/core.clj
@@ -114,34 +114,93 @@
 ;; Form Parsing
 ;;------------------------------------------------------------

-(defn parse-fn-or-macro
+(defn parse-defn-or-macro
+  [form]
+  (let [name- (second form)
+        docstring (let [ds (nth form 2)]
+                    (when (string? ds)
+                      (fix-docstring ds)))
+        attr-map (let [m (nth form (if docstring 3 2))]
+                   (when (map? m) m))
+        rest-forms (drop (cond-> 2 docstring inc attr-map inc) form)
+        signatures (if (vector? (first rest-forms))
+                     (take 1 rest-forms)
+                     (map first rest-forms))]
+    {:name name-
+     :docstring docstring
+     :signatures signatures}))
+
+(defn parse-def-fn
+  [form]
+  (let [name- (second form)
+        m (meta name-)
+        docstring (let [ds (:doc m)]
+                    (when (string? ds)
+                      (fix-docstring ds)))
+        signatures (when-let [arglists (:arglists m)]
+                     (when (= 'quote (first arglists))
+                       (second arglists)))]
+    {:name name-
+     :docstring docstring
+     :signatures signatures}))
+
+(defmulti parse-form*
+  (fn [form]
+    (cond
+      (= 'defn (first form))
+      "defn"
+
+      (= 'defmacro (first form))
+      "defmacro"
+
+      (and (= 'def (first form))
+           (list? (nth form 2 nil))
+           (= 'fn (first (nth form 2 nil)))
+           (not (:private (meta (second form)))))
+      "def fn"
+
+      :else nil)))
+
+(defmethod parse-form* "def fn"
+  [form]
+  (assoc (parse-def-fn form) :fn-or-macro "function"))
+
+(defmethod parse-form* "defn"
+  [form]
+  (assoc (parse-defn-or-macro form) :fn-or-macro "function"))
+
+(defmethod parse-form* "defmacro"
+  [form]
+  (assoc (parse-defn-or-macro form) :fn-or-macro "macro"))
+
+(defmethod parse-form* nil
+  [form]
+  nil)
+
+(defn parse-common
   [form ns- repo]
-  (let [fn-or-macro ({'defn "function" 'defmacro "macro"} (first form))
-        docstring (when fn-or-macro
-                    (let [ds (nth form 2)]
-                      (when (string? ds)
-                        (fix-docstring ds))))
-        m (meta form)
+  (let [m (meta form)
         lines [(:line m) (:end-line m)]
         num-lines (inc (- (:end-line m) (:line m)))
         source (join "\n" (take-last num-lines (split-lines (:source m))))
         filename (subs (:file m) (inc (count repo-dir)))
         github-link (get-github-file-link repo filename lines)]
-    (when fn-or-macro
-      {:ns ns-
-       :fn-or-macro fn-or-macro
-       :name (nth form 1)
-       :docstring docstring
-       :source source
-       :filename filename
-       :lines lines
-       :github-link github-link
-       })))
+    {:ns ns-
+     :source source
+     :filename filename
+     :lines lines
+     :github-link github-link}))
+
+(defn parse-form
+  [form ns- repo]
+  (when-let [specific (parse-form* form)]
+    (let [common (parse-common form ns- repo)]
+      (merge specific common))))

 (defn parse-api
   "Parse the functions and macros from the given repo file"
   [ns- repo file]
-  (keep #(parse-fn-or-macro % ns- repo) (get-forms ns- repo file)))
+  (keep #(parse-form % ns- repo) (get-forms ns- repo file)))

 (defn get-imported-macro-api
   [ns- repo file macro-api]
@@ -183,6 +242,7 @@
     [(cljsdoc-section "Name" (:name item))
      (cljsdoc-section "Type" (:fn-or-macro item))
      (cljsdoc-section "Docstring" (:docstring item))
+     (cljsdoc-section "Signatures" (join "\n" (:signatures item)))
      (cljsdoc-section "Filename" (:filename item))
      (cljsdoc-section "Source" (:source item))
      (cljsdoc-section "Github Link" (:github-link item))]))


wip: update introspection

wip: update introspection

--- src/graphql_clj/introspection.clj
+++ src/graphql_clj/introspection.clj
@@ -112,8 +112,7 @@

        ;; OBJECT and INTERFACE only
        :fields (when (contains? #{:OBJECT :INTERFACE} kind)
-                 (:fields type)) ; defer resolving of fields
-
+                 (filter #(not (= '__typename (:name %))) (:fields type))) ; defer resolving of fields
        ;; OBJECT only
        :interfaces [] ; TODO


less spacy caves

less spacy caves

--- src/cas/world.cljs
+++ src/cas/world.cljs
@@ -55,7 +55,7 @@
   [width height]
   (let [simpl (js/SimplexNoise. rand)
         coords (new-coord-map width height)
-        freq (/ 5.0 width)]
+        freq (/ 20.0 width)]
     (letfn [(simplex-tile [coord]
               (.noise2D simpl
                         (* freq (coord 0))
@@ -73,7 +73,7 @@
 (defn grid-to-stone
   [grid]
   (vec (map (fn [col] (vec (map (fn [cell]
-                                  (tile (if (<= cell 0.5)
+                                  (tile (if (<= cell 0.1)
                                     :air
                                     :stone))
                         )


Implement proper branch unstaging

Implement proper branch unstaging

--- src-cljs/cljs_workspace/om_branch_merge.cljs
+++ src-cljs/cljs_workspace/om_branch_merge.cljs
@@ -108,6 +108,10 @@
           (reset! merge-candidate nil))
         (reset! merge-candidate branch))))

+(defn unstage-branches []
+  (reset! merge-candidate nil)
+  (reset! staged-for-merge (atom {:from nil :into nil})))
+
 (defn merge-staged-branches [root-branch]
   (let [{:keys [from into]} @staged-for-merge]
     (merge-branches from into root-branch)))


Update table component documentation

Update table component documentation

--- src/cljs/org/broadinstitute/firecloud_ui/common/table.cljs
+++ src/cljs/org/broadinstitute/firecloud_ui/common/table.cljs
@@ -77,8 +77,16 @@
 ;;       :sort-initial (optional)
 ;;         A flag to set the initial column to sort.  Value is either :asc or :desc.  If present on multiple
 ;;         columns, the first one will be used.
+;;   :filters (OPTIONAL)
+;;     A vector of filters to apply to the data. Each item as the following properties:
+;;       :text (required)
+;;         A label for the filter.
+;;       :pred (required)
+;;         A function that, given a data item, returns true if that item matches the filter.
 ;;   :data (REQUIRED)
-;;     A sequence-of-sequences forming the data grid.
+;;     A sequence items that will appear in the table.
+;;   :->row (REQUIRED)
+;;     A function that takes a data item and returns a vector representing a table row.
 (react/defc Table
   {:get-default-props
    (fn []


fix transaction query to handle lot-id criteria

--- src/clj_money/models/storage/sql_storage.clj
+++ src/clj_money/models/storage/sql_storage.clj
@@ -486,9 +486,18 @@
                (str "The criteria is not valid: " explanation)
                {:criteria criteria
                 :explanation explanation}))))
-  (query db-spec (-> (h/select :*)
-                     (h/from :transactions)
-                     (h/where (map->where criteria)))))
+  (let [sql (-> (h/select :t.*)
+                (h/from [:transactions :t]))
+        sql (if (not (empty? (dissoc criteria :lot-id)))
+              (h/where sql (map->where (dissoc criteria :lot-id)))
+              sql)
+        sql (if (contains? criteria :lot-id)
+              (-> sql
+                  (h/join [:lots_transactions :lt]
+                          [:= :t.id :lt.transaction_id])
+                  (h/merge-where [:= :lt.lot_id (:lot-id criteria)]))
+              sql)]
+    (query db-spec sql)))

   (select-transactions-by-entity-id
     [_ entity-id options]


No longer hard code the width of the action column

--- src/cljs/mdr2/productions/in_production.cljs
+++ src/cljs/mdr2/productions/in_production.cljs
@@ -274,7 +274,7 @@
      [:td [production-link production]]
      [:td production_type]
      [:td state]
-     [:td {:width "14%"} [buttons production]]]))
+     [:td #_{:width "14%"} [buttons production]]]))

 (defn productions []
   (let [productions @(rf/subscribe [::productions-sorted])]


Remove spaces

Remove spaces

--- src-cljs/frontend/components/account.cljs
+++ src-cljs/frontend/components/account.cljs
@@ -67,7 +67,7 @@
     om/IRenderState
     (render-state [_ {:keys [show-modal?]}]
       (let [close-fn #(om/set-state! owner :show-modal? false)
-            tokens        (get-in app state/user-tokens-path)
+            tokens (get-in app state/user-tokens-path)
             create-token! #(raise! owner [:api-token-creation-attempted {:label %
                                                                          :on-success close-fn}])
             new-user-token (get-in app state/new-user-token-path)]


More needed rows.

More needed rows.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -498,7 +498,7 @@
             series-1-count (count series-1)
             series-1-mean (if (not= 0 series-1-count) (/ series-1-sum series-1-count) "NA")]
         (html
-         [:div {:class "row"}
+         [:div.row#summary-stats
           [:div {:class "col-md-3"}
            (bs/panel "Minimum" (str (.toFixed (js/Number. series-1-min) 3) " " unit))]
           [:div {:class "col-md-3"}


More property details formatting.

More property details formatting.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -607,6 +607,8 @@
                    [:dt "Built Form"] [:dd (:built_form property_data)]
                    [:dt "Age"] [:dd (:age property_data)]
                    [:dt "Ownership"] [:dd (:ownership property_data)]
+                   [:dt "Project Phase"] [:dd (:project_phase property_data)]
+                   [:dt "Monitoring Hierarchy"] [:dd (:monitoring_hierarchy property_data)]
                    [:dt "Practical Completion Date"] [:dd (:practical_completion_date property_data)]
                    [:dt "Construction Date"] [:dd (:construction_date property_data)]
                    [:dt "Conservation Area"] [:dd (:conservation_area property_data)]
@@ -619,20 +621,17 @@
                     [:img.img-thumbnail.tmg-responsive
                      {:src (str "https://s3-us-west-2.amazonaws.com/get-embed-data/" pic)}])]
                  [:div.col-md-6
-                  [:dl.dl-horizontal
-                   [:dt "Project Phase"] [:dd (:project_phase property_data)]
-                   [:dt "Other Notes"] [:dd (:other_notes property_data)]
-                   [:dt "Monitoring Hierarchy"] [:dd (:monitoring_hierarchy property_data)]
-                   [:dt "Monitoring Policy"] [:dd (:monitoring_policy property_data)]
-                   ]]
+                  (for [ti (:technology_icons property_data)]
+                    [:img.tmg-responsive {:src ti :width 80 :height 80}])]
                  [:div.col-md-12
                   (detail-section "Description" (:description property_data))
                   (detail-section "Project Summary" (:project_summary property_data))
                   (detail-section "Project Team" (:project_team property_data))
                   (detail-section "Design Strategy" (:design_strategy property_data))
-                  (detail-section "Energy Strategy" (:energy_strategy property_data))]
-                 [:div.col-md-12
-                  (om/build sensors-div data)]]
+                  (detail-section "Energy Strategy" (:energy_strategy property_data))
+                  (detail-section "Monitoring Policy" (:monitoring_policy property_data))
+                  (detail-section "Other Notes" (:other_notes property_data))]
+                 (om/build sensors-div data)]
                 )])))))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


No data label when choosing sensors.

No data label when choosing sensors.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -525,7 +525,7 @@
              (bs/panel "Average (mean)" (str (.toFixed (js/Number. series-1-mean) 3) " " unit))]
             [:div {:class "col-md-3"}
              (bs/panel "Range" (str (.toFixed (js/Number. (- series-1-max series-1-min)) 3) " " unit))]]
-           [:div.row#summary-stats [:div.col-md-12]]))))))
+           [:div.row#summary-stats [:div.col-md-12.text-center [:p.lead {:style {:padding-top 30}} "No data."]]]))))))

 (defn sensors-div [data owner]
   (reify


Additional unit test.

Additional unit test.

--- test/exploud/info_test.clj
+++ test/exploud/info_test.clj
@@ -79,3 +79,8 @@
        (asgard/launch-config-list anything) => configs-list
        (asgard/launch-config anything "wibble-poke-v004-20131101110801") => active-launch-config
        (asgard/launch-config anything "wibble-poke-v003-20131030110801") => inactive-launch-config))
+
+(fact "that no active ami is found for non-existent application."
+      (active-amis-for-app anything "waffle") => '()
+      (provided
+       (asgard/launch-config-list anything) => configs-list))


CMR-5973: Added release version to CMR search api and site pages.

--- search-app/src/cmr/search/site/static.clj
+++ search-app/src/cmr/search/site/static.clj
@@ -4,6 +4,7 @@
   (:require
    [cheshire.core :as json]
    [clj-http.client :as client]
+   [cmr.common-app.config :as common-config]
    [cmr.common-app.static :as static]
    [cmr.common.log :refer :all]
    [cmr.search.site.data :as data]
@@ -32,6 +33,7 @@
                            :execution-context :cli})
           {:site-title "CMR Search"
            :page-title "API Documentation"
+           :release-version (str "v " (common-config/release-version))
            :page-content (static/md-file->html "docs/api.md")})))

 (defn- generate-site-docs
@@ -44,6 +46,7 @@
                            :execution-context :cli})
           {:site-title "CMR Search"
            :page-title "Site Routes & Web Resource Documentation"
+           :release-version (str "v " (common-config/release-version))
            :page-content (static/md-file->html "docs/site.md")})))

 (defn- generate-site-resources


Allow messages to be received using get method.

--- src/clojure/catacumba/handlers/postal.clj
+++ src/clojure/catacumba/handlers/postal.clj
@@ -26,10 +26,9 @@
   "A postal protocol implementation on top of http."
   (:require [catacumba.serializers :as sz]
             [catacumba.http :as http]
+            [buddy.core.codecs :as codecs]
             [manifold.deferred :as md]
-            [promissum.core :as p]
-            [cats.core :as m]
-            [cats.monad.exception :as exc])
+            [promissum.core :as p])
   (:import ratpack.http.TypedData
            java.util.concurrent.CompletableFuture))

@@ -53,17 +52,14 @@
   [data _]
   (sz/encode data :transit+json))

-(defmethod decode :default
-  [_ _]
-  nil)
-
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Implementation
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 (defn- get-content-type
-  [^TypedData body]
-  (let [^String content-type (.. body getContentType getType)]
+  [context]
+  (let [^TypedData body (:body context)
+        ^String content-type (.. body getContentType getType)]
     (when content-type
       (keyword (.toLowerCase content-type)))))

@@ -147,6 +143,13 @@
           (encode content-type)
           (frame->http content-type)))))

+(defn- get-incoming-data
+  [context]
+  (if (= (:method context) :get)
+    (let [data (get-in context [:query-params :d] nil)]
+      (codecs/safebase64->bytes data))
+    (.getBytes ^TypedData (:body context))))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Public Api
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -165,10 +168,10 @@
    (router handler {}))
   ([handler options]
    (fn [context]
-     (let [body (:body context)
-           data (.getBytes ^TypedData (:body context))
-           content-type (get-content-type body)
-           frame (exc/try-on (decode data content-type))]
-       (if (and (exc/success? frame) (not (nil? @frame)))
-         (dispatch handler context content-type @frame)
-         (http/unsupported-mediatype (str (m/extract frame))))))))
+     (try
+       (let [content-type (get-content-type context)
+             data (get-incoming-data context)
+             frame (decode data content-type)]
+         (dispatch handler context content-type frame))
+       (catch Exception e
+         (http/unsupported-mediatype (str e)))))))


CMR-778: Fixed misspelling of :spatial

CMR-778: Fixed misspelling of :spatial

--- src/cmr/indexer/data/concepts/granule.clj
+++ src/cmr/indexer/data/concepts/granule.clj
@@ -61,7 +61,7 @@
       (let [geometries (seq (get-in granule [:spatial-coverage :geometries]))]
         (spatial/spatial->elastic-docs gsr granule))

-      (= gsr :no-spatil)
+      (= gsr :no-spatial)
       nil

       (= gsr :orbit)


Removed old constant.

Removed old constant.


fix bugs

fix bugs

--- src/com/billpiel/sayid/string_output2.clj
+++ src/com/billpiel/sayid/string_output2.clj
@@ -71,13 +71,10 @@

 (defn get-line-length
   [line]
-  (def l' line)
   (->> line (map :length) (apply +)))

 (defn buffer-lines-to-width
   [width column]
-  (def w' width)
-  (def c' column)
   (map (fn [line]
          (let [buf-length (->> line (map :length) (apply +) (- width))]
            (if (> buf-length 0)
@@ -94,6 +91,7 @@
         max-height (->> lines
                         (map count)
                         (apply max))
+        lines' (map #(take max-height (concat % (repeat []))) lines)
         widths (map #(->> %
                           (map get-line-length)
                           (apply max)
@@ -104,7 +102,7 @@
                   indent
                   (conj (mapv buffer-lines-to-width
                               widths
-                              lines)
+                              lines')
                         (repeat [(tkn "\n")]))))))

 (defn multi-line-indent2
@@ -266,7 +264,6 @@

 (defn assoc-tokens-pos
   [tokens]
-  (def t' tokens)
   (loop [[{:keys [length line-break line-meta?] :as head} & tail] tokens
          line-meta nil
          pos 0
@@ -298,25 +295,42 @@
        (remove #(-> % second nil?))
        (into {})))

+(defn apply-type-colors-to-token
+  [token]
+  (let [type->color {:int :cyan
+                     :string :magenta
+                     :keyword :yellow
+                     :symbol :cyan
+                     :truncator :black}
+        type->bg-color {:truncator :white}]
+    (merge token
+           (when-let [color (type->color (:type token))]
+             {:fg-color color})
+           (when-let [color (type->bg-color (:type token))]
+             {:bg-color color}))))
+
 (defn mk-text-props
   [{:keys [start end] :as token}]
-  [start end (remove-nil-vals (dissoc token
-                                      :coll?
-                                      :column
-                                      :end
-                                      :end-col
-                                      :end-column
-                                      :end-line
-                                      :length
-                                      :line
-                                      :line-meta?
-                                      :line-break
-                                      :start
-                                      :start-col
-                                      :start-column
-                                      :start-line
-                                      :string
-                                      :zipper))])
+  (util/$- -> token
+           (dissoc :coll?
+                   :column
+                   :end
+                   :end-col
+                   :end-column
+                   :end-line
+                   :length
+                   :line
+                   :line-meta?
+                   :line-break
+                   :start
+                   :start-col
+                   :start-column
+                   :start-line
+                   :string
+                   :zipper)
+           remove-nil-vals
+           apply-type-colors-to-token
+           [start end $]))

 (defn split-text-tag-coll
   [tokens]


Throw if the cluster host is nil

Throw if the cluster host is nil

This allows the test to fail-fast, instead of a more obscure error
later.

--- integration-tests/test-clustering/integs/cluster_test.clj
+++ integration-tests/test-clustering/integs/cluster_test.clj
@@ -71,6 +71,8 @@
                   60000 nil))
         host2 (-> #{"server-one" "server-two"} (disj host1) first)
         response (fn [s] (get-as-data "/cache" s))]
+    (when-not host1
+      (throw (IllegalStateException. "host1 is nil!")))
     (mark (swap! responses conj (response host1)))
     (stop host1)
     (mark (swap! responses conj (response host2)))


uglified smart_csps for hopefully significant speed improvements

--- src/edu/berkeley/ai/search/smart_csps.clj
+++ src/edu/berkeley/ai/search/smart_csps.clj
@@ -1,6 +1,6 @@
 (ns edu.berkeley.ai.search.smart-csps
  (:refer-clojure)
- (:import [java.util HashMap])
+ (:import [java.util HashMap Map ArrayList])
  (:require [edu.berkeley.ai.util :as util]
 	   [edu.berkeley.ai.util.propositions :as props]
 	   )
@@ -23,23 +23,42 @@

 ; Returns new-domain
 ; TODO: change to use keyset
-(defn filter-pos-domain [map pred domain]
-  (util/intersection-coll domain (keys (get map pred {}))))
+(defn filter-pos-domain [#^HashMap map pred domain]
+;  (println "fpd" map pred domain)
+  (util/intersection-coll domain (if-let [#^Map m (first (.get map pred))] (.keySet m) nil)))

 ;; TODO: make smarter?
 (defn filter-neg-domain [map pred domain]
 ;  (println map pred domain)
-   (reduce (fn [domain val] (if (true? (get (get map pred) val)) (disj domain val) domain)) domain domain))
+  (let [sub (first (get map pred))]
+    (reduce (fn [domain val] (if (true? (get sub val)) (disj domain val) domain)) domain domain)))
 ;  (util/difference domain (util/keyset (get map pred {}))))

-(defn simplify-map [map preds val]
-  (reduce (fn [map pred] (assoc map pred (get (get map pred) val)))
-	  map preds))
-
-
-(defn- all-solutions [vars-left initial-domains var-map const-map clause-maps inst-map]
+;(defn simplify-map [#^HashMap map preds val]
+;  (if (empty? preds) map
+;    (let [#^HashMap m (.clone map)]
+;      (doseq [pred preds]
+;        (.put m pred (get (.get m pred) val)))
+;      m)))
+
+(defn simplify-map [#^HashMap map preds val]
+;  (println "simpl" map preds val)
+  (doseq [pred preds]
+    (let [sub (.get map pred)
+	  fs (first sub)]
+      (.put map pred (cons (get fs val) sub)))))
+
+
+(defn unsimplify-map [#^HashMap map preds val]
+  (doseq [pred preds]
+    (.put map pred (rest (.get map pred)))))
+;  (reduce (fn [map pred] (assoc map pred (get (get map pred) val)))
+;	  map preds))
+
+
+(defn- all-solutions [vars-left initial-domains var-map const-map clause-maps inst-map #^ArrayList results]
 ;  (println vars-left initial-domains var-map const-map clause-maps inst-map "\n\n")
-  (if (empty? vars-left) [inst-map]
+  (if (empty? vars-left) (.add results inst-map);[inst-map]
     (let [[var arg?]    (first vars-left)
 	  [pos-const neg-const pos-fluent neg-fluent] (util/safe-get var-map var)
 	  const-domain
@@ -57,22 +76,40 @@
 	                const-domain
 	              pos-fluent)
 	          neg-fluent)])
-	     clause-maps)]
+	     clause-maps)
+	  all-const (concat pos-const neg-const)
+	  all-fluent (concat pos-fluent neg-fluent)
+	    ]
 ;      (println clause-domains "\n\n\n\n")
-      (util/forcat [val (apply util/union (map second clause-domains))]
-	(all-solutions
-	 (rest vars-left)
-	 initial-domains
-	 var-map
-	 (simplify-map const-map (concat pos-const neg-const) val)
-	 (map #(simplify-map % (concat pos-fluent neg-fluent) val) (map first (filter #((second %) val) clause-domains)))
-	 (if arg? inst-map (assoc inst-map var val)))))))
+;      (doall (util/forcat [val (apply util/union (map second clause-domains))]
+      (doseq [val (apply util/union (map second clause-domains))]
+	(let [rel-clause-maps (map first (filter #((second %) val) clause-domains))]
+	  (when (rest vars-left)
+	    (simplify-map const-map all-const val)
+	    (doseq [c rel-clause-maps] (simplify-map c all-fluent val)))
+;	  (let [ret
+		(all-solutions
+		 (rest vars-left)
+		 initial-domains
+		 var-map
+		 const-map
+		 rel-clause-maps
+		 (if arg? inst-map (assoc inst-map var val)) results);]
+	    (when (rest vars-left)
+	      (unsimplify-map const-map all-const val)
+	      (doseq [c rel-clause-maps] (unsimplify-map c all-fluent val)))
+	   ; ret
+	    )))))
+;	 (simplify-map const-map (concat pos-const neg-const) val)
+;	 (map #(simplify-map % (concat pos-fluent neg-fluent) val) (map first (filter #((second %) val) clause-domains)))
+;	 (if arg? inst-map (assoc inst-map var val)))))))

 (defstruct smart-csp :ordered-vars :unk-domains :var-pred-map :const-map :fluent-map-maker :unary-var :unary-val)

 (defn get-smart-csp-solutions [csp var-values allowed-pred-inst-maps]
+  (let [r (ArrayList.)]
   (all-solutions
    (util/safe-get csp :ordered-vars)
    (assoc
@@ -81,7 +118,8 @@
    (util/safe-get csp :var-pred-map)
    (util/safe-get csp :const-map)
    (map (util/safe-get csp :fluent-map-maker) allowed-pred-inst-maps)
-   {}))
+   {} r)
+  (seq r)))

@@ -163,11 +201,29 @@

 ;;; Making final maps.  TODO: precompile?
-(defn make-permuter [args var-ordering]
-  (let [arg-positions (map vector (iterate inc 1) (map #(util/position % var-ordering) args))
-	arg-permutation (map first (sort-by second arg-positions))]
-    (fn permute [#^clojure.lang.APersistentVector tuple]
-      (map (fn [ind] (.get tuple ind)) arg-permutation))))
+;(defn make-permuter [args var-ordering]
+;  (let [arg-positions (map vector (iterate inc 1) (map #(util/position % var-ordering) args))
+;	arg-permutation (map first (sort-by second arg-positions))]
+;    (fn permute [#^clojure.lang.APersistentVector tuple]
+;      (util/vec-map (fn [ind] (.get tuple ind)) arg-permutation))))
+
+(defn get-permutation [args var-ordering]
+  (let [arg-positions (map vector (iterate inc 1) (map #(util/position % var-ordering) args))]
+    (vec (map first (sort-by second arg-positions)))))
+
+
+; TODO: be smarter about map sizes?
+(defn my-assoc-in [#^HashMap m #^clojure.lang.APersistentVector key-vec #^clojure.lang.APersistentVector perm ind]
+;  (println m key-vec perm ind)
+  (if (< (inc ind) (count perm))
+      (let [key (.get key-vec (.get perm ind))
+	    #^HashMap m2
+             (or (.get m key)
+		 (let [#^HashMap m2 (HashMap.)]
+		   (.put m key m2)
+		   m2))]
+	(recur m2 key-vec perm (inc ind)))
+    (.put m (.get key-vec (.get perm ind)) true)))

 ;; TODO: filter based on domains?
@@ -180,12 +236,20 @@
 	    (when (or (seq (get true-tuple-map pred)) (seq (get poss-tuple-map pred))) {dummy-unary-val true}))
 	(fn value-map-maker-unary2 [true-tuple-map poss-tuple-map]
 	  (when (seq (get true-tuple-map pred)) {dummy-unary-val true})))
-    (let [permuter (make-permuter args var-ordering)]
+    (let [permutation (get-permutation args var-ordering)]
       (if pos?
   	  (fn value-map-maker1 [true-tuple-map poss-tuple-map]
-	    (reduce (fn [m t] (assoc-in m (permuter t) true)) {} (concat (get true-tuple-map pred) (get poss-tuple-map pred))))
+	    (let [#^HashMap m (HashMap.)]
+	      (doseq [tuple (concat (get true-tuple-map pred) (get poss-tuple-map pred))]
+		(my-assoc-in m tuple permutation 0))
+	      m))
+;	    (reduce (fn [m t] (assoc-in m (permuter t) true)) {} (concat (get true-tuple-map pred) (get poss-tuple-map pred))))
 	(fn value-map-maker2 [true-tuple-map poss-tuple-map]
-	  (reduce (fn [m t] (assoc-in m (permuter t) true)) {} (get true-tuple-map pred)))))))
+	  (let [#^HashMap m (HashMap.)]
+	      (doseq [tuple (get true-tuple-map pred)]
+		(my-assoc-in m tuple permutation 0))
+	      m))))))
+;	  (reduce (fn [m t] (assoc-in m (permuter t) true)) {} (get true-tuple-map pred)))))))

 (defn make-value-pred-map-maker
   [pos-pred-name-map neg-pred-name-map pred-instance-map var-ordering dummy-unary-var dummy-unary-val]
@@ -200,11 +264,18 @@
 	       pred
 	       (rest (util/safe-get pred-instance-map pred-gen))
 	       var-ordering
-	       dummy-unary-var dummy-unary-val)])]
+	       dummy-unary-var dummy-unary-val)])
+	sz (count map-makers)
+	bigsz (int (inc (* 1.12 sz)))]
     (fn pred-map-maker [[true-tuple-map poss-tuple-map]]
-      (util/map-map
-       (fn [[pn map-maker]] [pn (map-maker true-tuple-map poss-tuple-map)])
-       map-makers))))
+      (let [#^HashMap m (HashMap. bigsz 0.9)]
+	(doseq [[pn map-maker] map-makers]
+	  (.put m pn (list (map-maker true-tuple-map poss-tuple-map))))
+	m))))
+;      (HashMap.
+;      (util/map-map
+;       (fn [[pn map-maker]] [pn (map-maker true-tuple-map poss-tuple-map)])
+;       map-makers)))))


JC | Ensure indexes for each mongo collection

--- src/stonecutter/db/mongo.clj
+++ src/stonecutter/db/mongo.clj
@@ -71,18 +71,21 @@
     (log/debug "Connected to mongo.")
     db))

+(defn- create-mongo-store [db collection index]
+  (mc/ensure-index db collection {index 1} {:unique true})
+  (new-mongo-store db collection))
+
 (defn create-mongo-user-store [db]
-  (mc/ensure-index db user-collection {:login 1} {:unique true})
-  (new-mongo-store db user-collection))
+  (create-mongo-store db user-collection :login))

 (defn create-token-store [db]
-  (new-mongo-store db token-collection))
+  (create-mongo-store db token-collection :token))

 (defn create-auth-code-store [db]
-  (new-mongo-store db auth-code-collection))
+  (create-mongo-store db auth-code-collection :code))

 (defn create-client-store [db]
-  (new-mongo-store db client-collection))
+  (create-mongo-store db client-collection :client-id))

 (defn create-confirmation-store [db]
-  (new-mongo-store db confirmation-collection))
+  (create-mongo-store db confirmation-collection :confirmation-id))


change version to snapshot

change version to snapshot

--- kafka-clj/project.clj
+++ kafka-clj/project.clj
@@ -1,4 +1,4 @@
-(defproject kafka-clj "3.6.6"
+(defproject kafka-clj "3.6.6-SNAPSHOT"
   :description "fast kafka library implemented in clojure"
   :url "https://github.com/gerritjvv/kafka-fast"
   :license {:name "Eclipse Public License"


0 is a valid hour.

0 is a valid hour.

--- src/metabase/task/send_pulses.clj
+++ src/metabase/task/send_pulses.clj
@@ -153,7 +153,7 @@
    that are scheduled to run and send them."
   [hour weekday monthday monthweek]
   {:pre [(integer? hour)
-         (and (< 0 hour) (> 23 hour))
+         (and (<= 0 hour) (> 23 hour))
          (pulse-channel/day-of-week? weekday)
          (contains? #{:first :last :mid :other} monthday)
          (contains? #{:first :last :other} monthweek)]}


show-wishlist cljs

show-wishlist cljs

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -28,4 +28,9 @@
 (defpartial wishlist-title [title]
   [:input {:type "text" :class "title" :value title}])

+(defn show-wishlist [{:keys [wishes title] :as wishlist}]
+  (empty $content)
+  (empty $header)
+  (append $content (wish-ul wishes))
+  (append $header (wishlist-title title)))


more efficient update-wishlist

more efficient update-wishlist

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -85,10 +85,10 @@
   (letrem [neu (create-wishlist {:title "Default"})]
     (show-wishlist! neu)))

-(defn update-wishlist-rem []
-  (let [wishlist (wishlist-from-html)]
+(defn update-wishlist-title-rem []
+  (let [wishlist {:code (get-path) :title (title-from-html)}]
     (letrem [neu (update-wishlist wishlist)]
-      (show-wishlist! neu))))
+      (fn [e] nil))))

 (defn read-wishlist-rem [code]
   (letrem [neu (read-wishlist code)]


(PDB-3560) Restore file-with-binary-template-test

The puppet issue appears to have been resolved.

--- test/puppetlabs/puppetdb/integration/file_with_binary_template.clj
+++ test/puppetlabs/puppetdb/integration/file_with_binary_template.clj
@@ -4,9 +4,6 @@
             [puppetlabs.trapperkeeper.app :as tk-app]
             [me.raynes.fs :as fs]))

-;; Commenting this whole test until puppet can at least support the workaround
-;; below
-(comment
 (deftest ^:integration file-with-binary-template
   (with-open [pg (int/setup-postgres)
               pdb (int/run-puppetdb pg {})
@@ -32,4 +29,4 @@
         (is (= {:certname "binary-file-agent"
                 :type "File"
                 :title file-resource-path}
-               (first (int/pql-query pdb "resources [certname, type, title] { tag = 'binary_file' }")))))))))
+               (first (int/pql-query pdb "resources [certname, type, title] { tag = 'binary_file' }"))))))))


Now the source code for clojurescript libraries will go to cljs-src

--- src/cljs/cljs_repl_web/replumb_proxy.cljs
+++ src/cljs/cljs_repl_web/replumb_proxy.cljs
@@ -5,7 +5,7 @@

 (def repl-options
   "Static set of options for replumb.core/read-eval-call"
-  (merge (replumb/browser-options [(str io/base-path "/js/compiled/out/min")]
+  (merge (replumb/browser-options [(str io/base-path "/cljs-src")]
                                   io/fetch-file!)
          {:warning-as-error true
           :verbose false}))


(maint) Fix typo

(maint) Fix typo

--- src/clojure/puppetlabs/ssl_utils/core.clj
+++ src/clojure/puppetlabs/ssl_utils/core.clj
@@ -119,7 +119,7 @@
   (schema/cond-pre PublicKey PrivateKey))

 (def ExtensionContainer
-  "A schema for all the things that can hold and SSL extension."
+  "A schema for all the things that can hold an SSL extension."
   (schema/cond-pre
    X509Certificate
    PKCS10CertificationRequest


Some experiments with sorted keys

Some experiments with sorted keys

does not work very well.

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

--- src/conexp/contrib/algorithms/titanic.clj
+++ src/conexp/contrib/algorithms/titanic.clj
@@ -34,26 +34,27 @@
 (defn- subset-weight
   "Returns the minimum of the weights of all proper subsets of X."
   [max-weight X]
-  (minimum (conj (map #(set-weight (disj X %)) X)
+  (minimum (conj (map #(get set-weight (disj X %)) X)
                  max-weight)))

 (defn- titanic-closure
   "Computes the closure of X by the weights of its subsets."
+  ;; keys sorted by their weights (ascending)
+  ;; X is a key set
   [X base-set keys candidates]
   (loop [Y (apply union X (map #(closure (disj X %)) X)),
          elements (difference base-set Y)]
     (if-not (empty? elements)
-      (let [m   (first elements),
-            X+m (conj X m),
-            s   (or (set-weight X+m)
-                    (let [weight (minimum (doall (for [K keys, ;bottleneck!
-                                                       :when (subset? K X+m)]
-                                                   (set-weight K))))]
-                      (set-val! set-weight X+m weight)
-                      weight))]
-        (recur (if (= s (set-weight X))
-                 (conj Y m)
-                 Y)
+      (let [m        (first elements),
+            X-weight (set-weight X)
+            add?     (if-let [s (set-weight (conj X m))]
+                       (= s X-weight)
+                       (not (first (for [K keys,
+                                         :while (not= (get set-weight K) X-weight)
+                                         :when (and (contains? K m)
+                                                    (subset? (disj K m) X))]
+                                     K))))]
+        (recur (if add? (conj Y m) Y)
                (rest elements)))
       Y)))

@@ -88,11 +89,14 @@
         (set-val! closure X (titanic-closure X base-set keys candidates)))
       (let [next-key-set (set-of X [X candidates,
                                     :when (not= (subset-weight X)
-                                                (set-weight X))])]
+                                                (get set-weight X))])]
         (if-not (empty? next-key-set)
           (recur next-key-set
                  (titanic-generate next-key-set)
-                 (concat keys next-key-set))
+                 (sort (fn [a b]
+                         (= (get set-weight a)
+                            (weight-minimum [(get set-weight a) (get set-weight b)])))
+                       (concat next-key-set keys)))
           (distinct (map closure keys)))))))

 ;;;


don't throw away namespace segment on syntax-quoted ctor, cljs might need it

--- src/main/clojure/clojure/tools/reader.clj
+++ src/main/clojure/clojure/tools/reader.clj
@@ -700,7 +700,7 @@

                (.endsWith sym ".")
                (let [csym (symbol (subs sym 0 (dec (count sym))))]
-                 (symbol (.concat (name (resolve-symbol csym)) ".")))
+                 (symbol (str (resolve-symbol csym) ".")))
                :else (resolve-symbol form)))))

     (unquote? form) (second form)


[#40] Add regression test for date response parsing

--- api/test/clojure/org/akvo/flow_api/datastore/form_instance_test.clj
+++ api/test/clojure/org/akvo/flow_api/datastore/form_instance_test.clj
@@ -42,3 +42,10 @@
           (is (= 150 (count (:form-instances page-1))))
           (is (= 17 (count (:form-instances page-2))))
           (is (empty? (:form-instances page-3))))))))
+
+(deftest response-parsing
+  (testing "date question type"
+    (is (= (form-instance/parse-response "DATE" "1493039527580")
+           "2017-04-24T13:12:07.580Z"))
+    (is (= (form-instance/parse-response "DATE" "29-08-2013 02:00:00 CEST")
+           "2013-08-29T00:00:00Z"))))


desktop: Add aspect area for croppper

desktop: Add aspect area for croppper

--- apps/desktop/src_front/souptitle_desktop/manager/views/content.cljs
+++ apps/desktop/src_front/souptitle_desktop/manager/views/content.cljs
@@ -50,7 +50,8 @@
       {:space 80}
       [cropper {:src (:url cover)
                 :on-crop #(dispatch [:update-serial-crop-data %])
-                :crop-props {:data (clj->js (:crop-data cover))}}]]
+                :crop-props {:data (clj->js (:crop-data cover))
+                             :aspectRatio 1.9}}]]
      [serial-dropzone])])

 (defmethod content :season [{{:keys [title]} :meta}]


Remove dead code

Remove dead code

--- src/clj_chrome_devtools/cljs/test.clj
+++ src/clj_chrome_devtools/cljs/test.clj
@@ -87,7 +87,6 @@
   (let [file (io/file "." (subs uri 1))]
     (if (and (= request-method :get) (.canRead file))
       (do
-        #_(println "GET " (.getName file))
         {:status 200
          :headers {"Content-Type" (cond
                                     (str/ends-with? uri ".html")


Disable parinfer by default.

Disable parinfer by default.

--- src/cljs/editor/quil_site/editor.cljs
+++ src/cljs/editor/quil_site/editor.cljs
@@ -263,9 +263,8 @@
              :autoCloseBrackets true
              :extraKeys #js {"Ctrl-Enter" compile-selected}}))

-   (.init
-    js/parinferCodeMirror
-    @editor)
+   (.init js/parinferCodeMirror @editor)
+   (.disable js/parinferCodeMirror @editor)

   (let [id (j/data (j/$ "#source") "sketch-id")
         local (j/data (j/$ "#source") "is-local")]


Change if to when

Change if to when

--- src-cljs/frontend/components/builds_table.cljs
+++ src-cljs/frontend/components/builds_table.cljs
@@ -174,7 +174,7 @@
                    urls))]])

         [:div.metadata-item.revision
-         (if (:vcs_revision build)
+         (when (:vcs_revision build)
            (list (dashboard-icon "Builds-CommitNumber")
                  [:a {:title (build-model/github-revision build)
                       :href (build-model/github-commit-url build)}


simplify

simplify

--- src/cljs/just_married/home/views.cljs
+++ src/cljs/just_married/home/views.cljs
@@ -119,12 +119,7 @@
   []
   ;;TODO: there could be a better way to do this
   (into [:g]
-        (concat
-         [[navbar]]
-         ;; too much vector stuff here
-         (vector
-          (into [:div.container]
-                (map vector (vals SECTIONS)))))))
-
-
-(main-panel)
+        (cons
+         [navbar]
+         (vector (into [:div.container]
+                       (map vector (vals SECTIONS)))))))


Create empty-stream message

Create empty-stream message

--- src/cljs/salava/social/ui/stream.cljs
+++ src/cljs/salava/social/ui/stream.cljs
@@ -234,6 +234,15 @@
            (tip-event (not-verified-email (:email email)) state)
            ))])

+(defn empty-stream []
+  [:div
+   [:h2 "Well, you have cleaned the table!"]
+   [:div "Some tips:"]
+   [:ul
+    [:li "Create some cool pages and show how good you are! " [:a {:href (path-for "/page") } "My pages" ]]
+    [:li "Did you get some awesome badge and want to tell everybody how cool and fancy it is? You should rank it and comment to badge. " [:a {:href (path-for "/badges") } "My badges" ]]
+    [:li "Hahhaaa, Did you thought you was one of a kind? Well there is many other almost as cool as you are! " [:a {:href (path-for "/gallery/profiles") } "Profiles" ]]]])
+
 (defn content [state]
   (let [events (:events @state)
         tips (:tips @state)]
@@ -241,17 +250,27 @@
      [m/modal-window]
      [badges-pending state]
      (tips-container tips state)
+     (dump events)
+     (dump tips)
+     (if (and (empty? events) (not (:profile-picture-tip tips)) (not (:welcome-tip tips)) (empty? (:not-verified-emails tips)))
+       (empty-stream))
      (into [:div {:class "row"}]
            (for [event events]
              (cond
                (= "follow" (:verb event)) (follow-event event state)
                (= "message" (:verb event)) (message-event event state)
-               :else "")))]))
+               :else "")))
+
+     ]))

 (defn handler [site-navi]
-  (let [state (atom {:events []})]
+  (let [state (atom {:events []
+                     :tips {:profile-picture-tip false
+                            :welcome-tip false
+                            :not-verified-emails []}
+                     })]
     (init-data state)
     (fn []
       (layout/default site-navi (content state)))))


Fix concurrent update bug in Postgres

Fix concurrent update bug in Postgres

Sometimes Postgres was updated conceurrently. Fixed it by only making
certain tables once

--- src/webapp/framework/server/systemfns.clj
+++ src/webapp/framework/server/systemfns.clj
@@ -638,6 +638,9 @@
 (make-admin-table )
 (make-log-table   )

+(make-log-table-insert-trigger-function)
+(make-log-table-update-trigger-function)
+(make-log-table-delete-trigger-function)

@@ -650,9 +653,6 @@
 (defn do-real [& {:keys [:table-name]}]
   ;(println "table name: " table-name)

-  ( make-log-table-insert-trigger-function)
-  ( make-log-table-update-trigger-function)
-  ( make-log-table-delete-trigger-function)
   (create-realtime-trigger  :table-name  table-name))

@@ -855,10 +855,10 @@
                (do
                  (if (= (get query :db-table) (get realtime-log-entry :record_table_name))
                    (do
-                     ;(println (str "    "))
-                     ;(println (str "    " "Query"))
-                     ;(println (str "    " query))
-                     ;(println (str "    "))
+                     (println (str "    "))
+                     (println (str "    " "Query"))
+                     (println (str "    " query))
+                     (println (str "    "))

                      ;(println (str "    " "Before"))
                      ;(println (str "    " @(get @server-side-cached-queries query)))


Added compression option to build-cluster

--- src/clojure/clojurewerkz/cassaforte/client.clj
+++ src/clojure/clojurewerkz/cassaforte/client.clj
@@ -21,14 +21,14 @@
             [qbits.hayt.cql :as hayt])
   (:import [com.datastax.driver.core Statement ResultSet ResultSetFuture Host Session Cluster
             Cluster$Builder SimpleStatement PreparedStatement HostDistance PoolingOptions
-            SSLOptions]
+            SSLOptions ProtocolOptions$Compression]
            [com.datastax.driver.auth DseAuthProvider]
            [com.google.common.util.concurrent Futures FutureCallback]
            java.net.URI
            [javax.net.ssl TrustManagerFactory KeyManagerFactory SSLContext]
            [java.security KeyStore SecureRandom]))

-(declare build-ssl-options)
+(declare build-ssl-options select-compression)

 (defprotocol DummySession
   (executeAsync [_ query]))
@@ -66,7 +66,8 @@
            ssl
            ssl-options
            kerberos
-           protocol-version]}]
+           protocol-version
+           compression]}]
   (when force-prepared-queries
     (alter-var-root (var hayt/*prepared-statement*)
                     (constantly true)))
@@ -96,6 +97,8 @@
       (.withReconnectionPolicy builder reconnection-policy))
     (when load-balancing-policy
       (.withLoadBalancingPolicy builder load-balancing-policy))
+    (when compression
+      (.withCompression (select-compression compression)))
     (when ssl
       (.withSSL builder (build-ssl-options ssl)))
     (when ssl-options
@@ -121,6 +124,13 @@
     (.init ssl-context (.getKeyManagers keymanager) (.getTrustManagers trustmanager) nil)
     (SSLOptions. ssl-context ssl-cipher-suites)))

+(defn- ^ProtocolOptions$Compression select-compression
+  [compression]
+  (case compression
+    :snappy ProtocolOptions$Compression/SNAPPY
+    :lz4 ProtocolOptions$Compression/LZ4
+    ProtocolOptions$Compression/NONE))
+
 (defn ^Session connect
   "Connects to the Cassandra cluster. Use `build-cluster` to build a cluster."
   ([hosts]


fix garden compile

fix garden compile

--- src/leiningen/new/reagent_liveedit/project.clj
+++ src/leiningen/new/reagent_liveedit/project.clj
@@ -75,7 +75,7 @@
                         "cljsbuild" "once" "app"]
             "live"     ["pdo" "css," "minify," "fig," "server"]
             "once"     ["do" "cljsbuild" "once" "app,"
-                        "garden" "once" "dev,"
+                        "garden" "once,"
                         "minify-assets" "dev"]
             "dev"      ["do" "once," "live"]}


fix TCLI-94: use *print-err-fn* in tests

Signed-off-by: Sean Corfield <d7e19930cc1f42c2d0781f4d9e6f1fe5891bf9cf@corfield.org>

--- src/test/clojure/clojure/tools/cli_test.cljc
+++ src/test/clojure/clojure/tools/cli_test.cljc
@@ -97,12 +97,16 @@
     (when *assert*
       (is (re-find #"Warning:.* :flag"
                    (with-out-str
-                     (binding [*err* *out*]
-                       (compile-option-specs [[nil "--alpha" :validate nil :flag true]])))))
+                     #?(:clj (binding [*err* *out*]
+                               (compile-option-specs [[nil "--alpha" :validate nil :flag true]]))
+                        :cljs (binding [*print-err-fn* *print-fn*]
+                                (compile-option-specs [[nil "--alpha" :validate nil :flag true]]))))))
       (is (re-find #"Warning:.* :validate"
                    (with-out-str
-                     (binding [*err* *out*]
-                       (compile-option-specs [{:id :alpha :validate nil}]))))))))
+                     #?(:clj (binding [*err* *out*]
+                               (compile-option-specs [{:id :alpha :validate nil}]))
+                        :cljs (binding [*print-err-fn* *print-fn*]
+                                (compile-option-specs [{:id :alpha :validate nil}])))))))))

 (defn has-error? [re coll]
   (seq (filter (partial re-seq re) coll)))


Do not re-define Throwable, refer to it.

--- test/cljx/active/clojure/condition_test.cljx
+++ test/cljx/active/clojure/condition_test.cljx
@@ -1,5 +1,6 @@
 (ns active.clojure.condition-test
-  (:require [active.clojure.condition :refer (&condition combine-conditions #+clj define-condition-type #+clj guard)]
+  (:require [active.clojure.condition :refer (&condition combine-conditions #+clj define-condition-type #+clj guard
+                                              #+cljs Throwable)]
             [active.clojure.condition :as c]
             #+clj [clojure.test :refer :all]
             #+cljs [cemerick.cljs.test])
@@ -84,9 +85,6 @@
   (is (= "b2"
          (c2-b v5))))

-#+cljs
-(def Throwable js/Object)
-
 (deftest condition-types
   (map
    #(let [e ((first %1))]


better order of self discovering routes

better order of self discovering routes

--- src/restaurant_inspections_api/routes.clj
+++ src/restaurant_inspections_api/routes.clj
@@ -19,7 +19,7 @@
      :available-media-types ["application/json"]
      :handle-ok (fn [ctx] {:api-name "FRIA: Florida's Restaurant Inspections API"
                            :description "Florida's Restaurant inspections are available in csv files. Also available on an old http form on their website."
-                           :routes ["/" "/counties" "/wiki" "/inspections" "/inspections/:id"
+                           :routes ["/" "/wiki" "/counties" "/inspections" "/inspections/:id"
                                     "/businesses" "/violations"]})))

   (GET "/wiki" []


Revert no-doc on s function

Revert no-doc on s function

--- src/rdf-common/grafter/rdf/io.clj
+++ src/rdf-common/grafter/rdf/io.clj
@@ -42,7 +42,7 @@
   (->sesame-rdf-type [this] "Convert a native type into a Sesame RDF Type")
   (sesame-rdf-type->type [this] "Convert a Sesame RDF Type into a Native Type"))

-(defn ^:no-doc s
+(defn s
   "Cast a string to an RDF literal.  The second optional argument can
   either be a keyword corresponding to an RDF language tag
   e.g. :en, :en-gb, or :fr or a string or URI in which case it is


Update clj-http "3.10.0"

Update clj-http "3.10.0"

--- backend/project.clj
+++ backend/project.clj
@@ -11,7 +11,7 @@
                  [org.slf4j/jcl-over-slf4j "1.7.26" :exclusions [org.slf4j/slf4j-api]]
                  [org.slf4j/jul-to-slf4j "1.7.26" :exclusions [org.slf4j/slf4j-api]]
                  [cheshire "5.8.0" :exclusions [com.fasterxml.jackson.core/jackson-core]]
-                 [clj-http "3.9.0" :exclusions [org.apache.httpcomponents/httpcore org.apache.httpcomponents/httpclient org.apache.httpcomponents/httpmime]]
+                 [clj-http "3.10.0" :exclusions [org.apache.httpcomponents/httpcore org.apache.httpcomponents/httpclient org.apache.httpcomponents/httpmime]]
                  [clj-time "0.14.4"]
                  [com.layerware/hugsql "0.4.9"]
                  [commons-io/commons-io "2.6"]


(PDB-3374) Remove unneeded fixture from reports integration test

--- test/puppetlabs/puppetdb/integration/reports.clj
+++ test/puppetlabs/puppetdb/integration/reports.clj
@@ -186,8 +186,7 @@
       (Thread/sleep 1000))

     (let [initial-gc-count (counters/value (:report-purges pdb-services/admin-metrics))]
-      (with-open [pdb (int/run-puppetdb pg {:database {:report-ttl "1s"}})
-                  ps (int/run-puppet-server [pdb] {})]
+      (with-open [pdb (int/run-puppetdb pg {:database {:report-ttl "1s"}})]
         (let [start-time (System/currentTimeMillis)]
           (loop []
             (cond


CMR-202: changed additional archive centers to keywords

--- src/cmr/umm/echo10/collection/org.clj
+++ src/cmr/umm/echo10/collection/org.clj
@@ -50,8 +50,8 @@
     [:ArchiveCenter])

   (xml-elem->Organizations (x/parse-str cmr.umm.test.echo10.collection/all-fields-collection-xml))
-  (let [orgs (vector (c/map->Organization {:type "archive-center" :org-name "ac se"})
-                     (c/map->Organization {:type "processing-center" :org-name "pro se"}))
+  (let [orgs (vector (c/map->Organization {:type :archive-center :org-name "ac se"})
+                     (c/map->Organization {:type :processing-center :org-name "pro se"}))
         arctr (generate-archive-center orgs)
         prctr (generate-processing-center orgs)]
     (vector arctr prctr))


added testcase for x-swagger1st-keywordize feature

--- test/io/sarnowski/swagger1st/parser_test.clj
+++ test/io/sarnowski/swagger1st/parser_test.clj
@@ -238,3 +238,16 @@
             :body    (json-body
                        {:bar "baz"})}
            {"name" "testmap"}))))
+
+(deftest extract-body-parameter-without-keywords
+  (is (= {"foo/bar" "baz"
+          "bar"     "baz"}
+         (p/extract-parameter-body
+           {:uri     "/foo"
+            :headers {"content-type" "application/json"}
+            :swagger {:request {"consumes" ["application/json"]}}
+            :body    (json-body
+                       {"foo/bar" "baz"
+                        :bar      "baz"})}
+           {"name"                    "testmap"
+            "x-swagger1st-keywordize" false}))))


rename macro to be clearer that output is to logs

--- storm-core/src/clj/backtype/storm/log.clj
+++ storm-core/src/clj/backtype/storm/log.clj
@@ -47,7 +47,7 @@
   [& args]
   (apply log/log-stream args))

-(defmacro pprint-message
+(defmacro log-pprint
   [& args]
   `(let [^StringWriter writer# (StringWriter.)]
      (doall


Update doc string for step-debugger

Update doc string for step-debugger

--- cmma-clj/src/cmma/dev.clj
+++ cmma-clj/src/cmma/dev.clj
@@ -162,6 +162,7 @@
   Other locals:
    * form - the whole form you're stepping through
    * current-form - the current form/token you're on
+   * step - what the current-step evals to
    * progress - an atom'd vector of all forms/tokens you've seen so far - CURRENTLY REMOVED
    * *locals* - a map of all locals in scope"
   (let [progress (atom [])]


(PDB-4637) Include user and username in all test configs

Set both the database user and username in all test configs so that
there can be no confusion (given our defaulting in config.clj and jdbc
make-connection-pool).  If nothing else, this avoids a problem in some
of our tests where the test was overrode the :user via a merge,
when the config already had a :username, and hilarity ensued.

In the longer run (perhaps next major release), we're planning to halt
with a config error if both user and username are set and differ.

--- test/puppetlabs/puppetdb/testutils/db.clj
+++ test/puppetlabs/puppetdb/testutils/db.clj
@@ -39,6 +39,7 @@
    :subprotocol "postgresql"
    :subname "//127.0.0.1:5432/foo"
    :user "puppetdb"
+   :username "puppetdb"
    :password "xyzzy"})

 (defn db-admin-config
@@ -48,6 +49,7 @@
      :subprotocol "postgresql"
      :subname (format "//%s:%s/%s" (:host test-env) (:port test-env) database)
      :user (get-in test-env [:admin :name])
+     :username (get-in test-env [:admin :name])
      :password (get-in test-env [:admin :password])}))

 (defn routine-db-config
@@ -58,6 +60,7 @@
    :subprotocol "postgresql"
    :subname (format "//%s:%s/%s" (:host test-env) (:port test-env) database)
    :user (get-in test-env [:user :name])
+   :username (get-in test-env [:user :name])
    :password (get-in test-env [:user :password])
    :migrator-username (get-in test-env [:migrator :name])
    :migrator-password (get-in test-env [:migrator :password])


support erndering refactor to context

support erndering refactor to context

--- src/untangled/support/viewer.cljs
+++ src/untangled/support/viewer.cljs
@@ -97,8 +97,8 @@

 (c/defscomponent HistoryPlayer
                  "A component to playback history"
-                 [viewer]
-                 (let [op (state/op-builder viewer)
+                 [viewer context]
+                 (let [op (state/op-builder context)
                        application (core/new-application (:renderer viewer) (current-app-state viewer) :view-only true)]
                    (c/div {:className "app"}
                           (core/Root (current-app-state viewer) application)


Disable thread-info fn.

Disable thread-info fn.

--- src/dsbdp/main.clj
+++ src/dsbdp/main.clj
@@ -139,7 +139,7 @@
       (.start in-loop)
       (run-repeat (executor) (fn []
                                (stats-fn)
-                               (thread-info-fn) (println)
+                               ;(thread-info-fn) (println)
                                )
                   1000)
       (run-once (executor) (fn [] (System/exit 0)) 120000))))


Fix service-name token value so that it contains a string

--- src/leiningen/new/cljskel/project.clj
+++ src/leiningen/new/cljskel/project.clj
@@ -36,9 +36,8 @@
             [lein-release "1.0.73"]]

   ;; development token values
-  :env {
-        :environment-name "Dev"
-        :service-name {{name}}
+  :env {:environment-name "Dev"
+        :service-name "{{name}}"
         :service-port "3000"
         :service-url "http://localhost:%s/1.x"
         :restdriver-port "8081"
@@ -47,8 +46,7 @@
         :service-graphite-post-interval "1"
         :service-graphite-post-unit "MINUTES"
         :service-graphite-enabled "ENABLED"
-        :service-production "false"
-        }
+        :service-production "false"}

   :lein-release {:release-tasks [:clean :uberjar :pom :rpm]
                  :clojars-url "clojars@clojars.brislabs.com:"}


Ensure that source, resource, and asset paths don't overlap (fixes #235)

--- boot/core/src/boot/core.clj
+++ boot/core/src/boot/core.clj
@@ -615,11 +615,22 @@
 (defn- assert-set       [k new] (assert (set? new) (format "env %s must be a set" k)))
 (defn- canonical-repo   [repo]  (if (map? repo) repo {:url repo}))

+(defn- assert-disjoint
+  [env key new]
+  (util/with-let [_ new]
+    (let [paths   (set (->> (assoc env key new)
+                            ((juxt :source-paths :resource-paths :asset-paths))
+                            (reduce into #{})
+                            (keep #(some-> % io/file .getCanonicalFile))))
+          parents (set (mapcat (comp rest file/parent-seq) paths))]
+      (assert (empty? (set/intersection paths parents))
+              "The :source-paths, :resource-paths, and :asset-paths must not overlap."))))
+
 (defmethod pre-env! ::default       [key old new env] new)
 (defmethod pre-env! :directories    [key old new env] (set/union old new))
-(defmethod pre-env! :source-paths   [key old new env] (assert-set key new) new)
-(defmethod pre-env! :resource-paths [key old new env] (assert-set key new) new)
-(defmethod pre-env! :asset-paths    [key old new env] (assert-set key new) new)
+(defmethod pre-env! :source-paths   [key old new env] (assert-set key new) (assert-disjoint env key new))
+(defmethod pre-env! :resource-paths [key old new env] (assert-set key new) (assert-disjoint env key new))
+(defmethod pre-env! :asset-paths    [key old new env] (assert-set key new) (assert-disjoint env key new))
 (defmethod pre-env! :wagons         [key old new env] (add-wagon! old new env))
 (defmethod pre-env! :dependencies   [key old new env] (add-dependencies! old new env))
 (defmethod pre-env! :repositories   [key old new env] (->> new (mapv (fn [[k v]] [k (@repo-config-fn (canonical-repo v))]))))


Switch to react with addons

Switch to react with addons

--- src/gol/server.clj
+++ src/gol/server.clj
@@ -18,7 +18,7 @@
     [:body
      [:div#app]
      (include-js
-       "//fb.me/react-0.9.0.min.js"
+       "//fb.me/react-with-addons-0.9.0.min.js"
        "/js/build/goog/base.js"
        "/js/build/gol.js")
      [:script


version bump

version bump

--- resources/project.clj
+++ resources/project.clj
@@ -5,7 +5,7 @@
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.7.0"]
                  [org.clojure/clojurescript "1.7.145"]
-                 [org.omcljs/om "1.0.0-alpha11"]
+                 [org.omcljs/om "1.0.0-alpha13"]
                  [org.omcljs/ambly "0.6.0"]]
 :plugins [[lein-cljsbuild "1.1.0"]]
 :cljsbuild {:builds {:dev {:source-paths ["src"]


Add lein-ancient

Add lein-ancient

--- dot/lein/profiles.clj
+++ dot/lein/profiles.clj
@@ -1,5 +1,6 @@
 {:user
  {:plugins [[lein-vanity "0.2.0"]
+            [lein-ancient "0.5.5"]
             [jonase/eastwood "0.1.4"]
             [cider/cider-nrepl "0.8.0-SNAPSHOT"]]
   :dependencies [[slamhound "1.5.0"]]


Version bump slamhound

Version bump slamhound

--- dot/lein/profiles.clj
+++ dot/lein/profiles.clj
@@ -3,5 +3,5 @@
             [lein-ancient "0.5.5"]
             [jonase/eastwood "0.1.4"]
             [cider/cider-nrepl "0.8.0-SNAPSHOT"]]
-  :dependencies [[slamhound "1.5.0"]]
+  :dependencies [[slamhound "1.5.5"]]
   :aliases {"slamhound" ["run" "-m" "slam.hound"]}}}


Show the wraparound where we move to strings with more than one character.

--- test/kolmogorov_music/test/kolmogorov.clj
+++ test/kolmogorov_music/test/kolmogorov.clj
@@ -73,5 +73,5 @@

 (fact "We can construct all strings as a lazy sequence."
   (->> (lexicon) (subsequence 0 5)) => ["" " " "!" "\"" "#"]
-  (->> (lexicon) (subsequence 96 101)) => ["  " " !" " \"" " #" " $"]
+  (->> (lexicon) (subsequence 95 100)) => ["~" "  " " !" " \"" " #"]
   (nth (lexicon) 364645) => "GEB")


(PDB-3114) Don't wait on the future forever

Limit concurrent-catalog-resource-updates' wait on the first command to
60 seconds.

--- test/puppetlabs/puppetdb/command_test.clj
+++ test/puppetlabs/puppetdb/command_test.clj
@@ -1272,10 +1272,9 @@
                         (.countDown latch)
                         (.await latch)
                         (apply orig-replace-catalog! args))]
-          (let [first-message? (atom false)
-                fut (future
+          (let [fut (future
                       (handle-message (store-command' q command))
-                      (reset! first-message? true))
+                      ::handled-first-message)

                 new-wire-catalog (update wire-catalog :resources
                                          conj
@@ -1294,15 +1293,12 @@

             (handle-message (store-command' q new-catalog-cmd))

-            @fut
-
+            (is (= ::handled-first-message (deref fut (* 1000 60) nil)))
             (is (empty? (fs/list-dir (:path dlo))))
             (let [failed-cmdref (take-with-timeout!! command-chan default-timeout-ms)]
               (is (= 1 (count (:attempts failed-cmdref))))
               (is (-> failed-cmdref :attempts first :exception
-                      pg-serialization-failure-ex?)))
-
-            (is (true? @first-message?))))))))
+                      pg-serialization-failure-ex?)))))))))

 (let [cases [{:certname "foo.example.com"
               :command {:command (command-names :deactivate-node)


Lazily load tools.deps.alpha

Lazily load tools.deps.alpha

This decreases dev REPL loading time by ~10%.  6.099 to 5.4s decrease on
my machine.

--- lib/edge.app.dev/src/dev_extras.clj
+++ lib/edge.app.dev/src/dev_extras.clj
@@ -8,8 +8,7 @@
    [edge.system.meta :as system.meta]
    [integrant.repl]
    [integrant.repl.state]
-   io.aviso.ansi
-   clojure.tools.deps.alpha.repl))
+   io.aviso.ansi))

 (when (try
         (Class/forName "org.slf4j.bridge.SLF4JBridgeHandler")
@@ -52,7 +51,9 @@
   ^{:doc "Suspend the system, reload all code, and start the system again"} reset-all
   ^{:doc "Like halt, but doesn't completely stop some components.  This makes the components faster to start again, but means they may not be completely stopped (e.g. A web server might still have the port in use)"} suspend)

-(proxy-ns clojure.tools.deps.alpha.repl add-lib)
+(defn add-lib
+  [& args]
+  (apply (requiring-resolve 'clojure.tools.deps.alpha.repl/add-lib) args))

 (defmacro ^:private watch-var
   [s alias]


Description -> Desc

Description -> Desc

--- src/lens/parse.clj
+++ src/lens/parse.clj
@@ -12,7 +12,7 @@
 (defn first-translated-text []
   (fn [loc] (xml1-> loc :TranslatedText text)))

-(defn description [loc]
+(defn desc [loc]
   (xml1-> loc :Description (first-translated-text)))

 (defn question [loc]
@@ -33,7 +33,7 @@
 (defn parse-study-event-def-head [study-event-def]
   (-> {:id (oid study-event-def)
        :name (xml1-> study-event-def (attr :Name))}
-      (assoc-when :description (description study-event-def))))
+      (assoc-when :desc (desc study-event-def))))

 (defn parse-study-event-def! [bus study-event-def]
   (publish!! bus :study-event-def (parse-study-event-def-head study-event-def))
@@ -55,7 +55,7 @@
 (defn parse-form-def-head [form-def]
   (-> {:id (oid form-def)
        :name (xml1-> form-def (attr :Name))}
-      (assoc-when :description (description form-def))))
+      (assoc-when :desc (desc form-def))))

 (defn parse-form-def! [bus form-def]
   (publish!! bus :form-def (parse-form-def-head form-def))
@@ -77,7 +77,7 @@
 (defn parse-item-group-def-head [item-group-def]
   (-> {:id (oid item-group-def)
        :name (xml1-> item-group-def (attr :Name))}
-      (assoc-when :description (description item-group-def))))
+      (assoc-when :desc (desc item-group-def))))

 (defn parse-item-group-def! [bus item-group-def]
   (publish!! bus :item-group-def (parse-item-group-def-head item-group-def))
@@ -94,7 +94,7 @@
   (-> {:id (oid item-def)
        :name (xml1-> item-def (attr :Name))
        :data-type (convert-data-type (xml1-> item-def (attr :DataType)))}
-      (assoc-when :description (description item-def))
+      (assoc-when :desc (desc item-def))
       (assoc-when :question (question item-def))))

 (defn parse-item-def! [bus item-def]
@@ -117,7 +117,7 @@
 (defn parse-study-head [study]
   {:id (oid study)
    :name (xml1-> study :GlobalVariables :StudyName text)
-   :description (xml1-> study :GlobalVariables :StudyDescription text)})
+   :desc (xml1-> study :GlobalVariables :StudyDescription text)})

 (defn parse-study! [bus study]
   (log/debug "Start parsing study" (oid study))
@@ -131,15 +131,14 @@
   "Parses an ODM XML file at input and publishes various events on bus.

   The events are:
-    :study           - a study with :id, :name and :description
-    :study-event-def - a study-event-def with :id, :name, optional :description
+    :study           - a study with :id, :name and :desc
+    :study-event-def - a study-event-def with :id, :name, optional :desc and
+                       :study-id
+    :form-def        - a form-def with :id, :name, optional :desc and :study-id
+    :item-group-def  - an item-group-def with :id, :name, optional :desc and
+                       :study-id
+    :item-def        - an item-def with :id, :name, :data-type, optional :desc
                        and :study-id
-    :form-def        - a form-def with :id, :name, optional :description and
-                       :study-id
-    :item-group-def  - an item-group-def with :id, :name, optional :description
-                       and :study-id
-    :item-def        - an item-def with :id, :name, :data-type, optional
-                       :description and :study-id

   Returns nil after all events could be published."
   [bus input]


couple of minor spacing fixes [ci skip]

couple of minor spacing fixes [ci skip]

--- frontend/components/landing.cljs
+++ frontend/components/landing.cljs
@@ -49,7 +49,7 @@
    (home-button {:source "hero"} controls-ch)
    [:div
     [:p
-     [:i "CircleCI keeps your code safe."
+     [:i "CircleCI keeps your code safe. "
       [:a {:href "/security" :title "Security"} "Learn how."]]]]])

 (def stories-procedure
@@ -136,7 +136,7 @@
    [:div.center
     [:div.were-number-one
      [:h2
-      "CircleCI is the #1 hosted continuous deployment provider.But don't take our word for it, read what our awesome customers have to say."]]]
+      "CircleCI is the #1 hosted continuous deployment provider. But don't take our word for it, read what our awesome customers have to say."]]]
    [:div.customers-trust.row
     [:h4 [:span "Trusted By"]]
     (customer-image "Salesforce" "/img/logos/salesforce.png")


Only create when importing from vubis

Only create when importing from vubis

do not update. Give a flash message if some records were not imported.

--- src/mdr2/views.clj
+++ src/mdr2/views.clj
@@ -27,6 +27,8 @@
      [:h1 "Productions"]
      (when-let [errors (:errors (:flash request))]
        [:p [:ul.alert.alert-danger (for [e errors] [:li e])]])
+     (when-let [warnings (:warnings (:flash request))]
+       [:p [:ul.alert.alert-warning (for [w warnings] [:li w])]])
      (when-let [message (:message (:flash request))]
        [:p.alert.alert-success message])
      [:table#productions.table.table-striped
@@ -216,20 +218,25 @@

 (defn production-bulk-import
   [productions]
-  (doseq [[_ p] productions]
-    (-> p
-     prod/parse
-     prod/add-default-meta-data
-     ;; FIXME: does it make sense to update? What if the production
-     ;; has already been archived? I think we should probably make
-     ;; sure the production is in certain valid states
-     prod/update-or-create!
-     ;; productions from vubis do not need any manual structuring.
-     ;; They get their standard structure from a default template
-     prod/set-state-structured!
-     ;; write the dtbook template file
-     dtbook/dtbook-file))
-  (response/redirect-after-post "/"))
+  (let [created (doall (map (fn [[_ p]]
+                              (-> p
+                                  prod/parse
+                                  prod/add-default-meta-data
+                                  prod/create!))
+                            productions))
+        errors (remove map? created)
+        new (filter map? created)]
+    (doseq [p new]
+      ;; productions from vubis do not need any manual structuring.
+      ;; They get their standard structure from a default template
+      prod/set-state-structured!
+      ;; write the dtbook template file
+      dtbook/dtbook-file)
+    (-> (response/redirect-after-post "/")
+        (cond-> (seq errors)
+          (assoc :flash {:warnings (for [e errors]
+                                     (str (re-find #"PNX \d+" (first e))
+                                          " has already been imported"))})))))

 (defn production-repair-form
   [request & [errors]]


Handling errors in login; note that this breaks all other requests, though

--- web-client/test/test_burgerboard/huh.cljs
+++ web-client/test/test_burgerboard/huh.cljs
@@ -103,7 +103,7 @@
   (let [children (.-children (props-of component))]
     (cond
      (= (type children) js/Array)
-     (filter #(not (string? %)) (js->clj children))
+     (filter #(and (not (nil? %)) (not (string? %))) (js->clj children))
      (= js/undefined children)
      []
      :else


add tests for skipping three pirates and not allowing return to jail

--- test/cartagena/core_test.clj
+++ test/cartagena/core_test.clj
@@ -153,30 +153,48 @@
         (is (nil? (occupied-space-index space-index board)))))))

 (deftest move-back-test
-  (testing "Can move back to the first space with one or two pirates"
-    (let [player {:name "tanya" :color :orange :cards [:hat :skull :knife]}
-          from-space {:icon :hat :pirates [:black :orange]}
-          board [{:icon :bottle :pirates [:orange]}
-                 {:icon :knife :pirates []}
-                 {:icon :bottle :pirates [:black]}
-                 {:icon :skull :pirates []}
-                 from-space
-                 {:icon :skull :pirates [:black]}]
-          draw-pile [:gun :key]
-          discard-pile [:knife]
-          updated-spaces [{:icon :bottle :pirates [:orange]}
-                          {:icon :knife :pirates []}
-                          {:icon :bottle :pirates [:black :orange]}
-                          {:icon :skull :pirates []}
-                          {:icon :hat :pirates [:black]}
-                          {:icon :skull :pirates [:black]}]
-          expected {:player (assoc player :cards [:hat :skull :knife :gun])
-                    :board-spaces updated-spaces
-                    :draw-pile [:key]
-                    :discard-pile [:knife]}]
-      (is (= expected (move-back player from-space board draw-pile discard-pile)))))
-  (testing "Skips over spaces with three pirates")
-  (testing "Does not allow moving back to jail"))
+  (let [player {:name "tanya" :color :orange :cards [:hat :skull :knife]}
+        board [{:icon :jail :pirates []}
+               {:icon :bottle :pirates [:orange]}
+               {:icon :knife :pirates []}
+               {:icon :bottle :pirates [:black]}
+               {:icon :skull :pirates []}
+               {:icon :hat :pirates [:black :orange]}
+               {:icon :skull :pirates [:black]}]
+        from-space {:icon :hat :pirates [:black :orange]}
+        draw-pile [:gun :key]
+        discard-pile [:knife]]
+    (testing "Can move back to the first space with one or two pirates"
+      (let [updated-spaces [{:icon :jail :pirates []}
+                            {:icon :bottle :pirates [:orange]}
+                            {:icon :knife :pirates []}
+                            {:icon :bottle :pirates [:black :orange]}
+                            {:icon :skull :pirates []}
+                            {:icon :hat :pirates [:black]}
+                            {:icon :skull :pirates [:black]}]
+            expected {:player (assoc player :cards [:hat :skull :knife :gun])
+                      :board-spaces updated-spaces
+                      :draw-pile [:key]
+                      :discard-pile [:knife]}]
+        (is (= expected (move-back player from-space board draw-pile discard-pile)))))
+    (testing "Skips over spaces with three pirates"
+      (let [board (assoc board 3 {:icon :bottle :pirates [:black :black :black]})
+            updated-spaces [{:icon :jail :pirates []}
+                            {:icon :bottle :pirates [:orange :orange]}
+                            {:icon :knife :pirates []}
+                            {:icon :bottle :pirates [:black :black :black]}
+                            {:icon :skull :pirates []}
+                            {:icon :hat :pirates [:black]}
+                            {:icon :skull :pirates [:black]}]
+            expected {:player (assoc player :cards [:hat :skull :knife :gun])
+                      :board-spaces updated-spaces
+                      :draw-pile [:key]
+                      :discard-pile [:knife]}]
+        (is (= expected (move-back player from-space board draw-pile discard-pile)))))
+    (testing "Does not allow moving back to jail"
+      (let [board (assoc board 3 {:icon :bottle :pirates [:black :black :black]}
+                               1 {:icon :bottle :pirates []})]
+        (is (nil? (move-back player from-space board draw-pile discard-pile)))))))

 ;(deftest discard-card-test
 ;  (testing "Discarding a card adds it to the discard pile"


test readability

test readability

--- test/cellophane/dom_test.clj
+++ test/cellophane/dom_test.clj
@@ -1,7 +1,13 @@
 (ns cellophane.dom-test
   (:require [clojure.test :refer [deftest testing is are]]
+            [clojure.string :as str]
             [cellophane.next :as cellophane :refer [defui]]
             [cellophane.dom :as dom]))
+
+(defn- remove-whitespace [s]
+  (->> (str/split s #">\s+<")
+    (filter #(not (str/blank? %)))
+    (str/join "><")))

 (defn test-tags [tags res-fn]
   `(are [element# res#] (= (dom/render-element {:tag element# :react-id [0]}) res#)
@@ -40,8 +46,17 @@
   (testing "render-element renders simple function elements"
     (are [component res] (= (dom/render-element (dom/assign-react-ids component)) res)
       (simple-component) "
Hello World
"
-      (simple-nested-component) "

Title

"
-      (comp-nested-component) "

Hello World

Title

")))
+      (simple-nested-component) (remove-whitespace
+                                  "

+
Title

+
")
+      (comp-nested-component) (remove-whitespace
+                                "

+
Hello World

+

+
Title

+

+
"))))

 (defui SimpleComponent
   Object


Tests for function 'fourth'

Tests for function 'fourth'

--- test/clouseau/test_utils.clj
+++ test/clouseau/test_utils.clj
@@ -204,6 +204,33 @@
         (are [x y] (= x y)
             nil (third nil))))

+(deftest test-fourth-1
+    "Check the function clouseau/fourth."
+    (testing "the function clouseau/fourth."
+        (are [x y] (= x y)
+            4 (fourth [1 2 3 4 5])
+            4 (fourth '(1 2 3 4))
+            4 (fourth '(1 2 3 4 5)))))
+
+(deftest test-fourth-2
+    "Check the function clouseau/fourth."
+    (testing "the function clouseau/fourth."
+        (are [x y] (= x y)
+            nil (fourth [])
+            nil (fourth '())
+            nil (fourth [1])
+            nil (fourth '(1))
+            nil (fourth [1 2])
+            nil (fourth '(1 2))
+            nil (fourth [1 2 3])
+            nil (fourth '(1 2 3)))))
+
+(deftest test-fourth-not-NPE
+    "Check the function clouseau/fourth."
+    (testing "the function clouseau/fourth."
+        (are [x y] (= x y)
+            nil (fourth nil))))
+
 (deftest test-substring-1
     "Check the function clouseau.utils/substring."
     (testing "the function clouseau.utils/substring."


Two tests for the utility function replaceAll

--- test/clouseau/test_utils.clj
+++ test/clouseau/test_utils.clj
@@ -350,3 +350,21 @@
         (is (thrown? NullPointerException (endsWith "text" nil)))
         (is (thrown? NullPointerException (endsWith nil "text")))))

+(deftest test-replaceAll-1
+    "Check the function emender-jenkins.utils/replaceAll."
+    (testing "the function emender-jenkins.utils/replaceAll."
+        (are [x y] (= x y)
+            ""    (replaceAll "" "" "")
+            "b"   (replaceAll "a" "a" "b")
+            "bb"  (replaceAll "aa" "a" "b")
+            "bcb" (replaceAll "aca" "a" "b"))))
+
+(deftest test-replaceAll-2
+    "Check the function emender-jenkins.utils/replaceAll."
+    (testing "the function emender-jenkins.utils/replaceAll."
+        (are [x y] (= x y)
+            "b"     (replaceAll "aa" "aa" "b")
+            "bb"    (replaceAll "aaaa" "aa" "b")
+            "xbbx"  (replaceAll "xaaaax" "aa" "b")
+            "xbxbx" (replaceAll "xaaxaax" "aa" "b"))))
+


First pass over catalog entries.

First pass over catalog entries.

--- src/onyx/spec.cljc
+++ src/onyx/spec.cljc
@@ -20,6 +20,116 @@
   (s/coll-of (s/coll-of :onyx/name :kind vector? :count 2)
              :kind vector?
              :min-count 1))
+
+(s/def :onyx/batch-size pos-int?)
+
+(s/def :onyx/batch-timeout pos-int?)
+
+(s/def :onyx/bulk? boolean?)
+
+(s/def :onyx/batch-fn? boolean?)
+
+(s/def :onyx/deduplicate? boolean?)
+
+(s/def :onyx/uniqueness-key any?)
+
+(s/def :onyx/doc string?)
+
+(s/def :onyx/flux-policy #{:kill :continue :recover})
+
+(s/def :onyx/fn namespaced-keyword?)
+
+(s/def :onyx/group-by-key any?)
+
+(s/def :onyx/group-by-fn namespaced-keyword?)
+
+(s/def :onyx/input-retry-timeout pos-int?)
+
+(s/def :onyx/language #{:clojure :java})
+
+(s/def :onyx/max-peers pos-int?)
+
+(s/def :onyx/max-pending pos-int?)
+
+(s/def :onyx/medium keyword?)
+
+(s/def :onyx/min-peers pos-int?)
+
+(s/def :onyx/n-peers pos-int?)
+
+(s/def :onyx/name keyword?)
+
+(s/def :onyx/params
+  (s/coll-of keyword? :kind vector?))
+
+(s/def :onyx/pending-timeout pos-int?)
+
+(s/def :onyx/plugin keyword?)
+
+(s/def :onyx/required-tags
+  (s/coll-of keyword? :kind vector?))
+
+(s/def :onyx/restart-pred-fn keyword?)
+
+(s/def :onyx/type #{:input :function :output})
+
+(defmulti onyx-type :onyx/type)
+
+(defmethod onyx-type :input
+  [_]
+  (s/keys :req [:onyx/name
+                :onyx/plugin
+                :onyx/type
+                :onyx/batch-size]
+          :opt [:onyx/batch-timeout
+                :onyx/fn
+                :onyx/uniqueness-key
+                :onyx/deduplicate?
+                :onyx/n-peers
+                :onyx/min-peers
+                :onyx/max-peers
+                :onyx/params
+                :onyx/required-tags
+                :onyx/language
+                :onyx/doc]))
+
+(defmethod onyx-type :function
+  [_]
+  (s/keys :req [:onyx/name :onyx/type :onyx/fn :onyx/batch-size]
+          :opt [:onyx/batch-timeout
+                :onyx/batch-fn?
+                :onyx/uniqueness-key
+                :onyx/deduplicate?
+                :onyx/n-peers
+                :onyx/min-peers
+                :onyx/max-peers
+                :onyx/group-by-key
+                :onyx/group-by-fn
+                :onyx/params
+                :onyx/required-tags
+                :onyx/plugin
+                :onyx/language
+                :onyx/doc]))
+
+(defmethod onyx-type :output
+  [_]
+  (s/keys :req [:onyx/name
+                :onyx/plugin
+                :onyx/type
+                :onyx/batch-size]
+          :opt [:onyx/batch-timeout
+                :onyx/fn
+                :onyx/uniqueness-key
+                :onyx/deduplicate?
+                :onyx/group-by-key
+                :onyx/group-by-fn
+                :onyx/n-peers
+                :onyx/min-peers
+                :onyx/max-peers
+                :onyx/params
+                :onyx/required-tags
+                :onyx/language
+                :onyx/doc]))

 (s/def :lifecycle/task keyword?)

@@ -287,6 +397,13 @@
 (s/def :onyx.core/serialized-task any?)

 (s/def :onyx.core/workflow (s/get-spec :job/workflow))
+
+(s/def :onyx.core/task-map
+  (s/multi-spec onyx-type :onyx/type))
+
+(s/def :onyx.core/catalog
+  (s/coll-of (s/multi-spec onyx-type :onyx/type)
+             :kind vector?))

 (s/def :onyx.core/flow-conditions
   (s/get-spec :job/flow-conditions))
@@ -548,7 +665,9 @@
                 :onyx.core/emitted-exhausted?
                 :onyx.core/metadata
                 :onyx.core/serialized-task
+                :onyx.core/task-map
                 :onyx.core/workflow
+                :onyx.core/catalog
                 :onyx.core/flow-conditions
                 :onyx.core/windows
                 :onyx.core/triggers
@@ -562,14 +681,3 @@
                 :onyx.core/windows-state
                 :onyx.core/filter-state
                 :onyx.core/batch]))
-
-;;;
-
-
-
-
-{:onyx.core/catalog {:type [:catalog-entry]
-                     :doc "The full catalog for this job"}
- :onyx.core/task-map {:type :catalog-entry
-                      :doc "The catalog entry for this task"}}
-


Only call `set-pages*!' when pages have changed.

--- src/pepa/model.clj
+++ src/pepa/model.clj
@@ -159,7 +159,7 @@
 (defn document-pages
   "Returns a list of pages for the document with ID."
   [db id]
-  (db/query db ["SELECT p.file, p.number, p.rotation
+  (db/query db ["SELECT p.id, p.file, p.number, p.rotation
                  FROM pages AS p
                  JOIN document_pages AS dp on dp.page = p.id
                  WHERE dp.document = ?
@@ -272,7 +272,9 @@
             (db/update! conn :documents
                         props
                         ["id = ?" id])
-            (when (seq pages)
+            (when (and (seq pages)
+                       (not= (mapv :id (document-pages db id))
+                             (vec pages)))
               (set-pages*! db id (vec pages)))))
         (db/notify! conn :documents/updated {:id id}))
       (throw (ex-info (str "Couldn't find document with id " id)


bring in resources test

bring in resources test

--- test/infinitelives/test.cljs
+++ test/infinitelives/test.cljs
@@ -1,6 +1,7 @@
 (ns infinitelives.test
   (:require [cljs.test :refer-macros [run-all-tests]]
-            [infinitelives.pixi.canvas-test]))
+            [infinitelives.pixi.canvas-test]
+            [infinitelives.pixi.resources-test])

 (enable-console-print!)


Fixed test wait time

Fixed test wait time

--- test/littlepot/core_test.clj
+++ test/littlepot/core_test.clj
@@ -11,7 +11,7 @@
       ;; trigger data population
       (is (= :no-data (cook pot)))
       ;; wait to retrieved fully
-      (Thread/sleep 200)
+      (Thread/sleep 500)
       (is (= (range 10) (take 10 (repeatedly #(cook pot)))))
       ;; next portion is unavailable
       (is (every? #(= % :no-data) (take 100 (repeatedly #(cook pot)))))
@@ -30,7 +30,7 @@
       (is (= :no-data (cook pot)))
       (dotimes [batch-num 3]
         ;; wait to retrieved fully
-        (Thread/sleep 200)
+        (Thread/sleep 500)
         (is (= (range 10) (take 10 (repeatedly #(cook pot)))))
         ;; next portion is unavailable
         (if (< batch-num 2)
@@ -48,7 +48,7 @@
           pot (make-pot batch-data-fn)]
       ;; trigger data population
       (is (= :no-data (cook pot)))
-      (Thread/sleep 200)
+      (Thread/sleep 500)
       (is (every? #(= % :exhausted) (take 20 (repeatedly #(cook pot)))))
       (is (not (nil? (:last-error @pot)))))))


First draft at a compound effect.

First draft at a compound effect.

This turned out to be a *lot* more straightforward than I expected. A
good sign about the design of Afterglow so far.

--- src/afterglow/effects.clj
+++ src/afterglow/effects.clj
@@ -38,27 +38,26 @@
       "Arrange to finish as soon as possible; return true if can end immediately."))))

-;; So...
+;; See https://github.com/brunchboy/afterglow/blob/master/doc/rendering_loop.adoc#assigners
 ;;
-;; We are going to have types of assigners: :channel, :head-color, :head-rotation. Each will be
-;; associated with some kind of target. Channel: :u<universe-id>-c<channel-number> Head-related
-;; ones: :h<head-id>. We will run through the list of effects in priority order; each will
-;; spit out some number of assigners, which are a tuple:
+;; Afterglow runs through the list of effects in priority order; each will spit out some
+;; number of assigners, which are a tuple:
 (defrecord Assigner [^clojure.lang.Keyword kind ^clojure.lang.Keyword target-id target ^clojure.lang.IFn f]
   IAssigner
   (assign [this show snapshot target previous-assignment]
     (f show snapshot target previous-assignment)))

-;; We will gather these into a map, whose keys are the assigner kind, and whose values, in turn,
-;; are maps of assigners of that kind. Each key in the inner map is a target for which values are
+;; We will gather these into a map, whose keys are the assigner kind, and whose values, in turn, are
+;; maps of assigners of that kind. Each key in the inner map is a target ID for which values are
 ;; to be assigned, and the values are the priority-ordered list of assigners to run on that target.
 ;; On each DMX frame we will run through these lists in parallel, and determine the final assignment
 ;; value which results for each target. Finally, once that is done, the resulting assignments will be
 ;; resolved to DMX values by calling these:

 #_(defprotocol IAssignmentResolver
-  "Translates an attribute assignment (color, attitude, channel value) for an element of a light show
-  to the actual DMX values that will implement it."
+  "Translates an attribute assignment (e.g. color, direction, channel
+  value) for an element of a light show to the actual DMX values that
+  will implement it."
   (resolve-assignment [this show buffers target snapshot assignment]
     "Translate the assignment to appropriate setting for target DMX channels."))

@@ -120,3 +119,18 @@
   [kind heads param show]
   (let [snapshot (rhythm/metro-snapshot (:metronome show))]
     (map #(build-head-parameter-assigner kind % param show snapshot) heads)))
+
+(defn scene
+  "Scenes are a way to group a list of effects to run as a single
+  effect. All of their assigners are combined into a single list, in
+  the order in which the effects were added to the scene. Because of
+  the way Afterglow evaluates assigners, that means that if any
+  constituent effects try to assign to the same target, the later ones
+  will have a chance to override or blend with the earlier ones."
+  [scene-name & effects]
+  (Effect. scene-name
+           (fn [show snapshot]
+             (reduce (fn [result current] (or (still-active? current show snapshot) result)) false effects))
+           (fn [show snapshot] (mapcat #(generate % show snapshot) effects))
+           (fn [show snapshot]
+             (reduce (fn [result current] (and (end current show snapshot) result)) true effects))))


Fix test to reflect simplified Hex constructor.

--- test/afterglow/effects/color_test.clj
+++ test/afterglow/effects/color_test.clj
@@ -8,4 +8,4 @@

 (deftest test-extract-rgb
   (testing "Finding RGB color channels")
-  (is (= [:12-channel-mix-uv] (map :mode (#'afterglow.effects.color/find-rgb-heads [(chauvet/slimpar-hex3-irc)])))))
+  (is (= [:12-channel] (map :mode (#'afterglow.effects.color/find-rgb-heads [(chauvet/slimpar-hex3-irc)])))))


notify subscribers when text is saved

notify subscribers when text is saved

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -566,7 +566,8 @@
         db           (:db current-state)
         layer        (get-in current-state [:drawing :layers 0])]
     (when (layer-model/detectable? layer)
-      (d/transact! db [layer] {:can-undo? true}))))
+      (d/transact! db [layer] {:can-undo? true}))
+    (maybe-notify-subscribers! current-state nil nil)))

 (defmethod control-event :deleted-selected
   [browser-state message _ state]


remove an unnecessary cast!

remove an unnecessary cast!

--- src-cljs/frontend/controllers/controls.cljs
+++ src-cljs/frontend/controllers/controls.cljs
@@ -553,7 +553,7 @@
                                  (or (not (get-in previous-state [:drawing :moving?]))
                                      (some true? (map detectable-movement? original-layers layers))))
                         (d/transact! db layers {:can-undo? true}))
-                      (cast! [:mouse-moved [x y]]))
+                      (maybe-notify-subscribers! current-state x y))

      :else nil)))


Implementing the help command for interactive mode

--- src/app/interactive.clj
+++ src/app/interactive.clj
@@ -39,7 +39,10 @@
               (rp state)))
           (= command :HELP)
           (do
-            (println "Help...")
+            (println "h/help                      : print this help message")
+            (println "q/quit/exit                 : close the shell")
+            (println "list                        : list classes loaded")
+            (println "mc/many-constructors th NUM : list classes with NUM or more constructors")
             (rp state))
           (= command :LOAD)
           (let [dirnameWithApex (nth (nth (first ast) 2) 1),


(create-mapping): add [bolt] (singleton vector) as the value of the (degenerate) path: []

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -51,13 +51,18 @@
                                   (or (:lexicon (:generate model)) (:lexicon model)))))))
     []))

+(declare comp-path-to-bolts)
+
 (defn create-mapping [bolt comp-paths model depth max-depth]
-  (zipmap comp-paths
-          (map (fn [path]
-                 (babel.generate/comp-path-to-bolts
-                  bolt path model depth max-depth))
-               comp-paths)))
-
+  (merge
+   (zipmap comp-paths
+           (map (fn [path]
+                  (comp-path-to-bolts
+                   bolt path model depth max-depth))
+                comp-paths))
+   {[]
+    [bolt]}))
+
 (defn comp-path-to-bolts
   "return a lazy sequence of bolts for all possible complements that can be added to the end of the _path_ within _bolt_."
   [bolt path model depth max-depth]


Add dollar sign back in

Add dollar sign back in

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -843,7 +843,7 @@
           [:p
            (str (pm/paid-containers plan) " of these are paid")
            (if piggiebacked? ". "
-               (list ", at " (pm/stripe-cost plan) "/month. "))
+               (list ", at $" (pm/stripe-cost plan) "/month. "))
            (if (pm/grandfathered? plan)
              (list "We've changed our pricing model since this plan began, so its current price "
                    "is grandfathered in. "