Bad type hint.

Bad type hint.

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -197,7 +197,7 @@
         (let [t (System/currentTimeMillis)
               snapshot @publications
               to-remove (map first
-                             (filter (fn [[k v]] (>= (- ^long t ^long @(:last-used v)) idle))
+                             (filter (fn [[k v]] (>= (- t ^long @(:last-used v)) idle))
                                      snapshot))]
           (doseq [k to-remove]
             (let [pub (:publication (snapshot k))


Allow insts to be triggered in a more friendly way allowing for a mix of straight args and keyworded args. i.e. if you have (definst foo [freq 440 vol 0.5 bar 1] (sin-osc freq)) you can trigger it with (foo 220 :bar 0.1) and it will do the right thing.

--- src/overtone/studio/core.clj
+++ src/overtone/studio/core.clj
@@ -172,6 +172,22 @@
 ;                pan (:ugen (first pan-chans))]

+(defn merge-args
+  "Combine args passed to trigger synth/inst with known arg names. This allows
+  standard args followed by named args. For example, if the inst has the
+  arg-names [\"a\" \"b\" \"c\" \"d\"] then the user may trigger it with the
+  following args: [1 2 :d 4] which will result with an arg-name to arg binding
+  of {:a 1 :b 2 :d 4}"
+  [arg-names args]
+  (loop [arg-names arg-names
+         args args
+         result {}]
+    (cond (keyword? (first args)) (merge result (apply hash-map args))
+          (empty? args) result
+          :else (recur (rest arg-names)
+                       (rest args)
+                       (assoc result (keyword (first arg-names)) (first args))))))
+
 (defmacro inst [sname & args]
   `(let [[sname# params# ugens# constants#] (pre-synth ~sname ~@args)
          [params# ugens# constants#] (inst-prefix params# ugens# constants#)
@@ -184,8 +200,9 @@
          s-player# (synth-player sname# param-names#)
          player# (fn [& play-args#]
                    (let [ins# (get @instruments* sname#)
-                         pargs# (concat (mapcat vector (map keyword param-names#) play-args#)
-                                      [:out-bus (:out-bus ins#)])]
+                         pargs-map# (merge {:out-bus (:out-bus ins#)}
+                                           (merge-args param-names# play-args#))
+                         pargs# (flatten (seq pargs-map#))]
                      (apply s-player#
                             :tgt (:group ins#)
                             pargs#)))


cleanup :require)

cleanup :require)

--- src/paulkrake/datacenter.clj
+++ src/paulkrake/datacenter.clj
@@ -1,8 +1,5 @@
 (ns paulkrake.datacenter
-  (:require [net.cgrand.enlive-html :as html]
-            [paulkrake.score :as s]
-            [paulkrake.glicko2 :as g]
-            [clojure.data.json :as json]))
+  (:require [clojure.data.json :as json]))

 (defn to-clj-unmemoized [uri]
   (->> uri slurp json/read-str ))


Slightly better error message if React module is missing

Make sure to throw error even if asserts are disabled

--- src/reagent/impl/util.cljs
+++ src/reagent/impl/util.cljs
@@ -4,11 +4,11 @@
             [reagent.interop :refer-macros [$ $!]]
             [clojure.string :as string]))

-(defonce react (or (and (exists? js/React)
-                        js/React)
-                   (and (exists? js/require)
-                        (js/require "react"))))
-(assert react)
+(defonce react
+  (cond (exists? js/React) js/React
+        (exists? js/require) (or (js/require "react")
+                                 (throw (js/Error. "require('react') failed")))
+        :else (throw (js/Error. "js/React is missing"))))

 (def is-client (and (exists? js/window)
                     (-> js/window ($ :document) nil? not)))


[#1858] Add caddisfly fixture support in test

--- backend/test/akvo/lumen/fixtures.clj
+++ backend/test/akvo/lumen/fixtures.clj
@@ -1,5 +1,6 @@
 (ns akvo.lumen.fixtures
   (:require [akvo.lumen.component.error-tracker :refer [local-error-tracker]]
+            [akvo.lumen.component.caddisfly-test :refer (caddisfly)]
             [akvo.lumen.test-utils :as test-utils]
             [akvo.lumen.test-utils
              :refer
@@ -48,3 +49,11 @@
   [f]
   (binding [*error-tracker* (local-error-tracker {})]
     (f)))
+
+(def ^:dynamic *caddisfly*)
+
+(defn caddisfly-fixture
+  "Returns a fixture that binds a local error tracker to *error-tracker*"
+  [f]
+  (binding [*caddisfly* (caddisfly)]
+    (f)))


Update dependencies in example

Update dependencies in example

--- example/build.boot
+++ example/build.boot
@@ -1,13 +1,13 @@
 (set-env!
- :resource-paths #{"resources"}
+  :resource-paths #{"resources"}

- :dependencies
- '[[pandeiro/boot-http "0.6.1" :scope "test"]
-   [afrey/ring-html5-handler "0.0.1" :scope "test"]])
+  :dependencies
+  '[[pandeiro/boot-http "0.7.0" :scope "test"]
+    [afrey/ring-html5-handler "0.0.2" :scope "test"]])

 (require '[pandeiro.boot-http :refer [serve]])

 (deftask dev []
   (comp
-   (serve :handler 'afrey.ring-html5-handler/handler :reload true :port 8001)
-   (watch)))
+    (serve :handler 'afrey.ring-html5-handler/handler :reload true :port 8001)
+    (watch)))


CMR-5520: Testing description, typo fix.

--- system-int-test/test/cmr/system_int_test/search/collection_with_new_granule_search_test.clj
+++ system-int-test/test/cmr/system_int_test/search/collection_with_new_granule_search_test.clj
@@ -299,23 +299,24 @@
                               coll-spatial-match coll-w-june-2016-granule
                               coll-w-may-2010-granule coll-platform-match]))

-      (testing "has_granules_created_at success in mutliple formats with sort"
+      (testing "has_granules_created_at success in multiple formats with sort"
         (doseq [format [:atom :dif :dif10 :echo10 :iso19115 :json :opendata :xml :umm-json]]
-          (let [results (search/search-concept-ids-in-format
-                         format
-                         :collection
-                         {:has-granules-created-at [",2015-06-01T16:13:12Z"]
-                          :sort-key "entry_title"})
-                ;; expected results sorted by entry title
-                expected-results [coll-archive-center-match
-                                  coll-platform-match
-                                  coll-spatial-match
-                                  coll-w-may-2010-granule
-                                  coll-w-may-2015-granule
-                                  coll-temporal-no-match
-                                  coll-temporal-match]]
-            (is (= (map :concept-id expected-results)
-                   results))))))))
+          (testing (str "format: " format)
+            (let [results (search/search-concept-ids-in-format
+                           format
+                           :collection
+                           {:has-granules-created-at [",2015-06-01T16:13:12Z"]
+                            :sort-key "entry_title"})
+                  ;; expected results sorted by entry title
+                  expected-results [coll-archive-center-match
+                                    coll-platform-match
+                                    coll-spatial-match
+                                    coll-w-may-2010-granule
+                                    coll-w-may-2015-granule
+                                    coll-temporal-no-match
+                                    coll-temporal-match]]
+              (is (= (mapv :concept-id expected-results)
+                     results)))))))))

 (deftest collection-has-granules-revised-at-test
@@ -359,20 +360,21 @@
          "No matches"
          [",2090-01-01T12:34:56ZZ"] []))

-     (testing "has_granules_revised_at success in mutliple formats with sort"
+     (testing "has_granules_revised_at success in multiple formats with sort"
        (doseq [format [:atom :dif :dif10 :echo10 :iso19115 :json :opendata :xml :umm-json]]
-         (let [results (search/search-concept-ids-in-format
-                        format
-                        :collection
-                        {:has-granules-revised-at [",2015-06-01T16:13:12Z"]
-                         :sort-key "entry_title"})
-               ;; expected results sorted by entry title
-               expected-results [coll-archive-center-match
-                                 coll-platform-match
-                                 coll-spatial-match
-                                 coll-w-may-2010-granule
-                                 coll-w-may-2015-granule
-                                 coll-temporal-no-match
-                                 coll-temporal-match]]
-           (is (= (map :concept-id expected-results)
-                  results))))))))
+         (testing (str "format: " format)
+           (let [results (search/search-concept-ids-in-format
+                          format
+                          :collection
+                          {:has-granules-revised-at [",2015-06-01T16:13:12Z"]
+                           :sort-key "entry_title"})
+                 ;; expected results sorted by entry title
+                 expected-results [coll-archive-center-match
+                                   coll-platform-match
+                                   coll-spatial-match
+                                   coll-w-may-2010-granule
+                                   coll-w-may-2015-granule
+                                   coll-temporal-no-match
+                                   coll-temporal-match]]
+             (is (= (mapv :concept-id expected-results)
+                    results)))))))))


Sort inventory by pickup time

Sort inventory by pickup time

--- src/robinson/inventory.clj
+++ src/robinson/inventory.clj
@@ -85,6 +85,19 @@
                                                       #(assoc %1 :hotkey %2)
                                                       remaining-hotkeys
                                                       inventory))
+        inventory               (->> inventory
+                                  (reduce (fn [inventory item]
+                                    (log/info item (set items))
+                                    (conj
+                                      inventory
+                                      (if (some (set items) #{item (dissoc item :hotkey)})
+                                        (do (log/info item)
+                                          (assoc item :added-time (get-in state [:world :time])))
+                                        item)))
+                                    [])
+                                   (sort-by :added-time)
+                                   reverse
+                                   vec)
         _                       (log/info "new inventory with hotkeys" inventory)
         ;; find all the free hotkeys after filling in missing hotkeys into the newly added inventory items
         remaining-hotkeys       (vec (sort (vec (clojure.set/difference (set remaining-hotkeys) (set (map :hotkey inventory))))))
@@ -99,6 +112,7 @@
                                                (rc/append-log state (format "%s-%c" (get item :name) (get item :hotkey)))))
                            state
                            items))))))
+
 (defn inventory-hotkey->item
   [state hotkey]
   (first (filter (fn [item] (= hotkey (get item :hotkey))) (player-inventory state))))


Use the real ConnectionFactory when in-container, releasing the reference at undeploy using at-exit

--- modules/messaging/src/main/clojure/immutant/messaging.clj
+++ modules/messaging/src/main/clojure/immutant/messaging.clj
@@ -16,7 +16,9 @@
 ;; 02110-1301 USA, or see the FSF site: http://www.fsf.org.

 (ns immutant.messaging
+  (:use [immutant.utilities :only (at-exit)])
   (:import (javax.jms Session))
+  (:require [immutant.registry :as lookup])
   (:require [immutant.messaging.codecs :as codecs])
   (:require [immutant.messaging.hornetq-direct :as hornetq]))

@@ -54,7 +56,15 @@

 ;; privates

-(def connection-factory hornetq/connection-factory)
+(def ^:private connection-factory
+  (if-let [reference-factory (lookup/service "jboss.naming.context.java.ConnectionFactory")]
+    (let [reference (.getReference reference-factory)]
+      (try
+        (.getInstance reference)
+        (finally (at-exit #(do (println "JC: released" reference) (.release reference))))))
+    (do
+      (println "WARN: unable to obtain JMS Connection Factory so we must be outside container")
+      hornetq/connection-factory)))

 (defn- with-session [f]
   (with-open [connection (.createConnection connection-factory)


Check for nil strips in set-pixels.

Check for nil strips in set-pixels.

--- src/clojure/playasophy/wonderdome/display/pixel_pusher.clj
+++ src/clojure/playasophy/wonderdome/display/pixel_pusher.clj
@@ -26,9 +26,11 @@
 (defn- set-pixels!
   "Renders a sequence of pixel colors to an LED strip."
   [^Strip strip colors]
-  (dorun (map #(when %2 (.setPixel strip (unchecked-int %2) (int %1)))
-              (range (.getLength strip))
-              colors)))
+  (if strip
+    (dorun (map #(when %2 (.setPixel strip (unchecked-int %2) (int %1)))
+                (range (.getLength strip))
+                colors))
+    (log/warn "set-pixels called on nil strip!")))


* src/clj/cljs/core.clj: pass information about inline protocol fns along

--- src/clj/cljs/core.clj
+++ src/clj/cljs/core.clj
@@ -426,19 +426,22 @@
                  fpp-partitions
                  (range fast-path-protocol-partitions-count))]))))

-(defn dt->et [specs fields]
-  (loop [ret [] s specs]
-    (if (seq s)
-      (recur (-> ret
-                 (conj (first s))
-                 (into
-                   (reduce (fn [v [f sigs]]
-                             (conj v (vary-meta (cons f (map #(cons (second %) (nnext %)) sigs))
-                                                assoc :cljs.compiler/fields fields)))
-                           []
-                           (group-by first (take-while seq? (next s))))))
-             (drop-while seq? (next s)))
-      ret)))
+(defn dt->et
+  ([specs fields] (dt->et specs fields false))
+  ([specs fields inline]
+     (loop [ret [] s specs]
+       (if (seq s)
+         (recur (-> ret
+                    (conj (first s))
+                    (into
+                      (reduce (fn [v [f sigs]]
+                                (conj v (vary-meta (cons f (map #(cons (second %) (nnext %)) sigs))
+                                                   assoc :cljs.compiler/fields fields
+                                                         :protocol-inline inline)))
+                              []
+                              (group-by first (take-while seq? (next s))))))
+                (drop-while seq? (next s)))
+         ret))))

 (defn collect-protocols [impls env]
   (->> impls
@@ -458,7 +461,7 @@
          (deftype* ~t ~fields ~pmasks)
          (set! (.-cljs$lang$type ~t) true)
          (set! (.-cljs$lang$ctorPrSeq ~t) (fn [this#] (list ~(core/str r))))
-         (extend-type ~t ~@(dt->et impls fields))
+         (extend-type ~t ~@(dt->et impls fields true))
          ~t)
       `(do
          (deftype* ~t ~fields ~pmasks)
@@ -538,7 +541,7 @@
                     :skip-protocol-flag fpps)]
       `(do
          (~'defrecord* ~tagname ~hinted-fields ~pmasks)
-         (extend-type ~tagname ~@(dt->et impls fields))))))
+         (extend-type ~tagname ~@(dt->et impls fields true))))))

 (defn- build-positional-factory
   [rsym rname fields]


`cljs.repl/print-mapped-stacktrace` should take opts, prep for better source map caching

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -199,24 +199,25 @@
    print the ClojureScript stacktrace. The canonical stacktrace must be
    a vector of {:file <string> :function <string> :line <integer> :column <integer>}
    maps."
-  [stacktrace]
-  (let [read-source-map' (memoize read-source-map)
-        ns-info' (memoize ns-info)]
-    (doseq [{:keys [function file line column] :as frame} stacktrace]
-      (let [[sm {:keys [ns source-file] :as ns-info}] ((juxt read-source-map' ns-info') file)
-            [line' column'] (if ns-info
-                              (mapped-line-and-column sm line column)
-                              [line column])
-            name' (if (and ns-info function)
-                    (symbol (name ns) (cljrepl/demunge function))
-                    function)
-            file' (string/replace
-                    (.getCanonicalFile
-                      (if ns-info
-                        source-file
-                        (io/file file)))
-                    (str (System/getProperty "user.dir") File/separator) "")]
-        (println "\t" (str name' " (" file' ":" line' ":" column' ")"))))))
+  ([stacktrace] (print-mapped-stacktrace stacktrace nil))
+  ([stacktrace opts]
+    (let [read-source-map' (memoize read-source-map)
+          ns-info' (memoize ns-info)]
+      (doseq [{:keys [function file line column] :as frame} stacktrace]
+        (let [[sm {:keys [ns source-file] :as ns-info}] ((juxt read-source-map' ns-info') file)
+              [line' column'] (if ns-info
+                                (mapped-line-and-column sm line column)
+                                [line column])
+              name' (if (and ns-info function)
+                      (symbol (name ns) (cljrepl/demunge function))
+                      function)
+              file' (string/replace
+                      (.getCanonicalFile
+                        (if ns-info
+                          source-file
+                          (io/file file)))
+                      (str (System/getProperty "user.dir") File/separator) "")]
+          (println "\t" (str name' " (" file' ":" line' ":" column' ")")))))))

 (comment
   (cljsc/build "samples/hello/src"
@@ -248,7 +249,7 @@
     (when-let [st (:stacktrace ret)]
       (if (and (true? (:source-map opts))
                (vector? st))
-        (print-mapped-stacktrace st)
+        (print-mapped-stacktrace st opts)
         (println st))
       (flush))))


Added .delete call to the HDF file, to make sure that it closes out memory.

--- src/clj/forma/hdf.clj
+++ src/clj/forma/hdf.clj
@@ -44,10 +44,19 @@

 (defn metadata
   "Returns the metadata hashtable for the supplied (opened) MODIS file."
-  ([^Dataset modis arg]
-     (.GetMetadata_Dict modis arg))
+  ([^Dataset modis key]
+     (.GetMetadata_Dict modis key))
   ([modis]
      (metadata modis "")))
+
+(defn subdatasets-dict
+  "Returns the SUBDATASETS metadata Hashtable for a given filepath."
+  [hdf-file]
+  (let [path (str hdf-file)
+        dataset (gdal/Open path)]
+    (try
+      (metadata dataset "SUBDATASETS")
+      (finally (.delete dataset)))))

 (defn lookup
   "Looks up a key in the supplied hashtable."
@@ -84,12 +93,6 @@
   [entry]
   (let [[path] (split-entry entry)]
     (vector (subdataset-key path) (gdal/Open path))))
-
-(defn subdatasets-dict
-  "Returns the SUBDATASETS metadata Hashtable for a given filepath."
-  [hdf-file]
-  (let [path (str hdf-file)]
-    (metadata (gdal/Open path) "SUBDATASETS")))

 (defn raster-array
   "Unpacks the data inside of a MODIS band into a 1xN integer array."


update runner-install

update runner-install

Note in Runner's `:register` when a Resource has been installed

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -1019,6 +1019,7 @@
                                          (when no-cost " at no cost")))
              (trigger-event state side :runner-install installed-card)
              (when (has? c :subtype "Icebreaker") (update-breaker-strength state side c)))))))
+   (when (has? card :type "Resource") (swap! state assoc-in [:runner :register :installed-resource] true))
    (swap! state update-in [:bonus] dissoc :install-cost)))

 (defn server-list [state card]


Added condition for showing card name during movement Fixes #86

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -1387,7 +1387,7 @@
 (defn is-tagged? [state]
   (or (> (get-in state [:runner :tag]) 0)
       (> (get-in state [:runner :tagged]) 0)))
-
+
 (defn runner-install
   ([state side card] (runner-install state side card nil))
   ([state side {:keys [title type cost memoryunits uniqueness ] :as card}
@@ -1564,6 +1564,7 @@
   (let [c (update-in card [:zone] #(map to-keyword %))
         last-zone (last (:zone c))
         label (if (and (not (= last-zone :play-area))
+                       (not (and (= (:side c)  "Runner") (= last-zone :hand) (= server "Grip")))
                        (or (and (= (:side c)  "Runner") (not (:facedown c)))
                            (:rezzed c)
                            (:seen c)


No need to munge DATABASE_URL?

No need to munge DATABASE_URL?

--- src/clj_crud/main.clj
+++ src/clj_crud/main.clj
@@ -11,7 +11,7 @@
         database-url (let [db-url (second args)]
                        (assert (.startsWith db-url "postgres:")
                                (str "Something is wrong with the database argument: " (second args)))
-                       (.replace db-url "postgres:" "jdbc:postgresql:"))
+                       db-url)
         system (core/crud-system (core/production-config port database-url))]
     (component/start system)
     (.addShutdownHook (Runtime/getRuntime)


Parsing protocol version into constituent parts

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -315,7 +315,8 @@
     (try
       (let [^CloseableHttpResponse response (.execute client http-req context)
             ^HttpEntity entity (.getEntity response)
-            status (.getStatusLine response)]
+            status (.getStatusLine response)
+            protocol-version (.getProtocolVersion status)]
         {:body (coerce-body-entity entity conn-mgr response)
          :headers (parse-headers
                    (.headerIterator response)
@@ -325,7 +326,7 @@
          :repeatable? (if (nil? entity) false (.isRepeatable entity))
          :streaming? (if (nil? entity) false (.isStreaming entity))
          :status (.getStatusCode status)
-         :protocol-version (.getProtocolVersion status)
+         :protocol-version  {:name (.getProtocol protocol-version) :major (.getMajor protocol-version) :minor (.getMinor protocol-version)}
          :reason-phrase (.getReasonPhrase status)})
       (catch Throwable t
         (when-not (conn/reusable? conn-mgr)


fix stupid bug

fix stupid bug

--- src/domshot/core.cljs
+++ src/domshot/core.cljs
@@ -29,7 +29,7 @@
   (swap! attr-qualifiers conj fn))

 (defmethod add-qualifier :default [fn]
-  (swap! attr-qualifiers conj fn))
+  (swap! node-qualifiers conj fn))

 ;; ---- Serializing the dom ---- ;;
@@ -89,18 +89,3 @@
                             (clj->js (for [i (range (count (:children structure)))
                                            :let [child (nth (:children structure) i)]]
                                        (build child))))))))
-
-
-;; ---- Testing ---- TODO: delete this! ---- ;;
-
-(defn is-not-style [name _]
-  (not= "style" name))
-
-(defn is-not-empty-text [node]
-  (println "node" node)
-  true)
-
-(add-qualifier is-not-style :attribute)
-(add-qualifier is-not-empty-text)
-
-(println (snapshot (goog.dom/getElement "outer")))


remove janky tests at bottom of file

remove janky tests at bottom of file

--- src/domshot/core.cljs
+++ src/domshot/core.cljs
@@ -73,13 +73,3 @@
                             (clj->js (for [i (range (count (:children structure)))
                                            :let [child (nth (:children structure) i)]]
                                        (build child))))))))
-
-
-
-;; ---- Testing the api... TODO: delete these and test like a pro, not a noob D: ---- ;;
-
-(add-invalidator #(not= "SCRIPT" (.-nodeName %)))
-
-(.log js/console "snapshot result" (clj->js (snapshot)))
-
-(.log js/console "build result" (build (snapshot)))


RDC - Use mapv instead of vec map.

RDC - Use mapv instead of vec map.

--- src/icfp2015/cell.clj
+++ src/icfp2015/cell.clj
@@ -22,9 +22,8 @@
     :southeast [0 -1 1] })

 (defn translate-dir [direction]
-  (fn [coords]
-    (->> coords
+  (fn [cell]
+    (->> cell
       (offset->cube)
-      (map + (direction offsets))
-      (vec)
+      (mapv + (direction offsets))
       (cube->offset))))


Use `title` as atom entry title, instead of `clojure.core/name`

--- src/io/perun/atom.clj
+++ src/io/perun/atom.clj
@@ -54,7 +54,7 @@
             [:id (str "urn:uuid:" uuid)]
             [:title title]
             (if canonical-url
-              [:link {:href canonical-url :type "text/html" :title name}])
+              [:link {:href canonical-url :type "text/html" :title title}])
             [:published (iso-datetime (published post))]
             [:updated (iso-datetime (updated post))]
             ;; FIXME: plain text on xml:base property


Don't remove packaged files from the fileset

--- boot/core/src/boot/task/built_in.clj
+++ boot/core/src/boot/task/built_in.clj
@@ -439,7 +439,7 @@
           (util/info "Writing %s...\n" (.getName jarfile))
           (pod/with-call-worker
             (boot.jar/spit-jar! ~(.getPath jarfile) ~index ~manifest ~main))
-          (-> fileset (core/rm entries) (core/add-resource tgt) core/commit!))))))
+          (-> fileset (core/add-resource tgt) core/commit!))))))

 (core/deftask war
   "Create war file for web deployment."
@@ -464,7 +464,7 @@
           (util/info "Writing %s...\n" (.getName warfile))
           (pod/with-call-worker
             (boot.jar/spit-jar! ~(.getPath warfile) ~index {} nil))
-          (-> fileset (core/rm entries) (core/add-resource tgt) core/commit!))))))
+          (-> fileset (core/add-resource tgt) core/commit!))))))

 (core/deftask zip
   "Build a zip file for the project."
@@ -482,7 +482,7 @@
             (util/info "Writing %s...\n" (.getName zipfile))
             (pod/with-call-worker
               (boot.jar/spit-zip! ~(.getPath zipfile) ~index))
-            (-> fileset (core/rm entries) (core/add-resource tgt) core/commit!)))))))
+            (-> fileset (core/add-resource tgt) core/commit!)))))))

 (core/deftask install
   "Install project jar to local Maven repository.


fix container pills showing up with no actions

--- frontend/components/build.cljs
+++ frontend/components/build.cljs
@@ -65,10 +65,11 @@
     om/IRender
     (render [_]
       (let [{:keys [containers current-container-id]} container-data
-            controls-ch (om/get-shared owner [:comms :controls])]
+            controls-ch (om/get-shared owner [:comms :controls])
+            hide-pills? (or (>= 1 (count containers))
+                            (not (first (mapcat :actions containers))))]
         (html
-         [:div.containers.pagination.pagination-centered (when-not (< 1 (count containers))
-                                                           {:style {:display "none"}})
+         [:div.containers.pagination.pagination-centered (when hide-pills? {:style {:display "none"}})
           [:ul.container-list
            (for [container containers]
              (om/build container-pill


Adding newlines ; humans love newlines

Adding newlines ; humans love newlines

--- jvm-runner/src/clojure/codewars/runners/java.clj
+++ jvm-runner/src/clojure/codewars/runners/java.clj
@@ -2,11 +2,11 @@
   (:require [codewars.runners :refer [code-only full-project]]
             [codewars.clojure.test])
   (:import
-           [javax.tools ToolProvider SimpleJavaFileObject SimpleJavaFileObject ForwardingJavaFileManager]
-           [java.net URI]
-           [java.io PrintWriter ByteArrayOutputStream]
-           [org.junit.runner JUnitCore]
-           [codewars.java CwRunListener]))
+   [javax.tools ToolProvider SimpleJavaFileObject SimpleJavaFileObject ForwardingJavaFileManager]
+   [java.net URI]
+   [java.io PrintWriter ByteArrayOutputStream]
+   [org.junit.runner JUnitCore]
+   [codewars.java CwRunListener]))

 (defn class-name
   "Determine the class name of some java code (include package)"
@@ -58,7 +58,12 @@
               ;; TODO: Such hacks... :(
               (let [byte-code (.toByteArray (.openOutputStream byte-data))]
                 (proxy-super defineClass class-name byte-code nil))
-                (throw (java.lang.ClassNotFoundException. (str "Could not find " [class-name class-kind] " among possibilities: " (keys @class-codes)))))))]
+              (throw
+               (java.lang.ClassNotFoundException.
+                (str "Could not find "
+                     [class-name class-kind]
+                     " among possibilities: "
+                     (keys @class-codes)))))))]
     (proxy
         [ForwardingJavaFileManager]
         [standard-manager]


Add create/delete project repository methods.

--- src/uxbox/repo/projects.cljs
+++ src/uxbox/repo/projects.cljs
@@ -26,6 +26,19 @@
   [type data]
   (urc/req! {:url (str urc/url "/pages") :method :get}))

+(defmethod urc/-do :create/project
+  [_ data]
+  (let [params {:url (str urc/url "/projects")
+                :method :post
+                :body data}]
+    (urc/req! params)))
+
+(defmethod urc/-do :delete/project
+  [_ {:keys [id]}]
+  (let [params {:url (str urc/url "/projects/" id)
+                :method :delete}]
+    (urc/req! params)))
+
 (defmethod urc/-do :create/page
   [type {:keys [id] :as data}]
   (let [params {:url (str urc/url "/pages")


Improve metadata spec on icons service.

Improve metadata spec on icons service.

--- src/uxbox/services/icons.clj
+++ src/uxbox/services/icons.clj
@@ -23,12 +23,16 @@

 (s/def ::user uuid?)
 (s/def ::collection (s/nilable uuid?))
-(s/def ::width (s/and integer? pos?))
-(s/def ::height (s/and integer? pos?))
-(s/def ::view-box vector?)
+(s/def ::width (s/and number? pos?))
+(s/def ::height (s/and number? pos?))
+(s/def ::view-box (s/and (s/coll-of number?)
+                         #(= 4 (count %))
+                         vector?))
+
 (s/def ::content string?)
+(s/def ::mimetype string?)
 (s/def ::metadata
-  (s/keys :opt-un [::width ::height ::view-box]))
+  (s/keys :opt-un [::width ::height ::view-box ::mimetype]))

 (defn decode-metadata
   [{:keys [metadata] :as data}]


add a route to scale-to-width-down

add a route to scale-to-width-down

--- src/vignette/http/routes.clj
+++ src/vignette/http/routes.clj
@@ -76,6 +76,17 @@
                   :thumbnail-mode "scale-to-width"
                   :width size-regex}))

+(def scale-to-width-down-route
+  (route-compile "/:wikia:image-type/:top-dir/:middle-dir/:original/revision/:revision/:thumbnail-mode/:width"
+                 {:wikia wikia-regex
+                  :image-type image-type-regex
+                  :top-dir top-dir-regex
+                  :middle-dir middle-dir-regex
+                  :original original-regex
+                  :revision revision-regex
+                  :thumbnail-mode "scale-to-width-down"
+                  :width size-regex}))
+
 (defn create-request-handlers
   "Creates request handlers for a given route for GET & HEAD using the given route and
   map generation function."


Adding a menu item to move tab to new tabset

--- src/lt/objs/tabs.cljs
+++ src/lt/objs/tabs.cljs
@@ -456,7 +456,9 @@
       (object/raise to-ts :active))))

 (defn menu! [obj ev]
-  (-> (menu/menu [{:label "Close tab"
+  (-> (menu/menu [{:label "Move tab to new tabset"
+                   :click (fn [] (cmd/exec! :tabs.move-new-tabset))}
+                  {:label "Close tab"
                    :click (fn [] (object/raise obj :close))}])
       (menu/show-menu (.-clientX ev) (.-clientY ev))))


refer to secs

refer to secs

--- src/luffer/worker.clj
+++ src/luffer/worker.clj
@@ -12,7 +12,7 @@
             [clojurewerkz.elastisch.rest.bulk :as esbulk]
             [clojurewerkz.elastisch.rest.admin :as esadmin])
   (:use [luffer.models :only [plays join-play-with-models]]
-        [luffer.util :only [parse-int]]))
+        [luffer.util :only [parse-int secs]]))

 ;; Elasticsearch
 (def ^:private es-conn (es/connect (System/getenv "ES_HOST")))


0.3 -> 0.5 in core.clj

0.3 -> 0.5 in core.clj

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -54,7 +54,7 @@

 (def parse (insta/parser (clojure.java.io/resource "grammar")))

-(def version "0.3")
+(def version "0.5")

 ;; utility defns


work on supporting adds of namelists and keys (broken now)

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -33,12 +33,25 @@
 (defn nml-name [x]
   (nml-str (second x)))

+;;(defn nml-set [tree nml key val & sub]
+;; (let [child (if sub :nvsubseq :stmt)
+;;       match (if sub key nml)
+;;       vnew  (if sub (fn [tree] (parse val :start :values)) #(nml-set % nml key val true))
+;;       f     (fn [k v] [child k (if (= (nml-str k) match) (vnew v) v)])]
+;;   (insta/transform {child f} tree)))
 (defn nml-set [tree nml key val & sub]
-  (let [child (if sub :nvsubseq :stmt)
-        match (if sub key nml)
-        vnew  (if sub (fn [tree] (parse val :start :values)) #(nml-set % nml key val true))
-        f     (fn [k v] [child k (if (= (nml-str k) match) (vnew v) v)])]
-    (insta/transform {child f} tree)))
+  (let [child  (if sub :nvsubseq :stmt)
+        match  (if sub key nml)
+        parent (if sub :nvseq :s)
+        vnew   (if sub (fn [tree] (parse val :start :values)) #(nml-set % nml key val true))
+        f      (fn [k v] [child k (if (= (nml-str k) match) (vnew v) v)])]
+;;   (if sub (println (insta/transform {parent (fn [& children] [parent (if (some #(= (nml-str (second %)) match) children) children (conj children (parse (str key "=0") :start child)))])} tree)))
+    (println tree)
+    (println "###")
+    (let [t2 (if sub (insta/transform {parent (fn [& children] [parent (if (some #(= (nml-str (second %)) match) children) children (conj children (parse (str key "=0") :start child)))])} tree) tree)]
+      (println t2)
+      (println "###")
+      (insta/transform {child f} t2))))

 (defn nml-sets [tree sets]
   (loop [t tree s sets]
@@ -129,6 +142,7 @@
         sets (:set options)
         tree (nml-tree (first arguments))]
     (if (and gets sets) (fail "Do not mix get and set operations."))
+;;(println tree)
     (cond gets (nml-gets tree gets)
           sets (println (nml-str (nml-sets tree sets)))
           :else (println (nml-str tree)))))


work on bash output (function now)

work on bash output (function now)

--- src/nml/core.clj
+++ src/nml/core.clj
@@ -33,6 +33,9 @@
   (try (slurp in)
        (catch Exception e
          (fail (str "Could not read from '" in "'.")))))
+
+(defn- strmap [f coll]
+  (apply str (map f coll)))

 (defn- usage [summary]
   (doseq [x [""
@@ -86,7 +89,7 @@
         cjoin    #(string/join "," %)
         delegate #(map nml-str %)
         delesort  (fn [val] (delegate (sort-by #(nml-name %) val)))
-        list2str #(apply str (map nml-str %))
+        list2str #(strmap nml-str %)
         strfirst #(nml-str (first %))
         strlast  #(nml-str (last %))]
     (apply str (case key
@@ -197,24 +200,23 @@

 ;; formatting

+(defn- fmt-bash [m]
+  (let [ms  (sort m)
+        eq #(string/replace % "\"" "\\\"")
+        f0  (fn [[dataref values]]
+              (let [v (eq values)]
+                (str "'" dataref "') echo \"" v "\";;")))
+        f1  (fn [[name nvseq]]
+              (let [x (strmap f0 nvseq)]
+                (str "'" name "') case \"$2\" in " x "*) echo '';;esac;;" )))]
+    (str "ooo(){ case \"$1\" in " (strmap f1 ms) "*) echo '';;esac; }\n")))
+
 (defn- fmt-namelist [m]
   (let [f0 (fn [[dataref values]]
              (str "  " dataref "=" values "\n"))
         f1 (fn [[name nvseq]]
-             (str "&" name "\n" (apply str (map f0 (sort nvseq))) "/\n"))]
-    (apply str (map f1 (sort m)))))
-
-(defn- fmt-bash [m]
-  (let [ms (sort m)
-        f0 (fn [[name nvseq]] (str "declare -A nml_" name "\n"))
-        f1 (fn [[name nvseq]]
-             (apply str
-                    (map (fn [[dataref values]]
-                           (let [v (string/replace values "\"" "\\\"")]
-                             (str "nml_" name "[" dataref "]=\"" v "\"\n")))
-                           (sort nvseq))))]
-    (str (apply str (map f0 ms))
-         (apply str (map f1 ms)))))
+             (str "&" name "\n" (strmap f0 (sort nvseq)) "/\n"))]
+    (strmap f1 (sort m))))

 ;; main

@@ -236,4 +238,3 @@
       (cond gets  (nml-out out (nml-gets m gets (:no-prefix options)))
             sets  (nml-out out (fmt (nml-sets m sets)))
             :else (nml-out out (fmt m))))))
-;;           :else (nml-out out (fmt-bash m))))))


Do not publish on init

Do not publish on init

--- src/nube/app.clj
+++ src/nube/app.clj
@@ -264,7 +264,6 @@
   (init-routing-table)
   (car/with-new-pubsub-listener (redis-conf) {"updates" (fn [_] (init-routing-table))}
     (car/subscribe "updates"))
-  (redis! (car/publish "updates" 1))
   (future
     (loop []
       (health-check-instances)


cache transactions

cache transactions

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -2,6 +2,7 @@
   (:require [clj-statsd :as statsd]
             [clj-time.core :as time]
             [clojure.core.async :as async]
+            [clojure.core.memoize :as memo]
             [clojure.set :as set]
             [clojure.string :as str]
             [clojure.tools.logging :as log]
@@ -617,15 +618,24 @@
       (log/infof "sending %s tx-ids for %s to %s" (count tx-ids) (:document/id ?data) client-id)
       (?reply-fn {:tx-ids tx-ids}))))

+(def memo-frontend-tx-data (memo/lru (fn [tx-id]
+                                       (->> tx-id
+                                         (replay/reproduce-transaction *db*)
+                                         (datomic-common/frontend-document-transaction)
+                                         :read-only-data))
+                                     :lru/threshold 2000))
+
+(def ^:dynamic *db*)
+(defn get-frontend-tx-data [db tx-id]
+  (binding [*db* db]
+    (memo-frontend-tx-data tx-id)))
+
 (defmethod ws-handler :document/fetch-transaction [{:keys [client-id ?data ?reply-fn] :as req}]
   (check-document-access (-> ?data :document/id) req :read)
   (let [doc (->> ?data :document/id (doc-model/find-by-id (:db req)))
         tx-id (:tx-id ?data)]
     (if (= (:db/id doc) (:db/id (:transaction/document (d/entity (:db req) tx-id))))
-      (let [transaction (->> tx-id
-                          (replay/reproduce-transaction (:db req))
-                          (datomic-common/frontend-document-transaction)
-                          :read-only-data)]
+      (let [transaction (get-frontend-tx-data (:db req) tx-id)]
         (log/infof "sending %s txes from %s for %s to %s" (count (:tx-data transaction)) tx-id (:document/id ?data) client-id)
         (?reply-fn {:document/transaction transaction}))
       (throw+ {:status 403


reserve the first 5000 eids for the bot

reserve the first 5000 eids for the bot

--- src/pc/http/sente.clj
+++ src/pc/http/sente.clj
@@ -170,9 +170,7 @@
             ;; XXX should we ensure in the transactor that ids increase properly?
             used-from-partition (set (filter #(= remainder (mod % web-peer/multiple)) used-client-parts))
             start-eid (first (remove #(contains? used-from-partition %)
-                                     (iterate (partial + web-peer/multiple) (if (zero? remainder)
-                                                                              web-peer/multiple
-                                                                              remainder))))]
+                                     (iterate (partial + web-peer/multiple) (+ web-peer/multiple remainder))))]
         {:remainder remainder :multiple web-peer/multiple :next-id start-eid})
       (throw+ {:status 403
                :error-msg "There are too many users in the document."


Big speedups

Big speedups

* Rm all the linear searches to find which color to use to draw each key and note.  Just store left to right index on each piano-key and use that to find draw color.

--- src/playmary/one.cljs
+++ src/playmary/one.cljs
@@ -47,11 +47,6 @@
   [{w :w h :h playhead :playhead :as instrument}]
   {:x 0 :y (t->px instrument playhead) :w w :h h})

-(defn color-set
-  [instrument freq]
-  (nth colors (mod (util/index-of (-> instrument :piano-keys keys) freq)
-                   (count colors))))
-
 (defn draw-note
   [draw-ctx instrument note]
   (let [{x :x y :y w :w h :h} (note-rect note instrument)]
@@ -81,11 +76,10 @@
   (let [freqs (-> instrument :piano-keys keys)
         piano-key-w (piano-key-width instrument)]
     (dotimes [n (count freqs)]
-      (let [freq (nth freqs n)
-            note (latest-note instrument freq)
+      (let [note (latest-note instrument (nth freqs n))
             piano-key-on (and note (-> note :off nil?))]
         (set! (.-fillStyle draw-ctx)
-              ((if piano-key-on :light :dark) (color-set instrument freq)))
+              ((if piano-key-on :light :dark) (nth colors (mod n (count colors)))))
         (.fillRect draw-ctx
                    (* n piano-key-w)
                    (t->px instrument playhead)
@@ -113,8 +107,8 @@

 (defn create-instrument
   [scale]
-  {:piano-keys (into (sorted-map) (map (fn [freq] [freq {}])
-                                       scale))
+  {:piano-keys (into (sorted-map) (map-indexed (fn [i freq] [freq {:n i}])
+                                               scale))
    :notes [] :w 0 :h 0 :sound-ready false
    :px-per-ms 0.01
    :start (.getTime (js/Date.))


Minor fixes on loop/recur impl.

Minor fixes on loop/recur impl.

--- src/promesa/core.cljc
+++ src/promesa/core.cljc
@@ -37,8 +37,6 @@
       java.util.concurrent.CompletableFuture
       java.util.concurrent.CompletionStage
       java.util.concurrent.TimeoutException)))
-
-(def ^:dynamic *run-fn* exec/run!)

 ;; --- Promise

@@ -457,30 +455,37 @@
                             (pt/-promise (f#)))))
           (pt/-bind identity))))

+(def ^:dynamic *loop-run-fn* exec/run!)
+
 (defmacro loop
   [bindings & body]
   (c/let [bindings (partition 2 2 bindings)
           names (mapv first bindings)
           fvals (mapv second bindings)
           tsym (gensym "loop")
-          dsym (gensym "deferred")]
-    `(c/let [~dsym (promesa.core/deferred)
+          dsym (gensym "deferred")
+          rsym (gensym "run")]
+    `(c/let [~rsym *loop-run-fn*
+             ~dsym (promesa.core/deferred)
              ~tsym (fn ~tsym [params#]
                      (-> (promesa.core/all params#)
                          (promesa.core/then (fn [[~@names]]
+                                              ;; (prn "exec" ~@names)
                                               (do! ~@body)))
                          (promesa.core/handle
                           (fn [res# err#]
+                            ;; (prn "result" res# err#)
                             (cond
                               (not (nil? err#))
                               (promesa.core/reject! ~dsym err#)

                               (and (map? res#) (= (:type res#) :promesa.core/recur))
-                              (*run-fn* (fn [] (~tsym (:args res#))))
+                              (do (~rsym (fn [] (~tsym (:args res#))))
+                                  nil)

                               :else
                               (promesa.core/resolve! ~dsym res#))))))]
-       (*run-fn* (fn [] (~tsym ~fvals)))
+       (~rsym (fn [] (~tsym ~fvals)))
        ~dsym)))

 (defmacro recur


Add readme

Add readme

--- src/qttt/ui.cljs
+++ src/qttt/ui.cljs
@@ -13,6 +13,6 @@
       :om (om/main)
       :reagent (reagent/main)
       :quiescent (quiescent/main)
-      (js/alert "Please use the query string to set 'lib' to om, reagent or quiescent."))))
+      (js/alert "Please use the query string to set 'lib' to om, reagent or quiescent. For example, 'dev.html?lib=om'"))))


unused

unused

--- src/road/geo.clj
+++ src/road/geo.clj
@@ -1,7 +1,5 @@
 (ns road.geo
   (:require [clojure.string :as string]
-            [clojure.xml :as xml]
-            [clojure.zip :as zip]
             [clojure.data.json :as json]
             [clojure.pprint :refer [pprint]]
             [clj-xpath.core :as xp]))


woops

woops

--- src/wishlistd/cljs/main.cljs
+++ src/wishlistd/cljs/main.cljs
@@ -1,10 +1,8 @@
-(ns overtoneinterface.client.main
 (ns wishlistd.client.main
   (:require [crate.core :as crate])
   (:use [jayq.core :only [$ append delegate data]])
   (:use-macros [crate.macros :only [defpartial]]))

-(defpartial wish-li [desc url]
 (def $create ($ "#create-wishlist"))
 (def $content ($ "#box"))
 (def $header ($ "#title-box"))


Update docstring for {upper,lower]-case?

--- src/str/core.clj
+++ src/str/core.clj
@@ -360,7 +360,7 @@
   "Return s if s is all upper case.

   Characters without case, e.g. numbers, are considered to be trivially
-  true."
+  upper case."
   [^String s]
   {:pre [(string? s)]
    :post [(or (nil? %) (string? %))]}
@@ -374,7 +374,7 @@
   "Return s if s is all lower case.

   Characters without case, e.g. numbers, are considered to be trivially
-  true."
+  lower case."
   [^String s]
   {:pre [(string? s)]
    :post [(or (nil? %) (string? %))]}


fix indention

fix indention

--- src/sandbox/stack.clj
+++ src/sandbox/stack.clj
@@ -32,8 +32,7 @@
           FN-SEP = <optional-whitespace> ';' <optional-whitespace>
           PARAMS-SEP = <optional-whitespace> ',' <optional-whitespace>")

-(defn gen-program
-  [parser program]
+(defn gen-program [parser program]
   (into [] (insta/transform
             {:S (fn [ & args] args)
              :FN-CALL (fn [fn-id params] [:FN-CALL
@@ -47,28 +46,23 @@
              :FN-DECL-BODY (fn [& body] (into [] body))}
             (parser program))))

-(defn get-fn-decls
-  [program]
+(defn get-fn-decls [program]
   (->> program
        (filter #(= :FN-DECL (get % 0)))
        (into [])))

-(defn get-instructions
-  [program]
+(defn get-instructions [program]
   (->> program
        (filter #(not= :FN-DECL (get % 0)))
        (into [])))

-(defn get-fn-id-decl
-  [fn-decls fn-id]
+(defn get-fn-id-decl [fn-decls fn-id]
   (->> fn-decls
        (filter #(= (get % 1)
                    fn-id))
        (first)))

-
-(defn call-fn
-  [fn-decl fn-call]
+(defn call-fn [fn-decl fn-call]
   (let [decl-args-list (fn-decl 2)
         decl-body (fn-decl 3)
         fn-call-params (fn-call 2)]
@@ -98,18 +92,18 @@

 (defn call-stack [call]
   (let [zpr (z/vector-zip call)]
-           (loop [result []
-                  loc (-> zpr z/down)]
-             (if (-> loc z/end?)
-               result
-               (let [current-node (-> loc z/node)]
-                 (recur (if (and
-                             (not (vector? current-node))
-                             (not= :FN-CALL current-node)
-                             (not= :ID current-node))
-                          (conj result {(-> loc z/left z/node) current-node})
-       result)
-                        (-> loc z/next)))))))
+    (loop [result []
+           loc (-> zpr z/down)]
+      (if (-> loc z/end?)
+        result
+        (let [current-node (-> loc z/node)]
+          (recur (if (and
+                      (not (vector? current-node))
+                      (not= :FN-CALL current-node)
+                      (not= :ID current-node))
+                   (conj result {(-> loc z/left z/node) current-node})
+                   result)
+                 (-> loc z/next)))))))

 (defn program-call-stack [prog]
   (->> (expand-to-primitive-calls prog)


lexer: Some fixes to whitespace and in(de)dentation.

--- src/skylark/lexer.clj
+++ src/skylark/lexer.clj
@@ -123,9 +123,6 @@

 (def whitespace #{\space \tab \formfeed})

-(def &whitespace
-  (&repeat (&char-if whitespace)))
-
 (def crlf #{\return \newline})

 (def &eol
@@ -141,6 +138,9 @@
 (def &line-continuation
   (&do &backslash &eol))

+(def &whitespace
+  (&repeat (&or (&char-if whitespace) &line-continuation)))
+
 (def &leading-whitespace-continued
   (&let
     [column &leading-whitespace-raw
@@ -155,14 +155,17 @@

 (defn &indent [column]
   (fn [[in [top :as is] out :as σ]]
-    (if (> column top)
-      [nil [in (conj is column) (conj out :indent)]]
-      (loop [[top & ris :as is] is
-             out out]
-        (cond
-         (= column top) [nil [in is out]]
-         (or (empty? ris) (> column top)) ((&error {:r "invalid dedentation"}) σ)
-         :else (recur ris (conj out :dedent)))))))
+    (let [pos (in-position in)
+          info [*file* pos pos]
+          tok+ #(conj % [%2 nil info])]
+      (if (> column top)
+        [nil [in (conj is column) (tok+ out :indent)]]
+        (loop [[top & ris :as is] is
+               out out]
+          (cond
+           (= column top) [nil [in is out]]
+           (or (empty? ris) (> column top)) ((&error {:r "invalid dedentation"}) σ)
+           :else (recur ris (tok+ out :dedent))))))))

 (def &comment-eol
   (&do (&optional (&do (&char= \#) (&repeat (&char-if-not crlf)))) &eol))
@@ -336,9 +339,17 @@
 (defn python-lexer [input]
   (first (&python (init-state input))))

-
-
 (comment
-  (python-lexer "def hello \"abcd\"\n  foo\\nbar\n     # comment\n  baz\ndef quux\n  ur\"x\"")
-
+  (defn test-python-lexer [input]
+    (try (python-lexer input) (catch clojure.lang.ExceptionInfo x (.data x))))
+
+  (test-python-lexer "
+def hello \"abcd\"
+  foo\\
+bar '1 2 3'
+     # comment
+  baz
+def quux
+  ur\"x\"")
+  (python-lexer "def hello abcd\n  foo\n  baz\ndef quux\n  ur\"x\\\"\"")
 );comment


Tweak log levels.

Tweak log levels.

--- src/sql_file/core.clj
+++ src/sql_file/core.clj
@@ -53,7 +53,7 @@
 (defn run-script [ conn script-url ]
   "Run the database script at the given URL against a specific
 database connection."
-  (log/info "Run script" script-url)
+  (log/debug "Run script" script-url)
   (let [ script-text (slurp script-url) ]
     (do-statements conn (script/sql-statements script-text))))

@@ -62,7 +62,7 @@
 database connection. Exceptions will be logged and a boolean value
 will be returned that indicates whether or not the script execution
 was successful."
-  (log/info "Safe run script" script-url)
+  (log/debug "Safe run script" script-url)
   (try
     (run-script conn script-url)
     true


added more to server interactions

added more to server interactions

--- src/tutorial/untangled_tutorial/H_Server_Interactions.cljs
+++ src/tutorial/untangled_tutorial/H_Server_Interactions.cljs
@@ -40,13 +40,47 @@

   ### Data Merge

-  #### Ensuring queries from more that one part of the UI behave well
-
-  #### Normalization
-
+  Untangled overrides the built-in Om merge. Untangled's data merge has a number of extension that are useful for
+  simple application reasoning:
+
+  1. Merge is a deep merge, but with extra logic
+
+  Untangled merges your response via deep merge, meaning that existing data is not wiped out by default. Unfortunately,
+  this causes a different problem. Let's say you have two UI components that ask for similar information:
+
+  Component A asks for [:a]
+  Component A2 asks for [:a :b]
+
+  Of course, these queries are composed into a larger query, but you can imagine that if we use the query of A2, normalization
+  will put something like this somewhere in the app state: `{ :a 1 :b 2}`. Now, at a later time, say we re-run a load but
+  use component A's query. The response from the server will say something like `{:a 5}`, because all we asked for was
+  `:a`!  But what if both A and A2 are on the screen??? Well, depending on how you merge strange things can happen.
+
+  So, Untangled forms an opinion on this scenario:
+
+  - First, since it isn't a great thing to do, you should avoid it
+  - However, if you do it, Untangled merges with the following rules:
+      - If the query *asks* for an attribute, and the *response does not include it*, then it is always removed from the app state since the
+      server has clearly indicated it is gone.
+      - The the query *does not ask* for an attribute (which means the response cannot possibly contain it), then Untangled
+      will avoid removing it, even if other attributes come back (e.g. it will be a merge leaving the property that was
+      not asked for alone). This does indicate that your UI is possibly in a state inconsistent with the server, which
+      is the reason for the \"avoid this case\" advice.
+
+  ### Normalization
+
+  Normalization is always *on* in Untangled. You are forced to use the default database format. If you've passed an
+  atom as initial state then initial state is assumed to be pre-normalized, but normalization will always be on. Loads
+  must use real composed queries from the UI for normalization to work (the om `get-query` function adds info to assit
+  with normalization).
+
+  Therefore, you almost *never* want to use a hand-written query that has not been placed on a `defui`. It is perfectly
+  acceptable to define queries via defui to ensure normalization will work, and this will commonly be the case if your
+  UI needs to ask for data in a structure different from what you want to run against the server.

   ### Query Narrowing

+  The load functions allow you to elide parts of the query using `:without set`

   ## Mutations


Change field function patameters signature: remove named parameters.

--- src/suricatta/dsl.clj
+++ src/suricatta/dsl.clj
@@ -216,7 +216,8 @@
          (as-field* o))))

 (defn field
-  [data & {:keys [alias] :as opts}]
+  "Create a field instance."
+  [data {:keys [alias] :as opts}]
   (defer
     (let [f (field* data)]
       (if alias


tidy js-joda ns

tidy js-joda ns

--- src/tick/js_joda.cljs
+++ src/tick/js_joda.cljs
@@ -1,10 +1,6 @@
 (ns tick.js-joda
   (:require
-    [cljsjs.js-joda]
-    [cljsjs.js-joda-timezone]
-    ;[cljsjs.js-joda-locale]
-    ))
-
+    [cljsjs.js-joda]))

 (def Date js/Date)
 (def Clock (.. js/JSJoda -Clock))
@@ -26,11 +22,11 @@
 (def TemporalAdjusters (.. js/JSJoda -TemporalAdjusters))
 (def Temporal (.. js/JSJoda -Temporal))
 (def TemporalAmount (.. js/JSJoda -TemporalAmount))
+(def DateTimeFormatter (.. js/JSJoda -DateTimeFormatter))
+(def ResolverStyle (.. js/JSJoda -ResolverStyle))

-;; todo - get these from threeten-extra? https://github.com/js-joda/js-joda/issues/165
+;; Following are not yet implemented in js-joda https://github.com/js-joda/js-joda/issues/165
 (def OffsetDateTime (.. js/JSJoda -ZonedDateTime))
 (def OffsetTime (.. js/JSJoda -LocalTime))

-(def DateTimeFormatter (.. js/JSJoda -DateTimeFormatter))
-(def ResolverStyle (.. js/JSJoda -ResolverStyle))


Use superclasses Temporal and TemporalAmount over ZonedDateTime and Duration in timeline/periodic-seq

--- src/tick/timeline.clj
+++ src/tick/timeline.clj
@@ -4,11 +4,12 @@
   (:require
    [clojure.spec.alpha :as s])
   (:import
-   [java.time Duration ZonedDateTime]))
+   [java.time ZonedDateTime]
+   [java.time.temporal Temporal TemporalAmount]))

 (defn periodic-seq
   "Given a start time, create a timeline with times at constant intervals of period length"
-  ([^ZonedDateTime start ^Duration period]
+  ([^Temporal start ^TemporalAmount period]
    (iterate #(.addTo period %) start)))

 (s/def :tick/date #(instance? ZonedDateTime %))


Make cli print config location in --help

--- src/uio/main/main.clj
+++ src/uio/main/main.clj
@@ -19,6 +19,45 @@
     (apply println msg)))

 (def exit-1 "exit-1")
+
+(def default-config-url "res:///uio/main/default_config.clj")
+
+(defn load-config [url]
+  (->> (clojure.edn/read-string (slurp (uio/from url)))
+       (map (fn [[k v]]
+              [k (assoc v :origin url)]))
+       (into (array-map))))
+
+(defn home-config-url []
+  (let [home           (System/getProperty "user.home")     ; e.g. "/Users/joe"
+        _              (if (str/blank? home)
+                         (die "Couldn't get user home directory"))
+        config-dir-url (uio/with-parent (impl/replace-path "file:///" home) ".uio")
+        config-url     (uio/with-parent config-dir-url "config.clj")]
+    config-url))
+
+(defn load-or-save-home-config->url []
+  (let [config-url (home-config-url)]
+    (uio/mkdir (uio/parent-of config-url))
+    (uio/attrs (uio/parent-of config-url) {:perms "rwx------"})
+    (when-not (uio/exists? config-url)
+      (uio/copy default-config-url config-url))
+    (uio/attrs config-url {:perms "rw-------"})
+    config-url))
+
+(defn load-s3cfg []
+  (let [s3cfg-url (uio/with-parent
+                    (impl/replace-path "file:///" (System/getProperty "user.home"))
+                    ".s3cfg")]
+    (->> (str/split (slurp (uio/from s3cfg-url)) #"\n")
+         (remove #(#{\# \;} (first %)))
+         (map #(let [[k v] (str/split % #"\s?=\s?" 2)]      ; TODO respect comments. Use clojure-ini?
+                 [(keyword k) v]))
+         (into {})
+         ((fn [m]
+            {"s3://" {:origin s3cfg-url
+                      :access (or (:access_key m) (die "Can't find :access_key in ~/.s3cfg. Skipping"))
+                      :secret (or (:secret_key m) (die "Can't find :secret_key in ~/.s3cfg. Skipping"))}})))))

 (def ymd-hm-utc (doto (SimpleDateFormat. "yyyy-MM-dd hh:mm")
                       (.setTimeZone (TimeZone/getTimeZone "UTC"))))
@@ -92,7 +131,8 @@
   (println)
   (println "Version:" (get-version))
   (println "FS:     " (str/join " " (map name (:fs     (impl/list-available-implementations)))))
-  (println "Codecs: " (str/join " " (map name (:codecs (impl/list-available-implementations))))))
+  (println "Codecs: " (str/join " " (map name (:codecs (impl/list-available-implementations)))))
+  (println "Config: " (home-config-url)))

 (defn run [[op a b :as args]
            {:keys [recurse
@@ -177,43 +217,6 @@
 ;
 ; TODO fix S3: s3cmd ls s3://geopulse-ingest/teamcity/build_383/00/
 ;
-
-(def default-config-url "res:///uio/main/default_config.clj")
-
-(defn load-config [url]
-  (->> (clojure.edn/read-string (slurp (uio/from url)))
-       (map (fn [[k v]]
-              [k (assoc v :origin url)]))
-       (into (array-map))))
-
-(defn load-or-save-home-config->url []
-  (let [home           (System/getProperty "user.home")     ; e.g. "/Users/joe"
-        _              (if (str/blank? home)
-                         (die "Couldn't get user home directory"))
-        config-dir-url (uio/with-parent (impl/replace-path "file:///" home) ".uio")
-        _              (uio/mkdir config-dir-url)
-        _              (uio/attrs config-dir-url {:perms "rwx------"})
-        config-url     (uio/with-parent config-dir-url "config.clj")
-        _              (when-not (uio/exists? config-url)
-                         (uio/copy default-config-url
-                                   config-url))
-        _              (uio/attrs config-url {:perms "rw-------"})]
-    config-url))
-
-(defn load-s3cfg []
-  (let [s3cfg-url (uio/with-parent
-                    (impl/replace-path "file:///" (System/getProperty "user.home"))
-                    ".s3cfg")]
-    (->> (str/split (slurp (uio/from s3cfg-url)) #"\n")
-         (remove #(#{\# \;} (first %)))
-         (map #(let [[k v] (str/split % #"\s?=\s?" 2)]      ; TODO respect comments. Use clojure-ini?
-                 [(keyword k) v]))
-         (into {})
-         ((fn [m]
-            {"s3://" {:origin s3cfg-url
-                      :access (or (:access_key m) (die "Can't find :access_key in ~/.s3cfg. Skipping"))
-                      :secret (or (:secret_key m) (die "Can't find :secret_key in ~/.s3cfg. Skipping"))}})))))
-
 (defn -main [& args]
   (let [cli (parse-opts args
                         [["-r" "--recurse"        "Make `ls` recursive"                                     :default false]


ok so now what

ok so now what

--- src/util/funxions.clj
+++ src/util/funxions.clj
@@ -87,7 +87,7 @@
          (clojure.pprint/pprint (list ~'*fxn_defBlock_symbol* ~*fxn_defBlock_symbol*));symbol and its value
          ;(println ~e)
          ~@codeblocks
-         (= (~(:c x) ~(:d x))
+         #_(= (~(:c x) ~(:d x))
            (~(:e x) ~(:d x)))
          ;(prn ~(:c x) ~(:e x))
          )
@@ -106,7 +106,7 @@
      )
 (catch Compile$CompilerException c c))

-;TODO: throw on dup keys
+;TODO: throw on dup keys; - this is already happening on "eval"

 #_(
 => (defxn noes {:a ~(inc (+ 1 2)) :b firsta}
@@ -125,7 +125,7 @@

 ;(clojure.pprint/pprint

-#_(defxn foo
+(defxn foo
   ;`[clojure.set/join ~(+ 1 2)]
   ;if you want some form to be evaluate then place ~ before it
   ;this is the defblock
@@ -151,7 +151,7 @@
                 notnil? :all ;both spec and unspec
                 notnil? :all-specified; :all-sac
                 notnil? :except :unspecified
-                ~(partial > 0) :except :specified
+                ~(list partial > 0) :except :specified
                 (partial > 0) [:all [:not :specified] [:except [:a :c]] ]
                 ]
    ;invariants ran over all specified params but not over the unspecified(and thus optional ones which have the default value assigned)
@@ -180,7 +180,7 @@
   ;TODO: allow invariants functions for each param and throw when any of them fail(obviously)
   ;TODO: ignore optional params that weren't passed on call
   ;TODO: throw when required params aren't passed on call
-  (clojure.pprint/pprint fxn_defBlock);firsta)
+  (clojure.pprint/pprint (get_fxn_defBlock));firsta)
   )
 ;)


Print stack trace when unexpected exception is raised in the stream.

--- src/uxbox/rstore.cljs
+++ src/uxbox/rstore.cljs
@@ -90,6 +90,7 @@
   "A default error handler."
   [e]
   (println "Unexpected error: " e)
+  (js/console.error e.stack)
   (rx/throw e))

 (defn init


api added

api added

--- src/webdriver/new.clj
+++ src/webdriver/new.clj
@@ -277,6 +277,61 @@
     (mapv
      #(get-element-css-el driver el %)
      names)))
+
+;;
+;; active element
+;;
+
+(defmulti get-active-el dispatch-driver)
+
+(defmethods get-active-el [:chrome :phantom :safari]
+  [driver]
+  (with-resp driver :get
+    [:session (:session @driver) :element :active]
+    nil resp
+    (-> resp :value :ELEMENT)))
+
+(defmethod get-active-el :firefox
+  [driver]
+  (with-resp driver :get
+    [:session (:session @driver) :element :active]
+    nil resp
+    (-> resp :value first second)))
+
+;;
+;; element text and value
+;;
+
+(defn get-element-text-el [driver el]
+  (with-resp driver :get
+    [:session (:session @driver) :element el :text]
+    nil
+    resp
+    (:value resp)))
+
+(defn get-element-text [driver q]
+  (get-element-text-el driver (find driver q)))
+
+(defn get-element-value-el [driver el]
+  (with-resp driver :get
+    [:session (:session @driver) :element el :value]
+    nil
+    resp
+    (:value resp)))
+
+(defn get-element-value [driver q]
+  (get-element-value-el driver (find driver q)))
+
+;;
+;; cookes
+;;
+
+(defn get-cookies [driver]
+  (with-resp driver :get
+    [:session (:session @driver) :cookie]
+    nil
+    resp
+    (:value resp)))

 ;;
 ;; wait functions


WIP Hiding of detail sections.

WIP Hiding of detail sections.

--- src-cljs/kixi/hecuba/tabs/programmes.cljs
+++ src-cljs/kixi/hecuba/tabs/programmes.cljs
@@ -580,6 +580,12 @@

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; property-details
+(defn detail-section [title text]
+  (if (and text (re-seq #"[A-Za-z0-9]" text))
+    [:div [:h3 title]
+     [:p text]]
+    [:div {:class "hidden"}]))
+
 (defn property-details-div [data owner]
   (reify
     om/IRender
@@ -620,20 +626,11 @@
                    [:dt "Monitoring Policy"] [:dd (:monitoring_policy property_data)]
                    ]]
                  [:div.col-md-12
-                  [:h3 "Description"]
-                  [:p (:description property_data)]
-
-                  [:h3 "Project Summary"]
-                  [:p (:project_summary property_data)]
-
-                  [:h3 "Project Team"]
-                  [:p (:project_team property_data)]
-
-                  [:h3 "Design Strategy"]
-                  [:p (:design_strategy property_data)]
-
-                  [:h3 "Energy Strategy"]
-                  [:p (:energy_strategy property_data)]]
+                  (detail-section "Description" (:description property_data))
+                  (detail-section "Project Summary" (:project_summary property_data))
+                  (detail-section "Project Team" (:project_team property_data))
+                  (detail-section "Design Strategy" (:design_strategy property_data))
+                  (detail-section "Energy Strategy" (:energy_strategy property_data))]
                  [:div.col-md-12
                   (om/build sensors-div data)]]
                 )])))))


Fix hover state on "link" by providing :href

I know this looks awful, but we do it because it *is* awful. This isn't
a real link, and it shouldn't be marked up as an `<a>`. That's what
we've done, though, and to get the correct styles it needs to have an
`href` attribute; otherwise it's an old-school anchor, not a "link".

In these cases, we've set a precedent of using `"javascript:void(0)"`
because it works, it's easy to remove later, and it's extremely obvious
that it's a hack.

--- src-cljs/frontend/components/add_projects.cljs
+++ src-cljs/frontend/components/add_projects.cljs
@@ -404,7 +404,8 @@
     [:a {:href (gh-utils/third-party-app-restrictions-url) :target "_blank"}
      "GitHub's application permissions"]
     ". "
-    [:a {:on-click #(raise! owner [:refreshed-user-orgs {}])
+    [:a {:href "javascript:void(0)"
+         :on-click #(raise! owner [:refreshed-user-orgs {}])
          :class "active"}
      "Refresh this list"]
     " after you have updated permissions."]))


Heroku page: wording tweaks

Heroku page: wording tweaks

--- src-cljs/frontend/components/integrations.cljs
+++ src-cljs/frontend/components/integrations.cljs
@@ -121,9 +121,10 @@
                         :text [:p
                                "The deployment of your application is configured through just a "
                                "few lines of YAML that are kept safe in your source code. All "
-                               "you need to do to deploy to Heroku from CircleCI is configure your "
-                               "Heroku credentials in our UI, add a simple config file like this "
-                               "one into your project, and make a push. You can also easily deploy "
+                               "you need to do to deploy to Heroku from CircleCI is to "
+                               [:a {:href "/docs/continuous-deployment-with-heroku"}
+                                "configure your Heroku credentials in our UI, add a simple config file to your project, and push"]
+                               ". You can also easily deploy "
                                "different branches to different Heroku apps (e.g. one for staging "
                                "and one for production)."]}
                        {:type :text
@@ -139,7 +140,7 @@
                                " showing how to setup a more robust continuous delivery pipeline "
                                "with staging and prod environments."]}
                        {:type :video
-                        :title "Continuous deployment with CircleCI and Heroku: Part 1"
+                        :title "Continuous deployment with CircleCI and Heroku"
                         :thumbnail "/img/outer/integrations/video-placeholder.svg"
                         :video-id "Hfs_1yuWDf4"}]
             :bottom-header "Ready for world-class continuous delivery?"


Moving pricing page plan loading logic back up to the top level.

--- src-cljs/frontend/components/org_settings.cljs
+++ src-cljs/frontend/components/org_settings.cljs
@@ -330,8 +330,7 @@
   (reify
     om/IRender
     (render [_]
-      (let [
-            org-name (get-in app state/org-name-path)
+      (let [org-name (get-in app state/org-name-path)
             plan (get-in app state/org-plan-path)
             selected-containers (or (get-in app state/selected-containers-path)
                                     (max (pm/usable-containers plan)
@@ -347,89 +346,79 @@
             button-clickable? (not= (if piggiebacked? 0 (pm/paid-containers plan))
                                     selected-paid-containers)]
       (html
-        (if-not plan
-          (cond ;; TODO: fix; add plan
-            (nil? plan)
-              [:div.loading-spinner common/spinner]
-            (not (seq plan))
-              [:h3 (str "No plan exists for" org-name "yet. Follow a project to trigger plan creation.")]
-            :else
-              [:h3 "Something is wrong! Please submit a bug report."])
-
-          [:div#edit-plan {:class "pricing.page"}
-           (when-not (config/enterprise?)
+        [:div#edit-plan {:class "pricing.page"}
+         (when-not (config/enterprise?)
+           [:fieldset
+            [:legend (str "Our pricing is flexible and scales with you. Add as many containers as you want for $"
+                          container-cost "/month each.")]])
+         [:div.main-content
+          [:div.left-section
+           [:div.pricing-calculator-controls
+            [:h3 "Linux Containers"]
+            [:form
+             [:div.container-picker
+              [:p "More containers means faster builds and lower queue times."]
+              (om/build shared/styled-range-slider
+                        (merge app {:start-val selected-containers :min-val min-slider-val :max-val max-slider-val}))
+              [:div.container-input
+               [:input {:style {:margin "4px" :height "calc(2em + 2px)"}
+                        :type "text" :value selected-containers
+                        :on-change #(utils/edit-input owner state/selected-containers-path %
+                                                      :value (int (.. % -target -value)))}]
+               [:span.new-plan-total (str (pluralize-no-val selected-containers "container") (when-not (config/enterprise?) (str " for " (if (= 0 new-total) "Free!" (str "$" new-total "/month")))))]
+               (when (not (= new-total old-total))
+                 [:span.strikeout {:style {:margin "auto"}} (str "$" old-total "/month")])]]
              [:fieldset
-              [:legend (str "Our pricing is flexible and scales with you. Add as many containers as you want for $"
-                            container-cost "/month each.")]])
-           [:div.main-content
-            [:div.left-section
-             [:div.pricing-calculator-controls
-              [:h3 "Linux Containers"]
-              [:form
-               [:div.container-picker
-                [:p "More containers means faster builds and lower queue times."]
-                (om/build shared/styled-range-slider
-                          (merge app {:start-val selected-containers :min-val min-slider-val :max-val max-slider-val}))
-                [:div.container-input
-                 [:input {:style {:margin "4px" :height "calc(2em + 2px)"}
-                          :type "text" :value selected-containers
-                          :on-change #(utils/edit-input owner state/selected-containers-path %
-                                                        :value (int (.. % -target -value)))}]
-                 [:span.new-plan-total (str (pluralize-no-val selected-containers "container") (when-not (config/enterprise?) (str " for " (if (= 0 new-total) "Free!" (str "$" new-total "/month")))))]
-                 (when (not (= new-total old-total))
-                   [:span.strikeout {:style {:margin "auto"}} (str "$" old-total "/month")])]]
-               [:fieldset
-                (if (and (pm/can-edit-plan? plan org-name) (or (config/enterprise?) (pm/paid? plan)))
+              (if (and (pm/can-edit-plan? plan org-name) (or (config/enterprise?) (pm/paid? plan)))
+                (forms/managed-button
+                  [:button.btn.btn-large.btn-primary.center
+                   {:data-success-text "Saved",
+                    :data-loading-text "Saving...",
+                    :type "submit"
+                    :disabled (when-not button-clickable? "disabled")
+                    :on-click (when button-clickable?
+                                #(do (raise! owner [:update-containers-clicked
+                                                    {:containers selected-paid-containers}])
+                                     false))}
+                   (if (config/enterprise?)
+                     "Save changes"
+                     "Update plan")])
+                (if-not checkout-loaded?
+                  [:div.loading-spinner common/spinner [:span "Loading Stripe checkout"]]
                   (forms/managed-button
                     [:button.btn.btn-large.btn-primary.center
-                     {:data-success-text "Saved",
-                      :data-loading-text "Saving...",
+                     {:data-success-text "Paid!",
+                      :data-loading-text "Paying...",
+                      :data-failed-text "Failed!",
                       :type "submit"
                       :disabled (when-not button-clickable? "disabled")
                       :on-click (when button-clickable?
-                                  #(do (raise! owner [:update-containers-clicked
-                                                      {:containers selected-paid-containers}])
+                                  #(do (raise! owner [:new-plan-clicked
+                                                      {:containers selected-paid-containers
+                                                       :paid {:template (:id pm/default-template-properties)}
+                                                       :price new-total
+                                                       :description (str "$" new-total "/month, includes "
+                                                                         (pluralize selected-containers "container"))}])
                                        false))}
-                     (if (config/enterprise?)
-                       "Save changes"
-                       "Update plan")])
-                  (if-not checkout-loaded?
-                    [:div.loading-spinner common/spinner [:span "Loading Stripe checkout"]]
-                    (forms/managed-button
-                      [:button.btn.btn-large.btn-primary.center
-                       {:data-success-text "Paid!",
-                        :data-loading-text "Paying...",
-                        :data-failed-text "Failed!",
-                        :type "submit"
-                        :disabled (when-not button-clickable? "disabled")
-                        :on-click (when button-clickable?
-                                    #(do (raise! owner [:new-plan-clicked
-                                                        {:containers selected-paid-containers
-                                                         :paid {:template (:id pm/default-template-properties)}
-                                                         :price new-total
-                                                         :description (str "$" new-total "/month, includes "
-                                                                           (pluralize selected-containers "container"))}])
-                                         false))}
-                       "Pay Now"])))
-
-
-                (when-not (config/enterprise?)
-                  ;; TODO: Clean up conditional here - super nested and many interactions
-                  (if (or (pm/paid? plan) (and (pm/freemium? plan) (not (pm/in-trial? plan))))
-                    (list
-                      (when (< old-total new-total)
-                        [:span.help-block
-                         "We'll charge your card today, for the prorated difference between your new and old plans."])
-                      (when (> old-total new-total)
-                        [:span.help-block
-                         "We'll credit your account, for the prorated difference between your new and old plans."]))
-                    (if (pm/in-trial? plan)
-                      [:span "Your trial will end in " (pluralize (Math/abs (pm/days-left-in-trial plan)) "day")
-                       "."]
-                      ;; TODO: Only show for trial-plans?
-                      [:span "Your trial of " (pluralize (pm/trial-containers plan) "container")
-                       " ended " (pluralize (Math/abs (pm/days-left-in-trial plan)) "day")
-                       " ago. Pay now to enable builds of private repositories."])))]]]]]]))))))
+                     "Pay Now"])))
+
+              (when-not (config/enterprise?)
+                ;; TODO: Clean up conditional here - super nested and many interactions
+                (if (or (pm/paid? plan) (and (pm/freemium? plan) (not (pm/in-trial? plan))))
+                  (list
+                    (when (< old-total new-total)
+                      [:span.help-block
+                       "We'll charge your card today, for the prorated difference between your new and old plans."])
+                    (when (> old-total new-total)
+                      [:span.help-block
+                       "We'll credit your account, for the prorated difference between your new and old plans."]))
+                  (if (pm/in-trial? plan)
+                    [:span "Your trial will end in " (pluralize (Math/abs (pm/days-left-in-trial plan)) "day")
+                     "."]
+                    ;; TODO: Only show for trial-plans?
+                    [:span "Your trial of " (pluralize (pm/trial-containers plan) "container")
+                     " ended " (pluralize (Math/abs (pm/days-left-in-trial plan)) "day")
+                     " ago. Pay now to enable builds of private repositories."])))]]]]]])))))

 (defn containers [app owner]
   (reify
@@ -462,15 +451,24 @@
       (let [plan (get-in app state/org-plan-path)
             org-name (get-in app state/org-name-path)]
         (html
-          (if (pm/piggieback? plan org-name)
-            (plans-piggieback-plan-notification plan org-name)
-            [:div
-             (om/build linux-plan {:app app :checkout-loaded? checkout-loaded?})
-             (when (and (feature/enabled? :osx-plans)
-                        (get-in app state/org-osx-beta-path))
-               (list
-                 (om/build osx-plans plan)
-                 (om/build osx-faq osx-faq-items)))]))))))
+          (if-not plan
+            (cond ;; TODO: fix; add plan
+              (nil? plan)
+                [:div.loading-spinner common/spinner]
+              (not (seq plan))
+                [:h3 (str "No plan exists for" org-name "yet. Follow a project to trigger plan creation.")]
+              :else
+                [:h3 "Something is wrong! Please submit a bug report."])
+
+            (if (pm/piggieback? plan org-name)
+              (plans-piggieback-plan-notification plan org-name)
+              [:div
+               (om/build linux-plan {:app app :checkout-loaded? checkout-loaded?})
+               (when (and (feature/enabled? :osx-plans)
+                          (get-in app state/org-osx-beta-path))
+                 (list
+                   (om/build osx-plans plan)
+                   (om/build osx-faq osx-faq-items)))])))))))

 (defn piggyback-organizations [app owner]
   (om/component


v 0.4.3

v 0.4.3


Version 0.2.1-SNAPSHOT

Version 0.2.1-SNAPSHOT


(maint) Update clj-parent to 4.6.23

(maint) Update clj-parent to 4.6.23


Updated logback dependency to 1.2.10

Updated logback dependency to 1.2.10

See #1006


Adding test dependencies in Lein.

Adding test dependencies in Lein.


build fix

build fix


misc commidities/prices UI cleanup

misc commidities/prices UI cleanup

--- src/cljs/clj_money/views/commodities.cljs
+++ src/cljs/clj_money/views/commodities.cljs
@@ -29,7 +29,9 @@
   (commodities/select
     (map (fn [result]
            (-busy)
-           (swap! page-state assoc :commodities (sort-by :name result))))))
+           (swap! page-state #(-> %
+                                  (dissoc :prices-commodity)
+                                  (assoc :commodities (sort-by :name result))))))))

 (defn- save-commodity
   [page-state]
@@ -105,7 +107,7 @@
                                                           (t/years 1))
                                        (map vec)
                                        (load-in-chunks {:fetch-xf (comp (map #(hash-map :commodity-id (:id commodity)
-                                                                                :trade-date %))
+                                                                                :trade-date %))
                                                                         fetch-prices)}))]
     (swap! page-state assoc :ctl-chan ctl-ch)
     (go-loop [prices (<! items-ch)]
@@ -113,7 +115,9 @@
                (do
                  (swap! page-state update-in [:prices] (fnil concat []) prices)
                  (recur (<! items-ch)))
-               (swap! page-state assoc :all-prices-fetched? true)))
+               (swap! page-state #(-> %
+                                      (update-in [:prices] (fnil identity []))
+                                      (assoc :all-prices-fetched? true)))))
     (go (>! ctl-ch :fetch))))

 (defn- select-prices-commodity


Target element for opacity transition

Target element for opacity transition

--- src/cljs/gtfve/components/side_panel.cljs
+++ src/cljs/gtfve/components/side_panel.cljs
@@ -96,7 +96,13 @@
             transition-ch (utils/listen
                            (om/get-node owner)
                            EventType.TRANSITIONEND
-                           (chan 1 (filter #(= "opacity" (.. % -event_ -propertyName)))))
+                           (chan 1 (comp
+                                    (filter #(and (= "opacity" (.. % -event_ -propertyName))
+                                                  (let [classList (.. % -target -classList)]
+                                                    (and
+                                                     (.contains classList "tab-pane")
+                                                     (.contains classList "fade")))))
+                               )))
             active-in-ch (chan 1)]
         (go-loop []
           (let [[v c] (alts! [active-in-ch toggle-ch kill-ch])]


Fix indentation... again

Fix indentation... again

--- src/trapperkeeper_demo/trapperkeeper_demo_web_service.clj
+++ src/trapperkeeper_demo/trapperkeeper_demo_web_service.clj
@@ -20,8 +20,8 @@

   (start [this context]
     (let [host (get-in-config [:webserver :host])
-           port (get-in-config [:webserver :port])
-           url-prefix (get-route this)]
-          (log/infof "Meow web service started; visit http://%s:%s%s/world to check it out!"
-                     host port url-prefix))
-     context))
+          port (get-in-config [:webserver :port])
+          url-prefix (get-route this)]
+      (log/infof "Meow web service started; visit http://%s:%s%s/world to check it out!"
+                 host port url-prefix))
+    context))


CMR-3554: Addressed the PR comments.

CMR-3554: Addressed the PR comments.

--- ingest-app/src/cmr/ingest/services/humanizer_alias_cache.clj
+++ ingest-app/src/cmr/ingest/services/humanizer_alias_cache.clj
@@ -63,45 +63,55 @@
                      aliases-set (set (get field-alias-map (str/upper-case coll-field-name)))]
                 alias (set/difference aliases-set field-names-set)]
            (assoc coll-field field-name-key alias))]
-    field-aliases))
+    field-aliases))

-(defn update-collection-with-aliases
-  "Returns the collection with all the platform and tile aliases added.
-   Using platform aliases as an example:
-   Given plat-alias-map being {\"TERRA\" [\"AM-1\" \"am-1\"]},
-   which indicates AM-1 and am-1 are aliases of TERRA. That means that granules referring to
+(defn update-collection-with-platform-aliases
+  "Returns the collection with humanizer platform aliases added.
+   Given plat-alias-map being {\"TERRA\" [\"AM-1\" \"am-1\"]},
+   which indicates AM-1 and am-1 are aliases of TERRA. That means that granules referring to
    a collection through AM-1 or am-1 would be permitted if the collection had TERRA.
-   Here is one example:
+   Here is one example:
    Original collection platforms: [{:ShortName \"Terra\" :Otherfields \"other-terra-values\"}
                                    {:ShortName \"AM-1\" :Otherfields \"other-am-1-values\"}]
    updated collection platforms: [{:ShortName \"Terra\" :Otherfields \"other-terra-values\"}
                                   {:ShortName \"AM-1\" :Otherfields \"other-am-1-values\"}
                                   {:ShortName \"am-1\" :Otherfields \"other-terra-values\"}]
-   Note: If the ShortName of a platform alias already exists in the original collection platforms
-   We will keep the original one and not add the alias to the updated collection platforms.
+   Note: If the ShortName of a platform alias already exists in the original collection platforms
+   We will keep the original one and not add the alias to the updated collection platforms.
    In the above example, alias {:ShortName \"AM-1\" :Otherfields \"other-terra-values\"} is not added.
-   This is a conscious decision, not a bug."
-  [context collection umm-spec-collection?]
+   This is a conscious decision, not a bug."
+  [collection umm-spec-collection? humanizer-alias-map]
   (let [plat-key (if umm-spec-collection?
                    :Platforms
                    :platforms)
         plat-name-key (if umm-spec-collection?
                         :ShortName
                         :short-name)
-        tile-key (if umm-spec-collection?
+        platforms (get collection plat-key)
+        plat-alias-map (get humanizer-alias-map "platform")
+        platform-aliases (get-field-aliases platforms plat-name-key plat-alias-map)]
+    (-> collection
+        (update plat-key concat platform-aliases))))
+
+(defn update-collection-with-tile-aliases
+  "Returns the collection with humanizer tile aliases added"
+  [collection umm-spec-collection? humanizer-alias-map]
+  (let [tile-key (if umm-spec-collection?
                    :TilingIdentificationSystems
                    :two-d-coordinate-systems)
         tile-name-key (if umm-spec-collection?
                         :TilingIdentificationSystemName
                         :name)
-        alias-map (get-humanizer-alias-map context)
-        platforms (get collection plat-key)
-        plat-alias-map (get alias-map "platform")
-        platform-aliases (get-field-aliases platforms plat-name-key plat-alias-map)
         tiles (get collection tile-key)
-        tile-alias-map (get alias-map "tiling_system_name")
-        tile-aliases (get-field-aliases tiles tile-name-key tile-alias-map)
-        updated-collection (-> collection
-                               (update plat-key concat platform-aliases)
-                               (update tile-key concat tile-aliases))]
-    updated-collection))
+        tile-alias-map (get humanizer-alias-map "tiling_system_name")
+        tile-aliases (get-field-aliases tiles tile-name-key tile-alias-map)]
+    (-> collection
+        (update tile-key concat tile-aliases))))
+
+(defn update-collection-with-aliases
+  "Returns the collection with humanizer platform and tile aliases added."
+  [context collection umm-spec-collection?]
+  (let [humanizer-alias-map (get-humanizer-alias-map context)]
+    (-> collection
+        (update-collection-with-platform-aliases umm-spec-collection? humanizer-alias-map)
+        (update-collection-with-tile-aliases umm-spec-collection? humanizer-alias-map))))


Fix error in destructuring argument map

Fix error in destructuring argument map

--- src/uruk/core.clj
+++ src/uruk/core.clj
@@ -48,12 +48,12 @@
   https://docs.marklogic.com/javadoc/xcc/com/marklogic/xcc/types/package-summary.html"
   {"array-node()" java-json->clj-json ;; ArrayNode
    "boolean-node()" #(.asBoolean %)  ;; BooleanNode
-
+
    "cts:box" #(.asString %) ;; would be nice to convert box to seq of 4 numbers, unless that is disrupted by other element types
    "cts:circle" #(.asString %)
    "cts:point" #(.asString %)
    "cts:polygon" #(.asString %)
-
+
    "json:array" java-json->clj-json ;; JSArray
    "json:object" java-json->clj-json ;; JSObject

@@ -110,7 +110,7 @@
   overridden (in part or in whole) with the optional parameter
   `type-mapping`, which should contain a transformation function keyed
   by an XCC type string. See `types` above."
-  [result-sequence & [type-mapping]]
+  [result-sequence & [type-mapping]]
   ;; TODO throw informative exception if type not found in types
   (let [result (map (fn [item] (((merge types
                                        (when (map? type-mapping)
@@ -169,7 +169,7 @@
     ;; TODO A macro might be useful to replace the chain of when-lets with use-once variable names
     (when-let [epit (:effective-point-in-time options)]
       (.setEffectivePointInTime request (BigInteger. (str epit))))
-
+
     (when-let [locale (:locale options)]
       (.setLocale request locale)) ;; TODO enforce Locale object?
     (when-let [mar (:max-auto-retry options)]
@@ -178,7 +178,7 @@
       (.setQueryLanguage request ql))
     (when-let [rn (:request-name options)]
       (.setRequestName request rn))
-
+
     (when-let [rtl (:request-time-limit options)]
       (.setRequestTimeLimit request rtl))
     (when-let [rbs (:result-buffer-size options)]
@@ -285,7 +285,7 @@
   type conversion in `types`."
   ([session query]
    (execute-xquery session query {}))
-  ([session query [{:keys [options variables types]}]]
+  ([session query {:keys [options variables types]}]
    (submit-request (.newAdhocQuery session query) session query options variables types)))

 (defn execute-module
@@ -302,7 +302,7 @@

 (def valid-content-creation-options
   "Set of valid creation options for Content objects. See
-  https://docs.marklogic.com/javadoc/xcc/com/marklogic/xcc/ContentCreateOptions.html"
+  https://docs.marklogic.com/javadoc/xcc/com/marklogic/xcc/ContentCreateOptions.html"
   #{:buffer-size
     :collections
     :encoding
@@ -352,7 +352,7 @@
       (.setEncoding cco e))
     (when-let [f (:format options)]
       (.setFormat cco (doc-format f)))
-
+
     (when-let [g (:graph options)]
       (.setGraph cco g))
     (when-let [lang (:language options)]
@@ -374,7 +374,7 @@
                                                         (key (first permission)))))
                                                []
                                                perms))))
-
+
     (when-let [pk (:placement-keys options)]
       (.setPlaceKeys cco pk)) ;; FIXME bigint and long array casts?
     (when-let [q (:quality options)]
@@ -398,7 +398,7 @@
    :graph (.getGraph opts)
    :language (.getLanguage opts)
    :namespace (.getNamespace opts)
-   :permissions (map #(hash-map (.getRole %) (.toString (.getCapability %))) (.getPermissions opts))
+   :permissions (map #(hash-map (.getRole %) (.toString (.getCapability %))) (.getPermissions opts))
    :quality (.getQuality opts)
    :repair-level ((clojure.set/map-invert repair-level) (.getRepairLevel opts))
    :resolve-buffer-size (.getResolveBufferSize opts)
@@ -442,7 +442,7 @@
 ;;;; these functions within `with-open` after setting the transaction
 ;;;; mode to `:update` or `:query` on the session via the
 ;;;; `:transaction-mode` option.
-;;;;
+;;;;
 ;;;; See https://docs.marklogic.com/guide/xcc/concepts#id_23310
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;