Favor required transitions during random moves. Eventually may want to do something based on the time until the upcoming required transition.

--- src/player/ha_rollout.cljs
+++ src/player/ha_rollout.cljs
@@ -135,14 +135,15 @@
                     [choice time]])))))))

 (def close-duration 120)
+(def req-move-prob 0.5)

 (defn random-move [config]
   (pick-next-move config
-                  (fn [_config reqs opts required-time]
-                    (let [options (if (empty? reqs)
-                                    opts
-                                    (conj opts :required))
-                          choice (rand-nth options)
+                  (fn [_config reqs options required-time]
+                    (let [choice (if (and (not (empty? reqs))
+                                          (< (rand) req-move-prob))
+                                   :required
+                                   (rand-nth options))
                           time (if (= choice :required)
                                  required-time
                                  (let [start (iv/start-time (:interval choice))
@@ -187,7 +188,12 @@
         configs (mapv first config-moves)
         _ (println "configs:" (map config-brief
                                    configs))
-        moves (second (last config-moves))
+        moves (map (fn [[m t]]
+                     [(if (map? m)
+                        (update m :transition dissoc :guard :update)
+                        m)
+                      t])
+                   (second (last config-moves)))
         _ (println "moves:" moves)]
     [configs moves]))


Implement multi DELETE with 501 "Not Implemented" response

--- src/poky/protocol/http.clj
+++ src/poky/protocol/http.clj
@@ -209,9 +209,10 @@
     (PUT ["/:b" :b valid-key-regex]
          request
          (multi-handler kvstore multi-set request))
-    ;(DELETE ["/:b" :b valid-key-regex]
-    ;{})
-    ))
+    (DELETE ["/:b" :b valid-key-regex]
+            request
+            (-> (response "Multi-delete not supported yet")
+                (status 501)))))

 ;; ========


added get-icuser-by-email utility

added get-icuser-by-email utility

--- src/polismath/intercom.clj
+++ src/polismath/intercom.clj
@@ -56,6 +56,14 @@
         users))))

+(defn get-icuser-by-email
+  "Get the list of users from intercom (don't want to create intercom users for users that haven't
+  actually signed up"
+  [email]
+  (->
+    (str "https://api.intercom.io/users?email=" email)
+    (client/get intercom-http-params)
+    (parse-json-resp)))

 (defn update-icuser


less racy test

less racy test

--- test/cetcd/core_test.clj
+++ test/cetcd/core_test.clj
@@ -76,6 +76,7 @@
           watch-promise (etcd/watch-key "new-key" :callback (fn [result]
                                                               (reset! result-atom result)))]
       (etcd/set-key! "new-key" "new value")
+      @watch-promise
       (is (= "new value" (-> @result-atom :node :value))))))

 (deftest exceptional-errors-throw-exceptions


Sort the query-param map before generating the signature

--- src/shuppet/urlbuilder.clj
+++ src/shuppet/urlbuilder.clj
@@ -10,7 +10,6 @@
    [javax.crypto.spec SecretKeySpec]
    [org.apache.commons.codec.binary Base64]
    [org.joda.time DateTime DateTimeZone]))
-

 (def ^:const hmac-sha256-algorithm  "HmacSHA256")
 (def ^:const new-line "\n")
@@ -43,18 +42,18 @@
 (defn- bytes [str]
   (.getBytes str "UTF-8"))

-(defn- base64 [str]
-  (Base64/encodeBase64String str))
+(defn- base64 [b]
+  (Base64/encodeBase64String b))

-(defn- get-mac [key]
-  (let [signing-key (SecretKeySpec. (bytes key) hmac-sha256-algorithm)
+(defn- get-mac []
+  (let [signing-key (SecretKeySpec. (bytes (aws-secret)) hmac-sha256-algorithm)
         mac (Mac/getInstance hmac-sha256-algorithm)]
     (.init mac signing-key)
     mac))

 (defn- calculate-hmac [data]
   (try
-    (let [mac (get-mac (aws-secret))
+    (let [mac (get-mac)
           raw-mac (.doFinal mac (bytes data))]
       (base64 raw-mac))
     (catch Exception e
@@ -76,7 +75,8 @@
        (generate-query-string query-params)))

 (defn- generate-signature [method uri query-params]
-  (let [url (URL. uri)
+  (let [query-params (into (sorted-map) query-params)
+        url (URL. uri)
         host (lower-case (.getHost url))
         path (get-path url)
         data (url-to-sign method host path query-params)]
@@ -87,8 +87,7 @@
   [method uri params]
   (let [query-params (merge params auth-params)
         signature (generate-signature method uri query-params)
-        query-string (generate-query-string (merge query-params {"Signature" signature}))]
+        query-string (generate-query-string (merge {"Signature" signature} query-params))]
     (str uri "?" query-string)))

-
-;(build-url "get" "https://www.test.com" {"a" "1"})
+;(clj-http.client/get (build-url "get" "https://ec2.eu-west-1.amazonaws.com" {"Version" "2013-10-01" "Action" "DescribeSecurityGroups" }) {:throw-exceptions false})


improve buffer info ugen docstrings

improve buffer info ugen docstrings

--- src/overtone/sc/machinery/ugen/metadata/info.clj
+++ src/overtone/sc/machinery/ugen/metadata/info.clj
@@ -67,7 +67,9 @@
     :args [{:name "buf" :default 0 :doc "a buffer"}]
     :rates #{:kr :ir}
     :check (nth-input-buffer? 0)
-    :doc "returns the current number of allocated frames"}
+    :doc "returns the current number of allocated frames i.e. the size
+          of the buffer. This is the equivalent of Clojure's count on a
+          seq." }

    {:name "BufSamples"
     :args [{:name "buf" :default 0 :doc "a buffer"}]
@@ -79,7 +81,7 @@
     :args [{:name "buf" :default 0 :doc "a buffer"}]
     :rates #{:kr :ir}
     :check (nth-input-buffer? 0)
-    :doc "returns the current duration of a buffer"}
+    :doc "returns the current duration of a buffer in seconds."}

    {:name "BufChannels"
     :args [{:name "buf" :default 0 :doc "a buffer"}]


Allow stress test more time.

Allow stress test more time.

--- test/kabel/core_test.clj
+++ test/kabel/core_test.clj
@@ -61,5 +61,5 @@
                                   identity)]
       (<?? S (peer/start speer))
       (<?? S (peer/connect S cpeer url))
-      (<?? S (timeout 1000))
+      (<?? S (timeout 2000))
       (<?? S (peer/stop speer)))))


PDOK-1025: formatting

PDOK-1025: formatting

--- src/test/clojure/pdok/featured/mustache_test.clj
+++ src/test/clojure/pdok/featured/mustache_test.clj
@@ -17,9 +17,9 @@
 (def resultTemplate2Mapping "Eerst iets anders eerste stap en op het einde tweede stap")

 (deftest replace-template-with-different-templates-and-mappings
-  (is (= resultTemplateMapping (render-template-one-feature testTemplate (->MapProxy testMapping))))
-  (is (= resultTemplate2Mapping2 (render-template-one-feature testTemplate2 (->MapProxy testMapping2))))
-  (is (= resultTemplate2Mapping (render-template-one-feature testTemplate2 (->MapProxy testMapping)))))
+  (is (= resultTemplateMapping (render-template testTemplate (->MapProxy testMapping))))
+  (is (= resultTemplate2Mapping2 (render-template testTemplate2 (->MapProxy testMapping2))))
+  (is (= resultTemplate2Mapping (render-template testTemplate2 (->MapProxy testMapping)))))

 (def example-gml-bgt-wegdeel


Make booleans native

Make booleans native

--- src-backend/cljs/cljs_webrepl/repl.cljs
+++ src-backend/cljs/cljs_webrepl/repl.cljs
@@ -21,7 +21,7 @@
 (def current-ns replumb-repl/current-ns)

 (defn native? [obj]
-  (or (nil? obj) (string? obj) (number? obj) (keyword? obj) (coll? obj)))
+  (or (nil? obj) (boolean? obj) (string? obj) (number? obj) (keyword? obj) (coll? obj)))

 (defn obj->map* [obj acc key obj->map]


use assoc not assoc-in for top level keys

--- src-cljs/frontend/components/build.cljs
+++ src-cljs/frontend/components/build.cljs
@@ -225,8 +225,8 @@
                                (:oss project)
                                (> (:containers plan) 1))]
     (-> project
-        (assoc-in [:show-build-timing?] show-build-timing?)
-        (assoc-in [:org-name] (:org_name plan)))))
+        (assoc :show-build-timing? show-build-timing?)
+        (assoc :org-name (:org_name plan)))))

 (defn build-v1 [data owner]
   (reify


Test for the new function run-fetcher-one-iteration

--- test/emender_jenkins/job_data_fetcher_test.clj
+++ test/emender_jenkins/job_data_fetcher_test.clj
@@ -73,3 +73,18 @@
         (with-redefs [results/reload-all-results (fn [configuration] :ok)]
             (is (= :ok (try-to-fetch-data nil)))))))

+(deftest test-run-fetcher-one-iteration
+    "Checking the function run-fetcher-one-iteration."
+    (testing "the function run-fetcher-one-iteration."
+        (with-redefs [results/reload-all-results (fn [configuration] :ok)]
+            (reset! started-on    nil)
+            (reset! finished-on   nil)
+            (reset! last-duration nil)
+            (run-fetcher-one-iteration nil)
+            (is (not (nil? @started-on)))
+            (is (not (nil? @finished-on)))
+            (is (not (nil? @last-duration)))
+            (is (re-matches #"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d" @started-on))
+            (is (re-matches #"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d" @finished-on))
+            (is (>= @last-duration 0)))))
+


JC | Print out midje facts that are running to console


playgroud updated

playgroud updated

--- playground/aug.clj
+++ playground/aug.clj
@@ -1,7 +1,29 @@
 (ns aug
   (:require [clojure.spec.alpha :as s]
             [manifold.stream :as stream]
+            [clojure.core.async :as async]
             [clojure.spec.test.alpha :as stest]))

 (def input-stream (stream/stream))
+
+(def a (async/chan 10))
+(def b (async/chan 10))
+(def c (async/chan 3))
+(def d (async/chan 10))
+(def z (async/chan 10))
+
+
+(stream/connect c input-stream)
+(stream/connect a input-stream)
+(stream/connect input-stream b)
+(stream/connect input-stream d)
+
+(async/>!! a 12)
+(async/>!! z 12000)
+(async/close! c)
+(async/close! a)
+(stream/connect z input-stream)
+
+(async/<!! b)
+(async/<!! d)


Увеличил размер кнопок в диалогах действий

--- src-cljs/ixinfestor/omut.cljs
+++ src-cljs/ixinfestor/omut.cljs
@@ -391,6 +391,7 @@
       (ui-button {:text text
                   :type btn-type
                   :block? true
+                  :size :lg
                   :on-click (fn [_]
                               (modal-hide app)
                               (if act-fn


Cleanup serve-ball; normalize the ball velocity

--- src-cljs/pong/core.cljs
+++ src-cljs/pong/core.cljs
@@ -72,6 +72,12 @@

 (defn clamp [x min-val max-val]
   (max min-val (min max-val x)))
+
+(defn normalize [[x y]]
+  (let [length (.sqrt js/Math (+ (* x x) (* y y)))]
+    (if (pos? length)
+      [(/ x length) (/ y length)]
+      [x y])))
 ;; ==================================================================

 ;; Entities ---------------------------------------------------------
@@ -84,13 +90,14 @@
                  (partial draw-rect (:bg colours))))

 (defn update-ball [event world-state ent]
-  (let [{:keys [vx vy w h]} (:value ent)]
+  (let [{:keys [vx vy w h]} (:value ent)
+        [n-vx n-vy]         (normalize [vx vy])]
     (-> ent
         (update-in [:value :x] (fn [old-x]
-                                 (clamp (+ old-x vx) 0
+                                 (clamp (+ old-x n-vx) 0
                                         (- (:w canvas-size) w))))
         (update-in [:value :y] (fn [old-y]
-                                 (clamp (+ old-y vy) 0
+                                 (clamp (+ old-y n-vy) 0
                                         (- (:h canvas-size) h)))))))

 (def ball
@@ -139,13 +146,11 @@
   (assoc world-state
     :mouse-coords (client->canvas-coords canvas (client-coords event))))

-(defn serve-ball
-  "Serve the ball if it is not already in play."
-  [event world-state]
-  (assoc-in world-state [:entities 3 :value :vx]
-            (if (even? (rand-int 50))
-              1
-              -1)))
+(defn serve-ball [event world-state]
+  (update-in world-state [:entities 3 :value]
+             #(-> %
+                  (assoc :vx (rand-nth [-1 1]))
+                  (assoc :vy (rand-nth [-1 0 1])))))

 (defn render-scene
   "Loop over the entities calling each ones draw fn."


tweaks

tweaks

--- src-cljs/qcon/main.cljs
+++ src-cljs/qcon/main.cljs
@@ -21,7 +21,7 @@
 (def debug false)

 (def diagram-width 480)
-(def diagram-height 560)
+(def diagram-height 580)

 (def svg-attrs
   {:version "1.1" :width diagram-width :height diagram-height})
@@ -456,17 +456,23 @@
           (map-indexed
            (fn [i m] (assoc m :slideno (str "slide-" (inc i))))
            [{:title "Adventures with core.async"
-             :author "Malcolm Sparks"
+             :text "Malcolm Sparks — QCon 2014"
              }

             {:subtitle "Adventures with core.async"
              :event "QCon 2014"
              :author "Malcolm Sparks"
-             :company "JUXT"
+             :company "JUXT — https://juxt.pro"
              :email "malcolm@juxt.pro"
              :twitter "@malcolmsparks"
-             :slides "https://qcon.juxt.pro:8000"
-             }
+             }
+
+            {:subtitle "These slides"
+             :bullets ["Available in kit-form: http://github.com/juxt/qcon2014"
+                       "Available ready assembled: http://qcon.juxt.pro:8000"]
+             }
+
+            {:title "What is core.async?"}

             {:subtitle "What is core.async?"
              ;;:text "Here is the first slide"
@@ -476,24 +482,29 @@
                        "Available in Clojure and ClojureScript"]
              }

+            #_{
+             :background "/static/csplang.png"
+             }
+
             {:subtitle "Communicating Sequential Processes?"
-             :bullets ["Clojure library released May 2013"
-                       "Based on Communicating Sequential Processes"
-                       "Available in Clojure and ClojureScript"]
-             }
-
-            {:subtitle "What is core.async?"
+             :bullets ["Started with a paper in 1978 by Anthony Hoare"
+                       "Then a book a few years later"]
+             }
+
+            {
              :background "/static/cspdiag.jpg"
              }

-            {:subtitle "What is core.async?"
+            {:title "But what is core.async?"}
+
+            {
              :background "/static/webcam.jpg"
-             :bullets ["Sugary substance used for all kinds of purposes"
-                       ]
-             }
-
+
+             }

             {:title "But what is core.async?"}
+
+            {:title "Quick Tutorial"}

             {:title "Warning: Code ahead!"
              :warning true}
@@ -533,7 +544,7 @@
              :custom put-and-take-slide
              :code {:source "cljs/core/async.cljs"
                     :range [20 40]}
-             :opts {:buffer-size 7 :font-size "50pt" :radius 40}}
+             :opts {:buffer-size 7 :font-size "72pt" :radius 40}}

             {:subtitle "put and take with map< inc"
              :custom put-and-take-slide
@@ -601,10 +612,6 @@
             {:subtitle "Azondi"
              :url "https://github.com/OpenSensorsIO/azondi"
              :bullets ["Builds on MQTT Broker"]}
-
-            {:subtitle "This slide-deck"
-             :url "https://github.com/juxt/qcon"
-             :bullets [""]}

             ;; TODO Don't forget to mention Hecuba and Stentor (that they're free software)
             {:title "Q & A"


CMR-1805: Refactored collection indexing

--- indexer-app/src/cmr/indexer/data/concepts/collection.clj
+++ indexer-app/src/cmr/indexer/data/concepts/collection.clj
@@ -46,18 +46,19 @@
   [personnel]
   (first (filter person->email-contact personnel)))

-(defn- get-elastic-fields-for-collection
-  "Gets fields to be indexed from a collection umm."
-  [context provider-id concept-id umm-c]
-  (let [{{:keys [short-name long-name version-id processing-level-id collection-data-type]} :product
+(defn- get-elastic-fields-for-full-collection
+  "Get all the fields for a normal collection index operation."
+  [context concept collection]
+  (let [{:keys [concept-id provider-id native-id revision-date format]} concept
+        {{:keys [short-name long-name version-id processing-level-id collection-data-type]} :product
          :keys [entry-id entry-title summary temporal related-urls spatial-keywords associated-difs
-                temporal-keywords access-value personnel distribution]} umm-c
+                temporal-keywords access-value personnel distribution]} collection
         collection-data-type (if (= "NEAR_REAL_TIME" collection-data-type)
                                ;; add in all the aliases for NEAR_REAL_TIME
                                (concat [collection-data-type] k/nrt-aliases)
                                collection-data-type)
         personnel (person-with-email personnel)
-        platforms (:platforms umm-c)
+        platforms (:platforms collection)
         platform-short-names (map :short-name platforms)
         platform-long-names (remove nil? (map :long-name platforms))
         instruments (mapcat :instruments platforms)
@@ -66,23 +67,38 @@
         sensors (mapcat :sensors instruments)
         sensor-short-names (remove nil? (map :short-name sensors))
         sensor-long-names (remove nil? (map :long-name sensors))
-        project-short-names (map :short-name (:projects umm-c))
-        project-long-names (remove nil? (map :long-name (:projects umm-c)))
-        two-d-coord-names (map :name (:two-d-coordinate-systems umm-c))
-        archive-center-val (org/extract-archive-centers umm-c)
+        project-short-names (map :short-name (:projects collection))
+        project-long-names (remove nil? (map :long-name (:projects collection)))
+        two-d-coord-names (map :name (:two-d-coordinate-systems collection))
+        archive-center-val (org/extract-archive-centers collection)
         start-date (sed/start-date :collection temporal)
         end-date (sed/end-date :collection temporal)
         atom-links (map json/generate-string (ru/atom-links related-urls))
         ;; not empty is used below to get a real true/false value
         downloadable (not (empty? (ru/downloadable-urls related-urls)))
         browsable (not (empty? (ru/browse-urls related-urls)))
-        update-time (get-in umm-c [:data-provider-timestamps :update-time])
+        update-time (get-in collection [:data-provider-timestamps :update-time])
         update-time (f/unparse (f/formatters :date-time) update-time)
-        insert-time (get-in umm-c [:data-provider-timestamps :insert-time])
+        insert-time (get-in collection [:data-provider-timestamps :insert-time])
         insert-time (f/unparse (f/formatters :date-time) insert-time)
-        spatial-representation (get-in umm-c [:spatial-coverage :spatial-representation])
-        permitted-group-ids (acl/get-coll-permitted-group-ids context provider-id umm-c)]
-    (merge {:permitted-group-ids permitted-group-ids
+        spatial-representation (get-in collection [:spatial-coverage :spatial-representation])
+        permitted-group-ids (acl/get-coll-permitted-group-ids context provider-id collection)]
+    (merge {:concept-id concept-id
+            :concept-seq-id (:sequence-number (concepts/parse-concept-id concept-id))
+            :native-id native-id
+            :native-id.lowercase (str/lower-case native-id)
+            :permitted-group-ids permitted-group-ids
+            :entry-id entry-id
+            :entry-id.lowercase (str/lower-case entry-id)
+            :entry-title entry-title
+            :entry-title.lowercase (str/lower-case entry-title)
+            :provider-id provider-id
+            :provider-id.lowercase (str/lower-case provider-id)
+            :short-name short-name
+            :short-name.lowercase (when short-name (str/lower-case short-name))
+            :version-id version-id
+            :version-id.lowercase (when version-id (str/lower-case version-id))
+            :revision-date revision-date
             :access-value access-value
             :processing-level-id processing-level-id
             :processing-level-id.lowercase (when processing-level-id (str/lower-case processing-level-id))
@@ -103,9 +119,9 @@
             :two-d-coord-name.lowercase  (map str/lower-case two-d-coord-names)
             :spatial-keyword spatial-keywords
             :spatial-keyword.lowercase  (map str/lower-case spatial-keywords)
-            :attributes (attrib/psas->elastic-docs umm-c)
-            :science-keywords (sk/science-keywords->elastic-doc umm-c)
-            :science-keywords-flat (sk/flatten-science-keywords umm-c)
+            :attributes (attrib/psas->elastic-docs collection)
+            :science-keywords (sk/science-keywords->elastic-doc collection)
+            :science-keywords-flat (sk/flatten-science-keywords collection)
             :personnel (json/generate-string personnel)
             :start-date (when start-date (f/unparse (f/formatters :date-time) start-date))
             :end-date (when end-date (f/unparse (f/formatters :date-time) end-date))
@@ -115,6 +131,7 @@
             :browsable browsable
             :atom-links atom-links
             :summary summary
+            :metadata-format (name (mt/base-mime-type-to-format format))
             :related-urls (map json/generate-string related-urls)
             :update-time update-time
             :insert-time insert-time
@@ -123,19 +140,21 @@
             :coordinate-system (when spatial-representation
                                  (csk/->SCREAMING_SNAKE_CASE_STRING spatial-representation))
             ;; fields added to support keyword searches
-            :keyword (k/create-keywords-field concept-id umm-c)
+            :keyword (k/create-keywords-field concept-id collection)
             :long-name.lowercase (when long-name (str/lower-case long-name))
             :platform-ln.lowercase (map str/lower-case platform-long-names)
             :instrument-ln.lowercase (map str/lower-case instrument-long-names)
             :sensor-ln.lowercase (map str/lower-case sensor-long-names)
             :project-ln.lowercase (map str/lower-case project-long-names)
             :temporal-keyword.lowercase (map str/lower-case temporal-keywords)}
-           (get-in umm-c [:spatial-coverage :orbit-parameters])
-           (spatial->elastic umm-c)
-           (sk/science-keywords->facet-fields umm-c))))
+           (get-in collection [:spatial-coverage :orbit-parameters])
+           (spatial->elastic collection)
+           (sk/science-keywords->facet-fields collection))))

-(defmethod es/concept->elastic-doc :collection
-  [context concept collection]
+
+(defn- get-elastic-fields-for-tombstone-collection
+  "Get the subset of elastic field values that apply to a tombstone index operation."
+  [context concept]
   (let [{{:keys [short-name version-id entry-id entry-title]} :extra-fields
          :keys [concept-id provider-id native-id revision-date deleted format]} concept
         ;; only used to get default ACLs for tombstones
@@ -143,25 +162,29 @@
         tombstone-permitted-group-ids (acl/get-coll-permitted-group-ids context
                                                                         provider-id tombstone-umm)
         {:keys [access-value]} tombstone-umm]
-    (merge {:concept-id concept-id
-            :concept-seq-id (:sequence-number (concepts/parse-concept-id concept-id))
-            :native-id native-id
-            :native-id.lowercase (str/lower-case native-id)
-            :short-name short-name
-            :short-name.lowercase (when short-name (str/lower-case short-name))
-            :entry-id entry-id
-            :entry-id.lowercase (str/lower-case entry-id)
-            :entry-title entry-title
-            :entry-title.lowercase (str/lower-case entry-title)
-            :version-id version-id
-            :version-id.lowercase (when version-id (str/lower-case version-id))
-            :deleted (boolean deleted)
-            :provider-id provider-id
-            :provider-id.lowercase (str/lower-case provider-id)
-            :revision-date revision-date
-            :metadata-format (name (mt/base-mime-type-to-format format))
-            :permitted-group-ids tombstone-permitted-group-ids
-            :access-value access-value}
-           (when-not deleted
-             (get-elastic-fields-for-collection context provider-id concept-id collection)))))
+    {:concept-id concept-id
+     :concept-seq-id (:sequence-number (concepts/parse-concept-id concept-id))
+     :native-id native-id
+     :native-id.lowercase (str/lower-case native-id)
+     :short-name short-name
+     :short-name.lowercase (when short-name (str/lower-case short-name))
+     :entry-id entry-id
+     :entry-id.lowercase (str/lower-case entry-id)
+     :entry-title entry-title
+     :entry-title.lowercase (str/lower-case entry-title)
+     :version-id version-id
+     :version-id.lowercase (when version-id (str/lower-case version-id))
+     :deleted (boolean deleted)
+     :provider-id provider-id
+     :provider-id.lowercase (str/lower-case provider-id)
+     :revision-date revision-date
+     :metadata-format (name (mt/base-mime-type-to-format format))
+     :permitted-group-ids tombstone-permitted-group-ids
+     :access-value access-value}))

+(defmethod es/concept->elastic-doc :collection
+  [context concept collection]
+  (if (:deleted concept)
+    (get-elastic-fields-for-tombstone-collection context concept)
+    (get-elastic-fields-for-full-collection context concept collection)))
+


Dedup audio description

Dedup audio description

--- src/video_server/video.clj
+++ src/video_server/video.clj
@@ -78,7 +78,7 @@
                 :height height
                 :dimension (video-dimension width height)
                 :video (video-desc (:codec_name video))
-                :audio (str/join ", " (map #(audio-desc (:codec_name %)) audio))
+                :audio (str/join ", " (distinct (map #(audio-desc (:codec_name %)) audio)))
                 :modified (.lastModified file)
                 :url url
                 :mimetype (mimetype file)}]


Refactor var page initialization

Refactor var page initialization

--- src/cljs/clojuredocs/mods/var_page.cljs
+++ src/cljs/clojuredocs/mods/var_page.cljs
@@ -163,9 +163,8 @@
             _id #(merge % {:delete-state :error}))))
       (recur))))

-(defn init [$root]
-  (let [!state (atom (init-state))
-        ex-ch (chan)
+(defn init-examples [$root !state]
+  (let [ex-ch (chan)
         update-example-ch (chan)
         new-example-ch (chan)
         delete-ch (chan)]
@@ -191,9 +190,23 @@
     (om/root
       see-alsos/$see-alsos
       !state
-      {:target (sel1 $root :.see-alsos-widget)})
-
+      {:target (sel1 $root :.see-alsos-widget)})))
+
+
+(defn init-notes [$root])
+
+(defn init-see-alsos [$root !state]
+  (let [new-ch (chan)
+        delete-ch (chan)]
     (om/root
       notes/$notes
       !state
-      {:target (sel1 $root :.notes-widget)})))
+      {:target (sel1 $root :.notes-widget)
+       :init-state {:new-ch new-note-ch
+                    :delete-ch delete-note-ch}})))
+
+(defn init [$root]
+  (let [!state (atom (init-state))]
+    (init-examples $root !state)
+    (init-see-alsos $root !state)
+    (init-notes $root !state)))


Fix docstrings code style on poly1305 ns.

--- src/clojure/buddy/core/mac/poly1305.clj
+++ src/clojure/buddy/core/mac/poly1305.clj
@@ -34,8 +34,8 @@

 (defn resolve-engine
   "Given dynamic type engine, try resolve it to
-valid engine instance. By default accepts keywords
-and functions."
+  valid engine instance. By default accepts keywords
+  and functions."
   [engine]
   (cond
    (instance? Keyword engine) (let [factory (engine *available-engines*)]
@@ -49,9 +49,9 @@

 (defn key->poly1305key
   "Noramalizes any length byte array key to poly1305
-formatted byte array key.
-It uses sha3 (256 bit) for normalize the size to 32
-bytes and poly1305 algorithm for transform it."
+  formatted byte array key.
+  It uses sha3 (256 bit) for normalize the size to 32
+  bytes and poly1305 algorithm for transform it."
   [^bytes key]
   (let [bkey (sha3-256 key)]
     (Poly1305KeyGenerator/clamp bkey)
@@ -101,10 +101,10 @@

 (defprotocol Poly1305Mac
   "Protocol that defines a low level interface
-to poly 1305 algorithm and allows extend it for
-different types.
-It comes with default implementation for: string,
-bytes, input stream, file, url and uri."
+  to poly 1305 algorithm and allows extend it for
+  different types.
+  It comes with default implementation for: string,
+  bytes, input stream, file, url and uri."
   (make-poly1305 [obj key iv alg] "Calculate poly1305 mac for type."))

 (alter-meta! #'make-poly1305 assoc :no-doc true :private true)
@@ -140,8 +140,8 @@

 (defn poly1305
   "Make poly1305 mac for specified data, using arbitrary
-length key and 128 bits iv.
-Key can be any type that implements ByteArray protocol."
+  length key and 128 bits iv.
+  Key can be any type that implements ByteArray protocol."
   [input key ^bytes iv ^Keyword alg]
   {:pre [(= (count iv) 16)]}
   (let [key (->byte-array key)]


Generate properties at query leaves

Generate properties at query leaves

--- src/com/wsscode/pathom/specs/query.cljc
+++ src/com/wsscode/pathom/specs/query.cljc
@@ -95,10 +95,10 @@
                      [1 (gen-special-property env)]]))

    ::gen-query
-   (fn gen-query [{::keys [gen-query-expr gen-max-depth] :as env}]
+   (fn gen-query [{::keys [gen-property gen-query-expr gen-max-depth] :as env}]
      (if (> gen-max-depth 0)
        (gen/vector (gen-query-expr (update env ::gen-max-depth dec)))
-       (gen/return [])))
+       (gen/vector-distinct (gen-property env))))

    ::gen-mutation-key
    (fn gen-mutation-key [_] gen/symbol)


Give the protocol a slightly better name.

--- namespaces/common/src/main/clojure/immutant/logging.clj
+++ namespaces/common/src/main/clojure/immutant/logging.clj
@@ -18,7 +18,7 @@
 (ns ^:no-doc immutant.logging
     "Internal logging bridge. Not for public consumption.")

-(defprotocol MockLogger
+(defprotocol Logger
   (trace [this msg])
   (debug [this msg])
   (info [this msg])
@@ -35,7 +35,7 @@
       (eval `(import 'org.immutant.core.Immutant))
       (eval '(fn [n] (Immutant/getLogger n)))
       (catch Throwable _
-        (let [l (reify MockLogger
+        (let [l (reify Logger
                   (trace [_ msg])
                   (debug [_ msg])
                   (info [_ msg]


Add support for aliases to the specs for parsed queries

--- src/main/workflo/macros/specs/parsed_query.cljc
+++ src/main/workflo/macros/specs/parsed_query.cljc
@@ -30,10 +30,10 @@
 (s/def ::join-target
   (s/with-gen
     (s/or :model :workflo.macros.specs.query/model-name
-          :recursion :workflo.macros.specs.query/recursion
+          :recursion :workflo.macros.specs.query/join-recursion
           :properties ::query)
     #(gen/one-of [(s/gen :workflo.macros.specs.query/model-name)
-                  (s/gen :workflo.macros.specs.query/recursion)
+                  (s/gen :workflo.macros.specs.query/join-recursion)
                   (s/gen '#{[{:type :property :name name}]
                             [{:type :property :name name}
                              {:type :property :name email}]
@@ -45,23 +45,26 @@
 (s/def ::parameters
   :workflo.macros.specs.query/parameters)

+(s/def ::alias
+  :workflo.macros.specs.query/property-name)
+
 (s/def ::property
   (s/keys :req-un [:property/type ::name]
-          :opt-un [::parameters]))
+          :opt-un [::parameters ::alias]))

 (s/def ::unparameterized-property
   (s/keys :req-un [:property/type ::name]))

 (s/def ::link
   (s/keys :req-un [:link/type ::name ::link-id]
-          :opt-un [::parameters]))
+          :opt-un [::parameters ::alias]))

 (s/def ::unparameterized-link
   (s/keys :req-un [:link/type ::name ::link-id]))

 (s/def ::join
   (s/keys :req-un [:join/type ::name ::join-source ::join-target]
-          :opt-un [::parameters]))
+          :opt-un [::parameters ::alias]))

 (defmulti  typed-property-spec :type)


Improve byte array size estimates

Improve byte array size estimates

--- src/net/dishevelled/mailindex/backends/nnml.clj
+++ src/net/dishevelled/mailindex/backends/nnml.clj
@@ -27,18 +27,17 @@
   "Return the bytes of a message."
   [^String msg]
   (try
-    (let [f (file msg)]
+    (let [f (file msg)
+          compressed (.endsWith msg ".gz")]
       (cond
         ;; Straight into a byte buffer with no copying if it's small
-        (and (not (.endsWith msg ".gz")) (<= (.length f) SMALL-FILE-SIZE))
+        (and (not compressed) (<= (.length f) SMALL-FILE-SIZE))
         (java.nio.file.Files/readAllBytes (.toPath f))

         ;; Stream it otherwise
         :else
         (let [buf (byte-array 16384)
-              out (ByteArrayOutputStream. (.length f))]
-          ;; Our initial length is really just a guess here.  We'll be right for
-          ;; uncompressed files and wrong for everything else :)
+              out (ByteArrayOutputStream. (* (if compressed 3 1) (.length f)))]
           (with-open [^InputStream is (input-stream-for-file f)]
             (loop [len (.read is buf)]
               (when (>= len 0)


Check for nil device before creating gamepad input.

--- src/org/playasophy/wonderdome/input/gamepad.clj
+++ src/org/playasophy/wonderdome/input/gamepad.clj
@@ -107,13 +107,14 @@

 (defn snes
-  "Creates a new SNES gamepad input which will send button press events to the
-  given channel."
+  "Creates a new SNES gamepad input which will send button events to the given
+  channel."
   [channel]
   {:pre [(some? channel)]}
-  (usb/hid-input
-    channel
-    ; TODO: sometimes nil when refreshing code...
-    (usb/find-device snes-vendor-id snes-product-id)
-    snes-read-state
-    snes-state-events))
+  ; TODO: sometimes nil when refreshing code...
+  (if-let [device (usb/find-device snes-vendor-id snes-product-id)]
+    (usb/hid-input
+      channel
+      device
+      snes-read-state
+      snes-state-events)))


Convert axis values to be in [-1.0, 1.0].

--- src/org/playasophy/wonderdome/input/gamepad.clj
+++ src/org/playasophy/wonderdome/input/gamepad.clj
@@ -7,14 +7,16 @@
 ;;;;; HELPER FUNCTIONS ;;;;;

 (defn- byte-axis
-  "Converts a byte value from 00 to FF into a floating-point axis value."
+  "Converts a byte value from [00, FF] into a floating-point axis value from
+  [-1.0, 1.0]."
   [value]
   (->
     (cond
       (zero? value) 0
       (neg? value) (+ 0x101 value)
       :else (inc value))
-    (/ 256.0)))
+    (/ 128.0)
+    (- 1.0)))

 (defn- button-events
@@ -79,7 +81,7 @@
     (println "Incomplete data read from SNES controller:"
              (apply str (map (partial format "%02X") (take len buffer))))
     {:x-axis (byte-axis (aget buffer 0))
-     :y-axis (- 1.0 (byte-axis (aget buffer 1)))
+     :y-axis (- (byte-axis (aget buffer 1)))
      :X (bit-test (aget buffer 3) 0)
      :A (bit-test (aget buffer 3) 1)
      :B (bit-test (aget buffer 3) 2)


fix bug about nimbus.clj

fix bug about nimbus.clj

--- storm-core/src/clj/org/apache/storm/daemon/nimbus.clj
+++ storm-core/src/clj/org/apache/storm/daemon/nimbus.clj
@@ -1353,8 +1353,8 @@
         (str "Failed to submit topology. Topology requests more than " workers-allowed " workers."))))))

 (defn nimbus-topology-bases [storm-cluster-state]
-  map-val #(clojurify-storm-base %) (clojurify-structure
-                                        (StormCommon/topologyBases storm-cluster-state)))
+  (map-val #(clojurify-storm-base %) (clojurify-structure
+                                        (StormCommon/topologyBases storm-cluster-state))))

 (defn- set-logger-timeouts [log-config]
   (let [timeout-secs (.get_reset_log_level_timeout_secs log-config)


CMR-989: formatting

CMR-989: formatting

--- umm-lib/test/cmr/umm/test/validation/granule.clj
+++ umm-lib/test/cmr/umm/test/validation/granule.clj
@@ -86,6 +86,7 @@
         coll (merge (coll-with-range-date-times [coll-range]) {:entry-title "et"})
         assert-valid #(assert-valid-gran coll %)
         assert-invalid #(assert-invalid-gran coll %1 [:temporal] [%2])]
+
     (testing "Granule with no temporal coverage values is valid"
       (assert-valid (make-granule {})))


Use :last-processed-version instead of :latest-processed-version.

--- web-server/src/clj/hatnik/web/server/actions.clj
+++ web-server/src/clj/hatnik/web/server/actions.clj
@@ -10,7 +10,7 @@
 (defn create-action [user data]
   (let [version (ver/latest-release (:library data))
         action (assoc data
-                 :latest-processed-version version)
+                 :last-processed-version version)
         id (stg/create-action! @stg/storage (:id user) action)]
    (resp/response
     (if id
@@ -23,7 +23,7 @@
 (defn update-action [user id data]
   (let [version (ver/latest-release (:library data))
         action (assoc data
-                 :latest-processed-version version)]
+                 :last-processed-version version)]
     (stg/update-action! @stg/storage (:id user) id action)
     (resp/response
      {:result :ok


fix desugar ns specs tests, subject to ordering change

--- test/clj/cljs/analyzer_tests.clj
+++ test/clj/cljs/analyzer_tests.clj
@@ -267,9 +267,9 @@

 (deftest test-cljs-975
   (let [spec '((:require [bar :refer [baz] :refer-macros [quux]] :reload))]
-    (is (= (a/desugar-ns-specs spec)
-           '((:require-macros (bar :refer [quux]) :reload)
-             (:require (bar :refer [baz]) :reload))))))
+    (is (= (set (a/desugar-ns-specs spec))
+           (set '((:require-macros (bar :refer [quux]) :reload)
+                  (:require (bar :refer [baz]) :reload)))))))

 ;; =============================================================================
 ;; Namespace metadata


Four tests for the function message-for-me?

--- test/clj_mrazik/irc_bot_test.clj
+++ test/clj_mrazik/irc_bot_test.clj
@@ -176,3 +176,32 @@
         (is (not (message-to-channel? {:target "channel"})))
         (is (not (message-to-channel? {:target "channel message"})))))

+(deftest test-message-for-me?-1
+    "Check the behaviour of function clj-mrazik.irc-bot/message-for-me?"
+    (testing "the function message-for-me?"
+        (are [name special-prefix message] (message-for-me? name special-prefix {:target message})
+            "bot" "?" "bot:"
+            "bot" "?" "bot: message")))
+
+(deftest test-message-for-me?-2
+    "Check the behaviour of function clj-mrazik.irc-bot/message-for-me?"
+    (testing "the function message-for-me?"
+        (are [name special-prefix message] (message-for-me? name special-prefix {:text message :target "channel"})
+            "bot" "?" "bot:"
+            "bot" "?" "bot: message"
+            "bot" "?" "bot,"
+            "bot" "?" "bot, message")))
+
+(deftest test-message-for-me?-3
+    "Check the behaviour of function clj-mrazik.irc-bot/message-for-me?"
+    (testing "the function message-for-me?"
+        (are [name special-prefix message] (message-for-me? name special-prefix {:text message :target "channel"})
+            "bot" "?" "? message"
+            "bot" "?" "?: message")))
+
+(deftest test-message-for-me?-4
+    "Check the behaviour of function clj-mrazik.irc-bot/message-for-me?"
+    (testing "the function message-for-me?"
+        (is (not (message-for-me? "bot" "?" {:text "?" :target ""})))
+        (is (not (message-for-me? "bot" "?" {:text "" :target ""})))))
+


Pull data fn non-nil tests out into a macro

--- test/comic_reader/sites_test.clj
+++ test/comic_reader/sites_test.clj
@@ -4,25 +4,33 @@
             [comic-reader.scrape :as scrape]
             [net.cgrand.enlive-html :as html]))

+(defmacro test-data-functions-not-nil []
+  `(are [selector] (is (not= (selector)
+                             nil))
+     root-url
+     manga-list-format
+     manga-url-format
+     manga-pattern-match-portion
+
+     comic->url-format
+
+     chapter-list-selector
+     comic-list-selector
+     image-selector
+     page-list-selector
+
+     chapter-number-pattern
+     chapter-number-match-pattern
+
+     link-name-normalize
+     link-url-normalize
+
+     page-normalize-format
+     page-normalize-pattern))
+
 (deftest extract-comics-list-test
   (binding [options (read-site-options "manga-fox")]
-    (are [selector] (is (not= (selector)
-                              nil))
-      chapter-number-match-pattern
-      page-list-selector
-      link-url-normalize
-      manga-pattern-match-portion
-      page-normalize-format
-      manga-list-format
-      page-normalize-pattern
-      chapter-number-pattern
-      comic->url-format
-      link-name-normalize
-      chapter-list-selector
-      manga-url-format
-      root-url
-      comic-list-selector
-      image-selector)
+    (test-data-functions-not-nil)

     (let [html (html/html [:div {}])
           comics (extract-comics-list html)]


[BUG #2241] Fullscreen webview don't overlap topbar

--- src/status_im/chat/views/input/animations/expandable.cljs
+++ src/status_im/chat/views/input/animations/expandable.cljs
@@ -80,12 +80,8 @@
        :reagent-render
        (fn [{:keys [draggable? custom-header]} & elements]
          @to-changed-height @changes-counter @max-height
-         (let [{expandable-offset :expandable-offset
-                status-bar-height :height} (get-in p/platform-specific [:component-styles :status-bar :main])
-               bottom (+ @input-height @chat-input-margin)
-               height (if @fullscreen?
-                        (+ @max-height status-bar-height expandable-offset)
-                        anim-value)]
+         (let [bottom (+ @input-height @chat-input-margin)
+               height (if @fullscreen? @max-height anim-value)]
            [view style/overlap-container
             (when (and (not hide-overlay?)
                        (not @fullscreen?))


[#1142] Add linebreaks to long sql

[#1142] Add linebreaks to long sql

--- backend/src/akvo/lumen/lib/visualisation/map_config.clj
+++ backend/src/akvo/lumen/lib/visualisation/map_config.clj
@@ -124,7 +124,23 @@
               CASE WHEN aggregation IS NULL THEN
                   'grey'
                 ELSE
-                  concat('rgb(255,', 255 - floor(((aggregation::decimal - (select min(aggregation) from temp_table)::decimal) / ((select max(aggregation) from temp_table)::decimal - (select min(aggregation) from temp_table)::decimal)) * 255),',', 255 - floor(((aggregation::decimal - (select min(aggregation) from temp_table)::decimal) / ((select max(aggregation) from temp_table)::decimal - (select min(aggregation) from temp_table)::decimal)) * 255),')')
+                  concat(
+                    'rgb(255,',
+                    255 - floor(
+                      (
+                        (aggregation::decimal - (select min(aggregation) from temp_table)::decimal) /
+                        ((select max(aggregation) from temp_table)::decimal - (select min(aggregation) from temp_table)::decimal)
+                      ) * 255
+                    ),
+                    ',',
+                    255 - floor(
+                      (
+                        (aggregation::decimal - (select min(aggregation) from temp_table)::decimal) /
+                        ((select max(aggregation) from temp_table)::decimal - (select min(aggregation) from temp_table)::decimal)
+                      ) * 255
+                    ),
+                    ')'
+                  )
               END as shapefill
             from
               temp_table;


fix(editor-support): use ccw.swt/ui-async instead of java interop

--- ccw.core/src/clj/ccw/editors/clojure/editor_support.clj
+++ ccw.core/src/clj/ccw/editors/clojure/editor_support.clj
@@ -32,8 +32,7 @@
             [ccw.core.trace :as t]
             [ccw.swt :as swt])
   (:import ccw.editors.clojure.IClojureEditor
-           org.eclipse.ui.texteditor.SourceViewerDecorationSupport
-           ccw.util.DisplayUtil))
+           org.eclipse.ui.texteditor.SourceViewerDecorationSupport))

 #_(set! *warn-on-reflection* true)

@@ -142,4 +141,4 @@
   "The function wraps IClojureAwarePart.setStatusLineErrorMessage in an async ui-only call.
   Remember that passing nil as message resets the status line."
   [^IClojureEditor part message]
-  (DisplayUtil/asyncExec #(.setStatusLineErrorMessage part message)))
+  (swt/ui-async #(.setStatusLineErrorMessage part message)))


refine copy for top and bottom

refine copy for top and bottom

--- src-cljs/frontend/components/landing.cljs
+++ src-cljs/frontend/components/landing.cljs
@@ -67,10 +67,13 @@
               [:a {:role "button"} "Pricing"]
               [:a {:role "button"} "Blog"]
               (common/google-login :small)]]
-            [:div.our-philosphy-wrap.content
-             [:div.our-philosphy
-              [:h1 "Collaborating with your team should be easy from anywhere."]
-              [:p "Prototype ideas anywhere, with anyone, and on any device. No nonsense, it's just what you need, when you need it."]
+            [:div.our-philosphy-wrap
+             [:div.our-philosphy.content
+              ; [:h1 "Collaborating with your team should be easy from anywhere."]
+              [:h1 "Collaboration should be simple."]
+              ; [:p "Prototype ideas anywhere, with anyone, and on any device. No nonsense, it's just what you need, when you need it."]
+              ; [:p "Prototype anywhere on any device. No nonsense, it's just what you need, when you need it."]
+              [:p "Prototype anywhere on any device. No nonsense, just what you need when you need it."]
               [:div.call-to-action
                [:button.make-button
                 {:on-click #(cast! :landing-closed)}
@@ -132,13 +135,19 @@
           [:div.the-what
             [:div.our-proof]
             [:div.our-claim
-             [:div.our-philosphy-wrap.content
-              [:article.our-philosphy
-               [:h1 "It's pure prototyping, just focus on your ideas."]
-               [:p "Productive prototyping without all the nonsense."]
+             [:div.our-philosphy-wrap
+              [:div.our-philosphy.content
+               ; [:h1 "It's pure prototyping, just focus on your ideas."]
+               ; [:h1 "It's pure prototyping, that's it."]
+               ; [:h1 "Purely productive prototyping."]
+               [:h1 "It's purely productive prototyping."]
+               ; [:p "Productive prototyping without all the nonsense."]
+               [:p "Precursor is the easiest way to share ideas with your teammates, fast."]
                [:div.call-to-action
                 (common/google-login)
-                [:button {:on-click #(cast! :landing-closed)} "Or jump in first."]]]]
+                ; [:button {:on-click #(cast! :landing-closed)} "Or jump in first."]
+                (om/build make-button app)
+                ]]]
              [:div.navigation
               [:div.content
                [:a {:role "button"} "Precursor"]


Only show banners for trial licenses for now.

--- src-cljs/frontend/components/license.cljs
+++ src-cljs/frontend/components/license.cljs
@@ -16,8 +16,8 @@
 (defn- banner-for-license
   "Returns the banner for the given license, or nil if no banner applies."
   [license]
-  (case (:status license)
-    "current"
+  (case ((juxt :type :status) license)
+    ["trial" "current"]
     (let [days-until-expiry (days-until-api-time (:expiry_date license))]
       [:.license-banner {:class (:status license)}
        [:.indicator "Trial Account"]
@@ -27,7 +27,7 @@
         {:href "mailto:enterprise@circleci.com"}
         "Contact Sales…"]])

-    "in-violation"
+    ["trial" "in-violation"]
     (let [days-until-suspension (days-until-api-time (:hard_expiry_date license))]
       [:.license-banner {:class (:status license)}
        [:.indicator "Trial Expired"]


think that covers all of the privacy cases

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -428,14 +428,9 @@
       (let [{:keys [cast! db]} (om/get-shared owner)
             doc-id (:document/id app)
             doc (doc-model/find-by-id @db doc-id)
-            cant-edit-reason (cond (:team app)
-                                   nil
-
-                                   (not (contains? (get-in app [:cust :flags]) :flags/private-docs))
-                                   :no-private-docs-flag
-
-                                   (not (auth/owner? @db doc (get-in app [:cust])))
-                                   :not-creator)]
+            no-private-docs? (not (contains? (get-in app [:cust :flags]) :flags/private-docs))
+            cant-edit-privacy? (when-not (:team app)
+                                 (not (auth/owner? @db doc (get-in app [:cust]))))]
         (html
          [:div.menu-view
           (case (:document/privacy doc)
@@ -445,71 +440,69 @@
             :document.privacy/read-only (om/build read-only-sharing app)
             (om/build unknown-sharing app))

-          (case cant-edit-reason
-            :no-private-docs-flag
-            [:a.vein.make.stick.external {:href "/pricing"}
-             [:span "Need private docs? Start a free trial."]
-             (common/icon :arrow-right)]
-
-
-            [:form.privacy-select.vein.make.stick
-             [:input.privacy-radio {:type "radio"
-                                    :hidden "true"
-                                    :id "privacy-public"
-                                    :name "privacy"
-                                    :checked (keyword-identical? :document.privacy/public (:document/privacy doc))
-                                    :disabled (boolean cant-edit-reason)
-                                    :onChange #(if cant-edit-reason
-                                                 (utils/stop-event %)
-                                                 (cast! :document-privacy-changed
-                                                        {:doc-id doc-id
-                                                         :setting :document.privacy/public}))}]
-             [:label.privacy-label {:class (when cant-edit-reason "disabled")
-                                    :title (when (= :not-creator cant-edit-reason) "You must be the owner of this doc to change its privacy.")
-                                    :for "privacy-public"
-                                    :role "button"}
-              (common/icon :public)
-              [:span "Public"]
-              (when (= :not-creator cant-edit-reason)
-                [:small "(privacy change requires owner)"])]
-             [:input.privacy-radio {:type "radio"
-                                    :hidden "true"
-                                    :id "privacy-read-only"
-                                    :name "privacy"
-                                    :checked (keyword-identical? :document.privacy/read-only (:document/privacy doc))
-                                    :disabled (boolean cant-edit-reason)
-                                    :onChange #(if cant-edit-reason
-                                                 (utils/stop-event %)
-                                                 (cast! :document-privacy-changed
-                                                        {:doc-id doc-id
-                                                         :setting :document.privacy/read-only}))}]
-             [:label.privacy-label {:class (when cant-edit-reason "disabled")
-                                    :title (when (= :not-creator cant-edit-reason) "You must be the owner of this doc to change its privacy.")
-                                    :for "privacy-read-only"
-                                    :role "button"}
-              (common/icon :read-only)
-              [:span "Read-only"]
-              (when (= :not-creator cant-edit-reason)
-                [:small "(privacy change requires owner)"])]
-             [:input.privacy-radio {:type "radio"
-                                    :hidden "true"
-                                    :id "privacy-private"
-                                    :name "privacy"
-                                    :checked (keyword-identical? :document.privacy/private (:document/privacy doc))
-                                    :disabled (boolean cant-edit-reason)
-                                    :onChange #(if cant-edit-reason
-                                                 (utils/stop-event %)
-                                                 (cast! :document-privacy-changed
-                                                        {:doc-id doc-id
-                                                         :setting :document.privacy/private}))}]
-             [:label.privacy-label {:class (when cant-edit-reason "disabled")
-                                    :title (when (= :not-creator cant-edit-reason) "You must be the owner of this doc to change its privacy.")
-                                    :for "privacy-private"
-                                    :role "button"}
-              (common/icon :private)
-              [:span "Private"]
-              (when (= :not-creator cant-edit-reason)
-                [:small "(privacy change requires owner)"])]])])))))
+          [:form.privacy-select.vein.make.stick
+           [:input.privacy-radio {:type "radio"
+                                  :hidden "true"
+                                  :id "privacy-public"
+                                  :name "privacy"
+                                  :checked (keyword-identical? :document.privacy/public (:document/privacy doc))
+                                  :disabled (keyword-identical? :document.privacy/public (:document/privacy doc))
+                                  :onChange #(if cant-edit-privacy?
+                                               (utils/stop-event %)
+                                               (cast! :document-privacy-changed
+                                                      {:doc-id doc-id
+                                                       :setting :document.privacy/public}))}]
+           [:label.privacy-label {:class (when cant-edit-privacy? "disabled")
+                                  :title (when cant-edit-privacy? "You must be the owner of this doc to change its privacy.")
+                                  :for "privacy-public"
+                                  :role "button"}
+            (common/icon :public)
+            [:span "Public"]
+            (when cant-edit-privacy?
+              [:small "(privacy change requires owner)"])]
+           [:input.privacy-radio {:type "radio"
+                                  :hidden "true"
+                                  :id "privacy-read-only"
+                                  :name "privacy"
+                                  :checked (keyword-identical? :document.privacy/read-only (:document/privacy doc))
+                                  :disabled cant-edit-privacy?
+                                  :onChange #(if cant-edit-privacy?
+                                               (utils/stop-event %)
+                                               (cast! :document-privacy-changed
+                                                      {:doc-id doc-id
+                                                       :setting :document.privacy/read-only}))}]
+           [:label.privacy-label {:class (when cant-edit-privacy? "disabled")
+                                  p:title (when cant-edit-privacy? "You must be the owner of this doc to change its privacy.")
+                                  :for "privacy-read-only"
+                                  :role "button"}
+            (common/icon :read-only)
+            [:span "Read-only"]
+            (when cant-edit-privacy?
+              [:small "(privacy change requires owner)"])]
+           (if no-private-docs?
+             [:a.vein.make.stick.external {:href "/pricing"}
+              [:span "Need private docs? Start a free trial."]
+              (common/icon :arrow-right)]
+             (list
+              [:input.privacy-radio {:type "radio"
+                                     :hidden "true"
+                                     :id "privacy-private"
+                                     :name "privacy"
+                                     :checked (keyword-identical? :document.privacy/private (:document/privacy doc))
+                                     :disabled (boolean cant-edit-privacy?)
+                                     :onChange #(if cant-edit-privacy?
+                                                  (utils/stop-event %)
+                                                  (cast! :document-privacy-changed
+                                                         {:doc-id doc-id
+                                                          :setting :document.privacy/private}))}]
+              [:label.privacy-label {:class (when cant-edit-privacy? "disabled")
+                                     :title (when cant-edit-privacy? "You must be the owner of this doc to change its privacy.")
+                                     :for "privacy-private"
+                                     :role "button"}
+               (common/icon :private)
+               [:span "Private"]
+               (when cant-edit-privacy?
+                 [:small "(privacy change requires owner)"])]))]])))))

 (defn export [app owner]
   (reify


fix editing privacy on private docs

fix editing privacy on private docs

--- src-cljs/frontend/components/overlay.cljs
+++ src-cljs/frontend/components/overlay.cljs
@@ -413,9 +413,11 @@
       (let [{:keys [cast! db]} (om/get-shared owner)
             doc-id (:document/id app)
             doc (doc-model/find-by-id @db doc-id)
-            no-private-docs? (not (contains? (get-in app [:cust :flags]) :flags/private-docs))
-            cant-edit-privacy? (when-not (:team app)
-                                 (not (auth/owner? @db doc (get-in app [:cust]))))]
+            team? (boolean (:team app))
+            private-docs-flag? (contains? (get-in app [:cust :flags]) :flags/private-docs)
+            can-edit-privacy? (if team?
+                                (auth/has-team-permission? app (:team/uuid (:team app)))
+                                (auth/owner? @db doc (get-in app [:cust])))]
         (html
          [:section.menu-view
           (case (:document/privacy doc)
@@ -432,39 +434,39 @@
                                   :name "privacy"
                                   :checked (keyword-identical? :document.privacy/public (:document/privacy doc))
                                   :disabled (keyword-identical? :document.privacy/public (:document/privacy doc))
-                                  :onChange #(if cant-edit-privacy?
-                                               (utils/stop-event %)
+                                  :onChange #(if can-edit-privacy?
                                                (cast! :document-privacy-changed
                                                       {:doc-id doc-id
-                                                       :setting :document.privacy/public}))}]
-           [:label.privacy-label {:class (when cant-edit-privacy? "disabled")
-                                  :title (when cant-edit-privacy? "You must be the owner of this doc to change its privacy.")
+                                                       :setting :document.privacy/public})
+                                               (utils/stop-event %))}]
+           [:label.privacy-label {:class (when-not can-edit-privacy? "disabled")
+                                  :title (when-not can-edit-privacy? "You must be the owner of this doc to change its privacy.")
                                   :for "privacy-public"
                                   :role "button"}
             (common/icon :public)
             [:span "Public"]
-            (when cant-edit-privacy?
+            (when-not can-edit-privacy?
               [:small "(privacy change requires owner)"])]
            [:input.privacy-radio {:type "radio"
                                   :hidden "true"
                                   :id "privacy-read-only"
                                   :name "privacy"
                                   :checked (keyword-identical? :document.privacy/read-only (:document/privacy doc))
-                                  :disabled cant-edit-privacy?
-                                  :onChange #(if cant-edit-privacy?
-                                               (utils/stop-event %)
+                                  :disabled (not can-edit-privacy?)
+                                  :onChange #(if can-edit-privacy?
                                                (cast! :document-privacy-changed
                                                       {:doc-id doc-id
-                                                       :setting :document.privacy/read-only}))}]
-           [:label.privacy-label {:class (when cant-edit-privacy? "disabled")
-                                  :title (when cant-edit-privacy? "You must be the owner of this doc to change its privacy.")
+                                                       :setting :document.privacy/read-only})
+                                               (utils/stop-event %))}]
+           [:label.privacy-label {:class (when-not can-edit-privacy? "disabled")
+                                  :title (when-not can-edit-privacy? "You must be the owner of this doc to change its privacy.")
                                   :for "privacy-read-only"
                                   :role "button"}
             (common/icon :read-only)
             [:span "Read-only"]
-            (when cant-edit-privacy?
+            (when-not can-edit-privacy?
               [:small "(privacy change requires owner)"])]
-           (if no-private-docs?
+           (if (and can-edit-privacy? (not team?) (not private-docs-flag?))
              [:a.vein.external {:href "/pricing"}
               (common/icon :private)
               [:span "Private"]
@@ -476,19 +478,19 @@
                                      :id "privacy-private"
                                      :name "privacy"
                                      :checked (keyword-identical? :document.privacy/private (:document/privacy doc))
-                                     :disabled (boolean cant-edit-privacy?)
-                                     :onChange #(if cant-edit-privacy?
-                                                  (utils/stop-event %)
+                                     :disabled (not can-edit-privacy?)
+                                     :onChange #(if can-edit-privacy?
                                                   (cast! :document-privacy-changed
                                                          {:doc-id doc-id
-                                                          :setting :document.privacy/private}))}]
-              [:label.privacy-label {:class (when cant-edit-privacy? "disabled")
-                                     :title (when cant-edit-privacy? "You must be the owner of this doc to change its privacy.")
+                                                          :setting :document.privacy/private})
+                                                  (utils/stop-event %))}]
+              [:label.privacy-label {:class (when-not can-edit-privacy? "disabled")
+                                     :title (when-not can-edit-privacy? "You must be the owner of this doc to change its privacy.")
                                      :for "privacy-private"
                                      :role "button"}
                (common/icon :private)
                [:span "Private"]
-               (when cant-edit-privacy?
+               (when-not can-edit-privacy?
                  [:small "(privacy change requires owner)"])]))]])))))

 (defn export [app owner]


Profiles place holder.

Profiles place holder.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -662,7 +662,9 @@
                  ;; Profiles
                  [:div {:class (if (not= active-tab :profiles) "hidden" "col-md-12")}
                   [:h3 "Profiles"]
-                  [:p "Profiles go here..."]]]
+                  [:div.col-md-12.text-center
+                   [:p.lead {:style {:padding-top 30}}
+                    "Profiles go here."]]]]

                 )])))))


Tidy up of onClick for sorting.

Tidy up of onClick for sorting.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -512,12 +512,9 @@
     [:span {:class "label label-danger"} status]))

 (defn sorting-th [owner label header-key]
-  (let [{:keys [sort-key sort-asc]} (:sort-spec (om/get-state owner))]
-    [:th {:onClick (fn [_ _]
-                     (let [th-chan (:th-chan (om/get-state owner))]
-                       (log "Owner: " owner " th-chan " th-chan " header-key " header-key)
-                       (log "Clicked on: " header-key)
-                       (put! th-chan header-key (fn [closed] (if closed "I'm Closed!" "I work.")))))}
+  (let [{:keys [sort-spec th-chan]} (om/get-state owner)
+        {:keys [sort-key sort-asc]} sort-spec]
+    [:th {:onClick (fn [_ _] (put! th-chan header-key))}
      (str label " ")
      (if (= sort-key header-key)
        (if sort-asc


Property Details.

Property Details.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -148,6 +148,8 @@
         :headers {"Accept" "application/edn"}
         :response-format :text}))

+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; History loop - this drives the fetches and clear downs
 (defn history-loop [history-channel data]
   (go-loop []
     (let [nav-event (<! history-channel)
@@ -165,16 +167,20 @@
       (when (and old-programmes
                  (nil? programmes))
         (println "Clearing projects.")
-        (om/update! data [:projects :data] []))
+        (om/update! data [:projects :data] [])
+        (om/update! data [:projects :programme_id] nil))

       (when (and old-projects
                  (nil? projects))
         (println "Clearing properties.")
-        (om/update! data [:properties :data] []))
+        (om/update! data [:properties :data] [])
+        (om/update! data [:properties :project_id] nil))

       (when (and old-properties
                  (nil? properties))
         (println "Clearing devices, sensors and measurements.")
+        (om/update! data [:property-details :data] {})
+        (om/update! data [:property-details :property_id] nil)
         (om/update! data [:devices :data] [])
         (om/update! data [:sensors :data] [])
         (om/update! data [:measurements :data] []))
@@ -196,15 +202,20 @@
         (println "Setting selected project to: " projects)
         (om/update! data [:projects :selected] projects)
         (fetch-properties projects data))
+
+      (when (and properties
+                 (not= properties old-properties))
+        (om/update! data [:properties :selected] properties)
+        (om/update! data [:property-details :property_id] properties)
+        (om/update! data [:property-details :data] (->> @data
+                                                        :properties
+                                                        :data
+                                                        (filter #(= (:id %) properties))
+                                                        first)))

       ;; Update the new active components
       (om/update! data :active-components (-> nav-event :args :ids)))
     (recur)))
-
-(defn property-loop [property-chan data]
-  (go-loop []
-    (let [property-details (<! property-chan)]
-      (om/update! data [:property-details :data] property-details))))

 (defn selected-range-change
   [selected selection-key {{ids :ids search :search} :args}]
@@ -415,8 +426,7 @@

 (defmethod properties-table-html :has-data [properties owner]
   (let [table-id "properties-table"
-        history  (om/get-shared owner :history)
-        property-chan (om/get-shared owner :property-chan)]
+        history  (om/get-shared owner :history)]
     [:div.col-md-12
      [:table {:className "table table-hover"}
       [:thead
@@ -427,8 +437,7 @@
           [:tr
            {:onClick (fn [_ _]
                        (om/update! properties :selected id)
-                       (history/update-token-ids! history :properties id)
-                       (put! property-chan property-details))
+                       (history/update-token-ids! history :properties id))
             :className (if (= id (:selected properties)) "success")
             :id (str table-id "-selected")}
            [:td (:property_code property-details)]
@@ -485,7 +494,7 @@
     (render [_]
       (let [property-details (-> data :property-details :data)
             property_data (:property_data property-details)]
-        (html [:div.col-md-12
+        (html [:div {:class (str "col-md-12" (if (:property_id (:property-details data)) "" " hidden"))}
                [:h2 "Property Details"]
                (bs/panel
                 (:slug property-details)
@@ -790,8 +799,6 @@
         ;; handle navigation changes
         (history-loop (tap-history) data)

-        (property-loop property-chan data)
-
         (chart-ajax (tap-history)
                     (:chart data)
                     {:template "/4/entities/:properties/devices/:devices/measurements?startDate=:start-date&endDate=:end-date"


Fixed changed name on spit-csv fn

Fixed changed name on spit-csv fn

--- test/semantic_csv/files_test.clj
+++ test/semantic_csv/files_test.clj
@@ -5,12 +5,12 @@

 (def test-fn "test/test.csv")

-(deftest slurp-and-process-test
+(deftest slurp-csv-test
   (testing "should work"
-    (is (= (first (slurp-and-process test-fn))
+    (is (= (first (slurp-csv test-fn))
            {:this "1" :that "2" :more "stuff"})))
   (testing "should work with cast-fns"
-    (is (= (first (slurp-and-process test-fn :cast-fns {:this ->int}))
+    (is (= (first (slurp-csv test-fn :cast-fns {:this ->int}))
            {:this 1 :that "2" :more "stuff"}))))


Added function description

Added function description

--- test/trumpet_server/web_test.clj
+++ test/trumpet_server/web_test.clj
@@ -9,6 +9,7 @@
   (some #(if (func %) %) data))

 (defn find-href-in-response [response]
+  "Returns a function to which you can pass a rel that returns the href matching this rel"
   (fn [rel]
     (->> response :_links (find-first #(= (:rel %) rel)) :href)))


expand smart errors

expand smart errors

--- sidecar/src/figwheel_sidecar/config_check/type_check.clj
+++ sidecar/src/figwheel_sidecar/config_check/type_check.clj
@@ -553,6 +553,117 @@
                    :figg [['Fig [:subst :figg :figwheel] 'Yep]
                           ['Fig [:subst :figg :firstwheel] [:bad-value] [:bad-value]]
                           ['Fig [:subst :figg :fogwheel] [:bad-value]]])
+
+(defn path-count [orig-config [x & xs]]
+  (if-let [next-config (and (coll? orig-config) (get orig-config x))]
+    (inc (path-count next-config xs))
+    0))
+
+(defn path-score [orig-config path]
+  (if (empty? path) 0
+    (/ (path-count orig-config path)
+       (count path))))
+
+(defn best-path [orig-config paths]
+  (when (not-empty paths)
+    (first (max-val (mapv (juxt identity (partial path-score orig-config)) paths)))))
+
+#_(best-path {:some {:a 1 :c 3}} [[:thing :c]])
+
+#_(path-score {:some {:a 1 :c 3}} [[:thing :c]])
+
+#_(best-path {:a {:b {:c {:d 5}}}} [[:a :b :c :d :e] [:a :b :r]])
+
+(defn misplaced-key? [root-type orig-config parent-typ parent-config-value bad-key]
+  (let [potential-types (for [[ky _ [pt _ val-typ]] (schema-rules [:- bad-key])
+                              :when (not= pt parent-typ)]
+                          {:parent-type pt :child-type  val-typ})
+        correct-path-types
+        (filter
+         (comp not-empty :correct-paths)
+         (mapv
+          #(assoc %
+                  :correct-paths
+                  (get-paths-for-key root-type (get % :child-type) bad-key))
+          potential-types))
+        child-analysis (detailed-config-analysis {bad-key (get parent-config-value bad-key)})
+        correct-path-types
+        (filter (fn [{:keys [parent-type]}]
+                  (true? (analysis-type-matches parent-type child-analysis)))
+                correct-path-types)
+        best-fit-path  (best-path orig-config (mapcat :correct-paths correct-path-types))]
+    ;; TODO best path can't exist already!!
+    ;; make sure that value matches type
+    #_[bad-key child-analysis potential-types correct-path-types best-fit-path ]
+    #_(prn )
+    (when best-fit-path
+      (let [{:keys [parent-type child-type]}
+            (first (filter #((set (:correct-paths %)) best-fit-path) correct-path-types))]
+        {:Error :misplaced-key
+         :key bad-key
+         :correct-type [parent-type :> child-type]
+         :correct-paths [best-fit-path]
+         :confidence :high}))
+    ))
+
+;; TODO this is a duplicate of the above functionality
+;; please take a look at this
+;; more than likely can use a simple child analysis to determine this
+;; info in one function
+(defn misspelled-misplaced-key? [root-type orig-config parent-typ parent-config-value bad-key]
+  (let [potential-types (for [[ky _ [pt _ val-typ]] (schema-rules :-)
+                              :when (and
+                                     (not= pt parent-typ)
+                                     (similar-key 0 bad-key ky))]
+                          {:parent-type pt :child-type  val-typ :new-key ky})
+        correct-path-types
+        (filter
+         identity #_(comp not-empty :correct-paths)
+         (mapv
+          #(assoc %
+                  :correct-paths
+                  (get-paths-for-key root-type (get % :child-type) (get % :new-key)))
+          potential-types))
+        child-analysis-fn (fn [new-key]
+                            (detailed-config-analysis {new-key (get parent-config-value bad-key)}))
+        correct-path-types
+        (filter (fn [{:keys [parent-type new-key]}]
+                  (true? (analysis-type-matches parent-type (child-analysis-fn new-key))))
+                correct-path-types)
+        best-fit-path  (best-path orig-config (mapcat :correct-paths correct-path-types))]
+    ;; TODO best path can't exist already!!
+    ;; make sure that value matches type
+    #_[bad-key potential-types correct-path-types best-fit-path ]
+    #_(prn potential-types correct-path-types)
+    (when best-fit-path
+      (let [{:keys [parent-type new-key child-type]}
+            (first (filter #((set (:correct-paths %)) best-fit-path) correct-path-types))]
+        {:Error :misspelled-misplaced-key
+         :key bad-key
+         :correction new-key
+         :correct-type [parent-type :> child-type]
+         :correct-paths [best-fit-path]
+         :confidence :high}))))
+
+(with-schema
+  (index-spec
+   (spec 'Topper
+         {:some (ref-schema 'Some)
+          :thing (ref-schema 'Thing)})
+   (spec 'Some
+         {:a 1
+          :b 2})
+   (spec 'Thing
+         {:c 3
+          :d 4})
+   (spec 'Bing
+         {:c 4
+          :g 4}))
+  (misplaced-key? 'Topper
+                  {:some {:a 1 :c 3}}
+                  'Some {:a 1 :c 3}
+                  :c ))
+
 #_(pp)

 (defn unknown-key-error-helper [root-type parent-type bad-key value error]


Disable generative test for now

Disable generative test for now

--- test/flare/report_test.clj
+++ test/flare/report_test.clj
@@ -12,7 +12,7 @@
   (with-redefs [report* (fn [_] (throw (ex-info "what ever" {})))]
     (is (nil? (report :whatever)))))

-(defspec generate-report-always-returns-non-empty-list-when-given-diffs
+#_(defspec generate-report-always-returns-non-empty-list-when-given-diffs
   100
   (prop/for-all [[a b] (distinct-values gen/any gen/any)]
                 (not-empty (report (diff* a b)))))


Model warning data on figwheel's requirements

--- src/adzerk/boot_cljs/impl.clj
+++ src/adzerk/boot_cljs/impl.clj
@@ -3,6 +3,7 @@
             [boot.kahnsort :as kahn]
             [boot.pod :as pod]
             [boot.util :as butil]
+            [clojure.string :as str]
             [cljs.analyzer :as ana]
             [cljs.analyzer.api :as ana-api :refer [empty-state warning-enabled?]]
             [cljs.build.api :as build-api :refer [build inputs target-file-for-cljs-ns]]
@@ -66,25 +67,34 @@
 (defn compile-cljs
   "Given a seq of directories containing CLJS source files and compiler options
   opts, compiles the CLJS to produce JS files."
-  [input-path {:keys [optimizations] :as opts}]
+  [input-path {:keys [optimizations asset-path] :as opts}]
   ;; So directories need to be passed to cljs compiler when compiling in dev
   ;; or there are stale namespace problems with tests. However, if compiling
   ;; with optimizations other than :none adding directories will break the
   ;; build and defeat tree shaking and :main option.
   (let [dirs (:directories pod/env)
-        ; Includes also some tmp-dirs passed to this pod, but shouldn't matter
+        ;; Includes also some tmp-dirs passed to this pod, but shouldn't matter
         source-paths (concat (:source-paths pod/env) (:resource-paths pod/env))
         warnings (atom [])
         handler (fn [warning-type env extra]
                   (when (warning-enabled? warning-type)
                     (when-let [s (ana/error-message warning-type extra)]
-                      (let [path (util/find-original-path source-paths dirs ana/*cljs-file*)]
-                        (butil/warn "WARNING: %s %s\n" s (when (:line env)
-                                                           (str "at line " (:line env) " " path)))
-                        (swap! warnings conj {:message s
-                                              :file path
-                                              :line (:line env)
-                                              :type warning-type})))))]
+                      (let [path (if (= (-> env :ns :name) 'cljs.core)
+                                   ;; AR - figwheel does this as well
+                                   (-> asset-path
+                                       (str/replace #"/$" "")
+                                       (str "/cljs/core.cljs"))
+                                   (util/find-original-path source-paths dirs ana/*cljs-file*))
+                            warning-data {:line (:line env)
+                                          :column (:column env)
+                                          :ns (-> env :ns :name)
+                                          :file path
+                                          :type warning-type
+                                          :message s
+                                          :extra extra}]
+                        (butil/warn "WARNING: %s %s\n" s (when (:line env) (str "at line " (:line env) " " path)))
+                        (butil/dbug "%s\n" (butil/pp-str warning-data))
+                        (swap! warnings conj warning-data)))))]
     (try
       (build
         (inputs input-path)


Removed contrib dependency.

Removed contrib dependency.

--- src/appengine_magic/services/url_fetch.clj
+++ src/appengine_magic/services/url_fetch.clj
@@ -5,8 +5,7 @@
             FetchOptions$Builder
             HTTPHeader
             HTTPRequest
-            HTTPMethod])
-  (:require [clojure.contrib.string :as string]))
+            HTTPMethod]))

 (defonce *urlfetch-service* (atom nil))

@@ -30,7 +29,9 @@
   (map
    (fn [[name-key val]]
      (com.google.appengine.api.urlfetch.HTTPHeader.
-      (string/as-str name-key)
+      (if (keyword? name-key)
+          (.substring (str name-key) 1)
+          (str name-key))
       val))
    header-map))


filter dependents a little better

filter dependents a little better

--- support/src/figwheel/client/file_reloading.cljs
+++ support/src/figwheel/client/file_reloading.cljs
@@ -64,6 +64,7 @@
 (defn immutable-ns? [name]
   (or (#{"goog"
          "cljs.core"
+         "cljs.nodejs"
          "an.existing.path"
          "dup.base"
          "far.out"
@@ -148,7 +149,8 @@

 (defn get-all-dependents [nss]
   (let [topo-sort' (build-topo-sort ns->dependents)]
-    (reverse (apply concat (topo-sort' (set nss))))))
+    (filter (comp not immutable-ns?)
+            (reverse (apply concat (topo-sort' (set nss)))))))

 #_(prn "dependents" (get-all-dependents [ "example.core" "figwheel.client.file_reloading" "cljs.core"]))


+dei +della

+dei +della

--- src/babel/italiano/morphology/articles.clj
+++ src/babel/italiano/morphology/articles.clj
@@ -4,8 +4,16 @@
 (def l-apostrophe
   {

+   #"^dei$"
+   {:replace-with "de i"
+    :unify-with :top}
+
    #"^del$"
    {:replace-with "di il"
+    :unify-with :top}
+
+   #"^della$"
+   {:replace-with "di la"
     :unify-with :top}

    #"^l$"


more simplification

more simplification

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -137,10 +137,8 @@
               (let [path (first comp-paths)
                     bolts-at (first bolts-at-paths)]
                 (flatten
-                 (mapfn
-                  (fn [bolt-at]
-                    (let [bolt (assoc-in bolt path bolt-at)]
-                      (add-bolt-at top-bolt bolt path bolt-at model depth max-depth)))
+                 (mapfn #(let [bolt (assoc-in bolt path %)]
+                           (add-bolt-at top-bolt bolt path % model depth max-depth))
                   bolts-at))))))))

 (defn add-bolt-at [top-bolt bolt path bolt-at model depth max-depth]


logging

logging

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -118,7 +118,7 @@
                                   (flatten (vals lexicon))))]
                  (if (not (empty? subset))
                    (log/debug (str "lightning-bolts: " (get-in parent [:rule])
-                                   " : (optimizeme) size of subset of candidate heads: "
+                                   " : subset of candidate heads: "
                                    (count subset) " with spec: " (strip-refs spec)))
                    (log/debug (str "index returned a null set for spec:" (strip-refs spec))))
                  (log/trace (str "lightning-bolts: " (get-in parent [:rule])


re-enabling filtering-on-spec in (defn lightning-bolts)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -247,9 +247,10 @@
           (lazy-mapcat (fn [parent]
                          (if (= false (get-in parent [:head :phrasal] false))
                            (let [candidate-lexemes (get-lex parent :head index)
-                                 filter-on-spec {:synsem {:cat (get-in spec [:cat] :top)
-                                                          :sem (get-in spec [:synsem :sem] :top)}}
-                                 subset (filter #(or true (not (fail? (unifyc filter-on-spec %))))
+                                 filter-on-spec {:synsem {:cat (get-in parent [:head :cat] :top)
+                                                          :essere (get-in parent [:head :essere] :top)
+                                                          :sem (get-in parent [:head :synsem :sem] :top)}}
+                                 subset (filter #(not (fail? (unifyc filter-on-spec %)))
                                                 candidate-lexemes)]
                              (filter #(not (nil? %))
                                      (do (log/debug (str "trying over parent:" (:rule parent)))


revert changes to (defn lexemes-before-phrases)

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -269,12 +269,13 @@
   which makes returning true (i.e. lexemes first) increasingly likely
   as depth increases."
   [depth max-total-depth]
-  (and (not randomize-lexemes-before-phrases)
-       (> max-total-depth 0)
-       (let [prob (- 1.0 (/ (- max-total-depth depth)
-                            max-total-depth))]
-         (log/trace (str "P(c," depth ") = " prob " (c: probability of choosing lexemes rather than phrases given depth " depth ")"))
-         (> (* 10 prob) (rand-int 10)))))
+  (if (not randomize-lexemes-before-phrases)
+    false
+    (if (> max-total-depth 0)
+      (let [prob (- 1.0 (/ (- max-total-depth depth)
+                           max-total-depth))]
+        (log/trace (str "P(c," depth ") = " prob " (c: probability of choosing lexemes rather than phrases given depth " depth ")"))
+        (> (* 10 prob) (rand-int 10))))))

 (defn not-fail? [arg]
   (not (= :fail arg)))


logging improvement

logging improvement

--- src/babel/generate.cljc
+++ src/babel/generate.cljc
@@ -142,7 +142,7 @@
               (lightning-bolt grammar lexicon each-spec depth index morph total-depth))
             spec)
     (do
-      (log/debug (str "lightning-bolt(depth=" depth "; total-depth=" total-depth "; cat=" (get-in spec [:synsem :cat]) ")"))
+      (log/debug (str "lightning-bolt(depth=" depth "; total-depth=" total-depth "; cat=" (get-in spec [:synsem :cat]) "; spec=" (strip-refs spec) ")"))
       (let [morph (if morph morph (fn [input] (get-in input [:rule] :default-morph-no-rule)))
             depth (if depth depth 0)
             parents (shuffle (filter #(not (fail? %)) (mapfn (fn [rule] (unifyc spec rule)) grammar)))]


further reduce instances of model-creation

--- src/babel/italiano.cljc
+++ src/babel/italiano.cljc
@@ -14,16 +14,8 @@
    [clojure.string :as string]
    [dag_unify.core :refer [fail-path-between get-in strip-refs unifyc]]))

-(defonce medium-model (promise))
-(defn medium []
-  (if (realized? medium-model)
-    @medium-model
-    @(do
-       (println (str "creating Italian model..(will be slow the first time).."))
-       (let [result
-             (deliver medium-model (grammar/medium))]
-         (println (str "done."))
-         result))))
+(def medium
+  (grammar/medium))

 (defonce np-grammar-model (promise))
 (defn np-grammar []
@@ -53,7 +45,7 @@
   "analyze a word: as opposed to parsing which is multi-word."
   ;; TODO: should take a language model, not a lexicon
   ([surface-form]
-   (analyze surface-form (:lexicon (medium))))
+   (analyze surface-form (:lexicon medium)))
   ([surface-form lexicon]
    (morph/analyze surface-form lexicon)))

@@ -61,7 +53,7 @@
   ([]
    (let [max-total-depth generate/max-depth
          truncate-children true
-         model (medium)]
+         model medium]
      (generate {:modified false}
                :max-total-depth max-total-depth
                :truncate-children true
@@ -69,7 +61,7 @@
   ([spec & {:keys [model do-enrich max-total-depth truncate]
             :or {do-enrich true
                  max-total-depth generate/max-depth
-                 model (medium)
+                 model medium
                  truncate true}}]
    (log/debug (str "generating with spec: " (strip-refs spec) " with max-total-depth: " max-total-depth))
    (let [result (generate/generate spec model)]
@@ -113,7 +105,7 @@

   ([input]
    (let [input (preprocess input)]
-     (parse input (medium))))
+     (parse input medium)))

   ([input model]
    (let [model (if (future? model) @model model)


Eliminate reflection.

Eliminate reflection.

--- core/src/immutant/internal/options.clj
+++ core/src/immutant/internal/options.clj
@@ -68,7 +68,7 @@

 (defn ^java.util.Map opts->map
   "Converts an Option class into a map of name -> Option instance."
-  [class]
+  [^Class class]
   ;; clojure 1.7.0 no longer initializes classes on import, so we have
   ;; to force init here (see CLJ-1315)
   (Class/forName (.getName class))


Some uncommitted unit tests

Some uncommitted unit tests

--- test/takehome/unit/web.clj
+++ test/takehome/unit/web.clj
@@ -43,4 +43,22 @@
  (fact "Hello returns OK"
        (let [resp (request :get "/hello" {:params {:nickname "world"}})]
          (:status resp) => 200
-         (get-in resp [:body]) => "Hello world!\n")))
+         (get-in resp [:body]) => "Hello world!\n"))
+
+ (fact "Subscribe to topic returns OK"
+       (let [resp (request :post "/kittens_and_puppies/alice")]
+         (:status resp) => 200))
+
+ (fact "Unsubscribe from topic returns OK"
+       (let [resp (request :delete "/kittens_and_puppies/alice")]
+         (:status resp) => 200))
+
+ (fact "Unsubscribe from unsubscribed topic returns NOT_FOUND"
+       (let [resp (request :delete "/kittens_and_puppies/bob")]
+         (:status resp) => 404))
+
+ (fact "Publish to topic returns OK"
+       (let [resp (request :post "/kittens_and_puppies" {:params {:message "http://cuteoverload.files.wordpress.com/2014/10/unnamed23.jpg?w=750&h=1000"}})]
+         (:status resp) => 404))
+
+)


Added support for standard-behavior boolean attributes (i.e. attributes which take "" as true and nil as false) to normalize-attr-value.

--- src-cljs/freactive/dom.cljs
+++ src-cljs/freactive/dom.cljs
@@ -9,6 +9,7 @@

 (defprotocol IDOMImage
   "A protocol for things that can be represented as virtual DOM or contain DOM nodes.
+
 Can be used to define custom conversions to DOM nodes or text for things such as numbers
 or dates; or can be used to define containers for DOM elements themselves."
   (-get-dom-image [x]
@@ -170,6 +171,8 @@
   (cond
     (.-substring value) value
     (keyword? value) (name value)
+    (identical? value true) ""
+    (identical? value false) nil
     (satisfies? IDOMAttrValue value) (-get-attr-value value)
     :default (.toString value)))


Use resolve to fetch project workflow runs

--- src-cljs/frontend/send.cljs
+++ src-cljs/frontend/send.cljs
@@ -113,30 +113,6 @@
        ;; Wrap the callback to rename the key in the result back to the alias.
        #(cb (rename-keys %1 {aliased-from (:key ast)}) %2)]
       [expr cb])))
-
-(defn- merge-workflow-runs
-  [{vcs-type :organization/vcs-type
-    org-name :organization/name
-    project-name :project/name}
-   offset
-   limit
-   merge-fn
-   query]
-  (api/get-project-workflows
-   (callback-api-chan
-    (fn [response]
-      (let [novelty {:circleci/organization
-                     {:organization/project
-                      {:project/name project-name
-                       :project/organization {:organization/vcs-type vcs-type
-                                              :organization/name org-name}
-                       :routed-page {:connection/total-count (:total-count response)
-                                     :connection/edges (->> (:results response)
-                                                            (map adapt-to-run)
-                                                            (mapv #(hash-map :edge/node %)))}}}}]
-        (merge-fn novelty query))))
-   (vcs-url/vcs-url vcs-type org-name project-name)
-   {:offset offset :limit limit}))

 (def ^:private ignore-response-callback (fn [_response] nil))

@@ -402,6 +378,26 @@
               ;; rest of the query.
               (parser {:state (atom adapted)} (mapv om-next/ast->query (:children ast))))))))

+   :project/workflow-runs
+   (fn [env ast]
+     (-> (api-promise
+          api/get-project-workflows
+          (vcs-url/vcs-url (:organization/vcs-type env)
+                           (:organization/name env)
+                           (:project/name env))
+          {:offset (:connection/offset (:params ast))
+           :limit (:connection/limit (:params ast))})
+
+         (p/then
+          (fn [response]
+            (let [adapted {:connection/total-count (:total-count response)
+                           :connection/edges (->> (:results response)
+                                                  (map adapt-to-run)
+                                                  (mapv #(hash-map :edge/node %)))}]
+              ;; Run the adapted structure through a parser to match it to the
+              ;; rest of the query.
+              (parser {:state (atom adapted)} (mapv om-next/ast->query (:children ast))))))))
+
    :app/current-user
    (fn [env ast]
      (-> (api-promise api/get-orgs :include-user? true)
@@ -486,7 +482,8 @@
                                            :project/parallelism
                                            :project/oss?]}
                   {:organization/plan [*]}]
-                (:query ast))))))
+                (:query ast)))
+        (project-runs-ast? ast))))

 (defmulti send* key)

@@ -515,28 +512,6 @@
         (let [[expr cb] (de-alias-expression expr cb)
               ast (om-parser/expr->ast expr)]
           (cond
-            ;; Also :route/projects (but a separate expression for analytics, which
-            ;; doesn't actually need to hit the server)
-            (and (= :circleci/organization (:key ast))
-                 (= '[:organization/name] (:query ast)))
-            (let [{:keys [organization/vcs-type organization/name]} (:params ast)]
-              (cb {:circleci/organization {:organization/name name}} query))
-
-            ;; :route/workflow
-            (project-runs-ast? ast)
-            (let [{:keys [connection/offset connection/limit]}
-                  (:params (expr-ast/get-in ast [:organization/project :routed-page]))]
-              (merge-workflow-runs {:organization/vcs-type (-> ast :params :organization/vcs-type)
-                                    :organization/name (-> ast :params :organization/name)
-                                    :project/name (-> ast
-                                                      (expr-ast/get :organization/project)
-                                                      :params
-                                                      :project/name)}
-                                   offset
-                                   limit
-                                   cb
-                                   query))
-
             ;; :route/run
             (let [{:keys [key children]} ast]
               (and (= :circleci/run key)


Made date and postcode input fields not text areas

--- src-cljs/meetdown/view.cljs
+++ src-cljs/meetdown/view.cljs
@@ -49,21 +49,17 @@
                          :on-change (send-value! ui-channel #(m/map->ChangeEvent {:name name :speaker speaker :description % :date date }))}]]
    [:div.row.col-xs-12
     [:label.col-xs-4 "Event Date:"]
-    [:textarea.col-xs-6 {:type :text
+    [:input.col-xs-6 {:type :text
                          :placeholder "Date of the event..."
                          :defaultValue date
                          :on-change (send-value! ui-channel #(m/map->ChangeEvent {:name name :speaker speaker :description  description :date % }))}]]

-
-
    [:div.row.col-xs-12
     [:label.col-xs-4 "PostCode:"]
-    [:textarea.col-xs-6 {:type :text
+    [:input.col-xs-6 {:type :text
                          :placeholder "Post Code"
                          :defaultValue postCode
                          :on-change (send-value! ui-channel #(m/map->ChangeLocation {:postCode %}))}]]
-
-
    [:div.row.col-xs-12
     [:div.col-xs-4
      [:button.btn.btn-success


Fix kill-ch pending take bug

Fix kill-ch pending take bug

--- src/cljs/gtfve/components/maps_canvas/google.cljs
+++ src/cljs/gtfve/components/maps_canvas/google.cljs
@@ -77,8 +77,8 @@
           position-changed-ch (-> (maps/listen marker "position_changed")
                                   (utils/debounce 100))]
       (go-loop []
-        (let [[v ch] (alts! [position-changed-ch kill-ch])]
-          (if (= ch kill-ch)
+        (let [[v ch] (alts! [position-changed-ch kill-tap])]
+          (if (= ch kill-tap)
             ::done
             (let [[lat lng] (.getPosition marker)]
               (raise! owner [:change-added [:stop eid


Added new config fns for use by fs watchers.

--- src/cmr/dev/env/manager/components/dem/config.clj
+++ src/cmr/dev/env/manager/components/dem/config.clj
@@ -61,6 +61,10 @@

 ;; CMR-level config

+(defn service-paths
+  [system service-key]
+  (active-config system config/external-cfg-key service-key :source-paths))
+
 (defn service-ports
   [system]
   (active-config system config/external-cfg-key :ports))
@@ -68,6 +72,15 @@
 (defn service-port
   [system service-key]
   (active-config system config/external-cfg-key :ports service-key))
+
+;; Mixed-level config
+
+(defn enabled-service-paths
+  [system]
+  (->> (enabled-services system)
+       (map (fn [x] [x (service-paths system x)]))
+       (filter second)
+       (into {})))

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;   Lifecycle Implementation   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Fixing embedded elastic server.

Fixing embedded elastic server.

--- src/cmr/elastic_utils/embedded_elastic_server.clj
+++ src/cmr/elastic_utils/embedded_elastic_server.clj
@@ -6,7 +6,8 @@
            org.elasticsearch.node.NodeBuilder
            org.elasticsearch.node.Node)
   (:require [cmr.common.lifecycle :as lifecycle]
-            [clj-http.client :as client]))
+            [clj-http.client :as client]
+            [cmr.common.log :as log :refer (debug info warn error)]))

 {"path" {"data" "es_data/elastic_utils"}, "index" {"store" {"type" "memory"}}, "node" {"name" "embedded-elastic"}, "script" {"disable_dynamic" "true"}, "transport" {"tcp" {"port" "9334"}}, "http" {"port" "9234"}}


Implemented returning of refs created with execute-init from backend to frontend.

--- src/clj_formal_specifications_app/core.clj
+++ src/clj_formal_specifications_app/core.clj
@@ -40,9 +40,15 @@
   [ns]
   (map key (filter #(:action (meta (val %))) (ns-publics (symbol ns)))))

+(defn ns-spec-refs
+  [ns]
+  (map key (filter #(:spec-ref (meta (var-get (val %))))
+                   (ns-publics (symbol ns)))))
+
 (defn ns-specification
   [ns]
-  {:actions (ns-actions ns)})
+  {:actions (ns-actions ns)
+   :spec-refs (ns-spec-refs ns)})

 (defn compose
   [specification]