override correct namespace

override correct namespace

--- src/org/spootnik/fleet/config.clj
+++ src/org/spootnik/fleet/config.clj
@@ -9,7 +9,7 @@
    :console true
    :files  []
    :level  "info"
-   :overrides {:io.pithos "debug"}})
+   :overrides {:org.spootnik.fleet "debug"}})

 (defn find-ns-var
   "Find a symbol in a namespace"


mention keepalive loop in logs

mention keepalive loop in logs

--- src/org/spootnik/fleet/engine.clj
+++ src/org/spootnik/fleet/engine.clj
@@ -45,20 +45,22 @@
             (a/put! @subscription :close)
             (a/close! @subscription))
           (reset! subscription close-ch)
-          (go
-            (loop []
-              (let [tm  (a/timeout keepalive)
-                    sig (alts! [close-ch tm])]
-                (when (= tm sig)
-                  ;; every keepalive interval
-                  ;; send a dummy script on the wire to
-                  ;; keep machines alive
-                  (request this
-                           {:script_name "ping"
-                            :script ["ping"]
-                            :timeout 1000}
-                           (chan (a/dropping-buffer 0)))
-                  (recur)))))))
+          (when keepalive
+            (info "found keepalive, starting loop")
+            (go
+              (loop []
+                (let [tm  (a/timeout keepalive)
+                      sig (alts! [close-ch tm])]
+                  (when (= tm sig)
+                    ;; every keepalive interval
+                    ;; send a dummy script on the wire to
+                    ;; keep machines alive
+                    (request this
+                             {:script_name "ping"
+                              :script ["ping"]
+                              :timeout 1000}
+                             (chan (a/dropping-buffer 0)))
+                    (recur))))))))
       (request [this payload sink]
         (let [id                (str (java.util.UUID/randomUUID))
               payload           (assoc payload :id id)


Fix the build email

Fix the build email

--- src/circle/backend/build/email.clj
+++ src/circle/backend/build/email.clj
@@ -3,11 +3,9 @@
   (:use [clojure.tools.logging :only (info)]))

 (defn notify-build-results [build]
-  (let [code (format
-              "require 'simple_mailer'
-SimpleMailer.build_email('%s')" (-> @build :_id))]
-    (circle.ruby/eval code)))
-
+  (ruby/require-rails)
+  (ruby/ruby-require "simple_mailer")
+  (ruby/send (ruby/get-class "SimpleMailer") :build_email (-> @build :_id)))

 (defn send-build-error-email [build error]
   (ruby/require-rails)


more Clojure DSL helpers

more Clojure DSL helpers

--- src/clj/backtype/storm/clojure.clj
+++ src/clj/backtype/storm/clojure.clj
@@ -1,6 +1,7 @@
 (ns backtype.storm.clojure
   (:use [clojure.contrib.def :only [defnk defalias]])
   (:use [backtype.storm bootstrap util])
+  (:import [backtype.storm LocalCluster StormSubmitter])
   (:import [backtype.storm.generated StreamInfo])
   (:import [backtype.storm.tuple Tuple])
   (:import [backtype.storm.task OutputCollector IBolt])
@@ -181,3 +182,9 @@
 (defalias bolt-spec thrift/mk-bolt-spec)
 (defalias spout-spec thrift/mk-spout-spec)
 (defalias shell-bolt-spec thrift/mk-shell-bolt-spec)
+
+(defn submit-remote-topology [name conf topology]
+  (StormSubmitter/submitTopology name conf topology))
+
+(defn local-cluster []
+  (LocalCluster.))


add body so it will be converted to json

--- src/clj/clj_money/api/entities.clj
+++ src/clj/clj_money/api/entities.clj
@@ -13,4 +13,5 @@
 (defn delete
   [{{id :id} :params}]
   (entities/delete (env :db) id)
-  {:status 204})
+  {:status 204
+   :body []})


boosting Darwin should cost 1 credit

boosting Darwin should cost 1 credit

--- src/clj/game/cards-icebreakers.clj
+++ src/clj/game/cards-icebreakers.clj
@@ -149,9 +149,10 @@

    "Darwin"
    {:events {:runner-turn-begins
-             {:optional {:cost [:credit 1] :prompt "Place 1 virus counter on Darwin?"
-                         :msg "place 1 virus counter"
-                         :yes-ability {:effect (effect (add-prop card :counter 1)
+             {:optional {:prompt "Place 1 virus counter on Darwin?"
+                         :yes-ability {:cost [:credit 1]
+                                       :msg "place 1 virus counter"
+                                       :effect (effect (add-prop card :counter 1)
                                                        (update-breaker-strength card))}}}
              :purge {:effect (effect (update-breaker-strength card))}}
     :abilities [{:cost [:credit 2] :msg "break ICE subroutine"}]


schemas

schemas

--- src/cljc/salava/badge/schemas.cljc
+++ src/cljc/salava/badge/schemas.cljc
@@ -157,13 +157,13 @@
 (s/defschema UserBackpackEmail {:email s/Str
                                 :backpack_id (s/maybe s/Int)})

-(s/defschema Evidence {:id (s/maybe s/Str)
+(s/defschema Evidence {:id (s/maybe s/Int)
                        :name (s/maybe s/Str)
                        :narrative (s/maybe s/Str)
                        :url s/Str
-                       :resource_id (s/maybe s/Int)
-                       :resource_type s/Str
-                       :mime_type (s/maybe s/Str)} )
+                       (s/optional-key  :resource_id) (s/maybe s/Int)
+                       (s/optional-key  :resource_type) s/Str
+                       (s/optional-key  :mime_type) (s/maybe s/Str)} )


Add <??, a null-safe variant of <?.

Add <??, a null-safe variant of <?.

--- src/common/datomish/pair_chan.cljc
+++ src/common/datomish/pair_chan.cljc
@@ -71,6 +71,13 @@
      (consume-pair (cljs.core.async/<! ~pc-chan))
      (consume-pair (clojure.core.async/<! ~pc-chan))))

+(defmacro <??
+  "Takes from the channel if it's non-nil."
+  [pc-chan]
+  `(let [c# ~pc-chan]
+     (when c#
+       (datomish.pair-chan/<? c#))))
+
 (defn consume-pair
   "When passed a [value nil] pair, returns value. When passed a [nil error] pair,
   throws error. See also `<?`."


Don't bother caching agg.

Don't bother caching agg.

--- src/onyx/peer/aggregate.clj
+++ src/onyx/peer/aggregate.clj
@@ -26,11 +26,10 @@
   [{:keys [onyx.core/queue onyx.core/ingress-queues onyx.core/task-map] :as event}]
   (let [session (extensions/bind-active-session queue (first (vals ingress-queues)))
         drained (:drained-inputs @(:onyx.core/pipeline-state event))
-        uncached (into {} (remove (fn [[t _]] (get drained t)) ingress-queues))
         consumers (map (fn [[task queue-name]]
                          {:input task
                           :consumer (extensions/create-consumer queue session queue-name)})
-                       uncached)
+                       ingress-queues)
         halting-ch (chan 0)
         read-ch (chan 1)
         rets


remove unneeded local binding

remove unneeded local binding

--- src/prime_times/tabular.clj
+++ src/prime_times/tabular.clj
@@ -14,7 +14,6 @@
                              (map max ws acc)))
                          (map (comp count str) ks')
                          rows')
-          max-k (apply max widths)
           spacers (map #(apply str (repeat % "-")) widths)
           fmts (map #(str "%" % "s") widths)
           fmt-row (fn [leader nexter divider trailer row]


add thumbnail-auto-width-map

add thumbnail-auto-width-map

scale-to-height-down-route is the only one that does not require
width, therefore an equivalent of auto-height-map for width
is required.

--- src/vignette/http/route_helpers.clj
+++ src/vignette/http/route_helpers.clj
@@ -62,3 +62,7 @@
 (defn route->thumbnail-auto-height-map
   [request-map request]
   (route->thumbnail-map request-map request {:height :auto}))
+
+(defn route->thumbnail-auto-width-map
+  [request-map request]
+  (route->thumbnail-map request-map request {:width :auto}))


Rename macro to check if bucket exist

Rename macro to check if bucket exist

--- src/silly_image_store/handler.clj
+++ src/silly_image_store/handler.clj
@@ -21,12 +21,14 @@
         to-json (fn [n] {:name n :url (str base-url "/" n)})]
     (fn [names] (map to-json names))))

-(defn- bucket-exist? [bucket]
-  (some #{bucket} (store/list-image-dirs images-dir)))
-
 ; Routes
 (defn- not-found [thing]
   (route/not-found (str "No thing '" thing "' found")))
+
+(defmacro if-exist [bucket expression]
+  `(if (some #{~bucket} (store/list-image-dirs images-dir))
+     ~expression
+     (not-found ~bucket)))

 (defn- root-route [request sep link-names]
   (let [base-url (request-url request)
@@ -51,11 +53,6 @@
         bucket-names (store/list-image-dirs images-dir)]
     (json-list-response bucket-names)))

-(defmacro if-bucket-exist [bucket expression]
-  `(if (bucket-exist? ~bucket)
-     ~expression
-     (not-found ~bucket)))
-
 (defroutes app-routes
   (GET "/" [:as request] (root-route request "" [:images :buckets :random]))
   (GET "/images" request (list-images-route request no-bucket))
@@ -63,13 +60,13 @@
   (GET "/random" [] (serve-random-image-route no-bucket))
   (GET "/buckets" request list-buckets-route)
   (GET "/buckets/:bucket" [bucket :as request]
-       (if-bucket-exist bucket (root-route request "/" [:images :random])))
+       (if-exist bucket (root-route request "/" [:images :random])))
   (GET "/buckets/:bucket/images" [bucket :as request]
-       (if-bucket-exist bucket (list-images-route request bucket)))
+       (if-exist bucket (list-images-route request bucket)))
   (GET "/buckets/:bucket/images/:image" [bucket image]
-       (if-bucket-exist bucket (serve-image-route bucket image)))
+       (if-exist bucket (serve-image-route bucket image)))
   (GET "/buckets/:bucket/random" [bucket]
-       (if-bucket-exist bucket (serve-random-image-route bucket)))
+       (if-exist bucket (serve-random-image-route bucket)))
   (route/resources "/")
   (route/not-found "Not Found"))


Add failing test for map entry shove

Add failing test for map entry shove

map-entries fall into the :else branch where we return
`(into nil [7 4])` which is `'(4 7)` but should be `[7 4]` or `'(7 4)`

--- test/active/clojure/lens_test.cljc
+++ test/active/clojure/lens_test.cljc
@@ -180,6 +180,10 @@
 (deftest at-index-test
   (lens-laws-hold (lens/at-index 0) [12 42] 7 65)
   (lens-laws-hold (lens/at-index 1) '(12 42) 7 65)
+
+  ;; laws must hold for map-entries
+  (let [entry (first {3 4})]
+    (lens-laws-hold (lens/at-index 0) entry 7 65))

   (is (= [13 42]
          (lens/shove [13 0] (lens/at-index 1) 42)))


Rename the tests, properties and generators

--- test/cljs/tictactoe/game_test.cljs
+++ test/cljs/tictactoe/game_test.cljs
@@ -84,16 +84,16 @@
 ;; - The test should be based on visible API only: it means we should not
 ;; try to generate the internal state of the game. It would breach
 ;; encapsulation, and would thus break at any implementation change.
-(def coord-gen
+(def move-gen
   (gen/elements cst/coordinates))

 (def game-gen
   (gen/fmap
     #(play-moves (logic/new-game) %)
-    (gen/vector coord-gen 0 cst/cell-count)
+    (gen/vector move-gen 0 cst/cell-count)
     ))

-;; The following are all bad ideas
+;; The following are all bad ideas to base our game generation upon

 (def player-gen
   (gen/elements #{:cell/cross :cell/circle}))
@@ -113,7 +113,7 @@
 ;; Generative testing
 ;; ----------------------------------------------------------------------------

-(defn valid-next-game?
+(defn valid-game-transition?
   [old-game new-game move]
   (let [new-player (logic/get-next-player new-game)
         old-player (logic/get-next-player old-game)
@@ -126,16 +126,16 @@
       (= (dissoc old-board move) (dissoc new-board move))
       )))

-(defn valid-move-properties
+(defn game-move-properties
   [old-game]
-  (prop/for-all [move coord-gen]
+  (prop/for-all [move move-gen]
     (let [new-game (logic/on-move old-game move)]
-      (or (= old-game new-game) (valid-next-game? old-game new-game move))
+      (or (= old-game new-game) (valid-game-transition? old-game new-game move))
       )))

-(defn valid-undo-properties
+(defn game-undo-properties
   [old-game]
-  (prop/for-all [move coord-gen]
+  (prop/for-all [move move-gen]
     (let [new-game (logic/on-move old-game move)]
       (or
         (= old-game new-game)
@@ -143,13 +143,13 @@
         ))))

 (defspec try-move-from-start-game 100
-  (valid-move-properties (logic/new-game)))
+  (game-move-properties (logic/new-game)))

 (defspec try-move-from-valid-game 100
-  (prop/for-all [g game-gen] (valid-move-properties g)))
+  (prop/for-all [g game-gen] (game-move-properties g)))

 (defspec try-undo-from-valid-game 100
-  (prop/for-all [g game-gen] (valid-undo-properties g)))
+  (prop/for-all [g game-gen] (game-undo-properties g)))

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


Fix index values for labels.

Fix index values for labels.

--- src/oc/storage/resources/label.clj
+++ src/oc/storage/resources/label.clj
@@ -37,7 +37,7 @@
    (db-common/read-resource conn table-name label-uuid))

   ([conn :- lib-schema/Conn org-uuid :- lib-schema/UniqueID label-slug :- common/Slug]
-   (first (db-common/read-resources conn table-name :org-label [org-uuid label-slug]))))
+   (first (db-common/read-resources conn table-name :org-label [[org-uuid label-slug]]))))

 (defn slug-available?
   "Return true if the slug is not used by any org in the system."
@@ -147,4 +147,4 @@

 (schema/defn ^:always-validate list-labels-by-org-user :- [common/Label]
   [conn :- lib-schema/Conn org-uuid :- lib-schema/UniqueID user-id :- lib-schema/UniqueID]
-  (db-common/read-resources conn table-name :org-uuid-user-id-labels [org-uuid user-id]))+  (db-common/read-resources conn table-name :org-uuid-user-id-labels [[org-uuid user-id]]))


Add http end-to-end test for the svgparse functionality.

--- test/uxbox/tests/test_svgparse.clj
+++ test/uxbox/tests/test_svgparse.clj
@@ -17,6 +17,7 @@
       (t/is (contains? result :height))
       (t/is (contains? result :view-box))
       (t/is (contains? result :name))
+      (t/is (contains? result :content))
       (t/is (= 500.0 (:width result)))
       (t/is (= 500.0 (:height result)))
       (t/is (= [0.0 0.0 500.00001 500.00001] (:view-box result)))
@@ -29,6 +30,7 @@
       (t/is (contains? result :height))
       (t/is (contains? result :view-box))
       (t/is (contains? result :name))
+      (t/is (contains? result :content))
       (t/is (= 500.0 (:width result)))
       (t/is (= 500.0 (:height result)))
       (t/is (= [0.0 0.0 500.0 500.00001] (:view-box result)))
@@ -52,4 +54,36 @@
       (t/is (th/exception? e))
       (t/is (th/ex-info? e))
       (t/is (th/ex-with-code? e :uxbox.services.svgparse/invalid-result))))
+
+  (t/testing "valid http request"
+    (let [image (slurp (io/resource "uxbox/tests/_files/sample2.svg"))
+          path "/api/svg/parse"]
+      (with-server {:handler (uft/routes)}
+        (let [rsp (th/request {:method :post
+                               :path path
+                               :body image
+                               :raw? true})]
+          (t/is (= 200 (:status rsp)))
+          (t/is (contains? (:body rsp) :width))
+          (t/is (contains? (:body rsp) :height))
+          (t/is (contains? (:body rsp) :view-box))
+          (t/is (contains? (:body rsp) :name))
+          (t/is (contains? (:body rsp) :content))
+          (t/is (= 500.0 (:width (:body rsp))))
+          (t/is (= 500.0 (:height (:body rsp))))
+          (t/is (= [0.0 0.0 500.0 500.00001] (:view-box (:body rsp))))
+          (t/is (= "play.svg" (:name (:body rsp))))))))
+
+  (t/testing "invalid http request"
+    (let [path "/api/svg/parse"
+          image "<svg></svg>"]
+      (with-server {:handler (uft/routes)}
+        (let [rsp (th/request {:method :post
+                               :path path
+                               :body image
+                               :raw? true})]
+          (t/is (= 400 (:status rsp)))
+          (t/is (= :validation (get-in rsp [:body :type])))
+          (t/is (= ::svg/invalid-result (get-in rsp [:body :code])))))))
+
   )


parsing of promotions from serialized games

--- src/main/cljc/chessdojo/rules.cljc
+++ src/main/cljc/chessdojo/rules.cljc
@@ -397,11 +397,12 @@

 (def rank-names {"1" 0 "2" 1 "3" 2 "4" 3 "5" 4 "6" 5 "7" 6 "8" 7}) ; TODO: investigate (int \a) not supported in cljs (???)
 (def file-names {"a" 0 "b" 1 "c" 2 "d" 3 "e" 4 "f" 5 "g" 6 "h" 7}) ; TODO: investigate (int \1) not supported in cljs (???)
-(defn- ext-piece [str] (keyword (subs str 0 1)))
+(defn- ext-piece [str index] (keyword (subs str index (inc index))))
 (defn- ext-sqr [str index] (to-idx (keyword (subs str index))))
 (defn- ext-file [str index] (get file-names (subs str index (inc index))))
 (defn- ext-rank [str index] (get rank-names (subs str index (inc index))))

+; TODO: This seems super ugly. I guess it was done because Instaparse is not available in Clojurescript?
 (defn parse-move
   "Regexp-based parsing of single moves into move criterias."
   [input]
@@ -410,14 +411,16 @@
       (re-matches #"O-O" s) {:piece :K :castling :O-O}
       (re-matches #"O-O-O" s) {:piece :K :castling :O-O-O}
       (re-matches #"[a-h][1-8]" s) {:piece :P :to (ext-sqr s 0)}
-      (re-matches #"[N|B|R|Q|K].." s) {:piece (ext-piece s) :to (ext-sqr s 1)}
+      (re-matches #"[a-h][1-8]=[N|B|R|Q|K]" s) {:piece :P :to (ext-sqr s 0) :promote-to (ext-piece s 3)}
+      (re-matches #"[N|B|R|Q|K].." s) {:piece (ext-piece s 0) :to (ext-sqr s 1)}
       (re-matches #"[a-h]x[a-h][1-8]" s) {:piece :P :from-file (ext-file s 0) :capture :X :to (ext-sqr s 2)}
-      (re-matches #"[N|B|R|Q|K]x[a-h][1-8]" s) {:piece (ext-piece s) :capture :X :to (ext-sqr s 2)}
-      (re-matches #"[N|B|R|Q|K][a-h][a-h][1-8]" s) {:piece (ext-piece s) :from-file (ext-file s 1) :to (ext-sqr s 2)}
-      (re-matches #"[N|B|R|Q|K][1-8][a-h][1-8]" s) {:piece (ext-piece s) :from-rank (ext-rank s 1) :to (ext-sqr s 2)}
-      (re-matches #"[N|B|R|Q|K][a-h]x[a-h][1-8]" s) {:piece (ext-piece s) :from-file (ext-file s 1) :capture :X :to (ext-sqr s 3)}
-      (re-matches #"[N|B|R|Q|K][1-8]x[a-h][1-8]" s) {:piece (ext-piece s) :from-rank (ext-rank s 1) :capture :X :to (ext-sqr s 3)}
-      :default (throw (ex-info (str "Could not parse move") {:input s}))
+      (re-matches #"[a-h]x[a-h][1-8]=[N|B|R|Q|K]" s) {:piece :P :from-file (ext-file s 0) :capture :X :to (ext-sqr s 2) :promote-to (ext-piece s 5)}
+      (re-matches #"[N|B|R|Q|K]x[a-h][1-8]" s) {:piece (ext-piece s 0) :capture :X :to (ext-sqr s 2)}
+      (re-matches #"[N|B|R|Q|K][a-h][a-h][1-8]" s) {:piece (ext-piece s 0) :from-file (ext-file s 1) :to (ext-sqr s 2)}
+      (re-matches #"[N|B|R|Q|K][1-8][a-h][1-8]" s) {:piece (ext-piece s 0) :from-rank (ext-rank s 1) :to (ext-sqr s 2)}
+      (re-matches #"[N|B|R|Q|K][a-h]x[a-h][1-8]" s) {:piece (ext-piece s 0) :from-file (ext-file s 1) :capture :X :to (ext-sqr s 3)}
+      (re-matches #"[N|B|R|Q|K][1-8]x[a-h][1-8]" s) {:piece (ext-piece s 0) :from-rank (ext-rank s 1) :capture :X :to (ext-sqr s 3)}
+      :default (throw (ex-info (str "Could not parse move: " input) {:input s}))
       )))

 (defn disambiguate


Tune C* driver

Tune C* driver

--- src/org/spootnik/cyanite/store.clj
+++ src/org/spootnik/cyanite/store.clj
@@ -5,6 +5,7 @@
    swap implementations"
   (:require [clojure.string              :as str]
             [qbits.alia                  :as alia]
+            [qbits.alia.policy.load-balancing :as alia_lbp]
             [org.spootnik.cyanite.util   :refer [partition-or-time
                                                  go-forever go-catch
                                                  counter-inc!
@@ -127,7 +128,9 @@
                                           {:values [% tenant (int rollup)
                                                     (int period)
                                                     from to]
-                                           :fetch-size Integer/MAX_VALUE}))]
+                                           :fetch-size Integer/MAX_VALUE
+                                           }))]
+                           (doall rows)
                            (when rows
                              (doseq [row rows]
                                (let [time (long (:time row))
@@ -159,9 +162,22 @@
            batch_size 100}}]
   (info "creating cassandra metric store")
   (let [cluster (if (sequential? cluster) cluster [cluster])
-        session (-> (alia/cluster {:contact-points cluster
-                                   :pooling-options {:max-connections-per-host {:local 8192
-                                                                                :remote 8192}}})
+        session (-> (alia/cluster
+                     {:contact-points cluster
+                      :compression :lz4
+                      :pooling-options {:max-connections-per-host
+                                        {:local 8192
+                                         :remote 8192}
+                                        :max-simultaneous-requests-per-connection
+                                        {:local 128
+                                         :remote 128}
+                                        :load-balancing-policy
+                                        (alia_lbp/token-aware-policy
+                                         (alia_lbp/dc-aware-round-robin-policy ""))}
+                      :socket-options {:read-timeout-millis 1000000
+                                       :receive-buffer-size 8388608
+                                       :send-buffer-size 1048576
+                                       :tcp-no-delay? false}})
                     (alia/connect keyspace))
         insert! (insertq session)
         fetch!  (fetchqp session)]


fix reflection warning

fix reflection warning

--- src/main/clojure/org/dada/core.clj
+++ src/main/clojure/org/dada/core.clj
@@ -184,13 +184,19 @@
    version-key
    attributes))

-(defn model [#^String name #^Metadata metadata]
-  (let [names (.getAttributeNames metadata)
-	key-names (.getKeyAttributeNames metadata)
-	id-getter (.getAttributeGetter metadata (first key-names))
-	version-getter (.getAttributeGetter metadata (second key-names))]
-    (new VersionedModelView name metadata id-getter version-getter)))
-
+(defn model
+  ([#^String model-name #^Keyword key #^Keyword version #^Metadata metadata]
+   (let [id-getter (.getAttributeGetter metadata (name key))
+	 version-getter (.getAttributeGetter metadata (name version))]
+     (new VersionedModelView model-name metadata id-getter version-getter)))
+  ([#^String model-name #^Metadata metadata]
+   (let [names (.getAttributeNames metadata)
+	 key-names (.getKeyAttributeNames metadata)
+	 id-getter (.getAttributeGetter metadata (first key-names))
+	 version-getter (.getAttributeGetter metadata (second key-names))]
+     (new VersionedModelView model-name metadata id-getter version-getter))))
+
+;; this should really be collapsed into (model) above - but arity overloading is not sufficient...
 (defn clone-model [#^Model model #^String name]
   (let [metadata (.getMetadata model)
 	keys (.getKeyAttributeNames metadata)
@@ -238,6 +244,7 @@
 (defn make-transformer [#^ISeq init-fns #^Metadata metadata #^View view]
   (new
    Transformer
+   #^Collection
    (list view)
    #^Transformer$StatelessStrategy
    (proxy


Remove debug prints.

Remove debug prints.

--- src/org/spootnik/cyanite/store.clj
+++ src/org/spootnik/cyanite/store.clj
@@ -163,8 +163,6 @@
                (let [values (map
                              #(let [{:keys [metric tenant path time rollup period ttl]} %]
                                 (counter-inc! (keyword (str "tenants." tenant ".write_count")) 1)
-                                (when (and (sequential? metric) (> (count metric) 1))
-                                  (error "DATAERROR!!!" metric tenant path time rollup period))
                                 [(int ttl) [metric] tenant (int rollup) (int period) path time])
                              payload)]
                  (alia/execute-async
@@ -181,8 +179,6 @@
                  (info e "Store processing exception")))))
           ch))
       (insert [this ttl data tenant rollup period path time]
-        (when (and (sequential? data) (> (count data) 1))
-          (error "DATAERROR!!!" data tenant path time rollup period))
         (alia/execute-async
          session
          insert!


Working on 0107.

Working on 0107.

--- src/project_euler/problem_0106.clj
+++ src/project_euler/problem_0106.clj
@@ -23,6 +23,12 @@
 (defn count-2-partitions [n]
   (dec (int (Math/pow 2 (dec n)))))

+(defn comb [n k]
+  (loop [n n, k k, p 1]
+    (if (zero? k)
+      p
+      (recur (dec n) (dec k) (/ (* p n) k)))))
+
 (defn solution-for [n]
   (let [xs (range n)
         xs' (range )]
@@ -37,3 +43,19 @@
                            )))

          )))
+
+(defn count-subset-pairs-for [n]
+  (let [xs (range n)]
+    (->> (range 2 (/ (inc n) 2))
+         (map (fn [m] (* (combo/count-combinations xs m)
+                         (count-2-partitions m))))
+         )))
+
+(defn solution-for [n]
+  (->> (range 1 (inc (/ n 2)))
+       (map (fn [m] [m (- n m 1)]))
+       (map (fn [[m x]]
+              (for [k (range 2 (/ (+ x 3) 2))]
+                [m x k (* (comb x k)
+                          (comb (- x k) (- k 2)))])))
+       ))


fix for board name

fix for board name

--- src/oc/storage/resources/board.clj
+++ src/oc/storage/resources/board.clj
@@ -107,7 +107,7 @@
         clean
         (assoc :uuid (db-common/unique-id))
         (assoc :slug slug)
-        (assoc :name #(str/strip-tags % ["script"]))
+        (update :name #(str/strip-tags % ["script"]))
         (assoc :org-uuid org-uuid)
         (update :access #(or % default-access))
         (assoc :authors [(:user-id user)])


Better logging of query timing.

Better logging of query timing.

--- src/oc/storage/resources/entry.clj
+++ src/oc/storage/resources/entry.clj
@@ -10,11 +10,6 @@
             [oc.lib.text :as oc-str]
             [oc.storage.resources.common :as common]
             [oc.storage.resources.board :as board-res]))
-
-(defn- log-query-time
-  "Log the current time, the timestamp is in nanoseconds, 1/1000000000 to get seconds."
-  [step]
-  (timbre/debugf "StorageQueryTiming, %s, %d" step (. System (nanoTime))))

 (def temp-uuid "9999-9999-9999")

@@ -251,14 +246,12 @@
                            (str uuid "-v" revision-id)))

 (defn- update-entry [conn entry original-entry ts]
-  (log-query-time "update-entry, start")
   (let [merged-entry (merge original-entry (ignore-props entry))
         attachments (:attachments merged-entry)
         authors-entry (assoc merged-entry :author (:author entry))
         updated-entry (assoc authors-entry :attachments (timestamp-attachments attachments ts))
         _valid? (schema/validate common/Entry updated-entry)
         result (db-common/update-resource conn table-name primary-key original-entry updated-entry ts)]
-    (log-query-time "update-entry, finish")
     result))

 (defn- add-author-to-entry
@@ -272,7 +265,6 @@
   [conn uuid :- lib-schema/UniqueID entry user :- lib-schema/User]
   {:pre [(db-common/conn? conn)
          (map? entry)]}
-  (log-query-time "update-entry-no-version!")
   (when-let [original-entry (get-entry conn uuid)]
    (let [updated-entry (add-author-to-entry original-entry entry user)]
      (update-entry conn updated-entry original-entry (db-common/current-timestamp)))))
@@ -288,7 +280,6 @@
   [conn uuid :- lib-schema/UniqueID entry]
   {:pre [(db-common/conn? conn)
          (map? entry)]}
-  (log-query-time "update-entry-no-user!")
   (when-let [original-entry (get-entry conn uuid)]
     (update-entry conn entry original-entry (db-common/current-timestamp))))

@@ -303,7 +294,6 @@
   [conn uuid :- lib-schema/UniqueID entry user :- lib-schema/User]
   {:pre [(db-common/conn? conn)
          (map? entry)]}
-  (log-query-time "update-entry!")
   (when-let [original-entry (get-entry conn uuid)]
     (let [ts (db-common/current-timestamp)
           authors-entry (add-author-to-entry original-entry entry user)
@@ -332,7 +322,6 @@
   {:pre [(db-common/conn? conn)
          (map? entry-props)]}
   (when-let [original-entry (get-entry conn uuid)]
-    (log-query-time "publish-entry!, start")
     (let [authors (:author original-entry)
           ts (db-common/current-timestamp)
           publisher (lib-schema/author-for-user user)
@@ -351,7 +340,6 @@
             versioned-entry (create-version conn updated-entry entry-update)]
         ;; Delete the draft entry's interactions
         (db-common/delete-resource conn common/interaction-table-name :resource-uuid uuid)
-        (log-query-time "publish-entry!, finish")
         versioned-entry)))))

 (schema/defn ^:always-validate delete-entry!
@@ -383,19 +371,13 @@
   "Given the UUID of the entry, return a list of the comments for the entry."
   [conn uuid :- lib-schema/UniqueID]
   {:pre [(db-common/conn? conn)]}
-  (log-query-time "list-comments-for-entry, start")
-  (let [comments (filter :body (db-common/read-resources conn common/interaction-table-name "resource-uuid" uuid list-comment-properties))]
-    (log-query-time "list-comments-for-entry, finish")
-    comments))
+  (filter :body (db-common/read-resources conn common/interaction-table-name "resource-uuid" uuid list-comment-properties)))

 (schema/defn ^:always-validate list-reactions-for-entry
   "Given the UUID of the entry, return a list of the reactions for the entry."
   [conn uuid :- lib-schema/UniqueID]
   {:pre [(db-common/conn? conn)]}
-  (log-query-time "list-reactions-for-entry, start")
-  (let [reactions (filter :reaction (db-common/read-resources conn common/interaction-table-name "resource-uuid" uuid [:uuid :author :reaction :created-at]))]
-    (log-query-time "list-reactions-for-entry, finish")
-    reactions))
+  (filter :reaction (db-common/read-resources conn common/interaction-table-name "resource-uuid" uuid [:uuid :author :reaction :created-at])))

 ;; ----- Collection of entries -----

@@ -406,17 +388,13 @@
   "
   ([conn org-uuid :- lib-schema/UniqueID]
   {:pre [(db-common/conn? conn)]}
-  (log-query-time "list-entries-by-org(2), start")
-  (let [entry (db-common/read-resources conn table-name :org-uuid org-uuid)]
-    (log-query-time "list-entries-by-org(2), finish")
-    entry))
+  (db-common/read-resources conn table-name :org-uuid org-uuid))

   ([conn org-uuid :- lib-schema/UniqueID order start :- LongNumber
     direction allowed-boards :- (schema/maybe [AllowedBoard]) {:keys [must-see count container-id] :or {must-see false count false container-id nil}}]
   {:pre [(db-common/conn? conn)
           (#{:desc :asc} order)
           (#{:before :after} direction)]}
-  (log-query-time "list-entries-by-org(7), start")
   (let [index-name (if allowed-boards
                      :status-board-uuid
                      :status-org-uuid)
@@ -426,13 +404,11 @@
         filter-map (if-not must-see
                      [{:fn :contains :value (map :uuid allowed-boards) :field :board-uuid}]
                      [{:fn :contains :value (map :uuid allowed-boards) :field :board-uuid}
-                      {:fn :eq :field :must-see :value (boolean (#{true "true"} must-see))}])
-        result (db-common/read-all-resources-and-relations conn table-name index-name index-value "published-at" order
+                      {:fn :eq :field :must-see :value (boolean (#{true "true"} must-see))}])]
+    (db-common/read-all-resources-and-relations conn table-name index-name index-value "published-at" order
                                                            start direction filter-map :interactions common/interaction-table-name
                                                            :uuid :resource-uuid list-comment-properties
-                                                           {:count count :container-id container-id})]
-    (log-query-time "list-entries-by-org(7), finish")
-    result)))
+                                                           {:count count :container-id container-id}))))

 (schema/defn ^:always-validate paginated-entries-by-org
   "
@@ -454,19 +430,18 @@
           (#{:before :after} direction)
           (integer? limit)
           (#{:recent-activity :recently-posted :digest} sort-type)]}
-   (log-query-time "paginated-entries-by-org, start")
+   (timbre/info "entry-res/paginated-entries-by-org")
    (let [index-name (if allowed-boards
                       :status-board-uuid
                       :status-org-uuid)
          index-value (if allowed-boards
                        (map #(vec [:published (:uuid %)]) allowed-boards)
-                       [[:published org-uuid]])
-         result (storage-db-common/read-paginated-entries conn table-name index-name index-value order start direction
-                                                          limit sort-type common/interaction-table-name allowed-boards follow-data
-                                                          container-last-seen-at list-comment-properties nil
-                                                          {:count count :unseen unseen :container-id container-id})]
-     (log-query-time "paginated-entries-by-org, finish")
-     result)))
+                       [[:published org-uuid]])]
+     (time
+      (storage-db-common/read-paginated-entries conn table-name index-name index-value order start direction
+                                                limit sort-type common/interaction-table-name allowed-boards follow-data
+                                                container-last-seen-at list-comment-properties nil
+                                                {:count count :unseen unseen :container-id container-id})))))

 (schema/defn ^:always-validate paginated-entries-by-org-old
   "
@@ -488,13 +463,12 @@
           (#{:before :after} direction)
           (integer? limit)
           (#{:recent-activity :recently-posted :digest} sort-type)]}
-   (log-query-time "paginated-entries-by-org-old, start")
-   (let [result (storage-db-common/read-paginated-entries-old conn table-name :status-org-uuid [:published org-uuid] order start direction
-                                                              limit sort-type common/interaction-table-name allowed-boards follow-data
-                                                              container-last-seen-at list-comment-properties nil
-                                                              {:count count :unseen unseen :container-id container-id})]
-     (log-query-time "paginated-entries-by-org-old, finish")
-     result)))
+   (timbre/info "entry-res/paginated-entries-by-org-old")
+   (time
+    (storage-db-common/read-paginated-entries-old conn table-name :status-org-uuid [:published org-uuid] order start direction
+                                                  limit sort-type common/interaction-table-name allowed-boards follow-data
+                                                  container-last-seen-at list-comment-properties nil
+                                                  {:count count :unseen unseen :container-id container-id}))))

 (schema/defn ^:always-validate paginated-entries-by-board
   "
@@ -507,16 +481,15 @@
          (#{:before :after} direction)
          (integer? limit)
          (#{:recent-activity :recently-posted} sort-type)]}
-  (log-query-time "paginated-entries-by-board, start")
+  (timbre/info "entry-res/paginated-entries-by-board")
   (let [index-name (if (#{:draft :published} status) :status-board-uuid :board-uuid)
         index-value (if (#{:draft :published} status)
                       [[status (:uuid allowed-board)]]
-                      [[(:uuid allowed-board)]])
-        result (storage-db-common/read-paginated-entries conn table-name index-name index-value order start
-                                                         direction limit sort-type common/interaction-table-name
-                                                         [allowed-board] nil nil list-comment-properties nil {:count count})]
-    (log-query-time "paginated-entries-by-board, finish")
-    result))
+                      [[(:uuid allowed-board)]])]
+    (time
+     (storage-db-common/read-paginated-entries conn table-name index-name index-value order start
+                                               direction limit sort-type common/interaction-table-name
+                                               [allowed-board] nil nil list-comment-properties nil {:count count}))))

 (schema/defn ^:always-validate paginated-entries-by-board-old
   "
@@ -529,16 +502,15 @@
          (#{:before :after} direction)
          (integer? limit)
          (#{:recent-activity :recently-posted} sort-type)]}
-  (log-query-time "paginated-entries-by-board-old, start")
+  (timbre/info "entry-res/paginated-entries-by-board-old")
   (let [index-name (if (#{:draft :published} status) :status-board-uuid :board-uuid)
         index-value (if (#{:draft :published} status)
                       [[status (:uuid allowed-board)]]
-                      [[(:uuid allowed-board)]])
-        result (storage-db-common/read-paginated-entries-old conn table-name index-name index-value order start
-                                                             direction limit sort-type common/interaction-table-name
-                                                             [allowed-board] nil nil list-comment-properties nil {:count count})]
-    (log-query-time "paginated-entries-by-board-old, finish")
-    result))
+                      [[(:uuid allowed-board)]])]
+    (time
+     (storage-db-common/read-paginated-entries-old conn table-name index-name index-value order start
+                                                   direction limit sort-type common/interaction-table-name
+                                                   [allowed-board] nil nil list-comment-properties nil {:count count}))))

 (schema/defn ^:always-validate last-entry-of-board
   "
@@ -547,7 +519,7 @@
   "
   [conn board-uuid]
   {:pre [(db-common/conn? conn)]}
-  (storage-db-common/last-entry-of-board conn board-uuid))
+  (time (storage-db-common/last-entry-of-board conn board-uuid)))

 (schema/defn ^:always-validate list-entries-by-org-author

@@ -566,18 +538,17 @@
           (#{:before :after} direction)
           (integer? limit)
           (#{:recent-activity :recently-posted} sort-type)]}
-   (log-query-time "list-entries-by-org-author, start")
+   (timbre/info "entry-res/list-entries-by-org-author")
    (let [index-name (if allowed-boards
                       :status-board-uuid-author-id
                       :status-org-uuid-author-id)
          index-value (if allowed-boards
                        (map #(vec [:published (:uuid %) author-uuid]) allowed-boards)
-                       [[:published org-uuid author-uuid]])
-         result (storage-db-common/read-paginated-entries conn table-name index-name index-value order start direction
-                                                          limit sort-type common/interaction-table-name allowed-boards nil container-last-seen-at
-                                                          list-comment-properties nil {:count count :container-id container-id})]
-     (log-query-time "list-entries-by-org-author, finish")
-     result)))
+                       [[:published org-uuid author-uuid]])]
+     (time
+      (storage-db-common/read-paginated-entries conn table-name index-name index-value order start direction
+                                                limit sort-type common/interaction-table-name allowed-boards nil container-last-seen-at
+                                                list-comment-properties nil {:count count :container-id container-id})))))

 (schema/defn ^:always-validate list-entries-by-org-author-old

@@ -596,12 +567,11 @@
           (#{:before :after} direction)
           (integer? limit)
           (#{:recent-activity :recently-posted} sort-type)]}
-   (log-query-time "list-entries-by-org-author-old, start")
-   (let [result (storage-db-common/read-paginated-entries-old conn table-name :status-org-uuid-author-id [:published org-uuid author-uuid] order start direction
-                                                              limit sort-type common/interaction-table-name allowed-boards nil container-last-seen-at
-                                                              list-comment-properties nil {:count count :container-id container-id})]
-     (log-query-time "list-entries-by-org-author-old, finish")
-     result)))
+   (timbre/info "entry-res/list-entries-by-org-author-old")
+   (time
+    (storage-db-common/read-paginated-entries-old conn table-name :status-org-uuid-author-id [:published org-uuid author-uuid] order start direction
+                                                  limit sort-type common/interaction-table-name allowed-boards nil container-last-seen-at
+                                                  list-comment-properties nil {:count count :container-id container-id}))))

 (schema/defn ^:always-validate list-drafts-by-org-author
   "
@@ -609,12 +579,10 @@
   "
   [conn org-uuid :- lib-schema/UniqueID user-id :- lib-schema/UniqueID {:keys [count] :or {count false}}]
   {:pre [(db-common/conn? conn)]}
-  (log-query-time "list-drafts-by-org-author, start")
-  (let [result (db-common/read-resources-and-relations conn table-name :status-org-uuid-author-id [[:draft org-uuid user-id]]
-                                                       :interactions common/interaction-table-name :uuid :resource-uuid
-                                                       list-comment-properties {:count count})]
-    (log-query-time "list-drafts-by-org-author, finish")
-    result))
+  (timbre/info "entry-res/list-drafts-by-org-author")
+  (time (db-common/read-resources-and-relations conn table-name :status-org-uuid-author-id [[:draft org-uuid user-id]]
+                                                :interactions common/interaction-table-name :uuid :resource-uuid
+                                                list-comment-properties {:count count})))

 (schema/defn ^:always-validate list-entries-by-board
   "Given the UUID of the board, return the published entries for the board with any interactions."
@@ -622,21 +590,17 @@

   ([conn allowed-board :- AllowedBoard {:keys [count] :or {count false}}]
    {:pre [(db-common/conn? conn)]}
-   (log-query-time (str "list-entries-by-board(" (:uuid allowed-board) "), start"))
-   (let [result (db-common/read-resources-and-relations conn table-name :status-board-uuid [[:published (:uuid allowed-board)]]
-                                                        :interactions common/interaction-table-name :uuid :resource-uuid
-                                                        list-comment-properties {:count count})]
-     (log-query-time (str "list-entries-by-board(" (:uuid allowed-board) "), finish"))
-     result)))
+   (timbre/infof "entry-res/list-entries-by-board(%s)" (:uuid allowed-board))
+   (time (db-common/read-resources-and-relations conn table-name :status-board-uuid [[:published (:uuid allowed-board)]]
+                                                 :interactions common/interaction-table-name :uuid :resource-uuid
+                                                 list-comment-properties {:count count}))))

 (schema/defn ^:always-validate list-all-entries-by-board
   "Given the UUID of the board, return all the entries for the board."
   [conn allowed-board :- AllowedBoard]
   {:pre [(db-common/conn? conn)]}
-  (log-query-time "list-all-entries-by-board, start")
-  (let [result (db-common/read-resources conn table-name :board-uuid [(:uuid allowed-board)] ["uuid" "status"])]
-    (log-query-time "list-all-entries-by-board, finish")
-    result))
+  (timbre/info "entry-res/list-all-entries-by-board")
+  (time (db-common/read-resources conn table-name :board-uuid [(:uuid allowed-board)] ["uuid" "status"])))

 (schema/defn ^:always-validate list-all-entries-for-inbox
   "Given the UUID of the user, return all the entries the user has access to that have been published
@@ -654,18 +618,17 @@
    {:pre [(db-common/conn? conn)
           (#{:desc :asc} order)
           (integer? limit)]}
-   (log-query-time "list-all-entries-for-inbox, start")
+   (timbre/info "entry-res/list-all-entries-for-inbox")
    (let [index-name (if allowed-boards
                       :status-board-uuid
                       :status-org-uuid)
          index-value (if allowed-boards
                        (map #(vec [:published (:uuid %)]) allowed-boards)
-                       [[:published org-uuid]])
-         result (storage-db-common/read-all-inbox-for-user conn table-name index-name index-value order start limit
-                                                           common/interaction-table-name allowed-boards follow-data user-id
-                                                           list-comment-properties {:count count})]
-     (log-query-time "list-all-entries-for-inbox, finish")
-     result)))
+                       [[:published org-uuid]])]
+     (time
+      (storage-db-common/read-all-inbox-for-user conn table-name index-name index-value order start limit
+                                                 common/interaction-table-name allowed-boards follow-data user-id
+                                                 list-comment-properties {:count count})))))

 (schema/defn ^:always-validate list-entries-for-user-replies
   "List all activities with at least one comment where the user-id has been active part."
@@ -675,12 +638,10 @@
          (#{:desc :asc} order)
          (#{:before :after} direction)
          (integer? limit)]}
-  (log-query-time "list-entries-for-user-replies, start")
-  (let [result (time (storage-db-common/read-paginated-entries-for-replies conn org-uuid allowed-boards user-id order start
-                                                                           direction limit follow-data container-last-seen-at
-                                                                           list-comment-properties {:count count :unseen unseen}))]
-    (log-query-time "list-entries-for-user-replies, finish")
-    result))
+  (timbre/info "entry-res/list-entries-for-user-replies")
+  (time (storage-db-common/read-paginated-entries-for-replies conn org-uuid allowed-boards user-id order start
+                                                              direction limit follow-data container-last-seen-at
+                                                              list-comment-properties {:count count :unseen unseen})))

 ;; @FIXME: remove below fn
 (schema/defn ^:always-validate list-entries-for-user-replies-old
@@ -691,12 +652,10 @@
          (#{:desc :asc} order)
          (#{:before :after} direction)
          (integer? limit)]}
-  (log-query-time "list-entries-for-user-replies-old, start")
-  (let [result (time (storage-db-common/read-paginated-entries-for-replies-old conn org-uuid allowed-boards user-id order start direction limit
-                                                                     follow-data container-last-seen-at list-comment-properties
-                                                                     {:count count :unseen unseen}))]
-    (log-query-time "list-entries-for-user-replies-old, finish")
-    result))
+  (timbre/info "entry-res/list-entries-for-user-replies-old")
+  (time (storage-db-common/read-paginated-entries-for-replies-old conn org-uuid allowed-boards user-id order start direction limit
+                                                                  follow-data container-last-seen-at list-comment-properties
+                                                                  {:count count :unseen unseen})))

 ;; ----- Entry Bookmarks manipulation -----

@@ -708,19 +667,18 @@
    {:pre [(db-common/conn? conn)
           (#{:desc :asc} order)
           (#{:before :after} direction)]}
-   (log-query-time "list-all-bookmarked-entries, start")
+   (timbre/info "entry-res/list-all-bookmarked-entries")
    (let [index-name (if allowed-boards ;; empty array means user has 0 boards access
                       :status-board-uuid-bookmark-user-id-multi
                       :org-uuid-status-bookmark-user-id-map-multi)
          index-value (if allowed-boards
                        (map #(vec [:published (:uuid %) user-id]) allowed-boards)
-                       [[:published org-uuid user-id]])
-         result (storage-db-common/read-paginated-entries conn table-name index-name index-value order
-                                                          start direction limit :bookmarked-at
-                                                          common/interaction-table-name allowed-boards
-                                                          nil nil list-comment-properties user-id {:count count})]
-     (log-query-time "list-all-bookmarked-entries, finish")
-     result)))
+                       [[:published org-uuid user-id]])]
+     (time
+      (storage-db-common/read-paginated-entries conn table-name index-name index-value order
+                                                start direction limit :bookmarked-at
+                                                common/interaction-table-name allowed-boards
+                                                nil nil list-comment-properties user-id {:count count})))))

 (schema/defn ^:always-validate list-all-bookmarked-entries-old
   "Given the UUID of the user, return all the published entries with a bookmark for the given user."
@@ -730,13 +688,12 @@
    {:pre [(db-common/conn? conn)
           (#{:desc :asc} order)
           (#{:before :after} direction)]}
-   (log-query-time "list-all-bookmarked-entries-old, start")
-   (let [result (storage-db-common/read-paginated-entries-old conn table-name :org-uuid-status-bookmark-user-id-map-multi [:published org-uuid user-id] order
-                                                              start direction limit :bookmarked-at
-                                                              common/interaction-table-name allowed-boards
-                                                              nil nil list-comment-properties user-id {:count count})]
-     (log-query-time "list-all-bookmarked-entries-old, finish")
-     result)))
+   (timbre/info "entry-res/list-all-bookmarked-entries-old")
+   (time
+    (storage-db-common/read-paginated-entries-old conn table-name :org-uuid-status-bookmark-user-id-map-multi [:published org-uuid user-id] order
+                                                  start direction limit :bookmarked-at
+                                                  common/interaction-table-name allowed-boards
+                                                  nil nil list-comment-properties user-id {:count count}))))

 (schema/defn ^:always-validate add-bookmark! :- (schema/maybe common/Entry)
   "Add a bookmark for the give entry and user"
@@ -784,7 +741,7 @@
 (schema/defn ^:always-validate poll-reply-vote! :- (schema/maybe common/Entry)
   [conn entry-uuid :- lib-schema/UniqueID poll-uuid :- lib-schema/UniqueID
    reply-id :- lib-schema/UniqueID user-id :- lib-schema/UniqueID add?]
-  (storage-db-common/update-poll-vote conn table-name entry-uuid poll-uuid reply-id user-id add?))
+  (time (storage-db-common/update-poll-vote conn table-name entry-uuid poll-uuid reply-id user-id add?)))

 ;; ----- Pins -----


removing debugging namespace

removing debugging namespace

--- src/org/gensym/viddy/debugging.clj
+++ src/org/gensym/viddy/debugging.clj
@@ -1,138 +0,0 @@
-(ns org.gensym.viddy.debugging
-    (use [clj-time.coerce :only [from-date]]
-       [clj-time.predicates :only [sunday? saturday?]])
-  (:require
-   [org.gensym.viddy.queries.date-cache :as c]
-   [org.gensym.viddy.frequencies :as freq]
-   [org.gensym.viddy.timeslices :as ts]
-   [org.gensym.viddy.divvy-data :as d]
-   [org.gensym.viddy.queries.date-planner :as dp]
-   [org.gensym.viddy.storage :as storage]
-   [org.gensym.viddy.queries.divvy-history :as history]
-   [clj-time.format :as time-format]
-   [clj-time.core :as time]
-   [org.gensym.viddy.dbconnection :as dbconn] :reload-all))
-
-(def db-spec (dbconn/db-spec  (System/getenv "DATABASE_URL")))
-(def datasource (storage/make-divvy-data db-spec))
-(def divvy-cache (history/make-data-source datasource))
-
-(def date-time-format "YYYY-MM-dd'T'HH:mm:ssZ")
-(def time-formatter (time-format/formatter date-time-format))
-
-(defn- date-or-default [date-str-or-nil default-thunk]
-  (if (empty? date-str-or-nil)
-    (default-thunk)
-    (time-format/parse time-formatter date-str-or-nil)))
-
-(defn- request-daterange [req]
-  (let [to-date (date-or-default (get (:params req) "to_date") #(time/now))
-        from-date (date-or-default (get (:params req) "from_date") #(time/minus- to-date (time/months 1)))]
-    {:to (.toDate to-date)
-     :from (.toDate from-date)}))
-
-(defn available-docks [req station-id]
-  (let [dates (request-daterange req)]
-    (history/available-docks
-     divvy-cache
-     (read-string station-id)
-     (:from dates)
-     (:to dates))))
-
-(defn available-bikes-weekdays [req station-id]
-  (let [dates (request-daterange req)]
-      (history/available-bikes-weekdays
-              divvy-cache
-              (read-string station-id)
-              (:from dates)
-              (:to dates))))
-
-(defn bike-frequencies [req station-id]
-  (let [dates (request-daterange req)]
-    (c/produce-result (:steps divvy-cache)
-                      (:cache divvy-cache)
-                      :available-bikes-weekdays
-                      (:from dates)
-                      (:to dates)
-                      [(read-string station-id)])))
-
-
-(defn- dates [planstep]
-  (if (= 3 (count planstep))
-    [(get planstep 0) (get planstep 2)]
-    [(get planstep 0) (get planstep 1)]))
-
-
-(defn- produce-value! [cache key start end args]
-  (let [[found found-value] (c/maybe-find-for-date-range cache key start end args)]
-    (if found
-      found-value
-      (let [calc (c/calculate-for-date-range cache key start end args)]
-        (c/store-calculation cache key start end calc args)
-        calc))))
-
-
-(defn doit2 []
-  (let [cache  (:cache divvy-cache)
-        plan [[#inst "2014-02-18T02:47:17.512-00:00"  #inst "2014-02-18T03:00:00.000-00:00"]
-              [#inst "2014-02-19T00:00:00.000-00:00" [27 [1 :day]] #inst "2014-03-18T00:00:00.000-00:00"]
-]
-        all-dates (map dates plan)]
-
-
-    (reductions (fn [res [start end]]
-              (c/concat-calculation cache
-                                    :available-bikes-weekdays
-                                    res
-                                    (produce-value! cache :available-bikes-weekdays start end [349])))
-            (c/empty-calculation cache  :available-bikes-weekdays)
-            all-dates)))
-
-(defn doit []
-  (let [cache  (:cache divvy-cache)
-        dates [[#inst "2014-02-18T02:47:17.512-00:00"
-                #inst "2014-02-18T03:00:00.000-00:00"]
-               [#inst "2014-02-18T03:00:00.000-00:00"
-                #inst "2014-02-19T00:00:00.000-00:00"]
-               [#inst "2014-02-19T00:00:00.000-00:00"
-                #inst "2014-03-18T00:00:00.000-00:00"]
-               [#inst "2014-03-18T00:00:00.000-00:00"
-                #inst "2014-03-18T02:00:00.000-00:00"]
-               [#inst "2014-03-18T02:00:00.000-00:00"
-                #inst "2014-03-18T02:13:00.000-00:00"]
-               [#inst "2014-03-18T02:13:00.000-00:00"
-                #inst "2014-03-18T02:43:00.000-00:00"]
-               [#inst "2014-03-18T02:43:00.000-00:00"
-                #inst "2014-03-18T02:47:17.512-00:00"]]
-
-]
-
-    (map (fn [ [start end]]
-           (produce-value! cache :available-bikes-weekdays start end [349]))
-         dates)))
-
-(defn weekend? [station-update]
-  (let [t (from-date (:execution-time station-update))]
-    (or (saturday? t)
-        (sunday? t))))
-
-(def weekday? (comp not weekend?))
-
-
-
-(defn testit []
-
-  (let [cache (:cache divvy-cache)
-        key :available-bikes-weekdays
-
-        start  #inst "2014-02-19T00:00:00.000-00:00"
-        end  #inst "2014-03-18T00:00:00.000-00:00"
-        args  [349]]
-
-
-    (->> (d/station-updates datasource 349 start end)
-         (filter weekday?)
-         (map (fn [rec] [((comp ts/fifteen-minutes :execution-time) rec)
-                        (:available-bikes rec)]))
-         (map (fn [[k v]] {k (freq/create [v])}))
-         (apply merge-with freq/merge-freqs {}))))


Add :read-only as option for editor! (and readOnly to fromSelector)

--- src/org/knotation/editor/core.cljs
+++ src/org/knotation/editor/core.cljs
@@ -62,11 +62,12 @@
    "tree" "javascript"})

 (defn editor!
-  [editor-selector & {:keys [mode theme focus? completions]
+  [editor-selector & {:keys [mode theme focus? completions read-only]
                       :or {mode "sparql"
                            theme "default"
                            focus? true
-                           completions []}}]
+                           completions []
+                           read-only false}}]
   (styles/apply-style!)
   (let [elem (.querySelector js/document editor-selector)
         opts (clj->js {:lineNumbers true :gutters ["CodeMirror-linenumbers" "line-errors"]
@@ -98,7 +99,9 @@
     (set! (.-onmouseover (.getWrapperElement ed)) #(run-hooks! ed :on-hover %))
     (set! (.-onmouseout (.getWrapperElement ed)) #(run-hooks! ed :on-leave %))

-    (.on ed "change" complete/autocomplete)
+    (if read-only
+      (.setOption ed "readOnly" true)
+      (.on ed "change" complete/autocomplete))

     (on-hover!
      ed (fn [token]
@@ -114,7 +117,7 @@
   [editor-selector options]
   (let [opts (update
               (merge {:mode "sparql" :theme "default"
-                      :on-hover (.-onHover options)
+                      :on-hover (.-onHover options) :read-only (.-readOnly options)
                       :completions []
                       :focus? (not (not (.-focus options)))}
                      (dissoc (js->clj options :keywordize-keys true) :focus))


CMR-6537-4 updated json handler

CMR-6537-4 updated json handler

--- search-app/src/cmr/search/results_handlers/subscriptions_json_results_handler.clj
+++ search-app/src/cmr/search/results_handlers/subscriptions_json_results_handler.clj
@@ -37,5 +37,4 @@

 (defmethod qs/search-results->response [:subscription :json]
   [context query results]
-  (json/generate-string (select-keys results [:hits :took :items])))
-
+  (json/generate-string (select-keys results [:hits :took :items])))


Format not supported in clojurescript

Format not supported in clojurescript

--- src/wireframes/renderer/vector.clj
+++ src/wireframes/renderer/vector.clj
@@ -18,9 +18,9 @@

 (defn- transform [w h]
   (let [scale (compute-scale w h)]
-  (format "translate(%f,%f) scale(%f,%f)"
-          (double (/ w 2)) (double (/ h 2))
-          scale scale)))
+    (str
+      "translate(" (double (/ w 2)) "," (double (/ h 2)) ") "
+      "scale(" scale "," scale ")")))

 (defn walk-polygon [points-2d polygon]
   (letfn [(directive [cmd p]
@@ -32,7 +32,10 @@
         "Z")))

 (defn- style [fill-color edge-color sw]
-  (format "stroke-width:%f;stroke:%s;fill:%s" sw (rgba edge-color) (rgba fill-color)))
+  (str
+    "stroke-width:" sw ";"
+    "stroke:" (rgba edge-color) ";"
+    "fill:" (rgba fill-color) ";"))

 (defn wireframe-draw-fn [points-2d fill-color edge-color sw]
   (let [style (style fill-color edge-color sw)]


fix wrong function name

fix wrong function name

--- src/yeller_clojure_client/ring.clj
+++ src/yeller_clojure_client/ring.clj
@@ -3,7 +3,7 @@
             [ring.util.request :as req]))

 (defn format-extra [options request]
-  {:url (req/url request)
+  {:url (req/request-url request)
    :custom-data
    {:params (merge (:query-params request) (:form-params request))
     :session (:session request)


Improve the cron docs

Improve the cron docs

Fix https://github.com/yetibot/yetibot/issues/822

--- src/yetibot/core/commands/cron.clj
+++ src/yetibot/core/commands/cron.clj
@@ -89,12 +89,25 @@
   "cron <schedule> <command> # run <command> according to <schedule>.

    <schedule> must be a valid crontab string with 7 space-separated arguments:
+
    second minute hour day-of-week day-of-month month year

+   For example:
+
+     0 0 6 6 9 * 2010
+     | | | | | |   |
+     | | | | | |   +- 2010 only.
+     | | | | | +----- any day of the week.
+     | | | | +------- 9th month (September).
+     | | | +--------- 6th day of the month.
+     | | +----------- 6th hour of the day.
+     | +------------- Top of the hour (minutes = 0).
+     +--------------- Top of the minute (seconds = 0).
+
    Note: this is more expressive than standard cron which only supports 5
-   arguments: minutes hours day-of-month month day-of-week
+   arguments (lacking second and year).

-   See docs at http://docs.caudate.me/hara/hara-io-scheduler.html#schedule."
+   See docs at https://zcaudate.github.io/hara/hara-io-scheduler.html#schedule"
   [{[_ cron-schedule cmd] :match
     user :user
     {:keys [uuid room] :as chat-source} :chat-source}]


new quotas structure

new quotas structure

--- src/celestial/persistency/quotas.clj
+++ src/celestial/persistency/quotas.clj
@@ -7,42 +7,48 @@
     [slingshot.slingshot :refer  [throw+]]
     [clojure.core.strint :refer (<<)]))

-(defn used-key [spec]
-  [:quotas (figure-virt spec) :used])
+(defn used-key [{:keys [env] :as spec} k]
+  [:quotas env (figure-virt spec) :used :count])

 (entity quota :id username)

 (validation :user-exists (when-not-nil user-exists? "No matching user found"))

-(validation :quota* (every-kv {:limit #{:required :Integer}}))
+(validation :env
+   (every-kv {:subs/ANY {:subs/ANY {:limit #{:required :Integer}}}}))

 (def quota-v
-  {:username #{:required :user-exists} :quotas #{:required :Map :quota*}})
+  {:username #{:required :user-exists} :quotas #{:required :Map :env*}})

-(defn validate-quota [q]
-  (validate! q quota-v :error ::non-valid-quota))
+(defn validate-quota [{:keys [quotas] :as q}]
+  (validate! q quota-v :error ::non-valid-quota)
+  (doseq [[k e] quotas]
+    (validate! e {
+      :limits {:count #{:required :Integer}}
+      :used {:count #{:required :Integer}}})))

 (defn quota-assert
-  [{:keys [owner] :as spec}]
-  (let [hyp (figure-virt spec) {:keys [limit used]} (get-in (get-quota owner) [:quotas hyp])]
-    (when (= (count used) limit)
-      (throw+ {:type ::quota-limit-reached} (<< "Quota limit ~{limit} on ~{hyp} for ~{owner} was reached")))))
+  [{:keys [owner env] :as spec}]
+  (let [hyp (figure-virt spec)
+       {:keys [limits used]} (get-in (get-quota owner) [:quotas hyp env])]
+    (when (= (:count used) (:count limits))
+      (throw+ {:type ::quota-limit-reached} (<< "Quota limit ~{limits} on ~{hyp} for ~{owner} was reached")))))

-(defn quota-change [id {:keys [owner] :as spec} f]
+(defn quota-change [{:keys [owner] :as spec} f]
     (when (quota-exists? owner)
       (update-quota
-        (update-in (get-quota owner) (used-key spec) f id))))
+        (update-in (get-quota owner) (used-key spec) f))))

 (defn increase-use
   "increases user quota use"
   [id spec]
-  (quota-change id spec (fnil conj #{id})))
+  (quota-change spec inc))

 (defn decrease-use
   "decreases usage"
   [id {:keys [owner] :as spec}]
   (when-not (empty? (get-in (get-quota owner) (used-key spec)))
-    (quota-change id spec (fn [old id*] (clojure.set/difference old #{id*})))))
+    (quota-change spec dec)))

 (defmacro with-quota [action spec & body]
   `(do


saving.

saving.

--- src/clj/forma/hadoop/jobs/update.clj
+++ src/clj/forma/hadoop/jobs/update.clj
@@ -43,235 +43,234 @@
                           est-end)}}))

 (defmain RunUpdates
-  ([est-start est-end] (RunUpdates-main "/tmp" est-start est-end))
-  ([tmp-root est-start est-end]
-   (let [{conf :configurable storage :storage} (config est-start est-end)
-         path (fn [k & ss] (apply str (k storage) "/" ss))
-         adjusted-s3         (path :s3out "adjusted")
-         merged-trends-s3    (path :s3out "merged-trends")
-         beta-s3             (path :s3out "betas")
-         estimated-s3        (path :s3out "estimated")
-         merged-estimated-s3 (path :s3out "merged-estimated")
-         gfw-site-s3         (path :s3out "gfw-site")
-         forma-site-s3       (path :s3out "forma-site-" (:threshold conf))
-         david-s3            (path :s3out "david")]
-     (workflow
-      [tmp-root]
-      start-workflow
-      ([] (println "Starting workflow."))
-
-      preprocess-modis
-      ([]
-       (println "Preprocessing MODIS data")
-       (p/PreprocessModis (path :staging "MOD13A1/")
-                          (:pailpath storage)
-                          "{20}*"
-                          (:tiles conf)
-                          (:modis-layers conf)))
-
-      pre-rain
-      ([:tmp-dirs rain-output
-        :deps start-workflow]
-       (println "Preprocessing rain")
-       (p/PreprocessRain (path :archive "PRECL")
-                         rain-output
-                         (:spatial-res conf)
-                         (:temporal-res conf)))
-
-      rain->modis
-      ([:tmp-dirs exploded-rain-output
-        :deps pre-rain]
-       (println "Exploding rain into MODIS pixels")
-       (p/ExplodeRain rain-output
+  [est-start est-end run-date]
+  (let [{conf :configurable storage :storage} (config est-start est-end run-date)
+        path (fn [k & ss] (apply str (k storage) "/" ss))
+        adjusted-s3         (path :s3out "adjusted")
+        merged-trends-s3    (path :s3out "merged-trends")
+        beta-s3             (path :s3out "betas")
+        estimated-s3        (path :s3out "estimated")
+        merged-estimated-s3 (path :s3out "merged-estimated")
+        gfw-site-s3         (path :s3out "gfw-site")
+        forma-site-s3       (path :s3out "forma-site-" (:threshold conf))
+        david-s3            (path :s3out "david")]
+    (workflow
+     ["/tmp"]
+     start-workflow
+     ([] (println "Starting workflow."))
+
+     preprocess-modis
+     ([]
+      (println "Preprocessing MODIS data")
+      (p/PreprocessModis (path :staging "MOD13A1/")
+                         (:pailpath storage)
+                         "{20}*"
+                         (:tiles conf)
+                         (:modis-layers conf)))
+
+     pre-rain
+     ([:tmp-dirs rain-output
+       :deps start-workflow]
+      (println "Preprocessing rain")
+      (p/PreprocessRain (path :archive "PRECL")
+                        rain-output
+                        (:spatial-res conf)
+                        (:temporal-res conf)))
+
+     rain->modis
+     ([:tmp-dirs exploded-rain-output
+       :deps pre-rain]
+      (println "Exploding rain into MODIS pixels")
+      (p/ExplodeRain rain-output
+                     exploded-rain-output
+                     (:spatial-res conf)
+                     (:tiles conf)))
+
+     ndvi-timeseries
+     ([:tmp-dirs ndvi-series-output
+       :deps start-workflow]
+      (println "NDVI timeseries")
+      (ts/ModisTimeseries (:pailpath storage)
+                          ndvi-series-output
+                          (:spatial-res conf)
+                          (:temporal-res conf)
+                          "ndvi"))
+
+     ndvi-filter
+     ([:tmp-dirs filtered-ndvi-output
+       :deps ndvi-timeseries]
+      (println "Filtering NDVI")
+      (r/TimeseriesFilter (:spatial-res conf)
+                          (:temporal-res conf)
+                          ndvi-series-output
+                          (:static storage)
+                          filtered-ndvi-output))
+
+     adjust-series
+     ([:deps [rain->modis ndvi-filter]]
+      (println "Joining NDVI and rain series, adjusting length")
+      (r/AdjustSeries (:spatial-res conf)
+                      (:temporal-res conf)
+                      filtered-ndvi-output
                       exploded-rain-output
-                      (:spatial-res conf)
-                      (:tiles conf)))
-
-      ndvi-timeseries
-      ([:tmp-dirs ndvi-series-output
-        :deps start-workflow]
-       (println "NDVI timeseries")
-       (ts/ModisTimeseries (:pailpath storage)
-                           ndvi-series-output
-                           (:spatial-res conf)
-                           (:temporal-res conf)
-                           "ndvi"))
-
-      ndvi-filter
-      ([:tmp-dirs filtered-ndvi-output
-        :deps ndvi-timeseries]
-       (println "Filtering NDVI")
-       (r/TimeseriesFilter (:spatial-res conf)
-                           (:temporal-res conf)
-                           ndvi-series-output
-                           (:static storage)
-                           filtered-ndvi-output))
-
-      adjust-series
-      ([:deps [rain->modis ndvi-filter]]
-       (println "Joining NDVI and rain series, adjusting length")
-       (r/AdjustSeries (:spatial-res conf)
-                       (:temporal-res conf)
-                       filtered-ndvi-output
-                       exploded-rain-output
-                       adjusted-s3))
-
-      trends
-      ([:tmp-dirs trends-output
-        :deps adjust-series]
-       (println "Calculating trends stats")
-       (r/Trends (:spatial-res conf)
-                 (:temporal-res conf)
-                 est-end
-                 adjusted-s3
-                 trends-output
-                 est-start))
-
-      trends->pail
-      ([:deps trends]
-       (println "Adding trends series to pail")
-       (r/TrendsPail (:spatial-res conf)
-                     (:temporal-res conf)
-                     est-end
-                     trends-output
-                     (:pailpath storage)))
-
-      merge-trends
-      ([:deps trends->pail]
-       (println "Merging trends time series stored in pail")
-       (r/MergeTrends (:spatial-res conf)
-                      (:temporal-res conf)
-                      est-end
-                      (:pailpath storage)
-                      merged-trends-s3))
-
-      preprocess-fires
-      ([:tmp-dirs fire-output
-        :deps start-workflow]
-       (println "Preprocessing fires")
-       (p/PreprocessFire (path :archive "/fires")
-                         fire-output
-                         "500" "16"
-                         (:fire-start conf)
-                         (:tiles conf)))
-
-      forma-tap
-      ([:tmp-dirs forma-tap-output
-        :deps [preprocess-fires merge-trends]]
-       (println "Prepping FORMA tap for neighbor analysis")
-       (r/FormaTap (:spatial-res conf)
-                   (:temporal-res conf)
-                   est-start
-                   est-end
-                   fire-output
-                   merged-trends-s3
-                   forma-tap-output))
-
-      neighbors
-      ([:tmp-dirs neighbors-output
-        :deps forma-tap]
-       (println "Merging neighbors")
-       (r/NeighborQuery (:spatial-res conf)
-                        (:temporal-res conf)
-                        forma-tap-output
-                        neighbors-output))
-
-      beta-data-prep
-      ([:tmp-dirs beta-data-output
-        :deps neighbors]
-       (println "Beta data prep - only keep data through training period")
-       (r/BetaDataPrep (:spatial-res conf)
-                       (:temporal-res conf)
-                       neighbors-output
-                       (:static storage)
-                       beta-data-output
-                       true))
-
-      gen-betas
-      ([:deps beta-data-prep]
-       (println "Generating beta vectors")
-       (r/GenBetas (:spatial-res conf)
-                   (:temporal-res conf)
-                   (:training-end conf)
-                   beta-data-output
-                   beta-s3))
-
-      forma-estimate
-      ([:deps neighbors]
-       (println "Classify pixels using beta vectors")
-       (r/EstimateForma (:spatial-res conf)
-                        (:temporal-res conf)
-                        (:betas storage)
-                        neighbors-output
-                        (:static storage)
-                        estimated-s3
-                        (:super-eco? conf)))
-
-      probs-pail
-      ([:deps forma-estimate]
-       (println "Add probability output to pail")
-       (r/ProbsPail (:spatial-res conf)
+                      adjusted-s3))
+
+     trends
+     ([:tmp-dirs trends-output
+       :deps adjust-series]
+      (println "Calculating trends stats")
+      (r/Trends (:spatial-res conf)
+                (:temporal-res conf)
+                est-end
+                adjusted-s3
+                trends-output
+                est-start))
+
+     trends->pail
+     ([:deps trends]
+      (println "Adding trends series to pail")
+      (r/TrendsPail (:spatial-res conf)
                     (:temporal-res conf)
                     est-end
-                    estimated-s3
+                    trends-output
                     (:pailpath storage)))

-      merge-probs
-      ([:deps probs-pail]
-       (println "Merge probability time series.")
-       (r/MergeProbs (:spatial-res conf)
+     merge-trends
+     ([:deps trends->pail]
+      (println "Merging trends time series stored in pail")
+      (r/MergeTrends (:spatial-res conf)
                      (:temporal-res conf)
                      est-end
                      (:pailpath storage)
-                     merged-estimated-s3))
-
-      gadm2-eco-ids
-      ([:deps merge-probs]
-       (println "Merging in gadm2 and eco fields")
-       (r/ProbsGadm2 merged-estimated-s3
-                     (:gadm2 storage)
-                     (:static storage)
-                     (:gadm2eco storage)))
-
-      common-data-conversion
-      ([:deps gadm2-eco-ids]
-       (println "Prepping for website")
-       (r/FormaWebsite (:threshold conf)
-                       (:zoom conf)
-                       (:min-zoom conf)
+                     merged-trends-s3))
+
+     preprocess-fires
+     ([:tmp-dirs fire-output
+       :deps start-workflow]
+      (println "Preprocessing fires")
+      (p/PreprocessFire (path :archive "/fires")
+                        fire-output
+                        "500" "16"
+                        (:fire-start conf)
+                        (:tiles conf)))
+
+     forma-tap
+     ([:tmp-dirs forma-tap-output
+       :deps [preprocess-fires merge-trends]]
+      (println "Prepping FORMA tap for neighbor analysis")
+      (r/FormaTap (:spatial-res conf)
+                  (:temporal-res conf)
+                  est-start
+                  est-end
+                  fire-output
+                  merged-trends-s3
+                  forma-tap-output))
+
+     neighbors
+     ([:tmp-dirs neighbors-output
+       :deps forma-tap]
+      (println "Merging neighbors")
+      (r/NeighborQuery (:spatial-res conf)
+                       (:temporal-res conf)
+                       forma-tap-output
+                       neighbors-output))
+
+     beta-data-prep
+     ([:tmp-dirs beta-data-output
+       :deps neighbors]
+      (println "Beta data prep - only keep data through training period")
+      (r/BetaDataPrep (:spatial-res conf)
+                      (:temporal-res conf)
+                      neighbors-output
+                      (:static storage)
+                      beta-data-output
+                      true))
+
+     gen-betas
+     ([:deps beta-data-prep]
+      (println "Generating beta vectors")
+      (r/GenBetas (:spatial-res conf)
+                  (:temporal-res conf)
+                  (:training-end conf)
+                  beta-data-output
+                  beta-s3))
+
+     forma-estimate
+     ([:deps neighbors]
+      (println "Classify pixels using beta vectors")
+      (r/EstimateForma (:spatial-res conf)
+                       (:temporal-res conf)
+                       (:betas storage)
+                       neighbors-output
+                       (:static storage)
+                       estimated-s3
+                       (:super-eco? conf)))
+
+     probs-pail
+     ([:deps forma-estimate]
+      (println "Add probability output to pail")
+      (r/ProbsPail (:spatial-res conf)
+                   (:temporal-res conf)
+                   est-end
+                   estimated-s3
+                   (:pailpath storage)))
+
+     merge-probs
+     ([:deps probs-pail]
+      (println "Merge probability time series.")
+      (r/MergeProbs (:spatial-res conf)
+                    (:temporal-res conf)
+                    est-end
+                    (:pailpath storage)
+                    merged-estimated-s3))
+
+     gadm2-eco-ids
+     ([:deps merge-probs]
+      (println "Merging in gadm2 and eco fields")
+      (r/ProbsGadm2 merged-estimated-s3
+                    (:gadm2 storage)
+                    (:static storage)
+                    (:gadm2eco storage)))
+
+     common-data-conversion
+     ([:deps gadm2-eco-ids]
+      (println "Prepping for website")
+      (r/FormaWebsite (:threshold conf)
+                      (:zoom conf)
+                      (:min-zoom conf)
+                      (:spatial-res conf)
+                      (:temporal-res conf)
+                      (:cdm-temporal-res conf)
+                      (:training-end conf)
+                      (:nodata conf)
+                      (:gadm2eco storage)
+                      gfw-site-s3))
+
+     download-prep
+     ([:deps gadm2-eco-ids]
+      ;; # prep data for FORMA download
+      (println "Prepping data for FORMA download link")
+      (r/FormaDownload (:threshold conf)
                        (:spatial-res conf)
                        (:temporal-res conf)
-                       (:cdm-temporal-res conf)
-                       (:training-end conf)
                        (:nodata conf)
                        (:gadm2eco storage)
-                       gfw-site-s3))
-
-      download-prep
-      ([:deps gadm2-eco-ids]
-       ;; # prep data for FORMA download
-       (println "Prepping data for FORMA download link")
-       (r/FormaDownload (:threshold conf)
-                        (:spatial-res conf)
-                        (:temporal-res conf)
-                        (:nodata conf)
-                        (:gadm2eco storage)
-                        forma-site-s3))
-
-      blue-raster
-      ([:deps gadm2-eco-ids]
-       (println "Converting for Blue Raster")
-       (r/BlueRaster (:spatial-res conf)
-                     (:temporal-res conf)
-                     (:nodata conf)
-                     (:gadm2eco storage)
-                     (:static storage)
-                     (:blueraster storage)))
-
-      david-conversion
-      ([:deps gadm2-eco-ids]
-       (println "Converting for David")
-       (r/FormaDavid (:nodata conf)
-                     (:gadm2eco storage)
-                     (:static storage)
-                     david-s3))))))
+                       forma-site-s3))
+
+     blue-raster
+     ([:deps gadm2-eco-ids]
+      (println "Converting for Blue Raster")
+      (r/BlueRaster (:spatial-res conf)
+                    (:temporal-res conf)
+                    (:nodata conf)
+                    (:gadm2eco storage)
+                    (:static storage)
+                    (:blueraster storage)))
+
+     david-conversion
+     ([:deps gadm2-eco-ids]
+      (println "Converting for David")
+      (r/FormaDavid (:nodata conf)
+                    (:gadm2eco storage)
+                    (:static storage)
+                    david-s3)))))


Entities matched properly on re-upload.

Entities matched properly on re-upload.

Fixes #581

--- src/clj/kixi/hecuba/api/entities.clj
+++ src/clj/kixi/hecuba/api/entities.clj
@@ -299,7 +299,7 @@
 (defn store-entity [entity existing-entities user_id store]
   (let [query-entity (-> entity
                          (assoc :user_id user_id)
-                         (enrich-with-ids (-> existing-entities :entities :entities)))
+                         (enrich-with-ids existing-entities))
         entity_id (:entity_id query-entity)]
     (entities/insert (:hecuba-session store) query-entity)
     (log/infof "upserted entity_id: %s entity: %s" entity_id query-entity)


make get-trees more accepting

make get-trees more accepting

--- src/com/billpiel/mem_tracer/core.clj
+++ src/com/billpiel/mem_tracer/core.clj
@@ -161,11 +161,20 @@
   [v]
   (let [mk (meta v)]
     (cond
+      (sequential? v)
+      v
+
       ((some-fn ::ws/workspace
-                ::rec/recording) mk)
+                ::rec/recording
+                ::q/query-result)
+       mk)
       (:children v)

       (::trace/tree mk)
+      [v]
+
+      (every? #(contains? v %)
+              [:children :depth :args :name :return :arg-map :id])
       [v]

       :default


Removed editor examples

Removed editor examples

--- src/css-guide/styles/components.cljs
+++ src/css-guide/styles/components.cljs
@@ -1738,170 +1738,6 @@
                 (dom/button #js {:className "o-drawer__action"} "Help & Feedback"))))))
       (dom/div #js {:className "o-drawer__close"}))))

-(defexample editor-inactive
-  "# Editor Inactive Example"
-  (dom/div #js {}
-    (dom/section #js {:className "o-editor"}
-      (dom/header #js {:className "o-editor__toolbar has-actions"}
-        (dom/div #js {:className "o-editor__nav"})
-        (dom/div #js {:className "o-editor__info"}
-          (dom/div #js {:className "o-editor__actions o-button-group"}
-            ; "<!-- Edit -->"
-            (dom/button #js {:className "c-button c-button--large o-editor__edit"}
-              (dom/span #js {:className "c-icon"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"})))
-              (dom/span #js {:className "c-button__content u-hide@sm"} "Edit"))
-            ;"<!-- Delete -->"
-            (dom/button #js {:className "c-button c-button--large"}
-              (dom/span #js {:className "c-icon"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"}))))
-            ;"<!-- Move -->"
-            (dom/button #js {:className "c-button c-button--large"}
-              (dom/span #js {:className "c-icon"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"})))))))
-      (dom/div #js {:className "o-editor__content"}
-        (dom/input #js {:value "Hello, I'm content inside an editor! :)" :className "c-input"})))))
-
-(defexample editor-active
-  "# Editor Active Example"
-  (dom/div #js {}
-    (dom/section #js {:className "o-editor is-active"}
-      (dom/header #js {:className "o-editor__toolbar has-actions"}
-        (dom/div #js {:className "o-editor__nav"}
-          (dom/ul #js {:className "c-menu c-menu--inline"}
-            (dom/li #js {}
-              (dom/button #js {:className "c-menu__link is-active"} "Object"))
-            (dom/li #js {}
-              (dom/button #js {:className "c-menu__link"} "Options"))))
-        (dom/div #js {:className "o-editor__info"}
-          (dom/div #js {:className "o-editor__extras"}
-            (dom/span #js {:title "Key Attribute" :className "c-badge c-badge--round c-badge--positive"}
-              (dom/span #js {:className "c-icon c-icon--small"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M12.65 10C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"}))))
-            (dom/span #js {:title "Recommended Object" :className "c-badge c-badge--round c-badge--alterable"} "N")
-            (dom/button #js {:title "Add to Favorites" :className "c-button--favorite is-active"}
-              (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :className "c-icon" :viewBox "0 0 24 24"}
-                (dom/path #js {:d "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"}))))
-          (dom/div #js {:className "o-editor__actions o-button-group"}
-            ;"<!-- Done -->"
-            (dom/button #js {:className "c-button c-button--large o-editor__done"}
-              (dom/span #js {:className "c-icon is-positive"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"})))
-              (dom/span #js {:className "c-button__content u-hide@sm"} "Done"))
-            (dom/button #js {:className "c-button c-button--large"}
-              (dom/span #js {:className "c-icon"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"}))))
-            (dom/button #js {:className "c-button c-button--large"}
-              (dom/span #js {:className "c-icon"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"})))))))
-      (dom/div #js {:className "o-editor__content"}
-        (dom/input #js {:value "Hello, I'm content inside an editor! :)" :className "c-input"}))
-      (dom/footer #js {:className "o-editor__toolbar o-editor__toolbar--small"}
-        (dom/div #js {:className "u-start"}
-          (dom/span #js {:className "c-icon"}
-            (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-              (dom/path #js {:d "M7 10l5 5 5-5z"})))
-          " Conditions "
-          (dom/button #js {:className "c-button c-button--anchor js-add-conditions"}
-            (dom/span #js {:className "c-icon c-icon--small"}
-              (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                (dom/path #js {:d "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"})))
-            (dom/span #js {:className "c-button__content"} "Add Conditions")))
-        (dom/div #js {:className "u-column u-end"}
-          (dom/input #js {:type "checkbox" :id "c-checkbox-1" :checked "true" :className "c-checkbox"})
-          (dom/label #js {:htmlFor "c-checkbox-1"} " Required")))
-      (dom/div #js {:className "o-editor__content"}
-        (dom/div #js {:className "c-card c-card--round"}
-          (dom/div #js {:className "o-editor__conditionals c-card__title"}
-            (dom/div #js {:className "u-column--9"}
-              (dom/span #js {:className "c-icon"}
-                (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M7 10l5 5 5-5z"})))
-              (dom/span #js {} "If response ")
-              (dom/div #js {:className "u-wrapper"}
-                (dom/button #js {:className "u-wrapper__toggle "} "is")
-                (dom/ul #js {:id "test-dropdown" :aria-hidden "true" :className "c-menu" :tabIndex "-1"}
-                  (dom/li #js {}
-                    (dom/button #js {:className "c-menu__item"} "is"))
-                  (dom/li #js {} (dom/button #js {:className "c-menu__item"} "is not"))
-                  (dom/li #js {} (dom/button #js {:className "c-menu__item"} "contains"))))
-              (dom/div #js {:className "u-wrapper"}
-                (dom/button #js {:className "u-wrapper__toggle "} "Red wine")
-                (dom/ul #js {:id "test-dropdown" :aria-hidden "true" :className "c-menu" :tabIndex "-1"}
-                  (dom/li #js {}
-                    (dom/button #js {:className "c-menu__item"} "Red Wine"))
-                  (dom/li #js {}
-                    (dom/button #js {:className "c-menu__item"} "White Wine"))
-                  (dom/li #js {}
-                    (dom/button #js {:className "c-menu__item"} "Crux Scotch Ale"))))
-              (dom/span #js {} " then:"))
-            (dom/div #js {:className "u-column--3 u-end"}
-              (dom/button #js {:data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.0" :className "c-button c-button--icon"}
-                (dom/svg #js {:version "1.1" :width "24" :height "24" :aria-labelledby "title" :role "img" :data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.0.0" :className "c-icon c-icon--delete " :viewBox "0 0 24 24"}
-                  (dom/title #js {:data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.0.0.0"} "Delete")
-                  (dom/path #js {:d "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" :data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.0.0.1"})))
-              (dom/button #js {:className "c-button c-button--icon is-positive"}
-                (dom/svg #js {:http "" :www.w3.org "" :2000 "" :svg "" :width "24" :height "24" :className "c-icon c-icon--done-all xmlns=" :viewBox "0 0 24 24"}
-                  (dom/path #js {:d "M18 7l-1.41-1.41-6.34 6.34 1.41 1.41L18 7zm4.24-1.41L11.66 16.17 7.48 12l-1.41 1.41L11.66 19l12-12-1.42-1.41zM.41 13.41L6 19l1.41-1.41L1.83 12 .41 13.41z"})))
-              (dom/button #js {:className "c-button c-button--icon"}
-                (dom/svg #js {:version "1.1" :width "24" :height "24" :aria-labelledby "title" :role "img" :data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.2" :className "c-icon c-icon--open-with " :viewBox "0 0 24 24"}
-                  (dom/title #js {:data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.2.0"} "Open With")
-                  (dom/path #js {:d "M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z" :data-reactid ".0.2.$survey$ui$screens$surveys$Surveys_[=2panel].1.0.$survey$ui$screens$surveys$EditorCanvas_[=2panel =2editor =2survey-to-edit].2.0.0.0.1.0:$17592186045874.4:$condition-block-17592186045876.$17592186045876.1.2.1"})))))
-          (dom/section #js {:className "o-editor is-active" :tabIndex "-1"}
-            (dom/header #js {:role "toolbar" :className "o-editor__toolbar has-actions"}
-              (dom/div #js {:className "o-editor__nav"}
-                (dom/ul #js {:className "c-menu c-menu--inline"}
-                  (dom/li #js {}
-                    (dom/button #js {:className "c-menu__link is-active"} "Object"))
-                  (dom/li #js {} (dom/button #js {:className "c-menu__link"} "Options"))))
-              (dom/div #js {:className "o-editor__info"}
-                (dom/div #js {:className "o-editor__extras"}
-                  (dom/span #js {:title "Key Attribute" :className "c-badge c-badge--round c-badge--positive"}
-                    (dom/span #js {:className "c-icon c-icon--small"}
-                      (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                        (dom/path #js {:d "M12.65 10C11.83 7.67 9.61 6 7 6c-3.31 0-6 2.69-6 6s2.69 6 6 6c2.61 0 4.83-1.67 5.65-4H17v4h4v-4h2v-4H12.65zM7 14c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"}))))
-                  (dom/span #js {:title "Recommended Object" :className "c-badge c-badge--round c-badge--alterable"} "N")
-                  (dom/button #js {:title "Add to Favorites" :className "c-button--favorite is-active"}
-                    (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :className "c-icon" :viewBox "0 0 24 24"}
-                      (dom/path #js {:d "M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"})))
-                  (dom/div #js {:className "o-editor__actions o-button-group"} " " "<!-- Done -->" " "
-                    (dom/button #js {:className "c-button c-button--large o-editor__done"}
-                      (dom/span #js {:className "c-icon is-positive"}
-                        (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                          (dom/path #js {:d "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"})))
-                      (dom/span #js {:className "c-button__content u-hide@sm"} "Done"))
-                    (dom/button #js {:className "c-button c-button--large"}
-                      (dom/span #js {:className "c-icon"}
-                        (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                          (dom/path #js {:d "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"}))))
-                    (dom/button #js {:className "c-button c-button--large"}
-                      (dom/span #js {:className "c-icon"}
-                        (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                          (dom/path #js {:d "M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"}))))))))
-            (dom/div #js {:className "o-editor__content"}
-              (dom/input #js {:value "Hello, I'm content inside an editor! :)" :className "c-input"}))
-            (dom/footer #js {:className "o-editor__toolbar o-editor__toolbar--small"}
-              (dom/div #js {:className "u-start"}
-                (dom/button #js {:className "c-button c-button--anchor js-add-conditions"}
-                  (dom/span #js {:className "c-icon c-icon--small"}
-                    (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                      (dom/path #js {:d "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"})))
-                  (dom/span #js {:className "c-button__content"} "Add Conditions")))
-              (dom/div #js {:className "u-column u-end"}
-                (dom/input #js {:type "checkbox" :id "c-checkbox-1" :checked "true" :className "c-checkbox"})
-                (dom/label #js {:htmlFor "c-checkbox-1"} " Required"))))
-          (dom/button #js {:className "c-button c-button--anchor js-add-conditions"}
-            (dom/span #js {:className "c-icon c-icon--small"}
-              (dom/svg #js {:xmlns "http://www.w3.org/2000/svg" :width "24" :height "24" :viewBox "0 0 24 24"}
-                (dom/path #js {:d "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11h-4v4h-2v-4H7v-2h4V7h2v4h4v2z"})))
-            (dom/span #js {:className "c-button__content"} "Add Conditions")))))))

 (defexample icon-bar
   "# Icon Bar"
@@ -2475,7 +2311,6 @@

                This object is redesigned to be un-opinionated and flexible for almost any interactive list you might need in your app. The simplified markup resembles this node list:
                ``` shell\n.o-accordion [ --inline | --right | --small ]\n   __title   [ is-active | is-nested | is-selected ]\n   __content [ is-active ]\n     __group\n       __info\n       __actions\n         __action [ --informative | --success ]\n         __meta\n           __meta-item\n```"}
-          {:id :editor-inactive :title "Editor [Deprecated]" :examples [editor-inactive editor-active]}
           {:id :sidebar :title "Sidebar [Deprecated]" :examples [sidebar sidebar-right]}
           ])))


#7 add next and prev urls

#7 add next and prev urls

--- src/kalar_plugins/templates/page.clj
+++ src/kalar_plugins/templates/page.clj
@@ -7,15 +7,34 @@
             [kalar-core.file :as kfile]
             [hiccup.page :as hpage]))

+(defn- get-dst-path [^String src-path]
+  (kfile/get-dst (str/replace src-path #"\..*$" ".html")))

 (defn- compile-md [file]
   (let [file-path (.getAbsolutePath file)
         md (hp/load-markdown file-path)
-        dst (kfile/get-dst (str/replace file-path #"\..*$" ".html"))
+        dst (get-dst-path file-path)
         fnc (-> md :template first)]
     (kfile/touch dst)
     (require (symbol (str/replace fnc  #"/.*"  "")))
     (spit dst ((var-get (resolve (symbol fnc))) md))))
+
+(defn- create-neighbor-url [urls]
+  (map (fn [p n] {:previous-page p :next-page n})
+       (cons nil (drop-last urls))
+       (concat (rest urls) '(nil))))
+
+(defn- compile-serial-mds [dir]
+  (let [files (.listFiles (io/file dir))
+        mds (map #(merge (hp/load-md-excerpt (.getAbsolutePath %))
+                         {:url (get-dst-path (.getAbsolutePath %))})
+                 files)
+        neighbor-urls (create-neighbor-url (map #(.getAbsolutePath (:url %)) mds))
+        mds-with-neighbors (map (fn [m n] (merge m n)) mds neighbor-urls)
+        ]
+    (comment (partition-all))
+    (println mds-with-neighbors)
+    ))

 (plugin/defkalar-plugin
   page
@@ -24,6 +43,8 @@
     [this]
     (dorun
       (for [file (.listFiles (io/file (:page-dir (config/read-config))))]
-        (compile-md file)))))
+        (compile-md file)))
+    (compile-serial-mds (:posts-dir (config/read-config)))
+    ))