added generator functions for HTML lists

--- src/distillery/view/html.clj
+++ src/distillery/view/html.clj
@@ -83,6 +83,21 @@
   [css-class content]
   {:tag :span :attrs {:class css-class} :content (safe-content content)})

+(defn list-item
+  "Creates a list item."
+  [content]
+  {:tag :li :content (safe-content content)})
+
+(defn ulist
+  "Creates an unordered list with a given CSS class and a sequence of list items."
+  [css-class items]
+  {:tag :ul :attrs {:class css-class} :content (vec items)})
+
+(defn ulist
+  "Creates an ordered list with a given CSS class and a sequence of list items."
+  [css-class items]
+  {:tag :ol :attrs {:class css-class} :content (vec items)})
+
 (defn jshref
   "Creates a URI referencing a JavaScript call."
   [js]


mark-completed refactored

mark-completed refactored

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -94,9 +94,9 @@
                    {:_id _id}
                    {:$set {user-score-key score}}))))))

-(defn mark-completed [id code & [user]]
+(defn mark-completed [problem code & [user]]
   (let [user (or user (session/session-get :user))
-        approved (:approved (get-problem id))
+        {:keys [_id approved]} problem
         gist-link (html [:div.share
                          [:a.novisited {:href "/share/code"} "Share"]
                          " this solution with your friends!"])
@@ -104,17 +104,17 @@
         (cond
          (not approved) (str "You've solved the unapproved problem. Now you can approve it!")
          user (do
-                (when (not-any? #{id} (get-solved user))
-                  (update! :users {:user user} {:$addToSet {:solved id}})
-                  (update! :problems {:_id id} {:$inc {:times-solved 1}})
+                (when (not-any? #{_id} (get-solved user))
+                  (update! :users {:user user} {:$addToSet {:solved _id}})
+                  (update! :problems {:_id _id} {:$inc {:times-solved 1}})
                   (send total-solved inc))
-                (record-golf-score! user id (code-length code))
+                (record-golf-score! user _id (code-length code))
                 (str "Congratulations, you've solved the problem!"
-                     "
" (next-problem-link id)))
+                     "
" (next-problem-link _id)))
          :else (str "You've solved the problem! If you "
                     (login-link "log in") " we can track your progress."))]
-    (session/session-put! :code [id code])
-    (flash-msg (str message " " gist-link) (str "/problem/" id))))
+    (session/session-put! :code [_id code])
+    (flash-msg (str message " " gist-link) (str "/problem/" _id))))

 (def restricted-list '[use require in-ns future agent send send-off pmap pcalls])

@@ -132,7 +132,7 @@

 (defn run-code [id raw-code]
   (let [code (.trim raw-code)
-        {:keys [tests restricted]} (get-problem id)
+        {:keys [tests restricted] :as problem} (get-problem id)
         sb-tester (get-tester restricted)]
     (session/flash-put! :code code)
     (try
@@ -143,7 +143,7 @@
                  i 0]
             (session/flash-put! :failing-test i)
             (if-not test
-              (mark-completed id code)
+              (mark-completed problem code)
               (let [testcase (s/replace test "__" user-forms)]
                 (if (sb sb-tester (first (read-string-safely testcase)))
                   (recur more (inc i))


Use ForkJoinPool/commonPool as default executor.

--- src/futura/stream/common.clj
+++ src/futura/stream/common.clj
@@ -33,15 +33,16 @@
            org.reactivestreams.Publisher
            org.reactivestreams.Subscriber
            java.lang.AutoCloseable
+           java.util.Queue
+           java.util.concurrent.ForkJoinPool
            java.util.concurrent.Executor
-           java.util.concurrent.Executors
            java.util.concurrent.CountDownLatch
            java.util.concurrent.ConcurrentLinkedQueue))

 (declare runnable)

 (def ^:dynamic
-  *executor* (Executors/newSingleThreadExecutor))
+  *executor* (ForkJoinPool/commonPool))

 (defn terminate
   "Mark a subscrition as terminated


[#176] Add (enpoint.utils/get-api-root req)

--- api/src/clojure/org/akvo/flow_api/endpoint/utils.clj
+++ api/src/clojure/org/akvo/flow_api/endpoint/utils.clj
@@ -12,6 +12,11 @@
                  (url-encode v)))
        (s/join "&")))

+(defn get-api-root [request]
+  (let [scheme (name (:scheme request))
+        hostname (get (:headers request) "host")]
+    (str scheme "://" hostname "/")))
+
 (defn url-builder
   ([api-root instance path]
    (url-builder api-root instance path nil))


[#818] edit user panel header

[#818] edit user panel header

--- Dashboard/app/cljs/src/org/akvo/flow/dashboard/users/user_details.cljs
+++ Dashboard/app/cljs/src/org/akvo/flow/dashboard/users/user_details.cljs
@@ -6,7 +6,16 @@
             [sablono.core :as html :refer-macros (html)]
             [ajax.core :refer (ajax-request GET POST PUT DELETE)]))

-(defn panel-header [{:keys [on-save]} owner])
+(defn panel-header-section [{:keys [user]} owner]
+  (om/component
+   (html
+    [:div.row.panelHeader
+     [:div.col-xs-9.text-left.panelTitle
+      [:h4
+       (b/icon :pencil) " Edit " (get user "userName")]]
+     [:div.col-xs-3.text-right
+      [:button.btn.btn-primary
+       (b/icon :circle-arrow-left) " Go back"]]])))

 (defn update-input! [owner key]
   (fn [event]
@@ -90,7 +99,7 @@
   (om/component
    (html
     [:div
-     #_(om/build panel-header {:user user})
+     (om/build panel-header-section {:user user})
      (om/build user-edit-section {:user user
                                   :on-save #(dispatch :edit-user %)})
      #_(om/build roles-and-permissions-section {:user user :projects projects})


log error if couldn't run java -version

log error if couldn't run java -version

--- src-cljs/cuttle/exec.cljs
+++ src-cljs/cuttle/exec.cljs
@@ -66,7 +66,7 @@
         (fn [error stdout stderr]
           (if error
             (do
-              (log-info "couldn't run java -version")
+              (log-info "couldn't run java -version:" (.toString error))
               (put! out-chan false))
             (let [version (parse-java-version stderr)
                   valid? (>= version 7)]


flip card back if bad, destroy if they are same

--- Assets/game/core.clj
+++ Assets/game/core.clj
@@ -54,11 +54,11 @@

 ;; (shuffle (flatten (map #(repeat 2 (keyword %)) card-faces)))

-(doseq [[card face]
-        (->> card-faces
+(doseq [[card face] ; ~foreach, destruction
+        (->> card-faces ; ->> pipe operator
              (map #(repeat 2 %))
              flatten
-             shuffle
+             shuffle)
              (zipmap (cards)))]
   (card-set-face-texture! card face))

@@ -113,7 +113,8 @@
         flipped? (state go :flipped?)
         trigger (if flipped? "flipBack" "flip")]
     (update-state! go :flipped? #(not %))
-    (.SetTrigger animator trigger)))
+    (.SetTrigger animator trigger))
+  (cards-flip-back!-when-2))

 (defn cards-flipped []
   (filter #(state % :flipped?) (cards)))


initial language detection (doesn't set for the cljs though)

--- src/clj/just_married/api.clj
+++ src/clj/just_married/api.clj
@@ -1,7 +1,6 @@
 (ns just-married.api
   (:gen-class)
   (:require [buddy.auth :refer [authenticated? throw-unauthorized]]
-            [buddy.auth.accessrules :refer [restrict]]
             [buddy.auth.backends.httpbasic :refer [http-basic-backend]]
             [buddy.auth.middleware :refer [wrap-authentication wrap-authorization]]
             [hiccup.core :as html]
@@ -28,6 +27,8 @@

 (def ^:private security (= (env :secure) "true"))
 (def ^:private default-port 3000)
+(def ^:private default-language :en)
+(def ^:private available-languages #{:en :it})

 (defn- get-port
   []
@@ -35,8 +36,13 @@

 (defn- detect-language
   "Lookup in the request to find out what should be the default language to serve"
-  [request]
-  :en)
+  [request available-languages]
+  (let [accept-language (get  (:headers request) "accept-language")
+        parsed-languages (map (comp keyword first) (map #(clojure.string/split % #";")
+                                                        (clojure.string/split accept-language #",")))
+        only-available (filter #(contains? available-languages %) parsed-languages)]
+
+    (or (first only-available) default-language)))

 (defn guest-list
   "Page showing the list of guests, needs to be authenticated"
@@ -74,7 +80,8 @@
 (defroutes app-routes
   (GET "/" [] (render-page :initial :en))
   (GET "/enter" [] (render-page :initial :en))
-  (GET "/main" request (render-page :home (detect-language request)))
+  ;; do a redirect adding the extra information
+  (GET "/main" request (render-page :home (detect-language request available-languages)))
   (GET "/guests" request (guest-list request)))

 (def app


Fixed typos and re-tagged "Intro to Reduce"

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -664,8 +664,8 @@
            {:_id 64
             :title "Intro to reduce"
             :times-solved 0
-            :description "Reduce takes a 2 argument fuction and and an optional starting value. It then applies the function to the first 2 items in the sequence (or the starting value and the first element of the sequence). In the next iteration the function will be called on the previous return value and the next item from the sequence, thus reducing the entire collection to one value. Don't worry, it's not really that complicated."
-            :tags ["easy" "core-functions" "reduce"]
+            :description "Reduce takes a 2 argument function and an optional starting value. It then applies the function to the first 2 items in the sequence (or the starting value and the first element of the sequence). In the next iteration the function will be called on the previous return value and the next item from the sequence, thus reducing the entire collection to one value. Don't worry, it's not as complicated as it sounds."
+            :tags ["elementary" "seqs"]
             :tests ["(= 15 (reduce __ [1 2 3 4 5]))"
                     "(=  0 (reduce __ []))"
                     "(=  6 (reduce __ 1 [2 3]))"]})


Fix bug in completion reads.

Fix bug in completion reads.

--- src/onyx/messaging/aeron.clj
+++ src/onyx/messaging/aeron.clj
@@ -76,7 +76,7 @@
             (>!! release-ch completion-id))

           (= msg-type protocol/retry-msg-id)
-          (let [retry-id (protocol/read-retry buffer offset)]
+          (let [retry-id (protocol/read-retry buffer offset-rest)]
             (>!! retry-ch retry-id)))))

 (defn data-handler [f]
@@ -197,6 +197,8 @@
         receive-idle-strategy (:receive-idle-strategy messenger)

         ;; pass in handler to consumer constructor
+        ;;;;; FIXME: 10 is not the right fragment limit to use here
+        ;;;;; should at least be configurable
         accept-send-fut (future (try (.accept ^Consumer (consumer send-handler receive-idle-strategy 10) send-subscriber)
                                      (catch Throwable e (fatal e))))
         accept-aux-fut (future (try (.accept ^Consumer (consumer aux-handler receive-idle-strategy 10) aux-subscriber)
@@ -281,4 +283,3 @@
     (reset! pub nil))
   (.close ^uk.co.real_logic.aeron.Aeron (:conn peer-link))
   {})
-


Make ingress-ids in serialized task look like egress-ids

--- src/onyx/static/planning.clj
+++ src/onyx/static/planning.clj
@@ -44,7 +44,7 @@
         task-id (task-ids element-name)]
     {:id task-id
      :name element-name
-     :ingress-ids (or (map :id parents) [])
+     :ingress-ids (or (into {} (map (juxt :name :id) parents)) [])
      :egress-ids (egress-ids-from-children task-ids children)}))

 (defmethod create-task :function
@@ -63,7 +63,8 @@
   (let [task-name (:onyx/name element)]
     {:id (task-ids task-name)
      :name task-name
-     :ingress-ids (or (map :id parents) [])}))
+     :ingress-ids (into {} (map (juxt :name :id) parents))
+     :egress-ids []}))

 (defn to-dependency-graph [workflow]
   (reduce (fn [g edge]


Fix formatting

Fix formatting

--- src/overtone/helpers/lib.clj
+++ src/overtone/helpers/lib.clj
@@ -194,20 +194,20 @@
       arg-map)))

 (defmacro defunk [name docstring args & body]
-  (let [arg-names (map first (partition 2 args))
-        arg-keys (vec (map keyword arg-names))
-        default-map (apply hash-map (syms-to-keywords args))]
-    (let [arg-pairs (map #(str (first %) " " (second %)) (partition 2 args))
-          arg-pairs-str (apply str (interpose ", " arg-pairs))
-          arg-string (str "[" arg-pairs-str "]")
-          indented-doc   (indented-str-block docstring 55 2)
-          full-docstring (str arg-string "\n\n  " indented-doc)]
-      `(defn ~name
-         ~full-docstring
-         [& args#]
-         (let [{:keys [~@arg-names]}
-               (arg-mapper args# ~arg-keys ~default-map)]
-           ~@body)))))
+  (let [arg-names      (map first (partition 2 args))
+        arg-keys       (vec (map keyword arg-names))
+        default-map    (apply hash-map (syms-to-keywords args))
+        arg-pairs      (map #(str (first %) " " (second %)) (partition 2 args))
+        arg-pairs-str  (apply str (interpose ", " arg-pairs))
+        arg-string     (str "[" arg-pairs-str "]")
+        indented-doc   (indented-str-block docstring 55 2)
+        full-docstring (str arg-string "\n\n  " indented-doc)]
+    `(defn ~name
+       ~full-docstring
+       [& args#]
+       (let [{:keys [~@arg-names]}
+             (arg-mapper args# ~arg-keys ~default-map)]
+         ~@body))))

 (defn invert-map
   "Takes a map m and returns a new map that's keys are the m's vals and


Turn render! into a multimethod

Turn render! into a multimethod

--- src/play_clj/core_render.clj
+++ src/play_clj/core_render.clj
@@ -2,17 +2,19 @@

 ; rendering

-(defn render!
-  [{:keys [renderer ^Camera camera delta-time]}]
-  (assert renderer)
-  (cond
-    (isa? (type renderer) BatchTiledMapRenderer)
-    (doto ^BatchTiledMapRenderer renderer
-      (.setView camera)
-      .render)
-    (isa? (type renderer) Stage)
-    (doto ^Stage renderer
-      .draw)))
+(defmulti render! #(-> % :renderer type) :default nil)
+
+(defmethod render! nil [screen])
+
+(defmethod render! BatchTiledMapRenderer
+  [{:keys [^BatchTiledMapRenderer renderer ^Camera camera]}]
+  (when camera (.setView renderer camera))
+  (.render renderer))
+
+(defmethod render! Stage
+  [{:keys [^Stage renderer ^Camera camera]}]
+  (when camera (.setCamera renderer camera))
+  (.draw renderer))

 (defn tiled-map-layers
   [{:keys [^BatchTiledMapRenderer renderer]}]


adding the secretary library to the front-end requires

--- src-cljs/bitfondue/core.cljs
+++ src-cljs/bitfondue/core.cljs
@@ -1,7 +1,7 @@
 (ns ^:figwheel-always bitfondue.core
-    (:require
-     [reagent.core :as reagent :refer [atom]]
-     [ajax.core :refer [GET]]))
+    (:require [reagent.core :as reagent :refer [atom]]
+              [ajax.core :refer [GET]]
+              [secretary.core :as secretary :refer-macros [defroute]]))

 ;; define your app data so that it doesn't get over-written on reload


Completed 06_functions.clj clojure

Completed 06_functions.clj clojure

--- hackerrank/functional_programming/clojure/clojure-koans/src/koans/06_functions.clj
+++ hackerrank/functional_programming/clojure/clojure-koans/src/koans/06_functions.clj
@@ -8,33 +8,33 @@

 (meditations
   "Calling a function is like giving it a hug with parentheses"
-  (= __ (square 9))
+  (= 81 (square 9))

   "Functions are usually defined before they are used"
-  (= __ (multiply-by-ten 2))
+  (= 20 (multiply-by-ten 2))

   "But they can also be defined inline"
-  (= __ ((fn [n] (* 5 n)) 2))
+  (= 10 ((fn [n] (* 5 n)) 2))

   "Or using an even shorter syntax"
-  (= __ (#(* 15 %) 4))
+  (= 60 (#(* 15 %) 4))

   "Even anonymous functions may take multiple arguments"
-  (= __ (#(+ %1 %2 %3) 4 5 6))
+  (= 15 (#(+ %1 %2 %3) 4 5 6))

   "Arguments can also be skipped"
-  (= __ (#(* 15 %2) 1 2))
+  (= 30 (#(* 15 %2) 1 2))

   "One function can beget another"
-  (= 9 (((fn [] ___)) 4 5))
+  (= 9 (((fn [] (fn [y x] (+ x y)))) 4 5))

   "Functions can also take other functions as input"
   (= 20 ((fn [f] (f 4 5))
-           ___))
+           (fn [x y] (* x y))))

   "Higher-order functions take function arguments"
-  (= 25 (___
+  (= 25 ((fn [f] (f 5))
           (fn [n] (* n n))))

   "But they are often better written using the names of functions"
-  (= 25 (___ square)))
+  (= 25 ((fn [f] (f 5)) square)))


fixes #6 - misspelled function

fixes #6 - misspelled function

--- src/testdouble/cljs/csv.cljs
+++ src/testdouble/cljs/csv.cljs
@@ -4,13 +4,13 @@
 (defn- wrap-in-quotes [s]
   (str "\"" s "\""))

-(defn- seperate [data separator quote?]
+(defn- separate [data separator quote?]
   (str/join separator
             (cond->> data
               quote? (map wrap-in-quotes))))

 (defn- write-data [data separator newline quote?]
-  (str/join newline (map #(seperate % separator quote?) data)))
+  (str/join newline (map #(separate % separator quote?) data)))

 (def ^:private newlines
   {:lf "\n" :cr+lf "\r\n"})


Do not log in console.

Do not log in console.

--- src/time_tracker/logging.clj
+++ src/time_tracker/logging.clj
@@ -74,7 +74,6 @@
   ([level]
    (set-root-logger-level! "error")
    (set-logger-level! "time-tracker" level)
-   (add-root-logger-appender! (ConsoleAppender. (PatternLayout. "%-5p %c: %m%n")))
    (add-root-logger-appender! (RollingFileAppender. (PatternLayout. "%-5p %c: %m%n")
                                                     (from-config :log-file-prefix)
                                                     true))))


Add replace and append

Add replace and append

--- src/aurora/compiler.cljs
+++ src/aurora/compiler.cljs
@@ -181,6 +181,13 @@
      (do
        (let! notebook {})
        (let! failure "MatchFailure!")
+       ;; TODO handle nil cursors in replace and append
+       (fn value_replace [value_old cursor_old value_new cursor_new]
+         (cljs.core.assoc_in.call nil notebook.next_state cursor_old value_new)
+         ["ok" nil])
+       (fn value_append [value_old cursor_old value_new cursor_new]
+         (cljs.core.update_in.call nil notebook.next_state cursor_old cljs.core.conj value_new)
+         ["ok" nil])
        ~@(for! [page-id (:pages x)]
                `(do
                   ~(page->jsth index (get index page-id) page-id)


unified execption message handling in http resp

--- src/celestial/common.clj
+++ src/celestial/common.clj
@@ -37,7 +37,7 @@
   [& keys]
   (if-let [v (get-in config keys)]
     v
-    (throw+ {:type ::missing-conf :message (<< "No matching configuration keys ~{keys} found")})))
+    (throw+ {:type ::missing-conf} (<< "No matching configuration keys ~{keys} found"))))

 (defn get*
   "nil on missing version of get!"
@@ -74,12 +74,12 @@
    "Wraps validation error responses in the API layer"
    [& body]
   `(try+ ~@body
-    (catch (and (map? ~'%) (or (contains? ~'% :errors) (contains? ~'% :msg))) e#
+    (catch (map? ~'%) e#
       (info e#)
-      (bad-req e#))
+      (bad-req (select-keys ~'&throw-context [:message :object])))
     (catch Object e#
       (error e#)
-      (bad-req "Error happend, please contact admin"))
+      (bad-req {:message "Error happend, please contact admin"}))
    )
   )


import Closure JSModule & JSModuleGraph into cljs.closure

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -51,7 +51,8 @@
               CompilerOptions$LanguageMode SourceMap$Format
               SourceMap$DetailLevel ClosureCodingConvention SourceFile
               Result JSError CheckLevel DiagnosticGroups
-              CommandLineRunner AnonymousFunctionNamingPolicy]
+              CommandLineRunner AnonymousFunctionNamingPolicy
+              JSModule JSModuleGraph]
            [java.security MessageDigest]
            [javax.xml.bind DatatypeConverter]
            [java.nio.file Path Paths Files StandardWatchEventKinds WatchKey


re-add `cljs.closure/output-directory` for backwards compatibility, just defers to `cljs.util/output-directory`

--- src/clj/cljs/closure.clj
+++ src/clj/cljs/closure.clj
@@ -1022,7 +1022,10 @@
                  (util/mkdirs outfile)
                  (spit outfile (slurp (io/resource "cljs/bootstrap_node.js")))))
              ret))))))
-
+
+;; for backwards compatibility
+(defn output-directory [opts]
+  (util/output-directory opts))

 (comment


organize cljs.js-deps Java imports, add to-url case for java.net.URL

--- src/clj/cljs/js_deps.clj
+++ src/clj/cljs/js_deps.clj
@@ -1,11 +1,9 @@
 (ns cljs.js-deps
   (:require [clojure.java.io :as io]
             [clojure.string :as string])
-  (:import java.io.File
-           java.net.URL
-           java.net.URLClassLoader
-           java.util.zip.ZipFile
-           java.util.zip.ZipEntry))
+  (:import [java.io File]
+           [java.net URL URLClassLoader]
+           [java.util.zip ZipFile ZipEntry]))

 ; taken from pomegranate/dynapath
 ; https://github.com/tobias/dynapath/blob/master/src/dynapath/util.clj
@@ -47,6 +45,8 @@
 (defmulti to-url class)

 (defmethod to-url File [^File f] (.toURL (.toURI f)))
+
+(defmethod to-url URL [^URL url] url)

 (defmethod to-url String [s] (to-url (io/file s)))


fspecs accept ifns

fspecs accept ifns

--- src/clj/clojure/spec.clj
+++ src/clj/clojure/spec.clj
@@ -1412,12 +1412,12 @@
      (valAt [_ k not-found] (get specs k not-found))

      Spec
-     (conform* [_ f] (if (fn? f)
+     (conform* [_ f] (if (ifn? f)
                        (if (identical? f (validate-fn f specs *fspec-iterations*)) f ::invalid)
                        ::invalid))
      (unform* [_ f] f)
      (explain* [_ path via in f]
-               (if (fn? f)
+               (if (ifn? f)
                  (let [args (validate-fn f specs 100)]
                    (if (identical? f args) ;;hrm, we might not be able to reproduce
                      nil
@@ -1432,7 +1432,7 @@
                              (when fnspec
                                (let [cargs (conform argspec args)]
                                  (explain-1 fform fnspec (conj path :fn) via in {:args cargs :ret cret})))))))))
-                 {path {:pred 'fn? :val f :via via :in in}}))
+                 {path {:pred 'ifn? :val f :via via :in in}}))
      (gen* [_ _ _ _] (if gfn
              (gfn)
              (when-not fnspec


added above ground carbon specs to map of static characteristics


changed last to peek, in timeseries generation function.

--- src/clj/forma/trends.clj
+++ src/clj/forma/trends.clj
@@ -103,7 +103,7 @@
   [timeseries [missing-val]] [tuples]
   (let [[periods [val]] (apply map vector tuples)
         missing-struct (io/to-struct (repeat (io/count-vals val) missing-val))
-        [fp lp] ((juxt first last) periods)
+        [fp lp] ((juxt first peek) periods)
         chunks (sparse-expander missing-struct tuples :start fp)
         tupleize (comp (partial vector fp lp)
                        io/to-struct


Finishes doc strings

Finishes doc strings

--- src/clj_spotify/core.clj
+++ src/clj_spotify/core.clj
@@ -46,6 +46,7 @@

 ;TODO - better doc string
 ;TODO - rename to def-spotify-api-call
+;TODO - Maybe change everything to be sent through request body?
 (defmacro spotify-api-call
   "Creates a function f with doc-string d that calls the http-verb verb for url url."
   [f verb url doc-string]
@@ -287,23 +288,96 @@
 ;TODO - Change this fields string to be a map?
 (spotify-api-call get-a-playlist client/get (str spotify-api-url "users/user_id/playlists/playlist_id")
 " Takes two arguments, a map m with query parameters and an optional oauth-token t.
-    Compulsory key in  m is :user_id and :playlist_id, optional keys are :fields, :market, :limit and :ffset.
+    Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :market, :limit and :offset.
     :user_id is the users spotify id.
     :playlist_id is the playlist spotify id.
     :fields is a comma-separated string of fields to return from the playlist.
      See developer.spotify.com for a full list of field names.
-    :limit is the maxium number of tracks to return, default is 20.
-    :offset is the index of the first track to return, default is 0.
-
-    Example: (get-a-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\":limit 50 :offset 50} \"BQBw-JtC..._7GvA\")  ")
-
-(spotify-api-call get-a-playlists-tracks client/get (str spotify-api-url "users/user_id/playlists/playlist_id/tracks") "")
-(spotify-api-call create-a-playlist client/post (str spotify-api-url "users/user_id/playlists") "")
-(spotify-api-call add-tracks-to-a-playlist client/post (str spotify-api-url "users/user_id/playlists/playlist_id/tracks") "")
-(spotify-api-call remove-tracks-from-a-playlist client/delete (str spotify-api-url "users/user_id/playlists/playlist_id/tracks") "")
-(spotify-api-call reorder-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks") "")
-(spotify-api-call replace-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks") "")
-(spotify-api-call change-a-playlists-details client/put (str spotify-api-url "users/user_id/playlists/playlist_id") "")
+    :market is an ISO 3166-1 alpha-2 country code.
+    :limit is the maxium number of tracks to return, default is 20.
+    :offset is the index of the first track to return, default is 0.
+
+    Example: (get-a-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\" :market \"SE\" :limit 50 :offset 50} \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call get-a-playlists-tracks client/get (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory keys in  m are :user_id and :playlist_id, optional keys are :fields, :limit and :offset and :market.
+    :user_id is the users spotify id.
+    :playlist_id is the playlist spotify id.
+    :fields is a comma-separated string of fields to return from the playlist.
+     See developer.spotify.com for a full list of field names.
+    :limit is the maxium number of tracks to return, default is 20.
+    :offset is the index of the first track to return, default is 0.
+    :market is an ISO 3166-1 alpha-2 country code.
+
+    Example: (get-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :fields \"href,name,owner\":limit 50 :offset 50 :market \"SE\"} \"BQBw-JtC..._7GvA\")")
+
+;TODO - Deal with request body data for values of :name and :public.
+(spotify-api-call create-a-playlist client/post (str spotify-api-url "users/user_id/playlists")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory keys in m are :user_id and :name, optional key is :public.
+    :user_id is the users spotify id.
+    :name is the name for the new playlist.
+    :public is set to true if a playlist should be public and false if not.
+
+    Example: (create-a-playlist {:user_id \"elkalel\" :name \"The songs you didn't know you liked.\" :public true} \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call add-tracks-to-a-playlist client/post (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
+    :user_id is the users spotify id.
+    :playlist_id is the playlist spotify id.
+    :uris a list of spotify track uris.
+    :position the position to insert the tracks.
+
+    Example: (add-tracks-to-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
+spotify:track:1301WleyT98MSxVHPZCA6M\" :position 2} \"BQBw-JtC..._7GvA\")")
+
+;TODO - Deal with request body data, very nescessary here.
+;TODO - Deal with correct formatting of :tracks.
+;TODO - Additional doc string with optional and required values in :tracks.
+(spotify-api-call remove-tracks-from-a-playlist client/delete (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m are :user_id, :playlist_id and :tracks, optional keys is :snapshot_id.
+    :user_id is the users spotify id.
+    :playlist_id is the playlist spotify id.
+    :tracks an array of objects containing spotify URI strings and corresponding position maps.
+    :snapshot_id a playlist snapshot ID.
+     See the spotify developer API for the logic behind deleting tracks.
+
+    Example: (remove-tracks-from-playlist {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :tracks [{:uri \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh\", :positions [2]} {:uri \"spotify:track:1301WleyT98MSxVHPZCA6M\", :positions [7]}]}  \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call reorder-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m are :user_id, :playlist_id, :range_start and :insert_before, optional keys are :range_length and :snapshot_id.
+    :user_id is the users spotify id.
+    :playlist_id is the playlist spotify id.
+    :range_start the position of the first track to be reordered.
+    :insert_before the positions where the tracks should be inserted.
+    :range_length the amount of tracks to be reordered.
+    :snapshot_id a playlist snapshot ID.
+
+    Example: (reorder-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :range_start 1 :range_length 2 :insert_before 3} \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call replace-a-playlists-tracks client/put (str spotify-api-url "users/user_id/playlists/playlist_id/tracks")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m are :user_id and :playlist_id, optional keys are :uris and :position.
+    :user_id is the users spotify id.
+    :playlist_id is the playlist spotify id.
+    :uris a list of spotify track uris.
+
+    Example: (replace-a-playlists-tracks {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :uris \"spotify:track:4iV5W9uYEdYUVa79Axb7Rh,
+spotify:track:1301WleyT98MSxVHPZCA6M\"} \"BQBw-JtC..._7GvA\")")
+
+(spotify-api-call change-a-playlists-details client/put (str spotify-api-url "users/user_id/playlists/playlist_id")
+" Takes two arguments, a map m with query parameters and an optional oauth-token t.
+    Compulsory key in m are :user_id and :playlist_id, optional keys are :name and :public.
+    :user_id is the users spotify id.
+    :playlist_id is the playlist spotify id.
+    :name is the name for the new playlist.
+    :public is set to true if a playlist should be public and false if not.
+
+    Example: (change-a-playlists-details {:user_id \"elkalel\" :playlist_id \"6IIjEBw2BrRXbrSLerA7A6\" :name \"Fantastic playlist\" :public true} \"BQBw-JtC..._7GvA\")")

 ;Profiles
 (spotify-api-call get-a-users-profile client/get (str spotify-api-url "users/user_id")


Fix highlighting fn. Don't set a fixed note height

--- src/cljs/omnom/core.cljs
+++ src/cljs/omnom/core.cljs
@@ -1,25 +1,37 @@
 (ns omnom.core
   (:require [om.core :as om :include-macros true]
             [om-tools.dom :as dom :include-macros true]
-            [om-tools.core :refer-macros [defcomponent]]))
+            [om-tools.core :refer-macros [defcomponent]]
+            [goog.dom :as gdom]))

 (def app-state
   (atom
    {:notes [{:x 100
              :y 50
              :w 200
-             :h 150
              :content "# This is cool\nTite *tite* __tite__\n```js\nfunction add(a, b) {\n  return a + b;\n}\n```"}
             {:x 200
              :y 300
              :w 400
-             :h 200
              :content "[Gooooogle](http://google.com)"}
             {:x 500
              :y 20
              :w 200
-             :h 150
              :content "# Head\n## lines\n### are cool"}]}))
+
+(defn on-next-tick
+  [fn]
+  (js/setTimeout fn 0)
+  fn)
+
+(defn highlight!
+  [node]
+  (on-next-tick
+   #(let [pre-blocks (array-seq (gdom/getElementsByTagNameAndClass "pre" nil node))]
+     (doall
+      (map (fn [pre-block]
+             (.highlightBlock js/hljs pre-block))
+           pre-blocks)))))

 (defcomponent note-view
   [note owner]
@@ -28,22 +40,21 @@
    [_]
    {:mounted false})

+  (did-mount
+   [_]
+   (om/set-state! owner :mounted true))
+
   (render
    [_]
    (let [{:keys [x y w h content]} note]
      (when (om/get-state owner :mounted)
-       (js/setTimeout #(.highlightBlock js/hljs (om/get-node owner)) 0))
+       (highlight! (om/get-node owner)))
      (dom/div {:class "note"
-
-               :style
-               {:left x :top y
-                :width w :height h}
-
-               :dangerouslySetInnerHTML {:__html (js/marked content)}})))
-
-  (did-mount
-   [_]
-   (om/set-state! owner :mounted true)))
+               :style {:left x :top y :width w}
+               :dangerouslySetInnerHTML {:__html (js/marked content)}
+               :on-click (fn []
+                           (om/transact! note :content
+                                         #(str % "\n```javascript\nfunction meta-random() {\n  return " (rand-int 2048) ";\n}\n```")))}))))

 (defcomponent root-view
   [app owner]


Had the order of triangle vertices wrong

messed up with the normals


Remove dialog

Remove dialog

--- ui-gallery/desktop/src-common/ui_gallery/core.clj
+++ ui-gallery/desktop/src-common/ui_gallery/core.clj
@@ -9,9 +9,7 @@
   (fn [screen entities]
     (update! screen :camera (orthographic) :renderer (stage))
     (let [ui-skin (skin "uiskin.json")]
-      (table [(dialog "I'm a dialog" ui-skin :text "This is my content")
-              :row
-              [(image "clojure.png")
+      (table [[(image "clojure.png")
                :width 100
                :height 100
                :space-top 20


CMR-1862 Adds docstrings.

CMR-1862 Adds docstrings.

--- umm-spec-lib/src/cmr/umm_spec/iso19115_2_util.clj
+++ umm-spec-lib/src/cmr/umm_spec/iso19115_2_util.clj
@@ -44,6 +44,9 @@
     ["x" "y" "-"]))

 (defn tiling-system-string
+  "Returns an encoded ISO tiling system coordinate string from the given UMM tiling system. The
+  coordinate 1 and coordinate 2 prefixes and separator may be specified, or else they will be looked
+  up based on the tiling system name."
   ([tiling-system p1 p2 sep]
    (let [{{c1-min :MinimumValue
            c1-max :MaximumValue} :Coordinate1
@@ -59,6 +62,8 @@
    (apply tiling-system-string tiling-system (tiling-system-coding-params tiling-system))))

 (defn parse-tiling-system-coordinates
+  "Returns a map containing :Coordinate1 and :Coordinate2 from an encoded ISO tiling system
+  parameter string."
   [tiling-system-str]
   (let [[c1 c2] (for [[_ min-str max-str] (re-seq #"(-?\d+\.?\d*)[-,]?(-?\d+\.?\d*)?"
                                                   tiling-system-str)]


Better default name for wishlists

Better default name for wishlists


Clarified info text

Clarified info text


fix quote in log output

fix quote in log output

--- src/babel/english/writer.clj
+++ src/babel/english/writer.clj
@@ -53,7 +53,7 @@
                                                     " from language: '" source-language-short-name
                                                     "' with predicate: '"
                                                     (strip-refs (get-in source-expression [:structure :synsem :sem :pred]))
-                                                    "' into English; subj: '"
+                                                    "' into English; subj:'"
                                                     "'" (get-in source-expression [:structure :synsem :sem :subj :pred])
                                                     "'"))
                                     false


Remove commented code.

Remove commented code.

--- src/buddy/core/crypto.clj
+++ src/buddy/core/crypto.clj
@@ -156,20 +156,6 @@
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; High level api.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; (defn get-buffer-for-input
-;;   [^bytes input ^long blocksize]
-;;   (let [length (count input)
-;;         csize (double (/ input blocksize))]
-;;     (cond
-;;       (<= csize blocksize)
-;;       (byte-array blocksize)
-
-;;       (> csize blocksize)
-;;       (let [m (mod csize blocksize)]
-;;         (if (== m 0)
-;;           (byte-array (long csize))
-;;           (byte-array (+ (long csize) blocksize)))))))

 (defn split-by-blocksize
   "Split a byte array in blocksize blocks.


Add query templated URL to slice

Add query templated URL to slice

--- src/cfpb/qu/resources.clj
+++ src/cfpb/qu/resources.clj
@@ -100,8 +100,12 @@
                      query (params->Query params slicedef)
                      query (mongo/with-db (mongo/get-db dataset)
                              (query/execute (:table slicedef) query))
-                     resource (-> (hal/new-resource (str "/data/" dataset "/" (name slice)))
+                     href (str "/data/" dataset "/" (name slice))
+                     resource (-> (hal/new-resource href)
                                   (hal/add-link :rel "up" :href (str "/data/" dataset))
+                                  (hal/add-link :rel "query"
+                                                :href (str href ".{?format}?$where={?where}&$orderBy={?orderBy}&$select={?select}")
+                                                :templated true)
                                   (hal/add-properties {:dataset dataset :slice (name slice)})
                                   (hal/add-properties (-> query
                                                           (dissoc :slicedef :mongo :dimensions)


remove contrib dependency

remove contrib dependency

--- src/clj/clj_json/core.clj
+++ src/clj/clj_json/core.clj
@@ -1,16 +1,11 @@
 (ns clj-json.core
   (:import (clj_json JsonExt)
            (org.codehaus.jackson JsonFactory JsonParser JsonParser$Feature)
-<<<<<<< HEAD
-           (java.io StringWriter StringReader BufferedReader)))
-=======
            (java.io StringWriter StringReader BufferedReader))
-  (:use (clojure.contrib [def :only (defvar-)])
-        (clojure [walk :only (postwalk)]
+  (:use (clojure [walk :only (postwalk)]
                  [string :only (join)])))
->>>>>>> implement user extendable coercions

-(def ^{:tag JsonFactory, :private true} factory
+(def ^{:private true :tag JsonFactory} factory
   (doto (JsonFactory.)
     (.configure JsonParser$Feature/ALLOW_UNQUOTED_CONTROL_CHARS true)))


Fix set-* methods for cljs in protocol HybridBuffer

--- src/clj/seria/buffer.cljc
+++ src/clj/seria/buffer.cljc
@@ -133,9 +133,9 @@
                (get-byte-position   [this] (.-bytePosition this))
                (get-max-byte-length [this] (.-maxByteLength this))

-               (set-bit-position!    [this value] (set! (.-bitPosition this) value))
-               (set-byte-position!   [this value] (set! (.-bytePosition this) value))
-               (set-max-byte-length! [this value] (set! (.-maxByteLength this) value))
+               (set-bit-position!    [this value] (do (set! (.-bitPosition this) value) this))
+               (set-byte-position!   [this value] (do (set! (.-bytePosition this) value) this))
+               (set-max-byte-length! [this value] (do (set! (.-maxByteLength this) value) this))

                (get-bit-position!  [this amount] (let [position (.-bitPosition this)]
                                                    (set! (.-bitPosition this) (+ position amount))


Fixed prop access in node.js source

Fixed prop access in node.js source

--- src/cljs/cljs/nodejs.cljs
+++ src/cljs/cljs/nodejs.cljs
@@ -8,4 +8,4 @@
 (def process (js* "process"))

 ; Have ClojureScript print using Node's sys.print function
-(set! cljs.core/string-print (.print (require "sys")))
+(set! cljs.core/string-print (.-print (require "sys")))


reader support for regex, comment, discard, unreadable, and eof-is-error #30

--- src/cljs/cljs/reader.cljs
+++ src/cljs/cljs/reader.cljs
@@ -65,6 +65,11 @@
 ;; read helpers
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

+; later will do e.g. line numbers...
+(defn reader-error
+  [rdr & msg]
+  (throw (apply str msg)))
+
 (defn macro-terminating? [ch]
   (and (not= ch "#") (not= ch \') (contains? macros ch)))

@@ -78,13 +83,14 @@
       (do (unread rdr ch) (. sb (toString)))
       (recur (do (.append sb ch) sb) (read-char rdr)))))

-(defn- skip-line
+(defn skip-line
   "Advances the reader to the end of a line. Returns the reader"
-  [reader]
-  (let [ch (read-char reader)]
-    (if (or (= ch \n) (= ch \r) (nil? ch))
-      reader
-      (recur reader))))
+  [reader _]
+  (loop []
+    (let [ch (read-char reader)]
+      (if (or (= ch \n) (= ch \r) (nil? ch))
+        reader
+        (recur)))))

 (def int-pattern (re-pattern "([-+]?)(?:(0)|([1-9][0-9]*)|0[xX]([0-9A-Fa-f]+)|0([0-7]+)|([1-9][0-9]?)[rR]([0-9A-Za-z]+)|0[0-9]+)(N)?"))
 (def ratio-pattern (re-pattern "([-+]?[0-9]+)/([0-9]+)"))
@@ -123,8 +129,7 @@
   (cond
    (re-matches int-pattern s) (match-int s)
    (re-matches ratio-pattern s) (match-ratio s)
-   (re-matches float-pattern s) (match-float s)
-   :default (throw (str "Invalid number format [" s "]"))))
+   (re-matches float-pattern s) (match-float s)))

 (def escape-char-map {\t "\t"
                       \r "\r"
@@ -136,7 +141,7 @@

 (defn read-unicode-char
   [reader initch]
-  (throw "Unicode characters not supported by reader (yet)"))
+  (reader-error reader "Unicode characters not supported by reader (yet)"))

 (defn escape-char
   [buffer reader]
@@ -146,7 +151,7 @@
       mapresult
       (if (or (= \u ch) (numeric? ch))
         (read-unicode-char reader ch)
-        (throw (str "Unsupported escape charater: \\" ch))))))
+        (reader-error reader "Unsupported escape charater: \\" ch)))))

 (defn read-past
   "Read until first character that doesn't match pred, returning
@@ -161,7 +166,7 @@
   [delim rdr recursive?]
   (loop [a []]
     (let [ch (read-past whitespace? rdr)]
-      (when-not ch (throw "EOF"))
+      (when-not ch (reader-error rdr "EOF"))
       (if (= delim ch)
         a
         (if-let [macrofn (get macros ch)]
@@ -178,7 +183,7 @@

 (defn not-implemented
   [rdr ch]
-  (throw (str "Reader for " ch " not implemented yet")))
+  (reader-error rdr "Reader for " ch " not implemented yet"))

 (defn read-dispatch
   [rdr _]
@@ -186,15 +191,17 @@
         dm (get dispatch-macros ch)]
     (if dm
       (dm rdr _)
-      (throw (str "No dispatch macro for " ch)))))
+      (reader-error rdr "No dispatch macro for " ch))))

 (defn read-unmatched-delimiter
   [rdr ch]
-  (throw (str "Unmached delimiter " ch)))
+  (reader-error rdr "Unmached delimiter " ch))

 (defn read-list
   [rdr _]
   (apply list (read-delimited-list ")" rdr true)))
+
+(def read-comment skip-line)

 (defn read-vector
   [rdr _]
@@ -204,12 +211,8 @@
   [rdr _]
   (let [l (read-delimited-list "}" rdr true)]
     (when (odd? (count l))
-      (throw "Map literal must contain an even number of forms"))
+      (reader-error rdr "Map literal must contain an even number of forms"))
     (apply hash-map l)))
-
-(defn read-set
-  [rdr _]
-  (set (read-delimited-list "}" rdr true)))

 (defn read-number
   [reader initch]
@@ -218,7 +221,8 @@
     (if (or (nil? ch) (whitespace? ch) (contains? macros ch))
       (do
         (unread reader ch)
-        (match-number (. buffer (toString))))
+        (or (match-number (. buffer (toString)))
+            (reader-error reader "Invalid number format [" s "]")))
       (recur (do (.append buffer ch) buffer) (read-char reader)))))

 (defn read-string
@@ -226,7 +230,7 @@
   (loop [buffer (gstring/StringBuffer.)
          ch (read-char reader)]
     (cond
-     (nil? ch) (throw "EOF while reading string")
+     (nil? ch) (reader-error reader "EOF while reading string")
      (= "\\" ch) (recur (escape-char buffer reader) (read-char reader))
      (= \" ch) (. buffer (toString))
      :default (recur (do (.append buffer ch) buffer) (read-char reader)))))
@@ -260,15 +264,33 @@
   (fn [rdr _]
     (list sym (read rdr true nil true))))

+(defn throwing-reader
+  [msg]
+  (fn [rdr _]
+    (reader-error rdr msg)))
+
 (defn read-meta
   [rdr _]
   (let [m (desugar-meta (read rdr true nil true))]
     (when-not (map? m)
-      (throw "Metadata must be Symbol,Keyword,String or Map"))
+      (reader-error rdr "Metadata must be Symbol,Keyword,String or Map"))
     (let [o (read rdr true nil true)]
       (if (satisfies? IWithMeta o)
         (with-meta o (merge (meta o) m))
-        (throw "Metadata can only be applied to IWithMetas")))))
+        (reader-error rdr "Metadata can only be applied to IWithMetas")))))
+
+(defn read-set
+  [rdr _]
+  (set (read-delimited-list "}" rdr true)))
+
+(defn read-regex
+  [rdr ch]
+  (-> (read-string rdr ch) re-pattern))
+
+(defn read-discard
+  [rdr _]
+  (read rdr true nil true)
+  rdr)

 (def macros
      { \" read-string
@@ -290,18 +312,28 @@
        \# read-dispatch
        })

+;; omitted by design: var reader, eval reader
 (def dispatch-macros
-  {"{" read-set})
+  {"{" read-set
+   "<" (throwing-reader "Unreadable form")
+   "\"" read-regex
+   "!" read-comment
+   "_" read-discard})

 (defn read
   "Reads the first object from a PushbackReader. Returns the object read.
-Returns sentinel if the reader did not contain any forms."
+   If EOF, throws if eof-is-error is true. Otherwise returns sentinel."
   [reader eof-is-error sentinel is-recursive]
   (let [ch (read-char reader)]
     (cond
-     (nil? ch) sentinel
+     (nil? ch) (if eof-is-error (reader-error reader "EOF") sentinel)
      (whitespace? ch) (recur reader eof-is-error sentinel is-recursive)
-     (comment-prefix? ch) (recur (skip-line reader) eof-is-error sentinel is-recursive)
-     (macros ch) ((macros ch) reader ch)
-     (number-literal? reader ch) (read-number reader ch)
-     :default (read-symbol reader ch))))+     (comment-prefix? ch) (recur (read-comment reader ch) eof-is-error sentinel is-recursive)
+     :else (let [res
+                 (cond
+                  (macros ch) ((macros ch) reader ch)
+                  (number-literal? reader ch) (read-number reader ch)
+                  :else (read-symbol reader ch))]
+     (if (= res reader)
+       (recur reader eof-is-error sentinel is-recursive)
+       res)))))


Remove stray space

Remove stray space

--- src/cljs/fatlip/core.cljs
+++ src/cljs/fatlip/core.cljs
@@ -62,7 +62,7 @@
   "R nodes are created to assist in drawing the graph, when an edge skips over a layer.
   In that case, the r node is placed in the intervening layer, and an edge is created
   from last-node to r node"
-  (let [r-layer-id (inc (:layer-id last-node ))
+  (let [r-layer-id (inc (:layer-id last-node))
         r-node (make-node graph r-layer-id {:characters characters})
         g (-> graph
               (update-in [:layers r-layer-id :nodes] conj r-node)


Moar.

Moar.

--- src/clojurecraft/core.clj
+++ src/clojurecraft/core.clj
@@ -35,6 +35,10 @@
   0x1B :stanceupdate
   0x1C :entityvelocity
   0x1D :entitydestroy
+  0x1E :entity
+  0x1F :entityrelativemove
+  0x20 :entitylook
+  0x21 :entitylookandrelativemove
 })
 (def packet-ids (apply assoc {} (mapcat reverse packet-types)))

@@ -496,6 +500,32 @@
   (-> {}
     (assoc :eid (-read-int conn))))

+(defn read-packet-entity [conn]
+  (-> {}
+    (assoc :eid (-read-int conn))))
+
+(defn read-packet-entityrelativemove [conn]
+  (-> {}
+    (assoc :eid (-read-int conn))
+    (assoc :dx (-read-byte conn))
+    (assoc :dy (-read-byte conn))
+    (assoc :dz (-read-byte conn))))
+
+(defn read-packet-entitylook [conn]
+  (-> {}
+    (assoc :eid (-read-int conn))
+    (assoc :yaw (-read-byte conn))
+    (assoc :pitch (-read-byte conn))))
+
+(defn read-packet-entitylookandrelativemove [conn]
+  (-> {}
+    (assoc :eid (-read-int conn))
+    (assoc :dx (-read-byte conn))
+    (assoc :dy (-read-byte conn))
+    (assoc :dz (-read-byte conn))
+    (assoc :yaw (-read-byte conn))
+    (assoc :pitch (-read-byte conn))))
+

 ; Reading Wrappers -----------------------------------------------------------------
 (defn read-packet [conn packet-id]
@@ -504,32 +534,37 @@
     (println "\n----->")
     (println
       (cond
-        (= packet-type :keepalive)            (read-packet-keepalive conn)
-        (= packet-type :handshake)            (read-packet-handshake conn)
-        (= packet-type :login)                (read-packet-login conn)
-        (= packet-type :chat)                 (read-packet-chat conn)
-        (= packet-type :timeupdate)           (read-packet-timeupdate conn)
-        (= packet-type :equipment)            (read-packet-equipment conn)
-        (= packet-type :spawnposition)        (read-packet-spawnposition conn)
-        (= packet-type :useentity)            (read-packet-useentity conn)
-        (= packet-type :updatehealth)         (read-packet-updatehealth conn)
-        (= packet-type :respawn)              (read-packet-respawn conn)
-        (= packet-type :playerpositionlook)   (read-packet-playerpositionlook conn)
-        (= packet-type :playerdigging)        (read-packet-playerdigging conn)
-        (= packet-type :playerblockplacement) (read-packet-playerblockplacement conn)
-        (= packet-type :holdingchange)        (read-packet-holdingchange conn)
-        (= packet-type :usebed)               (read-packet-usebed conn)
-        (= packet-type :animate)              (read-packet-animate conn)
-        (= packet-type :entityaction)         (read-packet-entityaction conn)
-        (= packet-type :namedentityspawn)     (read-packet-namedentityspawn conn)
-        (= packet-type :pickupspawn)          (read-packet-pickupspawn conn)
-        (= packet-type :collectitem)          (read-packet-collectitem conn)
-        (= packet-type :addobjectvehicle)     (read-packet-addobjectvehicle conn)
-        (= packet-type :mobspawn)             (read-packet-mobspawn conn)
-        (= packet-type :entitypainting)       (read-packet-entitypainting conn)
-        (= packet-type :stanceupdate)         (read-packet-stanceupdate conn)
-        (= packet-type :entityvelocity)       (read-packet-entityvelocity conn)
-        (= packet-type :entitydestroy)        (read-packet-entitydestroy conn)
+        (= packet-type :keepalive)                 (read-packet-keepalive conn)
+        (= packet-type :handshake)                 (read-packet-handshake conn)
+        (= packet-type :login)                     (read-packet-login conn)
+        (= packet-type :chat)                      (read-packet-chat conn)
+        (= packet-type :timeupdate)                (read-packet-timeupdate conn)
+        (= packet-type :equipment)                 (read-packet-equipment conn)
+        (= packet-type :spawnposition)             (read-packet-spawnposition conn)
+        (= packet-type :useentity)                 (read-packet-useentity conn)
+        (= packet-type :updatehealth)              (read-packet-updatehealth conn)
+        (= packet-type :respawn)                   (read-packet-respawn conn)
+        (= packet-type :playerpositionlook)        (read-packet-playerpositionlook conn)
+        (= packet-type :playerdigging)             (read-packet-playerdigging conn)
+        (= packet-type :playerblockplacement)      (read-packet-playerblockplacement conn)
+        (= packet-type :holdingchange)             (read-packet-holdingchange conn)
+        (= packet-type :usebed)                    (read-packet-usebed conn)
+        (= packet-type :animate)                   (read-packet-animate conn)
+        (= packet-type :entityaction)              (read-packet-entityaction conn)
+        (= packet-type :namedentityspawn)          (read-packet-namedentityspawn conn)
+        (= packet-type :pickupspawn)               (read-packet-pickupspawn conn)
+        (= packet-type :collectitem)               (read-packet-collectitem conn)
+        (= packet-type :addobjectvehicle)          (read-packet-addobjectvehicle conn)
+        (= packet-type :mobspawn)                  (read-packet-mobspawn conn)
+        (= packet-type :entitypainting)            (read-packet-entitypainting conn)
+        (= packet-type :stanceupdate)              (read-packet-stanceupdate conn)
+        (= packet-type :entityvelocity)            (read-packet-entityvelocity conn)
+        (= packet-type :entitydestroy)             (read-packet-entitydestroy conn)
+        (= packet-type :entity)                    (read-packet-entity conn)
+        (= packet-type :entityrelativemove)        (read-packet-entityrelativemove conn)
+        (= packet-type :entitylook)                (read-packet-entitylook conn)
+        (= packet-type :entitylookandrelativemove) (read-packet-entitylookandrelativemove conn)
+
         :else (str "UNKNOWN PACKET TYPE: " packet-id)
         ))
     (println "\n\n\n")))


Convert to UNIX style line endings

Convert to UNIX style line endings

--- src/clj/genartlib/curves.clj
+++ src/clj/genartlib/curves.clj
@@ -1,42 +1,42 @@
-(ns genartlib.curves
-  (:use [genartlib.algebra :only [interpolate]]))
-
-(defn- single-chaikin-step [points tightness]
-  (loop [points points
-         new-points [(first points)]]
-    (if (<= (count points) 1)
-      (vec (concat new-points [(last points)]))
-      (let [[start-x start-y] (first points)
-            [end-x end-y] (second points)
-            q-x (interpolate start-x end-x (+ 0.0 tightness))
-            q-y (interpolate start-y end-y (+ 0.0 tightness))
-            r-x (interpolate start-x end-x (- 1.0 tightness))
-            r-y (interpolate start-y end-y (- 1.0 tightness))]
-        (recur (rest points) (concat new-points [[q-x q-y] [r-x r-y]]))))))
-
-(defn chaikin-curve
-
-  "Forms a Chaikin curve from a seq of points, returning a new
-   seq of points.
-
-   The tightness parameter controls how sharp the corners will be,
-   and should be a value between 0.0 and 0.5.  A value of 0.0 retains
-   full sharpness, and 0.5 creates maximum smoothness.
-
-   The depth parameter controls how many recursive steps will occur.
-   The more steps, the smoother the curve is (assuming tightness is
-   greater than zero). Suggested values are between 1 and 8, with a
-   good default being 4.
-
-   When points form a closed polygon, it's recommended that the start
-   point be repeated at the end of points to avoid a gap."
-
-  ([points] (chaikin-curve [points 4 0.25]))
-  ([points depth] (chaikin-curve [points depth 0.25]))
-
-  ([points depth tightness]
-    (loop [depth depth
-           points points]
-      (if (zero? depth)
-        points
-        (recur (dec depth) (single-chaikin-step points tightness))))))
+(ns genartlib.curves
+  (:use [genartlib.algebra :only [interpolate]]))
+
+(defn- single-chaikin-step [points tightness]
+  (loop [points points
+         new-points [(first points)]]
+    (if (<= (count points) 1)
+      (vec (concat new-points [(last points)]))
+      (let [[start-x start-y] (first points)
+            [end-x end-y] (second points)
+            q-x (interpolate start-x end-x (+ 0.0 tightness))
+            q-y (interpolate start-y end-y (+ 0.0 tightness))
+            r-x (interpolate start-x end-x (- 1.0 tightness))
+            r-y (interpolate start-y end-y (- 1.0 tightness))]
+        (recur (rest points) (concat new-points [[q-x q-y] [r-x r-y]]))))))
+
+(defn chaikin-curve
+
+  "Forms a Chaikin curve from a seq of points, returning a new
+   seq of points.
+
+   The tightness parameter controls how sharp the corners will be,
+   and should be a value between 0.0 and 0.5.  A value of 0.0 retains
+   full sharpness, and 0.5 creates maximum smoothness.
+
+   The depth parameter controls how many recursive steps will occur.
+   The more steps, the smoother the curve is (assuming tightness is
+   greater than zero). Suggested values are between 1 and 8, with a
+   good default being 4.
+
+   When points form a closed polygon, it's recommended that the start
+   point be repeated at the end of points to avoid a gap."
+
+  ([points] (chaikin-curve [points 4 0.25]))
+  ([points depth] (chaikin-curve [points depth 0.25]))
+
+  ([points depth tightness]
+    (loop [depth depth
+           points points]
+      (if (zero? depth)
+        points
+        (recur (dec depth) (single-chaikin-step points tightness))))))


remove crazy logs in beeminder

remove crazy logs in beeminder

--- src/clj/tictag/beeminder.clj
+++ src/clj/tictag/beeminder.clj
@@ -74,7 +74,6 @@
                    :query-params {:auth_token auth-token}})))

 (defn days-matching-tag [tags rows]
-  (timbre/tracef "Matching tags %s, rows %s" tags rows)
   (->> rows
        (filter #(match? tags (:tags %)))
        (map :local-day)
@@ -86,7 +85,6 @@
     (when-let [goals (seq (db/get-goals db (:beeminder user)))]
       (timbre/tracef "goals are %s, getting rows" goals)
       (let [rows (db/get-pings-by-user (:db db) user)]
-        (timbre/tracef "Rows: %s" rows)
         (doseq [{:keys [goal/name goal/tags]} goals]
           (timbre/debugf "Syncing goal: %s with tags %s" name tags)
           (let [{:keys [username token]} (:beeminder user)


simplify ai

simplify ai

--- src/cljs/triboard/ai/ai.cljs
+++ src/cljs/triboard/ai/ai.cljs
@@ -30,10 +30,10 @@
     ))

 (defn- worst-possible-score-from
-  [{:keys [player other-players] :as ai} game-state]
+  [{:keys [player other-players] :as ai} moves]
   (transduce
     (comp
-      (mapcat #(get (:moves game-state) %))
+      (mapcat #(get moves %))
       (map #(score-move ai %))
       (map #(get % player)))
     min
@@ -43,7 +43,8 @@
   [ai game [coord converted :as move]]
   (let [new-game (game/play-move game coord)
         move-diff (get (score-move ai move) (:player ai))
-        next-diff (worst-possible-score-from ai (game/current-state new-game))]
+        new-moves (:moves (game/current-state new-game))
+        next-diff (worst-possible-score-from ai new-moves)]
     (+ move-diff next-diff)))

 (defn- max-by


improve pileup performance

improve pileup performance

--- src/clojure/cljam/pileup.clj
+++ src/clojure/cljam/pileup.clj
@@ -2,23 +2,28 @@
   (:require (cljam [cigar :as cgr]
                    [bam :as bam])))

-(def ^:private window-width 500) ;; TODO: estiamte from actual data
-(def ^:private step 100) ;; TODO: estiamte from actual data
-(def ^:private center 50) ;; TODO: estiamte from actual data
+(def ^:private window-width 1250) ;; TODO: estiamte from actual data
+(def ^:private step 2000) ;; TODO: estiamte from actual data
+(def ^:private center (int (/ step 2))) ;; TODO: estiamte from actual data

-(defn- count-for-pos
+(defn- count-for-alignment
+  [^clojure.lang.PersistentHashMap aln
+   ^String rname
+   ^clojure.lang.LazySeq positions]
+  (if (= rname (:rname aln))
+    (let [left (:pos aln)
+          right (+ (:pos aln) (cgr/count-ref (:cigar aln)))]
+      (map (fn [p] (if (and (>= p left)
+                            (<= p right)) 1 0)) positions))
+    (take (count positions) (repeat 0))))
+
+(defn- count-for-positions
   "Returns a histogram value of the specified position."
-  [alns ^String rname ^Long pos]
-  (loop [alns2 alns
-         val 0]
-    (let [[aln & rst] alns2]
-      (if (nil? aln)
-        val
-        (if (and (= rname (:rname aln))
-                 (>= pos (:pos aln))
-                 (<= pos (+ (:pos aln) (cgr/count-ref (:cigar aln)))))
-          (recur rst (inc val))
-          (recur rst val))))))
+  [^clojure.lang.LazySeq alns
+   ^String rname positions]
+  (if (pos? (count alns))
+    (apply map + (map #(count-for-alignment % rname positions) alns))
+    (take (count positions) (repeat 0))))

 (defn rpositions
   ([^Long start ^Long end]
@@ -48,15 +53,15 @@
            refs)))

 (defn- pileup*
-  ([rdr rname rlength start end]
+  ([rdr ^String rname ^Long rlength ^Long start ^Long end]
      (flatten
       (let [parts (partition-all step (rpositions start end))]
         (map (fn [positions]
                (let [^Long pos (if (= (count positions) step)
                                  (nth positions center)
                                  (nth positions (quot (count positions) 2)))
-                     alns (read-alignments rdr rname rlength pos)]
-                 (map #(count-for-pos alns rname %) positions)))
+                     ^clojure.lang.LazySeq alns (read-alignments rdr rname rlength pos)]
+                 (count-for-positions alns rname positions)))
              parts)))))

 (defn pileup


Backup and restore are their own commands

--- src/com/okl/tokenmgr/cli.clj
+++ src/com/okl/tokenmgr/cli.clj
@@ -96,10 +96,13 @@
        "with values\n\n"
        "           load path_to_csv app -- loads in a new csv into a specified "
        "application\n\n"
-       "           export app path_to_csv -- exports the entire repository into"
+       "           export app path_to_csv -- exports the an application into"
        "a csv file\n\n"
-       "           import app path_to_csv -- loads the entire repository from a"
-       " csv file"))
+       "           import app path_to_csv -- loads the an application from a"
+       " csv file\n\n"
+       "           backup path_to_json -- exports the everything into json\n\n"
+       "           restore path_to_json -- restores from backup json file"))
+

 (defn- usage [parsed-opts]
   (if (:errors parsed-opts)
@@ -209,18 +212,17 @@

 (defn- do-import [parsed-opts]
   (let [parsed-args (:arguments parsed-opts)]
-    (if (= (count parsed-args) 2)
-      nil
-      (import-single-app parsed-opts)))
-  0)
+    (if (= (count parsed-args) 3)
+      (import-single-app parsed-opts)
+      1)))

 (defn- do-export [parsed-opts]
   (let [parsed-args (:arguments parsed-opts)]
-    (if (= (count parsed-args) 2)
-      (export-all-apps (second parsed-args))
+    (if (= (count parsed-args) 3)
       (export-single-app (second parsed-args) (second (rest parsed-args))
-                         (:delimiter (:options parsed-opts)))))
-  0)
+                         (:delimiter (:options parsed-opts)))
+      1)))
+

 (defn- do-backup [parsed-opts]
   (let [parsed-args (:arguments parsed-opts)]


Update alfa.clj

Update alfa.clj

--- practice/alfa.clj
+++ practice/alfa.clj
@@ -1,6 +1,11 @@
 (ns euler.practice.alfa)

-;;take''
+;;take
+(defn take' [a b]
+  (if (= (count b) a)
+    b
+    (take' a (butlast b))))
+
 (defn take'' [a b]
   (loop [la (dec a)
          lb '()]


Use a threadpool in the tree worker

Use a threadpool in the tree worker

--- src/cyanite_remover/core.clj
+++ src/cyanite_remover/core.clj
@@ -638,7 +638,6 @@
           (println title)
           (prog/init paths-count))
         (dorun (cp/upmap tpool walk (t-get tree-impl [])))
-        (walk [])
         (when-not @clog/print-log?
           (prog/done))
         (let [empty-paths (tp-get-data processor)]


Refactor filter function

Refactor filter function

--- src/day8/re_frame/trace.cljs
+++ src/day8/re_frame/trace.cljs
@@ -136,27 +136,13 @@
                                     (reset! val ""))
                                nil)}])))

-(defn construct-string [trace]
-  (clojure.string/lower-case (str (:operation trace) " " (:op-type trace))))
-
-(defn has-word [traces q]
-  (filter #(clojure.string/includes? (construct-string %) (:query q)) traces))
-
-(defn has-duration [traces q]
-  (filter #(< (js/parseInt (:query q)) (:duration %)) traces))
-
-(defn filter-by-word [traces queries]
-  (mapcat (partial has-word traces) queries))
-
-(defn filter-by-duration [traces queries]
-  (mapcat (partial has-duration traces) queries))
-
-(defn run-all-filters [traces queries]
-  (let [[word-queries duration-queries] (vals (group-by #(= (:filter-type %) "contains") queries))
-        traces-filtered-by-words      (filter-by-word traces word-queries)]
-    (if duration-queries
-      (filter-by-duration traces-filtered-by-words duration-queries)
-      traces-filtered-by-words)))
+(defn query->fn [query]
+  (if (= "contains" (:filter-type query))
+    (fn [trace]
+      (str/includes? (str/lower-case (str (:operation trace) " " (:op-type trace)))
+                    (:query query)))
+    (fn [trace]
+      (< (js/parseInt (:query query)) (:duration trace)))))

 (defn render-traces [showing-traces]
   (doall
@@ -196,10 +182,13 @@
     (fn []
       (let [showing-traces       (if (= @filter-items [])
                                    @traces
-                                   (run-all-filters @traces @filter-items))
+                                   (filter (apply every-pred (map query->fn @filter-items)) @traces))
             save-query           (fn [_]
+                                   (println @filter-type @filter-input)
                                    (swap! filter-items conj {:id (random-uuid)
-                                                             :query (str/lower-case @filter-input)
+                                                             :query (if (= @filter-type "contains")
+                                                                      (str/lower-case @filter-input)
+                                                                      (js/parseInt @filter-input))
                                                              :filter-type @filter-type}))]
         [:div
          [:div.filter-control {:style {:margin-bottom 20}}


Changes phrase-id to phrase in model.clj. Implements get-training-data fully.

--- src/cadence/model.clj
+++ src/cadence/model.clj
@@ -2,6 +2,7 @@
   (:refer-clojure :exclude [identity])
   (:require [monger.core :as mg]
             [monger.collection :as mc]
+            [monger.query :as mq]
             [noir.validation :as vali]
             [cadence.pattern-recognition :as patrec]
             [noir.options :as options]
@@ -123,24 +124,27 @@
 (defn get-training-data
   "Returns cadences to be used to train a classifier as a tuple of bad cadences
   and good cadences."
-  [user-id phrase-id]
-  (let [find-cadences (fn [by-user _]
-                        (mc/find-maps
-                          "cadences"
-                          {:phrase_id phrase-id
-                           :user_id (if (by-user)
-                                      user-id
-                                      {$ne user-id})
-                           :random_point {"$near" (rand)}}))]
-    [(find-cadences false 50) (find-cadences true 10)]))
+  [user-id phrase]
+  (let [find-cadences (fn [by-user l]
+                        (mq/with-collection "cadences"
+                          (mq/find {:phrase phrase
+                                 :user_id (if by-user
+                                            user-id
+                                            {$ne user-id})
+                                 :random_point {"$near" [(rand) 0]}})
+                          (mq/fields [:timeline :phrase])
+                          (mq/limit l)
+                          (mq/snapshot)))]
+    [(find-cadences false 200) (find-cadences true 50)]))

 (defn store-classifier
   "Stores the given classifier with the given user/phrase pair."
-  [user-id phrase-id classifier]
+  [user-id phrase classifier]
   ; TODO Implement
   (mc/insert "classifiers" {:user_id user-id
-                            :phrase_id phrase-id
+                            :phrase phrase
                             :classifier classifier
+                            :type :svm
                             ;; Initialize some counts for statistics
                             :attempts 0
                             :authentications 0
@@ -150,12 +154,11 @@

 (defn get-classifier
   "Gets the classifier needed for the specified user/phrase."
-  [user-id phrase-id]
+  [user-id phrase]
   (if-let [result (mc/find-one-as-map "classifiers"
-                                      {:user_id user-id :phrase_id phrase-id})]
+                                      {:user_id user-id :phrase phrase})]
     result
-    ; TODO Correct call to make-classifier
-    (let [dataset (apply patrec/create-dataset (get-training-data user-id phrase-id))
+    (let [dataset (patrec/create-dataset (get-training-data user-id phrase))
           classifier (patrec/gen-phrase-classifier dataset)]
-      (store-classifier user-id phrase-id classifier)
-      classifier)))
+      ;(store-classifier user-id phrase classifier)
+      {:classifier classifier :dataset dataset})))


Escape the % in the url for LaTeX

Escape the % in the url for LaTeX

--- src/catalog/latex.clj
+++ src/catalog/latex.clj
@@ -96,7 +96,7 @@
   "Return an url given a `record-id`"
   [record-id]
   (let [api-key "c97386a2-914a-40c2-bd8d-df4c273175e6"]
-    (format "http://online.sbs.ch/iguana/www.main.cls?v=%s&sUrl=search%%23RecordId=%s"
+    (format "http://online.sbs.ch/iguana/www.main.cls?v=%s&sUrl=search\\%%23RecordId=%s"
             api-key
             (string/replace record-id "/" "."))))


Playing around with String -> DOM stuff

Playing around with String -> DOM stuff

--- src/discuss/integration.cljs
+++ src/discuss/integration.cljs
@@ -1,10 +1,14 @@
 (ns discuss.integration
   "Listen for mouse clicks, get references and highlight them in the article."
   (:require-macros [cljs.core.async.macros :refer [go]])
-  (:require [goog.events :as events]
-            [cljs.core.async :refer [put! chan <!]]
-            [discuss.lib :as lib]
-            [discuss.extensions]))
+  (:require
+    [goog.dom :as gdom]
+    [goog.events :as events]
+    [cljs.core.async :refer [put! chan <!]]
+    [clojure.string :as string]
+    [discuss.lib :as lib]
+    [discuss.extensions])
+  (:import [goog.dom]))

 (defn get-selection
   "Return the stored selection of the user."
@@ -36,8 +40,24 @@
         (save-selected-text))))

 ;;; Integrate references and highlight them in the article
+;; So I have to iterate through all DOM elements...?
+;; http://stackoverflow.com/questions/4256339/javascript-how-to-loop-through-all-dom-elements-on-a-page
+(defn convert-reference [ref]
+  (let [body js/document.body.innerHTML
+        ;tspan (str "" ref "")
+        span (gdom/createElement "span")
+        tspan "foo"
+        regex-ref (re-pattern ref)
+        nbody (string/replace body regex-ref (.-innerHTML span))]
+    ;(gdom/setTextContent span ref)
+    (println "Convert...")
+    ;(set! (.. js/document -body -innerHTML) nbody)
+
+    ))
+
 (defn process-references
   "Receives references through the API and prepares them for the next steps."
   [refs]
   (println "Received" (count refs) "references")
-  (println refs))+  (println refs)
+  (convert-reference "Debug"))


Correct log message

Correct log message

--- src/exploud/messages/asg.clj
+++ src/exploud/messages/asg.clj
@@ -369,8 +369,9 @@
             (doseq [scheduled-action scheduled-actions]
               (let [[action-name description] scheduled-action
                     {:keys [cron desired-capacity max min]} description
-                    full-name (str/join "-" [auto-scaling-group-name (name action-name)])]
-                (log/write (format "Adding scheduled action '%s'." action-name))
+                    nice-action-name (name action-name)
+                    full-name (str/join "-" [auto-scaling-group-name nice-action-name])]
+                (log/write (format "Adding scheduled action '%s'." nice-action-name))
                 (auto/put-scheduled-update-group-action (aws/config environment region)
                                                         :auto-scaling-group-name auto-scaling-group-name
                                                         :desired-capacity desired-capacity


Use gensym instead of custom hack to guarantee uniqueness of watcher keys.

--- src/cljs/c2/core.cljs
+++ src/cljs/c2/core.cljs
@@ -37,10 +37,6 @@
     (if (undefined? d) nil d)))

-;;Used to generate unique IDs for auto-unify atom watchers
-(def ^:private auto-unify-id (atom 0))
-
-
 (defmulti unify!
   "Given container, data, and mapping-fn, calls (mapping datum idx) for each datum and appends resulting elements to container.
 Automatically updates elements mapped to data according to key-fn (defaults to index) and removes elements that don't match.
@@ -65,7 +61,7 @@
   [container !data & args]
   (let [redraw! #(apply unify! container % args)]
     ;;add watcher to redraw whenever atom is update
-    (add-watch !data (keyword (str "auto-unify" (swap! auto-unify-id inc)))
+    (add-watch !data (keyword (gensym "auto-unify!-"))
                (fn [_ _ old new] (when (not= old new)
                                   (redraw! new))))
     ;;initial draw


Problem added: Split a sequence

Problem added: Split a sequence

--- src/foreclojure/data_set.clj
+++ src/foreclojure/data_set.clj
@@ -490,4 +490,15 @@
             :description "The some function takes a predicate function and a collection.  It returns the first logical true value of (predicate x) where x is an item in the collection."
             :tags ["easy"]
             :tests ["(= __ (some #{2 7 6} [5 6 7 8]))"
-		    "(= __ (some #(when (even? %) %) [5 6 7 8]))"]})))+		    "(= __ (some #(when (even? %) %) [5 6 7 8]))"]})
+
+       (insert! :problems
+           {:_id 49
+            :title "Split a sequence"
+            :times-solved 0
+            :restricted ["split-at"]
+            :description "Write a function which will split a sequence into two parts."
+            :tags ["easy" "seqs" "core-functions"]
+            :tests ["(= (__ 3 [1 2 3 4 5 6]) [[1 2 3] [4 5 6]])"
+		    "(= (__ 1 [:a :b :c :d]) [[:a] [:b :c :d]])"
+                    "(= (__ 2 [[1 2] [3 4] [5 6]]) [[[1 2] [3 4]] [[5 6]]])"]})))


Make the Twitter link supply a default tweet content

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -2,10 +2,12 @@
   (:use [foreclojure.utils]
         [clojail core testers]
 	[somnium.congomongo]
-        [hiccup form-helpers])
+        [hiccup form-helpers]
+        [amalloy.utils.debug :only [?]])
   (:require [sandbar.stateful-session :as session]
             [clojure.string :as s]
-            [clj-github.gists :as gist]))
+            [clj-github.gists :as gist])
+  (:import (java.net URLEncoder)))

 (defn get-solved [user]
   (set
@@ -40,6 +42,14 @@
            (str "https://gist.github.com/"))
       (catch Throwable _ nil))))

+(defn tweet-link [id gist-url & [link-text]]
+  (let [status-msg (str "Check out how I solved http://4clojure.com/problem/"
+                        id " - " gist-url " #clojure #4clojure")]
+    (str ""
+         (or link-text "Twitter")
+         "")))
+
 (defn mark-completed [id code & [user]]
   (let [user (or user (session/session-get :user))
         gist-url (gist! user id code)
@@ -47,7 +57,7 @@
                     (str "
"
                          "Share this "
                          "solution"
-                         " on Twitter!"
+                         " on " (tweet-link id gist-url) "!"
                          "
")
                     (str "
Failed to create gist of "
                          "your solution
"))


Tidy up a little with destructuring

Tidy up a little with destructuring

--- src/foreclojure/problems.clj
+++ src/foreclojure/problems.clj
@@ -52,10 +52,8 @@

 (defn run-code [id raw-code]
   (let [code (.trim raw-code)
-	p (get-problem id)
-        tests (:tests p)
-        func-name (:function-name p)
-        sb-tester (get-tester (:restricted p))]
+	{:keys [tests restricted]} (get-problem id)
+        sb-tester (get-tester restricted)]
     (if (empty? code)
       (do
 	(session/flash-put! :code code)


Clean up

Clean up

--- src/i18n_word_guess/game.clj
+++ src/i18n_word_guess/game.clj
@@ -44,10 +44,10 @@
                   (reveal :front)
                   (reveal :back))]
     [{:timestamp (java.util.Date.)
-      :word word
-      :mask mask
-      :code (encode mask word)
-      :status :start}]))
+      :word      word
+      :mask      mask
+      :code      (encode mask word)
+      :status    :start}]))

 (defn step
   ([game new-guess]
@@ -55,24 +55,24 @@
   ([game new-guess reveal-side]
    (let [{:keys [word mask code status] :as prev-step} (last game)]
      (conj game
-           (merge {:timestamp (java.util.Date.)
-                   :word word
-                   :guess new-guess}
+           (merge {:word      word
+                   :guess     new-guess
+                   :timestamp (java.util.Date.)}
                   (cond
-                   (= new-guess word) {:mask (transparent-mask word)
-                                       :code word
-                                       :status (if (= status :win) :over :win)}
-                   (some #{new-guess} (map :guess game)) {:mask mask
-                                                          :code code
-                                                          :status :repeat}
+                   (= new-guess word) {:status (if (= status :win) :over :win)
+                                       :mask   (transparent-mask word)
+                                       :code   word}
+                   (some #{new-guess} (map :guess game)) {:status :repeat
+                                                          :mask   mask
+                                                          :code   code}
                    (check-guess code new-guess) (let [new-mask (reveal reveal-side mask)
                                                       new-mask (if (transparent? new-mask) mask new-mask)]
-                                                  {:mask new-mask
-                                                   :code (encode new-mask word)
-                                                   :status :ok})
-                   :else {:mask mask
-                          :code code
-                          :status :no-match}))))))
+                                                  {:status :ok
+                                                   :mask   new-mask
+                                                   :code   (encode new-mask word)})
+                   :else {:status :no-match
+                          :mask   mask
+                          :code   code}))))))

 ;;-----------------------------------------------------------------------------
 ;; Hints


Un-hardcode

Un-hardcode

--- src/icecap/handlers/http.clj
+++ src/icecap/handlers/http.clj
@@ -9,6 +9,6 @@
   {:url URI}
   [step]
   (let [ch (chan)
-        req (request {:url "http://www.rackspace.com"})]
+        req (request step)]
     (do (connect req ch)
         ch)))


Revamp the Doctopus NS docstring

Revamp the Doctopus NS docstring

--- src/doctopus/doctopus.clj
+++ src/doctopus/doctopus.clj
@@ -1,19 +1,11 @@
 (ns doctopus.doctopus
-  "Maybe this is an awesome idea? Maybe this is a sub-good idea. We should
-talk about it either way. The idea is: start defining an Entity we can flesh out.
-  Pin properties to. Give more shape.
+  "A Doctopus represents the entire, wriggling, living creature that is your
+  documentation. A Doctopus is a singluar abstraction -- at time of writing, you
+  can only have one. A Doctopus contains all of the configuration necessary for your docs to make it to the web.

-  My idea is that a Doctopus represents a *group* of docs. Maybe a collection of
-  repos, or all the docs for a single company, or all the docs for a functional
-  team within a company. Each Doctopus will have a Head -- a centralized notion
-  of what it is and what it does -- and some number of Tentacles -- individual
-  sources of documentation orchestrated by the Head.
-
-  Subject to all kinds of change. For instance: right now I've only really got a
-  gut feeling that a Doctopus needs a Head; I'm not sure I could precisely
-  articulate just _why_ yet.
-
-  I think: Doctopus has several Heads, which each have many Tentacles. I think."
+  Each Doctopus will have one or more Heads, which represent a logical grouping
+  of docs, and some number of Tentacles -- individual sources of documentation
+  orchestrated by the Head. "
   (:require [doctopus.doctopus.head :as h]
             [doctopus.doctopus.tentacle :as t]
             [me.raynes.fs :as fs])


Add invisible background to paths.

Add invisible background to paths.

In order to make more easy to the
user select and move them.

--- frontend/src/uxbox/main/ui/shapes/path.cljs
+++ frontend/src/uxbox/main/ui/shapes/path.cljs
@@ -25,7 +25,9 @@
   (let [modifiers (mx/react (common/modifiers-ref id))
         selected (mx/react common/selected-ref)
         selected? (contains? selected id)
-        shape (assoc shape :modifiers modifiers)]
+        shape (assoc shape
+                     :modifiers modifiers
+                     :background? true)]
     (letfn [(on-mouse-down [event]
               (common/on-mouse-down event shape selected))
             (on-double-click [event]
@@ -61,14 +63,19 @@

 (mx/defc path-shape
   {:mixins [mx/static]}
-  [{:keys [id modifiers rotation] :as shape}]
+  [{:keys [id modifiers background?] :as shape}]
   (let [{:keys [resize displacement]} modifiers
         shape (cond-> shape
                 displacement (geom/transform displacement)
-                resize (geom/transform resize)
-                (pos? rotation) (geom/rotate-shape))
-
-        props {:id (str id)
-               :d (render-path shape)}
-        attrs (merge props (attrs/extract-style-attrs shape))]
-    [:path attrs]))
+                resize (geom/transform resize))
+        pdata (render-path shape)
+        attrs (merge {:id (str id) :d pdata}
+                     (attrs/extract-style-attrs shape))]
+    (if background?
+      [:g {}
+       [:path {:stroke "transparent"
+               :fill "transparent"
+               :stroke-width "20px"
+               :d pdata}]
+       [:path attrs]]
+      [:path attrs])))


Correct parameter order is critical to success of algorithm

--- modules/core/src/main/clojure/immutant/utilities.clj
+++ modules/core/src/main/clojure/immutant/utilities.clj
@@ -98,6 +98,6 @@
   `(loop [x# ~start]
      (let [result# (try
                     ~@body
-                    (catch Exception e# (if (> ~end x#) (throw e#))))]
+                    (catch Exception e# (if (> x# ~end) (throw e#))))]
        (or result# (do (Thread/sleep x#) (recur (* 2 x#)))))))


payload fix

payload fix

--- src/ipython_clojure/core.clj
+++ src/ipython_clojure/core.clj
@@ -130,7 +130,7 @@
                       {:status           "ok"
                        :execution_count  @execution-count
                        :user_variables   {}
-                       :payload          [{}]
+                       :payload          [{:source "edit"}]
                        :user_expressions {}}
                       parent-header
                       {:dependencies_met "True"


Code review: Combine if/let to if-let

Code review: Combine if/let to if-let

--- src/cower/handler.clj
+++ src/cower/handler.clj
@@ -35,12 +35,11 @@
           {:status 201}))

   (GET "/packages/:name" [name]
-       (let [url (wcar* (car/get name))]
-         (if url
-           {:status 200
-            :body (write-json
-                   (key-value-to-map [name url]))}
-           {:status 404})))
+       (if-let [url (wcar* (car/get name))]
+         {:status 200
+          :body (write-json
+                 (key-value-to-map [name url]))}
+         {:status 404}))

   (DELETE "/packages/:name" [name]
           (do


state action used not the body itself

state action used not the body itself

--- src/crawler/crawl.clj
+++ src/crawler/crawl.clj
@@ -523,7 +523,10 @@
        (utils/sayln :src-url (-> url-queue first :src-url))
        (utils/sayln :src-path (-> url-queue first :path))
        (let [url  (-> url-queue first :url)
-             body (utils/download-with-cookie url)]
+             body (utils/download-with-cookie url)
+
+             unaltered-state-action (try (extract body url {} [])
+                                         (catch Exception e nil))]

          (cond (or (empty? url-queue)
                    (stop? {:visited    (count visited)
@@ -564,9 +567,12 @@
                            (-> url-queue first :path)
                            leaf-paths)
                           (dec leaf-limit)
-                          (let [corpus-entry {url {:body      body
-                                                   :leaf?     true
-                                                   :src-xpath (-> url-queue first :path)}}]
+                          (let [corpus-entry {url
+                                              {:body      unaltered-state-action
+                                               :leaf?     true
+                                               :src-xpath (-> url-queue
+                                                              first
+                                                              :path)}}]
                             (merge corpus corpus-entry)))))

                :else
@@ -595,9 +601,12 @@
                           stop?
                           leaf-paths
                           leaf-limit
-                          (let [corpus-entry {url {:body      body
-                                                   :leaf?     false
-                                                   :src-xpath (-> url-queue first :path)}}]
+                          (let [corpus-entry {url
+                                              {:body      unaltered-state-action
+                                               :leaf?     false
+                                               :src-xpath (-> url-queue
+                                                              first
+                                                              :path)}}]
                             (merge corpus corpus-entry))))))))))


added src-url info

added src-url info

--- src/crawler/crawl.clj
+++ src/crawler/crawl.clj
@@ -570,6 +570,9 @@
                           (let [corpus-entry {url
                                               {:body      unaltered-state-action
                                                :leaf?     true
+                                               :src-url   (-> url-queue
+                                                              first
+                                                              :src-url)
                                                :src-xpath (-> url-queue
                                                               first
                                                               :path)}}]
@@ -604,6 +607,9 @@
                           (let [corpus-entry {url
                                               {:body      unaltered-state-action
                                                :leaf?     false
+                                               :src-url   (-> url-queue
+                                                              first
+                                                              :src-url)
                                                :src-xpath (-> url-queue
                                                               first
                                                               :path)}}]


more refactoring

more refactoring

--- src/etcd_clojure/core.clj
+++ src/etcd_clojure/core.clj
@@ -21,10 +21,10 @@
   (future (function-to-call @future-to-watch)))

 (defmacro http-perform
-  ([body base]
-     `(parse-string (:body (~body (str ~base)))))
-  ([body base path]
-     `(parse-string (:body (~body (str ~base ~path))))))
+  ([method base]
+     `(parse-string (:body (~method (str ~base)))))
+  ([method base path]
+     `(parse-string (:body (~method (str ~base ~path))))))

 (defn connect!
   ([etcd-server-host] (connect! etcd-server-host 4001 7001))
@@ -50,22 +50,22 @@
 (defn get
   "Gets a value"
   [key]
-  (clojure.core/get-in (parse-string (:body (client/get (str (base-url) "/keys/" key)))) ["node" "value"]))
+  (clojure.core/get-in (http-perform client/get (str (base-url) "/keys/" key)) ["node" "value"]))

 (defn delete
   "Deletes a value"
   [key]
-  (parse-string (:body (client/delete (str (base-url) "/keys/" key)))))
+  (http-perform client/delete (str (base-url) "/keys/" key)))

 (defn delete-dir
   "Deletes a dir"
   [key]
-  (clojure.core/get-in (parse-string (:body (client/delete (str (base-url) "/keys/" key "?dir=true")))) ["node" "key"]))
+  (clojure.core/get-in (http-perform client/delete (str (base-url) "/keys/" key "?dir=true")) ["node" "key"]))

 (defn delete-dir-recur
   "Deletes a directory recursively"
   [key]
-  (clojure.core/get-in (parse-string (:body (client/delete (str (base-url) "/keys/" key "?dir=true&recursive=true")))) ["node" "key"]))
+  (clojure.core/get-in (http-perform client/delete (str (base-url) "/keys/" key "?dir=true&recursive=true")) ["node" "key"]))

 (defn create-in-order
   "Creates in order"
@@ -84,7 +84,7 @@
   "Lists the content of a directory recursively and in order"
   [key]
   (let [url (str (base-url) "/keys/" key "?recursive=true&sorted=true")]
-    (map #(clojure.core/get % "value") (clojure.core/get-in (parse-string (:body (client/get url ))) ["node" "nodes"]))))
+    (map #(clojure.core/get % "value") (clojure.core/get-in (http-perform client/get url)  ["node" "nodes"]))))

 (defn create-dir
   "Creates a dir"
@@ -92,12 +92,12 @@
   (let [data {:value val :dir true}
         url (str (base-url) "/keys/" key)]
     (if ttl
-      (clojure.core/get-in (parse-string (:body (client/put url {:form-params (assoc data :ttl ttl)}))) ["node" "key"])
+      (clojure.core/get-in (parse-string (:body client/put url {:form-params (assoc data :ttl ttl)})) ["node" "key"])
       (clojure.core/get-in (parse-string (:body (client/put url {:form-params data}))) ["node" "key"]))))

 (defn watch
   [key callback]
-  (let [f (future (parse-string (:body (client/get (str (base-url) "/watch/" key)))))]
+  (let [f (future (http-perform client/get (str (base-url) "/watch/" key)))]
     (when-done f #(callback %)) f))

 (defn stats


Make redirects work right when user specifies new passwords wrong

--- src/foreclojure/login.clj
+++ src/foreclojure/login.clj
@@ -43,7 +43,7 @@
         [:tr
          [:td (submit-button "Reset now")]])]]))

-(def-page do-reset-password! [old-pwd new-pwd repeat-pwd]
+(defn do-reset-password! [old-pwd new-pwd repeat-pwd]
   (with-user [{:keys [user pwd]}]
     (let [encryptor (StrongPasswordEncryptor.)]
       (assuming [(= new-pwd repeat-pwd)
@@ -54,7 +54,8 @@
           (update! :users {:user user}
                    {:$set {:pwd new-pwd-hash}}
                    :upsert false)
-          [:div#reset-succeeded "Password for " user " reset successfully"])
+          (html-doc
+           [:div#reset-succeeded "Password for " user " reset successfully"]))
         (flash-error why "/login/reset")))))

 (defroutes login-routes


#99 do not always check class of print-pretty

--- src/cheshire/core.clj
+++ src/cheshire/core.clj
@@ -59,14 +59,15 @@
                                      factory/json-factory)
                     ^Writer sw)
          print-pretty (:pretty opt-map)]
-     (condp instance? print-pretty
-       Boolean
-         (.useDefaultPrettyPrinter generator)
-       clojure.lang.IPersistentMap
-         (.setPrettyPrinter generator (create-pretty-printer print-pretty))
-       PrettyPrinter
-         (.setPrettyPrinter generator print-pretty)
-       nil)
+     (when print-pretty
+       (condp instance? print-pretty
+         Boolean
+           (.useDefaultPrettyPrinter generator)
+         clojure.lang.IPersistentMap
+           (.setPrettyPrinter generator (create-pretty-printer print-pretty))
+         PrettyPrinter
+           (.setPrettyPrinter generator print-pretty)
+         nil))
      (when (:escape-non-ascii opt-map)
        (.enable generator JsonGenerator$Feature/ESCAPE_NON_ASCII))
      (gen/generate generator obj
@@ -90,14 +91,15 @@
                                      factory/json-factory)
                     ^Writer writer)
          print-pretty (:pretty opt-map)]
-     (condp instance? print-pretty
-       Boolean
-         (.useDefaultPrettyPrinter generator)
-       clojure.lang.IPersistentMap
-         (.setPrettyPrinter generator (create-pretty-printer print-pretty))
-       PrettyPrinter
-         (.setPrettyPrinter generator print-pretty)
-       nil)
+     (when print-pretty
+       (condp instance? print-pretty
+         Boolean
+       (.useDefaultPrettyPrinter generator)
+         clojure.lang.IPersistentMap
+       (.setPrettyPrinter generator (create-pretty-printer print-pretty))
+         PrettyPrinter
+       (.setPrettyPrinter generator print-pretty)
+         nil))
      (when (:escape-non-ascii opt-map)
        (.enable generator JsonGenerator$Feature/ESCAPE_NON_ASCII))
      (gen/generate generator obj (or (:date-format opt-map)


add a option to skip updating when resource location is not unique

--- src/leiningen/namespaces.clj
+++ src/leiningen/namespaces.clj
@@ -91,7 +91,8 @@
 (defn initial-question [namespace project]
   (str "* ==> The location of " namespace " on " (str/upper-case project)
        " could not be determined.\n"
-       "      Please choose one of options (a number):"))
+       "      Please choose one of options (a number):"
+       (str "\n         + -1 -> to skip updating " namespace)))

 (defn localtion-question-with
   ([ns project [first & rest]]
@@ -99,7 +100,7 @@
   ([question index first [ffirst rrest]]
    (if (nil? first)
      question
-     (recur (str question "\n         + " index " -> " first)
+     (recur (str question "\n         +  " index " -> " first)
             (inc index)
             ffirst
             rrest))))
@@ -107,20 +108,20 @@
 (defn ask-for-localtion
   ([namespace paths] (ask-for-localtion namespace "source project" paths))
   ([namespace project paths]
-   (nth paths
-        (-> namespace
-            (localtion-question-with project paths)
-            (u/ask-user (partial u/is-number (count paths)))
-            (read-string)))))
+   (-> namespace
+       (localtion-question-with project paths)
+       (u/ask-user (partial u/is-number (count paths)))
+       (read-string))))

 (defn ask-for-localtion-and-update! [name target-project existing-source-paths target-paths]
-  (update-files!
-   (if (= 1 (count existing-source-paths))
-     (first existing-source-paths)
-     (ask-for-localtion name existing-source-paths))
-   (if (= 1 (count target-paths))
-     (first target-paths)
-     (ask-for-localtion name target-project target-paths))))
+  (let [source-location (if (= 1 (count existing-source-paths))
+                          0 (ask-for-localtion name existing-source-paths))
+        target-location (if (= 1 (count target-paths))
+                          0 (ask-for-localtion name target-project target-paths))]
+    (if (and (>= source-location 0) (>= target-location 0))
+      (update-files!
+       (nth existing-source-paths source-location)
+       (nth target-paths target-location)))))

 (defn safe-update! [name target-project source-paths target-paths]
   (let [existing-source-paths (filter u/exists? source-paths)


fix for facedown cards having events hooked up

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -1477,7 +1477,8 @@
                            :previous-zone (:zone target))]
        (update! state side (update-in card [:hosted] #(conj % c)))
        (when-let [events (:events (card-def target))]
-         (register-events state side events c))
+         (when installed
+           (register-events state side events c)))
        (when (and installed (:recurring (card-def c)))
          (card-init state side c false))
        (when-let [events (:events (card-def target))]


Reverting the prompt preventing stuff

Reverting the prompt preventing stuff

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -262,12 +262,8 @@
 (defn show-prompt
   ([state side card msg choices f] (show-prompt state side card msg choices f nil))
   ([state side card msg choices f {:keys [priority prompt-type show-discard] :as args}]
-   (let [prompt (if (string? msg) msg (msg state side card nil))]
-     (when (and (or (:number choices) (#{:credit :counter} choices) (> (count choices) 0))
-                (or (nil? card)
-                    (empty? (->> (get-in @state [side :prompt])
-                                 (map #(vec [(get-in % [:card :cid]) (:msg %)]))
-                                 (filter #(and (not (nil? (:cid card))) (= % (vec [(:cid card) msg]))))))))
+  (let [prompt (if (string? msg) msg (msg state side card nil))]
+     (when (or (:number choices) (#{:credit :counter} choices) (> (count choices) 0))
        (swap! state update-in [side :prompt]
               (if priority
                 #(cons {:msg prompt :choices choices :effect f :card card


Namespace fix

Namespace fix

--- src/doi_time/data.clj
+++ src/doi_time/data.clj
@@ -54,7 +54,7 @@
         (let [response (client/get page-query {:as :json})
               items (-> response :body :message :items)]
           (doseq [item items]
-            (let [doi (:DOI item)
+            (let [the-doi (:DOI item)
                   ; list of date parts in CrossRef date format
                   issuedInput (-> item :issued :date-parts first)
                   ; CrossRef date native format
@@ -69,7 +69,7 @@
                   depositedInput (-> item :deposited :date-parts first)
                   deposited (apply crdate/crossref-date depositedInput)
                   depositedDate (coerce/to-sql-date (crdate/as-date deposited))]
-              (insert-doi d/doi issuedDate issuedString depositedDate)))))))
+              (insert-doi the-doi issuedDate issuedString depositedDate)))))))

 (defn get-resolutions
   "Get the first and last redirects or nil if it doesn't exist."


Use build-spend-msg

Use build-spend-msg

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -755,12 +755,12 @@

 (defn trash-resource [state side args]
   (let [trash-cost (max 0 (- 2 (or (get-in @state [:corp :trash-cost-bonus]) 0)))]
-    (when (pay state side nil :click 1 :credit trash-cost)
+    (when-let [cost-str (pay state side nil :click 1 :credit trash-cost)]
       (resolve-ability state side
                        {:prompt "Choose a resource to trash"
                         :choices {:req #(= (:type %) "Resource")}
                         :effect (effect (trash target)
-                                        (system-msg (str "spends [Click] and " trash-cost " [Credits] to trash "
+                                        (system-msg (str (build-spend-msg cost-str "trash")
                                                          (:title target))))} nil nil))))

 (defn trash-prevent [state side type n]