change `cljs.repl/repl*` so it destructures the same keys as `clojure.main/repl`

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -24,7 +24,8 @@
             [cljs.source-map :as sm])
   (:import [java.io File PushbackReader FileWriter]
            [java.net URL]
-           [javax.xml.bind DatatypeConverter]))
+           [javax.xml.bind DatatypeConverter]
+           [clojure.lang LineNumberingPushbackReader]))

 (def ^:dynamic *cljs-verbose* false)

@@ -526,10 +527,26 @@
       (doseq [file (comp/cljs-files-in src-dir)]
         (ana/analyze-file (str "file://" (.getAbsolutePath file)) opts)))))

+(defn repl-prompt []
+  (print (str "ClojureScript:" ana/*cljs-ns* "> ")))
+
+(defn repl-caught [e]
+  )
+
 (defn repl*
-  [repl-env opts]
-  (print "To quit, type: ")
-  (prn :cljs/quit)
+  [repl-env {:keys [init need-prompt prompt flush read eval print caught]
+             :or {init        #()
+                  need-prompt (if (instance? LineNumberingPushbackReader *in*)
+                                #(.atLineStart ^LineNumberingPushbackReader *in*)
+                                #(identity true))
+                  prompt      repl-prompt
+                  flush       flush
+                  read        repl-read
+                  eval        eval
+                  print       prn
+                  caught      repl-caught}
+             :as opts}]
+  (print "To quit, type: " :cljs/quit)
   (let [ups-deps (cljsc/get-upstream-deps)
         {:keys [analyze-path repl-verbose warn-on-undeclared special-fns static-fns] :as opts
          :or   {warn-on-undeclared true}}
@@ -576,7 +593,7 @@
              (loop []
                ;; try to let things flush before printing prompt
                (Thread/sleep 10)
-               (print (str "ClojureScript:" ana/*cljs-ns* "> "))
+               (prompt)
                (flush)
                (let [rdr (readers/source-logging-push-back-reader
                            (PushbackReader. (io/reader *in*))


CLJS-979: ClojureScript REPL needs error handling for the special functions

Wrapped the execution of special functions with a general error handler.
Validated that the argument to in-ns is a symbol.

--- src/clj/cljs/repl.clj
+++ src/clj/cljs/repl.clj
@@ -18,7 +18,8 @@
             [cljs.source-map :as sm]
             [clojure.tools.reader :as reader]
             [clojure.tools.reader.reader-types :as readers]
-            [cljs.util :as util])
+            [cljs.util :as util]
+            [clojure.stacktrace :as trace])
   (:import [java.io File PushbackReader]
            [javax.xml.bind DatatypeConverter]))

@@ -279,6 +280,9 @@
        ([repl-env env form]
          (self repl-env env form nil))
        ([repl-env env [_ [quote ns-name] :as form] _]
+         ;; guard against craziness like '5 which wreaks havoc
+         (when-not (and (= quote 'quote) (symbol? ns-name))
+           (throw (IllegalArgumentException. "Argument to in-ns must be a symbol.")))
          (when-not (ana/get-namespace ns-name)
            (swap! env/*compiler* assoc-in [::ana/namespaces ns-name] {:name ns-name})
            (-evaluate repl-env "<cljs repl>" 1
@@ -393,8 +397,13 @@

               (and (seq? form) (is-special-fn? (first form)))
               (do
-                ((get special-fns (first form))
-                  repl-env env form opts)
+                (try
+                  ((get special-fns (first form)) repl-env env form opts)
+                  (catch Throwable ex
+                    (println "Failed to execute special function:" (pr-str (first form)))
+                    (trace/print-cause-trace ex 12)))
+                ;; flush output which could include stack traces
+                (flush)
                 (newline)
                 (recur))


Installing facedown should not cost MU mtgred/netrunner#636

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -1329,7 +1329,7 @@
        (trigger-event state side :pre-install card)
        (let [cost (install-cost state side card
                                 (concat extra-cost (when (and (not no-cost) (not facedown)) [:credit cost])
-                                        (when memoryunits [:memory memoryunits])))]
+                                        (when (and memoryunits (not facedown)) [:memory memoryunits])))]
          (when (and (or (not uniqueness) (not (in-play? state card)) facedown)
                     (if-let [req (:req (card-def card))]
                       (or facedown (req state side card nil)) true)


Pass the pre-moved and post-moved cards to :card-moved.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -154,7 +154,7 @@
                  (when-let [events (:events (card-def c))]
                    (unregister-events state side c)
                    (register-events state side events c))))))
-         (trigger-event state side :card-moved moved-card)
+         (trigger-event state side :card-moved card moved-card)
          moved-card)))))

 (defn draw
@@ -501,7 +501,7 @@
                                              (str "prevents " (if (= prevent Integer/MAX_VALUE) "all" prevent )
                                                   " " (name type) " damage")
                                              "will not prevent damage"))
-                               (resolve-damage state side type (max 0 (- n (or prevent 0))) args))))
+                               (resolve-damage state side type (max 0 (- n (or prevent 0))) args)))))
                 (resolve-damage state side type n args))))))

 (defn shuffle! [state side kw]


Fix for accessing agendas.

Fix for accessing agendas.

--- src/clj/game/core.clj
+++ src/clj/game/core.clj
@@ -409,9 +409,11 @@
   (swap! state update-in [:bonus :trash] (fnil #(+ % n) 0)))

 (defn trash-cost [state side {:keys [trash] :as card}]
-  (-> trash
-      (+ (or (get-in @state [:bonus :trash]) 0))
-      (max 0)))
+  (if (nil? trash)
+    nil
+    (-> trash
+        (+ (or (get-in @state [:bonus :trash]) 0))
+        (max 0))))

 (defn install-cost-bonus [state side n]
   (swap! state update-in [:bonus :install-cost] (fnil #(+ % n) 0)))


Fix parser_test

Fix parser_test

--- test/com/wsscode/pathom/parser_test.clj
+++ test/com/wsscode/pathom/parser_test.clj
@@ -954,11 +954,3 @@
             {:com.wsscode.pathom.core/path   []
              :com.wsscode.pathom.trace/event :com.wsscode.pathom.parser/process-key
              :key                            :sub}                                                 1}))))
-
-(pc/defresolver batch-sample [env input]
-  {::pc/input     #{:some/id}
-   ::pc/output    [:some/output]
-   ::pc/transform pc/transform-batch-resolver}
-  ; input will always be a sequence now, also note ::pc/batch? true will be automatically
-  ; add by the pc/transform-batch-resolver helper
-  ...)


rename select-aggregate -> do-aggregate

rename select-aggregate -> do-aggregate

--- src/main/clojure/org/dada/demo/whales.clj
+++ src/main/clojure/org/dada/demo/whales.clj
@@ -381,15 +381,15 @@
 	aggregator-fn (eval (symbol (str "make-" aggregator "-aggregator")))]
     (aggregator-fn metadata model-name key-val attribute)))

-(defn select-aggregate
+(defn do-aggregate
   "apply an aggregator view to a model"
   [model key-name key-val aggregator attribute]
   (connect model (make-aggregator model key-name key-val aggregator attribute)))

-(def blue-whales-sum-length (select-aggregate blue-whales :type "blue whale" 'sum :length))
-(def blue-whales-count-length (select-aggregate blue-whales :type "blue whale" 'count :length))
-(def blue-whales-average-length (select-aggregate blue-whales :type "blue whale" 'average :length))
+(def blue-whales-sum-length (do-aggregate blue-whales :type "blue whale" 'sum :length))
+(def blue-whales-count-length (do-aggregate blue-whales :type "blue whale" 'count :length))
+(def blue-whales-average-length (do-aggregate blue-whales :type "blue whale" 'average :length))

 (insert *metamodel* blue-whales-sum-length)
 (insert *metamodel* blue-whales-count-length)
@@ -413,7 +413,7 @@
       aggregator-attr-key :weight
       aggregator-symbol 'count ;; 'sum, 'average, 'count

-      aggregation (select-aggregate
+      aggregation (do-aggregate
       		   filtration
 		   filter-attr-key filter-attr-value aggregator-symbol aggregator-attr-key)
   ]


Dummy impl

Dummy impl

--- test/onyx/messaging/dummy_messenger.clj
+++ test/onyx/messaging/dummy_messenger.clj
@@ -13,3 +13,6 @@
 (defmethod extensions/peer-site onyx.messaging.dummy_messenger.DummyMessenger
   [messenger]
   {:address 1})
+
+(defmethod extensions/open-peer-site :dummy-messenger
+  [_ _] "localhost")


Add --add-jar option to sift task (fixes #67)

--- boot/core/src/boot/task/built_in.clj
+++ boot/core/src/boot/task/built_in.clj
@@ -251,6 +251,12 @@
   files into resource files, for example, etc. If --invert is also specified
   the transformation is done to paths that DO NOT match.

+  The --add-jar option extracts the contents of a jar file on the classpath
+  and adds them to the fileset. The PROJECT part of the argument specifies the
+  group-id/artifact-id symbol associated with the jar, and the MATCH portion
+  selects which entries in the jar will be extracted. If --invert is also
+  specified then entries whose paths DO NOT match the regex will be extracted.
+
   The --with-meta option specifies a set of metadata keys files in the fileset
   must have. Files without one of these keys will be filtered out. If --invert
   is also specified then files that DO have one of these keys will be filtered
@@ -272,17 +278,19 @@
   the fileset. Only paths matching one of these will be kept. If --invert is
   also specified then only paths NOT matching one of the regexes will be kept."

-  [a to-asset REGEX     #{regex}    "The set of regexes of paths to move to assets."
-   r to-resource REGEX  #{regex}    "The set of regexes of paths to move to resources."
-   s to-source REGEX    #{regex}    "The set of regexes of paths to move to sources."
-   w with-meta KEY      #{kw}       "The set of metadata keys files must have."
-   M add-meta REGEX:KEY {regex kw}  "The map of path regex to meta key to add."
-   m move MATCH:REPLACE {regex str} "The map of regex to replacement path strings."
-   i include REGEX      #{regex}    "The set of regexes that paths must match."
-   v invert             bool        "Perform the inverse operation on the fileset."]
+  [a to-asset MATCH        #{regex}    "The set of regexes of paths to move to assets."
+   r to-resource MATCH     #{regex}    "The set of regexes of paths to move to resources."
+   s to-source MATCH       #{regex}    "The set of regexes of paths to move to sources."
+   j add-jar PROJECT:MATCH {sym regex} "The map of jar to path regex of entries in jar to unpack."
+   w with-meta KEY         #{kw}       "The set of metadata keys files must have."
+   M add-meta MATCH:KEY    {regex kw}  "The map of path regex to meta key to add."
+   m move MATCH:REPLACE    {regex str} "The map of regex to replacement path strings."
+   i include MATCH         #{regex}    "The set of regexes that paths must match."
+   v invert                bool        "Invert the sense of matching."]

   (core/with-pre-wrap fileset
-    (let [negate   #(if-not invert % (not %))
+    (let [tmp      (core/temp-dir!)
+          negate   #(if-not invert % (not %))
           include* (when-not invert include)
           exclude* (when invert include)
           keep?    (partial file/keep-filters? include* exclude*)
@@ -308,9 +316,18 @@
           withmeta #(or (and (not with-meta) %1)
                         (if (negate (some with-meta (keys %2))) %1 (core/rm %1 [%2])))]
       (util/info "Sifting output files...\n")
+      (doseq [[proj re] add-jar]
+        (let [inc (when-not invert [re])
+              exc (when invert [re])
+              env (core/get-env)
+              dep (->> env :dependencies (filter #(= proj (first %))) first)
+              jar (pod/resolve-dependency-jar (core/get-env) dep)]
+          (util/info "Adding jar entries from %s...\n" (.getName (io/file jar)))
+          (pod/unpack-jar jar tmp :include inc :exclude exc)))
       (-> fileset
           (core/fileset-reduce core/ls remover to-src to-rsc to-ast mover withmeta)
           (#(core/add-meta % (addmeta %)))
+          (core/add-resource tmp)
           core/commit!))))

 (core/deftask add-repo


Rename `parent-directory` to more simplier `parent`.

--- src/datoteka/core.clj
+++ src/datoteka/core.clj
@@ -170,7 +170,7 @@
     (->> (Files/getPosixFilePermissions path *no-follow*)
          (PosixFilePermissions/toString))))

-(defn parent-directory
+(defn parent
   "Get parent path if it exists."
   [path]
   (.getParent ^Path (pt/-path path)))


Still trying to resolve issues with concurrency and build/test.

--- test/clj_ravendb/client_watching_test.clj
+++ test/clj_ravendb/client_watching_test.clj
@@ -14,9 +14,9 @@
       (let [document {:test 2 :name id}
             ch (chan)
             watcher (watch-documents client [id] ch {:wait 0})
-            _ (Thread/sleep 2000)
+            _ (Thread/sleep 4000)
             _ (put-document! client id document)
-            _ (Thread/sleep 2000)
+            _ (Thread/sleep 4000)
             actual (first (:results (<!! ch)))
             actual (dissoc actual :last-modified-date)
             actual (dissoc actual :etag)]
@@ -28,10 +28,10 @@
       (let [document {:test 2 :name id}
             ch (chan)
             watcher (watch-index client {:index index-name} ch {:wait 0})
-            _ (Thread/sleep 2000)
+            _ (Thread/sleep 4000)
             _ (put-document! client id document)
-            _ (Thread/sleep 2000)
-            actual (first (:results (<!! ch)))]
+            _ (Thread/sleep 4000)
+            actual (first (filter (fn [r] (= (:name r) id)) (:results (<!! ch))))]
         ((:stop watcher))
         (is (= actual document)))))


Make api-key a dynamic var

Make api-key a dynamic var

--- src/googlica/core.clj
+++ src/googlica/core.clj
@@ -39,7 +39,7 @@
   "Generates global variables that are used throughout the generated namespace"
   [root-url service-path]
   `[(def ~'base-url ~(str root-url service-path))
-    (def ~'*api-key* nil)
+    (def (~'vary-meta ~'*api-key* ~'assoc :dynamic true) nil)
     ~'(defn ?assoc
         "Same as assoc, but skip the assoc if v is nil"
         [m & kvs]
@@ -48,7 +48,6 @@
              (filter second)
              (map vec)
              (into m)))])
-

 (defn split-required-params
   "Returns a vector of two maps: first with the required params, second with the optional"


Use local address of dabas-

Use local address of dabas-

--- src/discuss/config.cljs
+++ src/discuss/config.cljs
@@ -4,7 +4,7 @@

 (def user "Q2hyaXN0aWFu")

-(def api {:host "http://dbas/"
+(def api {:host "http://localhost:4284/"
           :init "api/elektroautos"
           :base "api/"
           :add  {:add-start-statement "add/start_statement"


OO: Remove unnecessary threading macro

OO: Remove unnecessary threading macro

--- src/hatti/charting.cljc
+++ src/hatti/charting.cljc
@@ -80,8 +80,7 @@
    metadata of this above value would be:
    {:bins ['1 to 2', '3 to 4', '5 to 6', '7 to 8', '9 to 10']}"
      [answers bins typ]
-     (let [numbers (->> answers
-                        (map (str->int typ)))
+     (let [numbers (map (str->int typ) answers)
            mx (reduce max (remove nil? numbers))
            mn (reduce min (remove nil? numbers))
            s (scale/linear :domain [mn mx] :range [0 (- bins (/ 1 10000))])


fixing validation

fixing validation

--- src/kvm/validations.clj
+++ src/kvm/validations.clj
@@ -28,7 +28,7 @@

 (def kvm-entity
   {:kvm {
-     :node {:required :Keyword}
+     :node #{:required :Keyword}
     }
    })


small tweak to ensure we are properly identifying map/vector classes for field base typing.

--- src/metabase/driver.clj
+++ src/metabase/driver.clj
@@ -264,22 +264,25 @@
 (defn class->base-type
   "Return the `Field.base_type` that corresponds to a given class returned by the DB."
   [klass]
-  (or ({Boolean                      :BooleanField
-        Double                       :FloatField
-        Float                        :FloatField
-        Integer                      :IntegerField
-        Long                         :IntegerField
-        String                       :TextField
-        java.math.BigDecimal         :DecimalField
-        java.math.BigInteger         :BigIntegerField
-        java.sql.Date                :DateField
-        java.sql.Timestamp           :DateTimeField
-        java.util.Date               :DateField
-        java.util.UUID               :TextField
-        org.postgresql.util.PGobject :UnknownField} klass)
+  (or ({Boolean                         :BooleanField
+        Double                          :FloatField
+        Float                           :FloatField
+        Integer                         :IntegerField
+        Long                            :IntegerField
+        String                          :TextField
+        java.math.BigDecimal            :DecimalField
+        java.math.BigInteger            :BigIntegerField
+        java.sql.Date                   :DateField
+        java.sql.Timestamp              :DateTimeField
+        java.util.Date                  :DateField
+        java.util.UUID                  :TextField
+        clojure.lang.PersistentArrayMap :DictionaryField
+        clojure.lang.PersistentHashMap  :DictionaryField
+        clojure.lang.PersistentVector   :ArrayField
+        org.postgresql.util.PGobject    :UnknownField} klass)
       (condp isa? klass
-        clojure.lang.IPersistentMap    :DictionaryField
-        clojure.lang.IPersistentVector :ArrayField
+        clojure.lang.IPersistentMap     :DictionaryField
+        clojure.lang.IPersistentVector  :ArrayField
         nil)
       (do (log/warn (format "Don't know how to map class '%s' to a Field base_type, falling back to :UnknownField." klass))
           :UnknownField)))


%b launches an editable multine buffer

%b launches an editable multine buffer

--- src/multi_repl/core.clj
+++ src/multi_repl/core.clj
@@ -37,7 +37,6 @@
 (defn new-repl [command]
   (map->Repl {:command command}))

-
 (defn format-response [response]
   (clojure.set/rename-keys response {"result" :result
                                      "error" :error
@@ -81,7 +80,12 @@
           .readLine
           clojure.string/trim-newline))

-(defn println-console [console & args]
+(defn cprint [console & args]
+  (binding [*out* (:out console)]
+    (apply print args)
+    (.flush *out*)))
+
+(defn cprintln [console & args]
   (binding [*out* (:out console)]
     (apply println args)))

@@ -104,25 +108,82 @@
   (let [{:keys [repl console]} system
         {:keys [error etype result]} (eval-in-repl repl line)]
     (if error
-      (do (println-console console "ETYPE:" etype)
-          (println-console console "ERROR:" error))
-      (println-console console result))))
+      (do (cprintln console "ETYPE:" etype)
+          (cprintln console "ERROR:" error))
+      (cprintln console result))))
+
+(defn newline? [c] (= c 13))
+(defn escape?  [c] (= c 27))
+(defn percent? [c] (= c 37))
+
+(defn min-dec [x minimum]
+  (max (dec x) minimum))
+
+(defn max-inc [x maximum]
+  (min (inc x) maximum))
+
+(defn insert [vec pos item]
+  (print-err "vec" vec)
+  (print-err "pos" pos)
+  (print-err "item" item)
+  (apply conj (subvec vec 0 pos) item (subvec vec pos)))
+
+(defn insert-char [buffer [x y] c]
+  (update-in buffer [y] insert x (char c)))
+
+(defn inc-x [cursor] (update-in cursor [0] inc))
+(defn dec-x [cursor] (update-in cursor [0] min-dec 0))
+(defn inc-y [cursor] (update-in cursor [1] inc))
+(defn dec-y [cursor] (update-in cursor [1] min-dec 0))
+
+(defn set-x [cursor n] (assoc cursor 0 n))
+(defn set-y [cursor n] (assoc cursor 1 n))
+
+(defn start-buffer [console]
+  (let [reader (:reader console)]
+    (loop [buffer [[]]
+           cursor [0 0]
+           c (.readCharacter reader)]
+      (print-err "buffer" buffer)
+      (print-err "cursor" cursor)
+      (cprint console (char c))
+      (cond
+        (escape? c) (let [escape-seq [(.readCharacter reader) (.readCharacter reader)]]
+                      (cprint console (char (nth escape-seq 0)))
+                      (cprint console (char (nth escape-seq 1)))
+                      (condp = escape-seq
+                        [91 65] (recur buffer
+                                       (dec-y cursor)
+                                       (.readCharacter reader))
+                        [91 66] (recur buffer
+                                       (inc-y cursor)
+                                       (.readCharacter reader))
+                        [91 67] (recur buffer
+                                       (inc-x cursor)
+                                       (.readCharacter reader))
+                        [91 68] (recur buffer
+                                       (dec-x cursor)
+                                       (.readCharacter reader))))
+        (newline? c) (do (cprint console (char 27))
+                         (cprint console (char 91))
+                         (cprint console (char 83))
+                         (recur (conj buffer [])
+                            (-> cursor inc-y (set-x 0))
+                            (.readCharacter reader)))
+        (percent? c) (let [c (.readCharacter reader)]
+                       (if (= c 114)
+                         (clojure.string/join "\n" (map #(apply str %) buffer))
+                         (recur buffer cursor c)))
+        :else (recur (insert-char buffer cursor c)
+                     (update-in cursor [0] inc)
+                     (.readCharacter reader))))))

 (defmulti run-line (fn [system line] line))

 (defmethod run-line "%b" [system line]
-  (let [console (:console system)]
-    (loop [buffer [line]]
-      (print-err "buffer" buffer)
-      (if (= (last buffer) "%r")
-        (let [command (->> buffer
-                           drop-first-and-last
-                           (clojure.string/join "\n"))]
-          (remove-n-from-history console (count buffer))
-          (add-to-history console command)
-          (eval-and-print system command))
-        (recur (->> (read-console-line console)
-                    (conj buffer)))))))
+  (let [console (:console system)
+        buffer (start-buffer console)]
+    (eval-and-print system buffer)))

 (defmethod run-line "exit" [system _]
   (component/stop system)


Remove unused shit

Remove unused shit

--- src/ombs/view/admin.clj
+++ src/ombs/view/admin.clj
@@ -1,27 +0,0 @@
-(ns ombs.view.admin
-  (:require
-    [net.cgrand.enlive-html :as h]
-    [net.cgrand.reload :as reload]
-    [noir.session :as sess]
-    [ombs.validate :refer [errors-string]]
-    [ombs.core :as core]
-    [ombs.db.admin :refer [get-fees]]
-    [ombs.view.event :refer [event-elem]]
-    [ombs.view.fees :refer [fee-elem]]
-    ))
-
-(h/deftemplate page "../resources/public/admin.html"
-  [username & [page page-size]] ;
-  [:#user] (h/content username)
-  [:#error] (h/content (errors-string))
-  [:.debt] (h/content (str (core/debt username)))
-  [:section.events] (h/content (map #(event-elem %) (core/events)))
-  [:section.fees] (let [fees (get-fees)]
-                    (if (not= fees {})
-                      (h/content (map #(fee-elem %) fees)) ; partition by 100, to get pages. then map on pages.
-                      nil
-                      ))
-  ;[:.page-line] (h/content (get-pages)
-  )
-
-(reload/auto-reload *ns*)


New messaging interfaces

New messaging interfaces

--- src/onyx/extensions.clj
+++ src/onyx/extensions.clj
@@ -36,13 +36,11 @@

 (defmulti peer-site (fn [messenger] (type messenger)))

-(defmulti send-peer-site (fn [messenger] (type messenger)))
+(defmulti assign-site-resources (fn [messenger peer-sites] (type messenger)))

-(defmulti acker-peer-site (fn [messenger] (type messenger)))
+(defmulti open-peer-site (fn [messenger assigned] (type messenger)))

-(defmulti completion-peer-site (fn [messenger] (type messenger)))
-
-(defmulti connect-to-peer (fn [messenger event peer-site] (type messenger)))
+(defmulti connect-to-peer (fn [messenger event peer-site site-resources] (type messenger)))

 (defmulti receive-messages (fn [messenger event] (type messenger)))


fix copy/paste bug

fix copy/paste bug

--- src/pc/http/datomic.clj
+++ src/pc/http/datomic.clj
@@ -27,7 +27,7 @@

 (defn notify-team-subscribers [transaction]
   (when-let [frontend-tx (datomic-common/frontend-team-transaction transaction)]
-    (sente/notify-document-transaction (:db-after transaction) frontend-tx)))
+    (sente/notify-team-transaction (:db-after transaction) frontend-tx)))

 ;; TODO: this should use a channel instead of a future
 (defn send-emails [transaction]


Further docstring and general fn updates

--- src/processing/core.clj
+++ src/processing/core.clj
@@ -480,7 +480,6 @@

   Available blend modes are:

-
   :blend      - linear interpolation of colours: C = A*factor + B
   :add        - additive blending with white clip:
                                             C = min(A*factor + B, 255)
@@ -702,30 +701,100 @@
      (.createFont *applet* (str name) (float size) smooth charset)))

 (defn create-graphics
+  "Creates and returns a new PGraphics object of the types P2D, P3D,
+  and JAVA2D. Use this class if you need to draw into an off-screen
+  graphics buffer. It's not possible to use create-graphics with
+  OPENGL, because it doesn't allow offscreen use. The PDF renderer
+  requires the filename parameter. The DXF renderer should not be used
+  with create-graphics, it's only built for use with begin-raw and
+  end-raw.
+
+  It's important to call any drawing commands between begin-draw and
+  end-draw statements. This is also true for any commands that affect
+  drawing, such as smooth or colorMode.
+
+  Unlike the main drawing surface which is completely opaque, surfaces
+  created with create-graphics can have transparency. This makes it
+  possible to draw into a graphics and maintain the alpha channel. By
+  using save to write a PNG or TGA file, the transparency of the
+  graphics object will be honored. Note that transparency levels are
+  binary: pixels are either complete opaque or transparent. For the
+  time being (as of release 1.2.1), this means that text characters
+  will be opaque blocks. This will be fixed in a future release (Issue
+  80)."
   ([w h renderer]
      (.createGraphics *applet* (int w) (int h) renderer))
   ([w h renderer path]
-     (.createGraphics *applet* (int w) (int h) renderer path)))
-
-(defn create-image [w h format]
+     (.createGraphics *applet* (int w) (int h) renderer (str path))))
+
+(defn create-image
+  "Creates a new PImage (the datatype for storing images). This
+  provides a fresh buffer of pixels to play with. Set the size of the
+  buffer with the width and height parameters. The format parameter
+  defines how the pixels are stored. See the PImage reference for more
+  information.
+
+  Be sure to include all three parameters, specifying only the width
+  and height (but no format) will produce a strange error.
+
+  Prefer using create-image over initialising new PImage instances
+  directly."
+  [w h format]
   (.createImage *applet* (int w) (int h) (int format)))

-(defn create-input [filename]
-  (PApplet/createInput (java.io.File. filename)))
+(defn create-input
+  "This is a method for advanced programmers to open a Java
+  InputStream. The method is useful if you want to use the facilities
+  provided by PApplet to easily open files from the data folder or
+  from a URL, but want an InputStream object so that you can use other
+  Java methods to take more control of how the stream is read.
+
+  If the requested item doesn't exist, null is returned.
+
+  If not online, this will also check to see if the user is asking for
+  a file whose name isn't properly capitalized. If capitalization is
+  different an error will be printed to the console. This helps
+  prevent issues that appear when a sketch is exported to the web,
+  where case sensitivity matters, as opposed to running from inside
+  the Processing Development Environment on Windows or Mac OS, where
+  case sensitivity is preserved but ignored.
+
+  The filename passed in can be:
+  - A URL, for instance (open-stream \"http://processing.org/\";
+  - A file in the sketch's data folder
+  - The full path to a file to be opened locally (when running as an
+    application)
+
+  If the file ends with .gz, the stream will automatically be gzip
+  decompressed. If you don't want the automatic decompression, use the
+  related function create-input-raw."
+  [filename]
+  (PApplet/createInput (java.io.File. (str filename))))

 (defn create-input-raw
-  "Call openStream() without automatic gzip decompression."
+  "Call create-input without automatic gzip decompression."
   [filename]
   (.createInputRaw *applet* filename))

-(defn create-output [filename]
-  (PApplet/createOutput (java.io.File. filename)))
-
-(defn create-path [filename] (PApplet/createPath filename))
-
-(defn create-reader [filename] (.createReader *applet* filename))
-
-(defn create-writer [filename] (.createWriter *applet* filename))
+(defn create-output
+  "Similar to create-input, this creates a Java OutputStream for a
+  given filename or path. The file will be created in the sketch
+  folder, or in the same folder as an exported application.
+
+  If the path does not exist, intermediate folders will be created. If
+  an exception occurs, it will be printed to the console, and null
+  will be returned.
+
+  This method is a convenience over the Java approach that requires
+  you to 1) create a FileOutputStream object, 2) determine the exact
+  file location, and 3) handle exceptions. Exceptions are handled
+  internally by the function, which is more appropriate for sketch
+  projects.
+
+  If the output filename ends with .gz, the output will be
+  automatically GZIP compressed as it is written."
+  [filename]
+  (PApplet/createOutput (java.io.File. (str filename))))

 (def ^{:private true}
   cursor-modes {:arrow PConstants/ARROW
@@ -796,8 +865,8 @@

 (defn curve-point
   "Evalutes the curve at point t for points a, b, c, d. The parameter
-  t varies between 0 and 1, a and d are points on the curve, and b and
-  c are the control points. This can be done once with the x
+  t varies between 0 and 1, a and d are points on the curve, and b c
+  and are the control points. This can be done once with the x
   coordinates and a second time with the y coordinates to get the
   location of a curve at t."
   [a b c d t]
@@ -834,9 +903,6 @@
   ([x y] (.curveVertex *applet* (float x) (float y)))
   ([x y z] (.curveVertex *applet* (float x) (float y) (float z))))

-;; $$dataFile
-;; $$dataPath
-
 (defn day
   "Get the current day of the month (1 through 31)."
   []
@@ -875,7 +941,6 @@
   color mode. The nx, ny, and nz parameters specify the direction the
   light is facing. For example, setting ny to -1 will cause the
   geometry to be lit from below (the light is facing directly upward)"
-
   [r g b nx ny nz]
   (.directionalLight *applet* (float r) (float g) (float b)
                      (float nx) (float ny) (float nz)))
@@ -938,11 +1003,11 @@

 (defn emissive
   "Sets the emissive color of the material used for drawing shapes
-   drawn to the screen. Used in combination with ambient, specular,
-   and shininess in setting the material properties of shapes.
+  drawn to the screen. Used in combination with ambient, specular, and
+  shininess in setting the material properties of shapes.

   If passed one arg - it is assumed to be an int (i.e. a color),
-   multiple args are converted to floats."
+  multiple args are converted to floats."
   ([c] (if (int-like? c) (emissive-int c) (emissive-float c)))
   ([r g b] (emissive-float r g b)))

@@ -1095,6 +1160,8 @@
   ([x y] (.get *applet* (int x) (int y)))
   ([x y w h] (.get *applet* (int x) (int y) (int w) (int h))))

+(declare load-pixels)
+
 (defn pixels
   "Array containing the values for all the pixels in the display
   window. This array is therefore the size of the display window. If
@@ -1228,6 +1295,20 @@
   (.hue *applet* (int col)))

 (defn image
+  "Displays images to the screen. Processing currently works with GIF,
+  JPEG, and Targa images. The color of an image may be modified with
+  the tint function and if a GIF has transparency, it will maintain
+  its transparency. The img parameter specifies the image to display
+  and the x and y parameters define the location of the image from its
+  upper-left corner. The image is displayed at its original size
+  unless the width and height parameters specify a different size. The
+  image-mode fn changes the way the parameters work. A call to
+  (image-mode :corners) will change the width and height parameters to
+  define the x and y values of the opposite corner of the image.
+
+  Starting with release 0124, when using the default (JAVA2D)
+  renderer, smooth will also improve image quality of resized
+  images."
   ([^PImage img x y] (.image *applet* img (float x) (float y)))
   ([^PImage img x y c d] (.image *applet* img (float x) (float y)
                                   (float c) (float d)))
@@ -1235,7 +1316,33 @@
      (.image *applet* img (float x) (float y) (float c) (float d)
              (float u1) (float v1) (float u2) (float v2))))

-(defn image-mode [mode] (.imageMode *applet* (int mode)))
+(def ^{:private true}
+  image-modes {:corner CORNER
+               :corners CORNERS
+               :center CENTER})
+
+(defn- resolve-image-mode
+  [mode]
+  (if (keyword? mode)
+    (get image-modes mode)
+    mode))
+
+(defn image-mode
+  "Modifies the location from which images draw. The default mode is :corner.
+   Available modes are:
+
+  :corner  - specifies the location to be the upper left corner and
+             uses the fourth and fifth parameters of image to set the
+             image's width and height.
+
+  :corners - uses the second and third parameters of image to set the
+             location of one corner of the image and uses the fourth
+             and fifth parameters to set the opposite corner.
+
+  :center  - draw images centered at the given x and y position."
+  [mode]
+  (let [mode (resolve-image-mode mode)]
+    (.imageMode *applet* (int mode))))

 (defn light-falloff
   "Sets the falloff rates for point lights, spot lights, and ambient
@@ -1296,8 +1403,15 @@
   (.lights *applet*))

 (defn light-specular
-  [x y z]
-  (.lightSpecular *applet* (float x) (float y) (float z)))
+  "Sets the specular color for lights. Like fill, it affects only the
+  elements which are created after it in the code. Specular refers to
+  light which bounces off a surface in a perferred direction (rather
+  than bouncing in all directions like a diffuse light) and is used
+  for creating highlights. The specular quality of a light interacts
+  with the specular material qualities set through the specular and
+  shininess functions."
+  [r g b]
+  (.lightSpecular *applet* (float r) (float g) (float b)))

 (defn line
   "Draws a line (a direct path between two points) to the screen. The
@@ -1313,7 +1427,12 @@
      (.line *applet* (float x1) (float y1) (float z1)
             (float x2) (float y2) (float z2))))

-(defn load-bytes [filename] (PApplet/loadBytes filename))
+(defn load-bytes
+  "Reads the contents of a file or url and places it in a byte
+  array. The filename parameter can also be a URL to a file found
+  online."
+  [filename]
+  (PApplet/loadBytes (str filename)))

 (defn load-font
   "Loads a font into a variable of type PFont. To load correctly,
@@ -1338,9 +1457,35 @@
   [filename]
   (.loadFont *applet*  (str filename)))

-(defn load-image [filename] (.loadImage *applet* filename))
-
-(defn load-matrix [] (.loadMatrix *applet*))
+(defn load-image
+  "Loads an image into a variable of type PImage. Four types of
+  images ( .gif, .jpg, .tga, .png) images may be loaded. To load
+  correctly, images must be located in the data directory of the
+  current sketch. In most cases, load all images in setup to preload
+  them at the start of the program. Loading images inside draw will
+  reduce the speed of a program.
+
+  The filename parameter can also be a URL to a file found online.
+
+  The extension parameter is used to determine the image type in cases
+  where the image filename does not end with a proper
+  extension. Specify the extension as the second parameter to
+  load-image, as shown in the third example on this page.
+
+  If an image is not loaded successfully, the null value is returned
+  and an error message will be printed to the console. The error
+  message does not halt the program, however the null value may cause
+  a NullPointerException if your code does not check whether the value
+  returned from load-image is nil.
+
+  Depending on the type of error, a PImage object may still be
+  returned, but the width and height of the image will be set to
+  -1. This happens if bad image data is returned or cannot be decoded
+  properly. Sometimes this happens with image URLs that produce a 403
+  error or that redirect to a password prompt, because load-image
+  will attempt to interpret the HTML as image data."
+  [filename]
+  (.loadImage *applet* (str filename)))

 (defn load-pixels
   "Loads the pixel data for the display window into the pixels[]
@@ -1372,7 +1517,11 @@
   [val]
   (PApplet/log (float val)))

-(defn start-loop [] (.loop *applet*))
+(defn start-loop
+  "Causes Processing to continuously execute the code within
+  draw. If no-loop is called, the code in draw stops executing."
+  []
+  (.loop *applet*))

 (defn mag
   "Calculates the magnitude (or length) of a vector. A vector is a
@@ -1383,16 +1532,28 @@
   ([a b] (PApplet/mag (float a) (float b)))
   ([a b c] (PApplet/mag (float a) (float b) (float c))))

-(defn map-to [val istart istop ostart ostop]
-  (PApplet/map (float val) (float istart) (float istop) (float ostart) (float ostop)))
-
-(defn map-to-double [val istart istop ostart ostop]
-  (PApplet/map (double val) (double istart) (double istop) (double ostart) (double ostop)))
-
-(defn mask
-  ([^ints alpha-array] (.mask *applet* alpha-array)))
-
-(defn mask-image [^PImage img] (.mask *applet* img))
+(defn map-range
+  "Re-maps a number from one range to another. In the example above,
+  the number '25' is converted from a value in the range 0..100 into a
+  value that ranges from the left edge (0) to the right edge (width)
+  of the screen.
+
+  Numbers outside the range are not clamped to 0 and 1, because
+  out-of-range values are often intentional and useful."
+  [val low1 high1 low2 high2]
+  (PApplet/map (float val) (float low1) (float high1) (float low2) (float high2)))
+
+(defn mask-image
+  "Masks part of an image from displaying by loading another image and
+  using it as an alpha channel.  This mask image should only contain
+  grayscale data, but only the blue color channel is used. The mask
+  image needs to be the same size as the image to which it is
+  applied.
+
+   This method is useful for creating dynamically generated alpha
+   masks."
+  [^PImage img]
+  (.mask *applet* img))

 (defn millis
   "Returns the number of milliseconds (thousandths of a second) since
@@ -1406,9 +1567,32 @@
   []
   (PApplet/minute))

-(defn model-x [x y z] (.modelX *applet* (float x) (float y) (float z)))
-(defn model-y [x y z] (.modelY *applet* (float x) (float y) (float z)))
-(defn model-z [x y z] (.modelZ *applet* (float x) (float y) (float z)))
+(defn model-x
+  "Returns the three-dimensional x, y, z position in model space. This
+  returns the x value for a given coordinate based on the current set
+  of transformations (scale, rotate, translate, etc.) The x value can
+  be used to place an object in space relative to the location of the
+  original point once the transformations are no longer in use."
+  [x y z]
+  (.modelX *applet* (float x) (float y) (float z)))
+
+(defn model-y
+  "Returns the three-dimensional x, y, z position in model space. This
+  returns the y value for a given coordinate based on the current set
+  of transformations (scale, rotate, translate, etc.) The y value can
+  be used to place an object in space relative to the location of the
+  original point once the transformations are no longer in use."
+  [x y z]
+  (.modelY *applet* (float x) (float y) (float z)))
+
+(defn model-z
+  "Returns the three-dimensional x, y, z position in model space. This
+  returns the z value for a given coordinate based on the current set
+  of transformations (scale, rotate, translate, etc.) The z value can
+  be used to place an object in space relative to the location of the
+  original point once the transformations are no longer in use."
+  [x y z]
+  (.modelZ *applet* (float x) (float y) (float z)))

 (defn month
   "Returns the current month as a value from 1 - 12."
@@ -1425,7 +1609,11 @@
   []
   (. *applet* :mouseY))

-(defn no-cursor [] (.noCursor *applet*))
+(defn no-cursor
+  "Hides the cursor from view. Will not work when running the in full
+  screen (Present) mode."
+  []
+  (.noCursor *applet*))

 (defn no-fill
  "Disables filling geometry. If both no-stroke and no-fill are called,
@@ -1467,21 +1655,77 @@
   ([x y z] (.noise *applet* (float x) (float y) (float z))))

 (defn noise-detail
-  ([int detail] (.noiseDetail *applet* (int detail)))
-  ([int detail falloff] (.noiseDetail *applet* (int detail) (float falloff))))
-
-(defn noise-seed [what] (.noiseSeed *applet* (int what)))
-
-(defn no-lights [] (.noLights *applet*))
-
-(defn no-loop [] (.noLoop *applet*))
+  "Adjusts the character and level of detail produced by the Perlin
+  noise function. Similar to harmonics in physics, noise is computed
+  over several octaves. Lower octaves contribute more to the output
+  signal and as such define the overal intensity of the noise, whereas
+  higher octaves create finer grained details in the noise
+  sequence. By default, noise is computed over 4 octaves with each
+  octave contributing exactly half than its predecessor, starting at
+  50% strength for the 1st octave. This falloff amount can be changed
+  by adding an additional function parameter. Eg. a falloff factor of
+  0.75 means each octave will now have 75% impact (25% less) of the
+  previous lower octave. Any value between 0.0 and 1.0 is valid,
+  however note that values greater than 0.5 might result in greater
+  than 1.0 values returned by noise.
+
+  By changing these parameters, the signal created by the noise
+  function can be adapted to fit very specific needs and
+  characteristics."
+  ([octaves] (.noiseDetail *applet* (int octaves)))
+  ([octaves falloff] (.noiseDetail *applet* (int octaves) (float falloff))))
+
+(defn noise-seed
+  "Sets the seed value for noise. By default, noise produces different
+  results each time the program is run. Set the value parameter to a
+  constant to return the same pseudo-random numbers each time the
+  software is run."
+  [val]
+  (.noiseSeed *applet* (int val)))
+
+(defn no-lights
+  "Disable all lighting. Lighting is turned off by default and enabled
+  with the lights fn. This function can be used to disable lighting so
+  that 2D geometry (which does not require lighting) can be drawn
+  after a set of lighted 3D geometry."
+  []
+  (.noLights *applet*))
+
+(defn no-loop
+  "Stops Processing from continuously executing the code within
+  draw. If start-loop is called, the code in draw will begin to run
+  continuously again. If using no-loop in setup, it should be the last
+  line inside the block.
+
+  When no-loop is used, it's not possible to manipulate or access the
+  screen inside event handling functions such as mouse-pressed or
+  key-pressed. Instead, use those functions to call redraw or
+  loop which will run draw, which can update the screen
+  properly. This means that when no-loop has been called, no drawing
+  can happen, and functions like save-frame or load-pixels may not
+  be used.
+
+  Note that if the sketch is resized, redraw will be called to
+  update the sketch, even after no-oop has been
+  specified. Otherwise, the sketch would enter an odd state until
+  loop was called."
+  []
+  (.noLoop *applet*))

 (defn norm
   "Normalize a value to exist between 0 and 1 (inclusive)."
   [val start stop]
   (PApplet/norm (float val) (float start) (float stop)))

-(defn normal [nx ny nz] (.normal *applet* (float nx) (float ny) (float nz)))
+(defn normal
+  "Sets the current normal vector. This is for drawing three
+  dimensional shapes and surfaces and specifies a vector perpendicular
+  to the surface of the shape which determines how lighting affects
+  it. Processing attempts to automatically assign normals to shapes,
+  but since that's imperfect, this is a better option when you want
+  more control. This function is identical to glNormal3f() in OpenGL."
+  [nx ny nz]
+  (.normal *applet* (float nx) (float ny) (float nz)))

 (defn no-smooth
   "Draws all geometry with jagged (aliased) edges."
@@ -1493,18 +1737,37 @@
   []
   (.noStroke *applet*))

-(defn no-tint [] (.noTint *applet*))
-
-(defn open [^String filename] (PApplet/open filename))
-
-;; $$open -- overload
+(defn no-tint
+  "Removes the current fill value for displaying images and reverts to
+  displaying images with their original hues."
+  []
+  (.noTint *applet*))

 (defn ortho
+  "Sets an orthographic projection and defines a parallel clipping
+  volume. All objects with the same dimension appear the same size,
+  regardless of whether they are near or far from the camera. The
+  parameters to this function specify the clipping volume where left
+  and right are the minimum and maximum x values, top and bottom are
+  the minimum and maximum y values, and near and far are the minimum
+  and maximum z values. If no parameters are given, the default is
+  used: ortho(0, width, 0, height, -10, 10)."
   ([] (.ortho *applet*))
-  ([l r b t near far] (.ortho *applet* (float l) (float r) (float b)
-                              (float t) (float near) (float far))))
+  ([left right bottom top near far]
+     (.ortho *applet* (float left) (float right) (float bottom) (float top) (float near) (float far))))

 (defn perspective
+  "Sets a perspective projection applying foreshortening, making
+  distant objects appear smaller than closer ones. The parameters
+  define a viewing volume with the shape of truncated pyramid. Objects
+  near to the front of the volume appear their actual size, while
+  farther objects appear smaller. This projection simulates the
+  perspective of the world more accurately than orthographic
+  projection. The version of perspective without parameters sets the
+  default perspective and the version with four parameters allows the
+  programmer to set the area precisely. The default values are:
+  perspective(PI/3.0, width/height, cameraZ/10.0, cameraZ*10.0) where
+  cameraZ is ((height/2.0) / tan(PI*60.0/360.0));"
   ([] (.perspective *applet*))
   ([fovy aspect z-near z-far]
      (.perspective *applet* (float fovy) (float aspect)
@@ -1615,7 +1878,13 @@
   ([min max] (.random *applet* (float min) (float max))))

-(defn random-seed [w] (.randomSeed *applet* (float w)))
+(defn random-seed
+  "Sets the seed value for random. By default, random produces
+  different results each time the program is run. Set the value
+  parameter to a constant to return the same pseudo-random numbers
+  each time the software is run."
+  [w]
+  (.randomSeed *applet* (float w)))

 (defn rect
   "Draws a rectangle to the screen. A rectangle is a four-sided shape
@@ -1626,19 +1895,85 @@
   [x y width height]
   (.rect *applet* (float x) (float y) (float width) (float height)))

-(defn rect-mode [mode] (.rectMode *applet* (int mode)))
-
-(defn red [what] (.red *applet* (int what)))
-
-(defn redraw [] (.redraw *applet*))
+(def ^{:private true}
+  rect-modes {:corner CORNER
+              :corners CORNERS
+              :center CENTER
+              :radius RADIUS})
+
+(defn- resolve-rect-mode
+  [mode]
+  (if (keyword? mode)
+    (get rect-modes mode)
+    mode))
+
+(defn rect-mode
+  "Modifies the location from which rectangles draw. The default mode
+  is :corner. Available modes are:
+
+
+  :corner  - Specifies the location to be the upper left corner of the
+             shape and uses the third and fourth parameters of rect to
+             specify the width and height.
+
+  :corners - Uses the first and second parameters of rect to set the
+             location of one corner and uses the third and fourth
+             parameters to set the opposite corner.
+
+  :center  - Draws the image from its center point and uses the third
+             and forth parameters of rect to specify the image's width
+             and height.
+
+  :radius  - Draws the image from its center point and uses the third
+             and forth parameters of rect() to specify half of the
+             image's width and height."
+
+  [mode]
+  (let [mode (resolve-rect-mode mode)]
+    (.rectMode *applet* (int mode))))
+
+(defn red
+  "Extracts the red value from a color, scaled to match current color-mode."
+  [c]
+  (.red *applet* (int c)))
+
+(defn redraw
+  "Executes the code within the draw fn one time. This functions
+  allows the program to update the display window only when necessary,
+  for example when an event registered by mouse-pressed or
+  key-pressed occurs.
+
+  In structuring a program, it only makes sense to call redraw
+  within events such as mouse-pressed. This is because redraw does
+  not run draw immediately (it only sets a flag that indicates an
+  update is needed).
+
+  Calling redraw within draw has no effect because draw is
+  continuously called anyway."
+  []
+  (.redraw *applet*))

 (defn request-image
-  ([filename] (.requestImage *applet* filename))
-  ([filename extension] (.requestImage *applet* filename extension)))
-
-(defn reset-matrix [] (.resetMatrix *applet*))
-
-(defn reverse-array [arr] (PApplet/reverse arr))
+  "This function load images on a separate thread so that your sketch
+  does not freeze while images load during setup. While the image is
+  loading, its width and height will be 0. If an error occurs while
+  loading the image, its width and height will be set to -1. You'll
+  know when the image has loaded properly because its width and height
+  will be greater than 0. Asynchronous image loading (particularly
+  when downloading from a server) can dramatically improve
+  performance.
+
+  The extension parameter is used to determine the image type in cases
+  where the image filename does not end with a proper
+  extension. Specify the extension as the second parameter to
+  request-image."
+  ([filename] (.requestImage *applet* (str filename)))
+  ([filename extension] (.requestImage *applet* (str filename) (str extension))))
+
+(defn reset-matrix
+  "Replaces the current matrix with the identity matrix. The
+  equivalent function in OpenGL is glLoadIdentity()"
+  [] (.resetMatrix *applet*))

 (defn rotate
   "Rotates a shape the amount specified by the angle parameter. Angles
@@ -1705,14 +2040,28 @@
   [angle]
   (.rotateZ *applet* (float angle)))

-(defn round [what] (PApplet/round (float what)))
-
-(defn saturation [what] (.saturation *applet* (int what)))
-
-(defn save [filename] (.save *applet* filename))
-
-;; $$saveBytes
-;; $$saveFile
+(defn round
+  "Calculates the integer closest to the value parameter. For example,
+  round(9.2) returns the value 9."
+  [val]
+  (PApplet/round (float val)))
+
+(defn saturation
+  "Extracts the saturation value from a color."
+  [c]
+  (.saturation *applet* (int c)))
+
+(defn save
+  "Saves an image from the display window. Images are saved in TIFF,
+  TARGA, JPEG, and PNG format depending on the extension within the
+  filename parameter. For example, image.tif will have a TIFF image
+  and image.png will save a PNG image. If no extension is included in
+  the filename, the image will save in TIFF format and .tif will be
+  added to the name. All images saved from the main drawing window
+  will be opaque. To save images without a background, use
+  create-graphics."
+  [filename]
+  (.save *applet* (str filename)))

 (defn save-frame
   "Saves an image identical to the current display window as a
@@ -1727,10 +2076,6 @@
   (save-frame \"pretty-pic-####.jpg\")"
   ([] (.saveFrame *applet*))
   ([name] (.saveFrame *applet* (str name))))
-
-;; $$savePath
-;; $$saveStream
-;; $$saveStrings

 (defn scale
   "Increases or decreases the size of a shape by expanding and
@@ -1777,17 +2122,38 @@
   []
   (PApplet/second))

-;; $$selectFolder
-;; $$selectInput
-;; $$selectOutput
-
 (defn set-pixel
-  [x y c] (.set *applet* (int x) (int y) (int c)))
-
-(defn set-image-at
-  [dx dy ^PImage src] (.set *applet* (int dx) (int dy) src))
-
-(defn shininess [shine] (.shininess *applet* (float shine)))
+  "Changes the color of any pixel in the display window. The x and y
+  parameters specify the pixel to change and the color parameter
+  specifies the color value. The color parameter is affected by the
+  current color mode (the default is RGB values from 0 to 255).
+
+  Setting the color of a single pixel with (set x, y) is easy, but not
+  as fast as putting the data directly into pixels[].
+
+  This function ignores imageMode().
+
+  Due to what appears to be a bug in Apple's Java implementation, the
+  point() and set() methods are extremely slow in some circumstances
+  when used with the default renderer. Using P2D or P3D will fix the
+  problem. Grouping many calls to point or set-pixel together can also
+  help. (Bug 1094)"
+  [x y c]
+  (.set *applet* (int x) (int y) (int c)))
+
+(defn set-image
+  "Writes an image directly into the display window. The x and y
+  parameters define the coordinates for the upper-left corner of the
+  image."
+  [x y ^PImage src]
+  (.set *applet* (int x) (int y) src))
+
+(defn shininess
+  "Sets the amount of gloss in the surface of shapes. Used in
+  combination with ambient, specular, and emissive in setting
+  the material properties of shapes."
+  [shine]
+  (.shininess *applet* (float shine)))

 (defn sin
   "Calculates the sine of an angle. This function expects the values
@@ -1802,9 +2168,6 @@
   (println "Deprecated - size should be specified as a :size key to applet or defapplet")
   nil)

-;; $$sketchFile
-;; $$sketchPath
-
 (defn smooth
   "Draws all geometry with smooth (anti-aliased) edges. This will slow
   down the frame rate of the application, but will enhance the visual
@@ -1815,6 +2178,12 @@
   (.smooth *applet*))

 (defn specular
+  "Sets the specular color of the materials used for shapes drawn to
+  the screen, which sets the color of hightlights. Specular refers to
+  light which bounces off a surface in a perferred direction (rather
+  than bouncing in all directions like a diffuse light). Used in
+  combination with emissive, ambient, and shininess in setting
+  the material properties of shapes."
   ([gray] (.specular *applet* (float gray)))
   ([gray alpha] (.specular *applet* (float gray) (float alpha)))
   ([x y z] (.specular *applet* (float x) (float y) (float z)))
@@ -1841,6 +2210,14 @@
   ([ures vres] (.sphereDetail *applet* (int ures) (int vres))))

 (defn spotlight
+  "Adds a spot light. Lights need to be included in the draw to
+  remain persistent in a looping program. Placing them in the setup
+  of a looping program will cause them to only have an effect the
+  first time through the loop. The affect of the r, g, and b
+  parameters is determined by the current color mode. The x, y, and z
+  parameters specify the position of the light and nx, ny, nz specify
+  the direction or light. The angle parameter affects angle of the
+  spotlight cone."
   ([r g b x y z nx ny nz angle concentration]
      (.spotLight *applet* r g b x y z nx ny nz angle concentration))
   ([[r g b] [x y z] [nx ny nz] angle concentration]
@@ -1888,6 +2265,10 @@
   ([rgb alpha] (.stroke *applet* (int rgb) (float alpha))))

 (defn stroke
+  "Sets the color used to draw lines and borders around shapes. This
+  color is either specified in terms of the RGB or HSB color depending
+  on the current color-mode (the default color space is RGB, with
+  each value in the range from 0 to 255)."
   ([rgb] (if (int-like? rgb) (stroke-int rgb) (stroke-float rgb)))
   ([rgb alpha] (if (int-like? rgb) (stroke-int rgb alpha) (stroke-float rgb alpha)))
   ([x y z] (stroke-float x y z))
@@ -2111,7 +2492,7 @@
   recording shape data, use :model until you're ready to capture the
   geometry with begin-raw."
   [mode]
-  (let [mode (resove-text-mode mode)]
+  (let [mode (resolve-text-mode mode)]
     (.textMode *applet* (int mode))))

 (defn text-size
@@ -2121,17 +2502,48 @@
   [size]
   (.textSize *applet* (float size)))

-(defn texture [^PImage img] (.texture *applet* img))
-
-(defn texture-mode [mode] (.textureMode *applet* (int mode)))
-
-(defmulti text-width #(= (class %) (class \a)))
-
-(defmethod text-width true
-  [c] (.textWidth *applet* (char c)))
-
-(defmethod text-width false
-  [^String s] (.textWidth *applet* s))
+(defn texture
+  "Sets a texture to be applied to vertex points. The texture fn must
+  be called between begin-shape and end-shape and before any calls to
+  vertex.
+
+  When textures are in use, the fill color is ignored. Instead, use
+  tint to specify the color of the texture as it is applied to the
+  shape."
+  [^PImage img]
+  (.texture *applet* img))
+
+(def ^{:private true}
+  texture-modes {:image IMAGE
+                :normalized NORMALIZED})
+
+(defn- resolve-texture-mode
+  [mode]
+  (if (keyword? mode)
+    (get texture-modes mode)
+    mode))
+
+(defn texture-mode
+  "Sets the coordinate space for texture mapping. There are two
+  options, :image and :normalized.
+
+  :image refers to the actual coordinates of the image and :normalized
+  refers to a normalized space of values ranging from 0 to 1. The
+  default mode is :image. In :image, if an image is 100 x 200 pixels,
+  mapping the image onto the entire size of a quad would require the
+  points (0,0) (0,100) (100,200) (0,200). The same mapping in
+  NORMAL_SPACE is (0,0) (0,1) (1,1) (0,1)."
+  [mode]
+  (let [mode (resolve-texture-mode mode)]
+    (.textureMode *applet* (int mode))))
+
+(defn text-width
+  "Calculates and returns the width of any character or text string."
+  [data]
+  (let [data  (if (= (class data) (class \a))
+                (char data)
+                (str data))]
+    (.textWidth *applet* data)))

 (defn tint-float
   "Sets the fill value for displaying images. Images can be tinted to


Make it possible to use the psql event store

--- src/rill/cli.clj
+++ src/rill/cli.clj
@@ -1,14 +1,14 @@
 (ns rill.cli
-  (:require [rill.event-store.atom-store :refer [atom-event-store]]
+  (:require [rill.event-store.psql :refer [psql-event-store]]
             [rill.event-channel :refer [event-channel]]
             [rill.event-stream :refer [all-events-stream-id]]
             [rill.event-store.atom-store.event :refer [unprocessable?]]
             [clojure.core.async :refer [<!!]])
   (:gen-class))

-(defn -main [url user password]
-  {:pre [url user password]}
-  (let [ch (event-channel (atom-event-store url {:user user :password password})
+(defn -main [url]
+  {:pre [url]}
+  (let [ch (event-channel (psql-event-store url)
                           all-events-stream-id -1 0)]
     (println "Printing all events...")
     (loop []


rename `test` not to conflict clojure.core/test

--- src/s7p/core.clj
+++ src/s7p/core.clj
@@ -74,7 +74,7 @@
                    (pick-winner-and-second-price (:floorPrice req))
                    (winnotice req result))))

-(defn test [req]
+(defn test-run [req]
   (let [xf (comp
             (map (fn [dsp] [dsp (http/post (:url dsp) (json-request-option req))]))
             (map validate))]
@@ -85,6 +85,6 @@
     (loop []
       (when-let [{:keys [req result]} (<!! c)]
         (if (= 1 (:test req))
-          (test req)
+          (test-run req)
           (work req result))
         (recur)))))


Revert "CMR-688: Began support for personell with ECHO10."

This reverts commit cc4ec8531b90a166c8853879c366a4da9c1ec537.

--- umm-lib/src/cmr/umm/echo10/collection/personnel.clj
+++ umm-lib/src/cmr/umm/echo10/collection/personnel.clj
@@ -44,21 +44,6 @@
                      :state-province state-province
                      :street-address-lines street-address-lines})))

-(defn- xml-elem->personnel
-  "Return a list of ContactPersons for the parsed xml structure."
-  [collection-element]
-  (for [contact-element (cx/elements-at-path contact-element [:Contacts])]
-        (let [role (cx/string-at-path contact-element [:Role])
-        first-name (cx/string-at-path contact-element [:ContactPersons :ContactPerson :FirstName])
-        last-name (cx/string-at-path contact-element [:ContactPersons :ContactPerson :LastName])
-        middle-name (cx/string-at-path contact-element [:ContactPersons :ContactPerson :MiddleName])
-        addresses (xml-elem->addresses contact-element)
-        emails (xml-elem->emails contact-element)
-        phones (xml-elem->phones contact-element)]
-          (c/map->ContactPerson {
-
-
-

  roles

@@ -81,9 +66,9 @@
    phones

-(defn xml-elem->personnels
+(defn xml-elem->personnel
   [collection-element]
-  (let [pe (cx/element-at-path collection-element [:Personnel])
+  (let [contacts (cx/element-at-path collection-element [:Contacts])
         roles (cx/strings-at-path pe [:Role])
         first-name (cx/string-at-path pe [:First_Name])
         middle-name (cx/string-at-path pe [:Middle_Name])


Make sure that default-handle-key-down calls preventDefault only when the input is handled

--- src/reabledit/util.cljs
+++ src/reabledit/util.cljs
@@ -104,53 +104,49 @@
                 previous-row
                 next-row]}
         (move-candidates column-keys row-ids column-key row-id)
-        move-fn! (partial move-to-cell! row-change-fn state row-ids)]
+        move-fn! (fn [column row]
+                   (.preventDefault e)
+                   (move-to-cell! row-change-fn state row-ids column row))
+        enable-edit! (fn [& input]
+                       (.preventDefault e)
+                       (if input
+                         (enable-edit! state row-data column (first input))
+                         (enable-edit! state row-data column)))]
     (cond

       ;; CMD / CTRL -combinations, when edit mode is not enabled
       (and (not (:edit @state)) meta?)
-      (do
-        (.preventDefault e)
-        (case keycode
+      (case keycode

-          ;; Home selects the first cell
-          36 (move-fn! first-column first-row)
+        ;; Home selects the first cell
+        36 (move-fn! first-column first-row)

-          ;; Arrow keys move to the beginning of row or col
-          37 (move-fn! first-column current-row)
-          38 (move-fn! current-column first-row)
-          39 (move-fn! last-column current-row)
-          40 (move-fn! current-column last-row)
-          nil))
+        ;; Arrow keys move to the beginning of row or col
+        37 (move-fn! first-column current-row)
+        38 (move-fn! current-column first-row)
+        39 (move-fn! last-column current-row)
+        40 (move-fn! current-column last-row)
+        nil)

       ;; Home moves to the beginning of row if not in edit mode
       (and (not (:edit @state)) (= keycode 36))
-      (do
-        (.preventDefault e)
-        (move-fn! first-column current-row))
+      (move-fn! first-column current-row)

       ;; Shift + tab moves one cell backwards
       (and shift? (= keycode 9))
-      (do
-        (.preventDefault e)
-        (move-fn! previous-column current-row))
+      (move-fn! previous-column current-row)

       ;; Tab always moves one cell forward
       (= keycode 9)
-      (do
-        (.preventDefault e)
-        (move-fn! next-column current-row))
+      (move-fn! next-column current-row)

       ;; Enter in editing mode disables it and moves selection to cell under
       (and (:edit @state) (= keycode 13))
-      (do
-        (.preventDefault e)
-        (move-fn! current-column next-row))
+      (move-fn! current-column next-row)

       (nil? (:edit @state))
       (let [key (-> e .-key)
             from-charcode (.fromCharCode js/String keycode)]
-        (.preventDefault e)
         (cond

           ;; Arrow keys in navigation mode change the selected cell
@@ -160,19 +156,17 @@
           (= keycode 40) (move-fn! current-column next-row)

           ;; Enter and F2 in navigation mode enable editing mode
-          (= keycode 13) (enable-edit! state row-data column)
-          (= keycode 113) (enable-edit! state row-data column)
+          (= keycode 13) (enable-edit!)
+          (= keycode 113) (enable-edit!)

           ;; Most keycodes take the user to edit mode
-          (= (count key) 1) (enable-edit! state row-data column key)
+          (= (count key) 1) (enable-edit! key)

           ;; If key property was not available, do you best with keyCode
           (and from-charcode (re-matches #"\d|\w" from-charcode))
-          (enable-edit! column
-                        row-data
-                        state (if shift?
-                                from-charcode
-                                (.toLowerCase from-charcode)))
+          (enable-edit! (if shift?
+                          from-charcode
+                          (.toLowerCase from-charcode)))

           :else
           nil)))))


Count the types of updates performed, not just the total

--- src/route_ccrs/core.clj
+++ src/route_ccrs/core.clj
@@ -14,5 +14,11 @@
                (ccr/get-last-known-ccr r c)
                (ccr/select-current-ccr (:db sys) o))))
          (filter seq)
-         (reduce (fn [c u] (ccr/update! (:db sys) u) (+ c 1)) 0)
+         (reduce
+           (fn [c u]
+             (let [t (-> u second first)
+                   tc (get c t 0)]
+               (ccr/update! (:db sys) u)
+               (assoc c t (+ tc 1))))
+           {})
          (log/info "calculation complete, updated:"))))


Sort all the things

Sort all the things

--- src/tyranitar/store.clj
+++ src/tyranitar/store.clj
@@ -120,7 +120,7 @@
   [list]
   (let [data (map data-from-repo-item list)
         grouped-app-list (group-by :app data)
-        result (into {} (map (fn [[k v]] {(keyword k) {:repositories (mapv #(dissoc % :app :env) v)}}) grouped-app-list))]
+        result (into (sorted-map) (map (fn [[k v]] {(keyword k) {:repositories (mapv #(dissoc % :app :env) v)}}) grouped-app-list))]
     result))

 (defn get-repository-list


startup fix

startup fix

--- src/listopia/core.clj
+++ src/listopia/core.clj
@@ -24,10 +24,10 @@
 (defn -main
   ([]     (-main 8000))
   ([port] (jetty/run-jetty app
-                           {:port (int port)})))
+                           {:port (Integer. port)})))

 (defn -dev-main
   ([]     (-dev-main 8000))
   ([port] (jetty/run-jetty (wrap-reload #'app)
-                           {:port (int port)})))
+                           {:port (Integer. port)})))


rearrange join-model args slightly

rearrange join-model args slightly

--- dada2-core/src/test/clojure/org/dada2/test_join_model.clj
+++ dada2-core/src/test/clojure/org/dada2/test_join_model.clj
@@ -234,9 +234,13 @@
   (reify
    View
    ;; singleton changes
-   (on-upsert [_ upsertion] ((swap*! indeces lhs-upsert lhs-pk-key lhs-fk-keys upsertion join-fn join-pk joined-model) []) nil) ;TODO - pass in views to notifier
-   (on-delete [_ deletion]  ((swap*! indeces lhs-delete  lhs-pk-key lhs-fk-keys deletion join-fn join-pk joined-model) []) nil) ;TODO - pass in views to notifier
-   ;; batch changes
+   (on-upsert [_ upsertion]
+     ;;TODO - pass in views to notifier
+     ((swap*! indeces lhs-upsert lhs-pk-key lhs-fk-keys upsertion join-fn join-pk joined-model) []) nil)
+   (on-delete [_ deletion]
+     ;;TODO - pass in views to notifier
+     ((swap*! indeces lhs-delete  lhs-pk-key lhs-fk-keys deletion join-fn join-pk joined-model) []) nil)
+   ;; batch changes - TODO
    (on-upserts [_ upsertions] (swap! indeces lhs-upserts lhs-fk-keys upsertions join-fn) nil)
    (on-deletes [_ deletions]  (swap! indeces lhs-deletes lhs-fk-keys deletions join-fn) nil)))

@@ -280,7 +284,7 @@

 ;;; attach lhs to all rhses such that any change to an rhs initiates an
 ;;; attempt to [re]join it to the lhs and vice versa.
-(defn- join-views [join-fn join-pk [lhs-model lhs-pk-key lhs-fk-keys joined-model] & rhses]
+(defn- join-views [join-fn join-pk joined-model [lhs-model lhs-pk-key lhs-fk-keys] & rhses]
   (let [rhs-count (count rhses)
         ;; need 2 pass initialisation
 	indeces (atom [(lhs-init rhs-count)
@@ -310,8 +314,8 @@
   (^String toString [this] name)
   )

-(defn join-model [name joins join-fn join-pk]
-  (let [state (apply join-views join-fn join-pk joins)]
+(defn join-model [name joined-model joins join-fn join-pk]
+  (let [state (apply join-views join-fn join-pk joined-model joins)]
     (->JoinModel name state (atom []))))

 ;;--------------------------------------------------------------------------------
@@ -357,7 +361,7 @@
 	bs (versioned-optimistic-map-model (str :bs) :name :version >)
 	cs (versioned-optimistic-map-model (str :cs) :name :version >)
 	joined-model (versioned-optimistic-map-model (str :joined) :name :version abc-more-recent-than?)
-	join (join-model "join-model" [[as :name [:fk-b :fk-c] joined-model][bs :name :b][cs :name :c]] join-abc :name)
+	join (join-model "join-model" joined-model [[as :name [:fk-b :fk-c]][bs :name :b][cs :name :c]] join-abc :name)
 	view (test-view "test")
 	a1 (->A :a1 0 :b :c)
 	a1v1 (->A :a1 1 :b :c)


Only print server boot instructions if server isn't connected

--- src/overtone/core.clj
+++ src/overtone/core.clj
@@ -61,9 +61,10 @@
   'overtone.libs.freesound
   'overtone.version)

-(println "--> Please boot a server to start making noise:
+(when-not (server-connected?)
+  (println "--> Please boot a server to start making noise:
     * (boot-server)             ; boot default server (honours config)
     * (boot-internal-server)    ; boot an internal server
     * (boot-external-server)    ; boot an external server
     * (connect-external-server) ; connect to an existing external server
-")
+"))


allow test être-as-aux to accept vp-aux or vp-aux-22

--- test/babel/test/fr.cljc
+++ test/babel/test/fr.cljc
@@ -408,7 +408,8 @@
                               {:head (last (get lex "suis"))}))
                      (:grammar (small))))]
     (is (not (empty? result)))
-    (is (= (get-in (first result) [:rule]) "vp-aux"))))
+    (is (or (= (get-in (first result) [:rule]) "vp-aux")
+            (= (get-in (first result) [:rule]) "vp-aux-22")))))

 (deftest vp-aux-test
   (let [rule (first (filter #(= (:rule %) "vp-aux")


Generalize wrapping code

Generalize wrapping code

--- src/play_clj/core.clj
+++ src/play_clj/core.clj
@@ -108,17 +108,17 @@

 (defn set-screen-with-options!
   "Internal use only"
-  [^Game game screens error-fn]
+  [^Game game screens & {:keys [wrap]}]
   (let [add-inputs! (fn []
                       (input! :set-input-processor (InputMultiplexer.))
                       (doseq [{:keys [input-listeners]} screens]
                         (doseq [listener input-listeners]
                           (add-input! listener))))
         run-fn! (fn [k & args]
-                  (try
-                    (doseq [screen screens]
-                      (apply (get screen k) args))
-                    (catch Exception e (error-fn e))))]
+                  (doseq [screen screens]
+                    (if wrap
+                      (wrap (get screen k) args)
+                      (apply (get screen k) args))))]
     (.setScreen game (reify Screen
                        (show [this] (add-inputs!) (run-fn! :show))
                        (render [this d] (run-fn! :render d))
@@ -135,7 +135,7 @@

     (set-screen! hello-world main-screen text-screen)"
   [game & screens]
-  (set-screen-with-options! game screens #(throw %)))
+  (set-screen-with-options! game screens))

 (defn update!
   "Runs the equivalent of `(swap! screen-atom assoc ...)`, where `screen-atom`


Fix finally impl on cljs.

Fix finally impl on cljs.

--- src/promesa/impl.cljc
+++ src/promesa/impl.cljc
@@ -88,8 +88,8 @@
          ([it f] (.then it #(f % nil) #(f nil %)))
          ([it f e] (.then it #(f % nil) #(f nil %))))
        (-finally
-         ([it f] (-handle it f) it)
-         ([it f executor] (-handle it f executor) it))
+         ([it f] (.then it #(f % nil) #(f nil %)) it)
+         ([it f executor] (.then it #(f % nil) #(f nil %)) it))
        (-catch
          ([it f] (.catch it #(f %)))))))


Make core/react a function

Make core/react a function

That allows us to make react loading lazy in the future.

--- src/reagent/core.cljs
+++ src/reagent/core.cljs
@@ -13,7 +13,8 @@

 (def is-client util/is-client)

-(def react util/react)
+(defn react []
+  util/react)

 (defn create-element
   "Create a native React element, by calling React.createElement directly.
@@ -33,13 +34,13 @@
    (create-element type nil))
   ([type props]
    (assert (not (map? props)))
-   ($ react createElement type props))
+   ($ (react) createElement type props))
   ([type props child]
    (assert (not (map? props)))
-   ($ react createElement type props child))
+   ($ (react) createElement type props child))
   ([type props child & children]
    (assert (not (map? props)))
-   (apply ($ react :createElement) type props child children)))
+   (apply ($ (react) :createElement) type props child children)))

 (defn as-element
   "Turns a vector of Hiccup syntax into a React element. Returns form unchanged if it is not a vector."


translating create pager.js to clojurescript

--- examples/lesson-carousel-starter-kit/src/carousel/core.cljs
+++ examples/lesson-carousel-starter-kit/src/carousel/core.cljs
@@ -8,6 +8,18 @@
 (defonce FamousEngine (.. famous -core -FamousEngine))
 (defonce GestureHandler (.. famous -components -GestureHandler))
 (defonce Size (.. famous -core -Size))
+
+(defonce PhysicsEngine (.. famous -physics -PhysicsEngine))
+(defonce physics (.. famous -physics))
+(defonce math (.. famous -math))
+(defonce Box (.. physics -Box))
+(defonce Spring (.. physics -Spring))
+(defonce RotationalSpring (.. physics -RotationalSpring))
+(defonce RotationalDrag (.. physics -RotationalDrag))
+(defonce Quaternion (.. math -Quaternion))
+(defonce Vec3 (.. math -Vec3))
+
+(defonce ABSOLUTE (.. Size -ABSOLUTE))

 (defn decorate-arrow-node [arrow-node text]
   (.. (DOMElement. arrow-node)
@@ -20,7 +32,7 @@
       (setProperty "zIndex" "2"))
   (.. (GestureHandler. arrow-node) (on "tap" (fn []
                                                (println text))))
-
+
   )

 (defn decorate-dots [dots-node]
@@ -47,7 +59,7 @@
           (setProperty "borderRadius"  "5px")
           (setProperty "border"  "2px solid white")
           (setProperty "boxSizing"  "border-box")))
-
+
     (.. dots-node (addComponent resize))))

 (defn create-dots [root-node]
@@ -55,10 +67,10 @@
     (doseq [i (range 5)
             :let [dot-node (.. root-dot addChild)]]
       (.. dot-node
-          (setSizeMode (.. Size -ABSOLUTE) (.. Size -ABSOLUTE))
+          (setSizeMode ABSOLUTE  ABSOLUTE)
           (setAbsoluteSize 5 5)))
     (.. root-dot
-        (setSizeMode (.. Size -ABSOLUTE) (.. Size -ABSOLUTE))
+        (setSizeMode ABSOLUTE ABSOLUTE)
         (setAbsoluteSize 20 20)
         (setPosition 0 -50 0)
         (setAlign 0.5 1 0)
@@ -66,7 +78,50 @@
     root-dot))

 (defn create-pager [root-node]
-  (let [pager-node (.. root-node addChild)]
+  (let [pager-node (.. root-node addChild)
+        simulation (PhysicsEngine.)
+        url-base "http://demo.famo.us.s3.amazonaws.com/hub/apps/carousel/Museo_del_Prado_-_Goya_-_Caprichos_-_No._"
+        image-names ["01_-_Autorretrato._Francisco_Goya_y_Lucientes2C_pintor_thumb.jpg"
+                "02_-_El_si_pronuncian_y_la_mano_alargan_al_primero_que_llega_thumb.jpg"
+                "03_-_Que_viene_el_Coco_thumb.jpg"
+                "04_-_El_de_la_rollona_thumb.jpg"
+                "05_-_Tal_para_qual_thumb.jpg"
+                "06_-_Nadie_se_conoce_thumb.jpg"
+                "07_-_Ni_asi_la_distingue_thumb.jpg"
+                "09_-_Tantalo_thumb.jpg"
+                "10_-_El_amor_y_la_muerte_thumb.jpg"
+                "11_-_Muchachos_al_avC3ADo_thumb.jpg"
+                "12_-_A_caza_de_dientes_thumb.jpg"
+                "13_-_Estan_calientes_thumb.jpg"]
+        image-elements (map (fn [image-name]
+                              (let [_image-url (str url-base image-name)
+                                    image-url (str "url('" _image-url "')")
+                                    image-node (.. root-node addChild)
+                                    el (DOMElement. image-node)
+                                    box (Box. {:mass 100 :size [100 100 100]})
+                                    anchor (Vec3. 1 0 0)
+                                    spring (Spring. nil box {:period 0.5 :dampingRatio 0.5 :anchor anchor})
+                                    quaternion (.. (Quaternion.) (fromEuler 0  (/ (.. js/Math -PI) -2) 0))
+                                    rotational-spring (RotationalSpring nil  box {:period 1 :dampingRatio 0.2 :anchor quaternion})]
+                                (.. image-node
+                                    (setSizeMode ABSOLUTE ABSOLUTE ABSOLUTE)
+                                    (setAbsoluteSize 500 500 0)
+                                    (setAlign 0.5 0.5)
+                                    (setMountPoint 0.5 0.5)
+                                    (setOrigin 0.5 0.5))
+                                (.. el
+                                    (setProperty "backgroundImage"  image-url)
+                                    (setProperty "background-repeat" "no-repeat")
+                                    (setProperty "background-size" "cover"))
+                                ))
+                            image-names)
+
+        pager {:node pager-node
+               :onUpdate (fn [time]
+                           (.. simulation (update time))
+
+                           )
+               }]
     pager-node
     )
   )


protect from socket errors

protect from socket errors

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -1,7 +1,8 @@
 (ns riemann.xymon
   "Forwards events to Xymon"
-  (:require [clojure.java.io :as io]
-            [clojure.string  :as s])
+  (:require [clojure.java.io       :as io]
+            [clojure.string        :as s]
+            [clojure.tools.logging :refer [error]])
   (:import java.net.Socket))

 (defn format-line
@@ -18,10 +19,13 @@
   "Connects to Xymon server, sends line, then closes the connection.
    This is a blocking operation and should happen on a separate thread."
   [opts line]
-  (with-open [sock   (Socket. (:host opts) (:port opts))
-              writer (io/writer sock)]
-    (.write writer line)
-    (.flush writer)))
+  (try
+    (with-open [sock   (Socket. (:host opts) (:port opts))
+                writer (io/writer sock)]
+      (.write writer line)
+      (.flush writer))
+    (catch Exception e
+      (error e "could not reach xymon host"))))

 (defn xymon
   "Returns a function which accepts an event and sends it to Xymon.


xymon.clj: event->disable: using ttl as duration

--- src/riemann/xymon.clj
+++ src/riemann/xymon.clj
@@ -63,10 +63,11 @@
   Fields mapping is the same as event-status'.
   "
   [{:keys [host service duration description]
-    :or {host "" service "*" duration "" description ""}}]
+    :or {host "" service "*" ttl "" description ""}}]
   (let [host (host->xymon host)
         service (service->xymon service)]
-    (format "disable %s.%s %s %s" host service duration description)))
+    (format "disable %s.%s %s %s"
+            host service (int (ceil (/ ttl 60))) description)))

 (defn send-line
   "Connects to Xymon server, sends line, then closes the connection.


add octave syntax to note, work on fixing rests

--- src/semitone/core.clj
+++ src/semitone/core.clj
@@ -61,9 +61,11 @@
                           :repeat-length 0
                           :notes (rest notes)}))
           (if-let [m (re-matches #"([-=])[-=]*" (name length))]
-            (merge state {:repeat-length (* (:length state) (count (name length)))
-                          :key (if (= "=" (get m 1)) (:key state) nil)
-                          :notes (rest notes)})
+            (do
+              (pprint m)
+              (merge state {:repeat-length (* (:length state) (count (name length)))
+                            :key (if (= "=" (get m 1)) (:key state) nil)
+                            :notes (rest notes)}))
             state))
         :else state))))

@@ -75,21 +77,22 @@
       (merge state {:key (first notes) :notes (rest notes)})
       (let [note (clojure.string/replace (name (first notes)) #"__[0-9]+__auto__$" "#")]
         ;; note on/off / key pressure by key name
-        (if-let [m (re-matches #"(&|-|)([a-gA-G])(#|##|b|bb|n|)(-|)" note)]
+        (if-let [m (re-matches #"(&|-|)([a-gA-G])(#|##|b|bb|n|)(-?[0-9]+|)(-|)" note)]
           (let [note-map {"C" -12 "D" -10 "E" -8 "F" -7 "G" -5 "A" -3 "B" -1
                           "c" 0 "d" 2 "e" 4 "f" 5 "g" 7 "a" 9 "b" 11}
                 accidental-map {"#" 1 "##" 2 "b" -1 "bb" -2 "n" 0 "" nil}
                 key-pressure (= "&" (get m 1))
                 key (get note-map (get m 2))
+                octave (if (= "" (get m 4)) (:octave state) (Integer. (get m 4)))
                 accidental (or (get accidental-map (get m 3))
                                (get (:key-signature state) (clojure.string/lower-case (get m 2)))
                                0)]
             (merge state {:key-type (if key-pressure ShortMessage/POLY_PRESSURE ShortMessage/NOTE_ON)
                           :tie (cond
                                  (= "-" (get m 1)) :end
-                                 (= "-" (get m 4)) :begin
+                                 (= "-" (get m 5)) :begin
                                  :else nil)
-                          :key (mod (+ (* (+ 1 (:octave state)) 12) key accidental) 128)
+                          :key (mod (+ (* (+ 1 octave) 12) key accidental) 128)
                           :param (if key-pressure :key-pressure :octave)
                           :notes (rest notes)}))
           ;; cc
@@ -138,7 +141,7 @@
                            {:key-type ShortMessage/NOTE_ON
                             :tie (cond
                                    (= "-k" (get m 1)) :end
-                                   (= "-" (get m 4)) :begin
+                                   (= "-" (get m 5)) :begin
                                    :else nil)
                             param value
                             :param param}
@@ -198,7 +201,7 @@
                       :cc-value 0
                       :tempo 120
                       :length (.getResolution (.getSequence sequencer))
-                      :repeat-length 0}
+                      :repeat-length (.getResolution (.getSequence sequencer))}
                      (or state {}))]
     (loop [notes notes state state]
       (if (not (empty? notes))
@@ -325,6 +328,6 @@

   ;; add some music to the sequencer and start
   ;; (pprint (play sequencer `(:tempo 120 i c d e f g a b > c)))
-  (pprint (play sequencer `(=== == =)))
+  (pprint (play sequencer `(c - d - e - f - g)))
   (println (.getSequence sequencer)))


Rename :generated to :sample-edn

Rename :generated to :sample-edn

--- test/transit/verify.clj
+++ test/transit/verify.clj
@@ -164,7 +164,7 @@
     (try
       (let [results (-> results
                         (assoc-in [:tests :sample-file] (test-sample-files proc encoding ))
-                        (assoc-in [:tests :generated] (test-edn proc encoding)))]
+                        (assoc-in [:tests :sample-edn] (test-edn proc encoding)))]
         (stop-process proc)
         results)
       (catch Throwable e


scaling

scaling

--- src/sormilla/core.clj
+++ src/sormilla/core.clj
@@ -31,6 +31,15 @@
   `(let [t# (.getTransform ~g)]
      ~@body
      (.setTransform ~g t#)))
+
+(defn normalizer [[f1 f2] [t1 t2]]
+  (let [r (/ (- t2 t1) (- f2 f1))]
+    (fn [v]
+      (+ (* (- v f1) r) t1))))
+
+(defn scale [v fmin fmax tmin tmax]
+  (let [r (/ (- tmax tmin) (- fmax fmin))]
+    (+ (* (- v fmin) r) tmin)))

 (defn render [^Graphics2D g ^long w ^long h frame]
   (.setColor g background-color)
@@ -69,8 +78,10 @@
       (.setClip g (Rectangle. 0 0 (dec (/ w 2)) (dec (- h th))))
       (with-trans g
         (.translate g (double (/ w 4)) (double (/ (- h th) 2)))
-        (.translate g (:yaw left-hand) (:pitch left-hand))
-        (.rotate g (:roll left-hand))
+        (.translate g
+          (scale (:yaw left-hand) -0.6 +0.6 (/ w -4) (/ w 4))
+          (scale (:pitch left-hand) -1.5 +1.5 (/ w 4) (/ w -4)))
+        (.rotate g (- (:roll left-hand)))
         (.setColor g left-hand-lo-color)
         (.fillOval g -150 -20 300 40)
         (.setColor g left-hand-color)
@@ -100,8 +111,8 @@

 (defn dymmy-source []
   {:left {:finger-count    3
-          :pitch           10.0
-          :yaw             -30.0
+          :pitch           1.0
+          :yaw             0.0
           :roll            0.1}
    :right {:finger-count   1
            :pitch          0.5


cleanup

cleanup

--- src/sormilla/leap.clj
+++ src/sormilla/leap.clj
@@ -4,14 +4,26 @@

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

+(defn x [^Finger finger]
+  (-> finger .tipPosition .getX))
+
+(defn middle-finger ^Finger [^FingerList fingers]
+  (when (pos? (.count fingers))
+    (nth (sort-by x (seq fingers)) (/ (.count fingers) 2))))
+
+(defn direction ^Vector [^Finger finger]
+  (when finger
+    (.direction finger)))
+
 (defn ->hand [^Hand hand]
-  (when (and hand (.isValid hand))
-    (let [fingers     (.fingers hand)
-          direction   (-> fingers .frontmost .direction)]
-      {:quality       (.count fingers)
-       :pitch         (-> direction .pitch double)
-       :yaw           (-> direction .yaw double)
-       :roll          (-> hand .palmNormal .roll double)})))
+  (when (.isValid hand)
+    (let [fingers  (.fingers hand)
+          aim      (-> fingers middle-finger direction)]
+      (when aim
+        {:quality       (.count fingers)
+         :pitch         (-> aim .pitch double)
+         :yaw           (-> aim .yaw double)
+         :roll          (-> hand .palmNormal .roll double)}))))

 (defn connect ^Controller []
   (Controller.))
@@ -22,7 +34,7 @@
   (let [hands         (-> connection .frame .hands)
         hand-count    (.count hands)]
     [(when (> hand-count 1) (->hand (.leftmost hands)))
-     (when (pos? hand-count) (->hand (.rightmost hands)))]))
+     (when (> hand-count 0) (->hand (.rightmost hands)))]))

 (comment


Rewrite get-fuzzy so it does less work when the key is at hand.

--- src/stencil/utils.clj
+++ src/stencil/utils.clj
@@ -64,8 +64,10 @@
   ([map key]
      (get-fuzzy map key nil))
   ([map key not-found]
-     (get map key (get map (name key)
-                       (get map (keyword key) not-found)))))
+     (or (get map key)
+         (get map (name key))
+         (get map (keyword key))
+         not-found)))

 (defn assoc-fuzzy
   "Just like clojure.core/assoc, except considers keys that are keywords and


Add retry mechanism to rstore.

Add retry mechanism to rstore.

That allows does not close all streams on first 1024 errors.

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

 (defn init
   "Initializes the stream event loop and
@@ -102,6 +102,7 @@
         state-s (->> update-s
                      (rx/scan #(-apply-update %2 %1) state)
                      (rx/catch on-error)
+                     (rx/retry 1024)
                      (rx/share))]

     ;; Process event sources: combine with the latest model and the result will be
@@ -110,6 +111,7 @@
       (rx/with-latest-from vector state-s $)
       (rx/flat-map (fn [[event model]] (-apply-watch event model stream)) $)
       (rx/catch on-error $)
+      (rx/retry 1024 $)
       (rx/on-value $ emit!))

     ;; Process effects: combine with the latest model to process the new effect


clear out current-project data when you go to the dashboard

--- frontend/controllers/navigation.cljs
+++ frontend/controllers/navigation.cljs
@@ -104,7 +104,8 @@
              :navigation-settings {:show-settings-link false}
              :recent-builds nil)
       (state-utils/set-dashboard-crumbs args)
-      state-utils/reset-current-build))
+      state-utils/reset-current-build
+      state-utils/reset-current-project))

 (defmethod post-navigated-to! :dashboard
   [history-imp navigation-point args previous-state current-state]


Don't use version ranges, depend on Clojure 1.5.1

--- metrics-clojure-core/project.clj
+++ metrics-clojure-core/project.clj
@@ -1,6 +1,6 @@
 (defproject metrics-clojure "0.10.0-SNAPSHOT"
   :description "A Clojure façade for Coda Hale's metrics library."
-  :dependencies [[org.clojure/clojure "[1.2.1,1.4.0]"]
+  :dependencies [[org.clojure/clojure             "1.5.1"]
                  [com.yammer.metrics/metrics-core "2.2.0"]]
   :repositories {"repo.codahale.com" "http://repo.codahale.com"
                  ;; to get Clojure snapshots


Allows raw specs as parameters

Allows raw specs as parameters

--- modules/reitit-core/src/reitit/spec.cljc
+++ modules/reitit-core/src/reitit/spec.cljc
@@ -74,7 +74,7 @@
 ;; coercion
 ;;

-(s/def :reitit.core.coercion/kw-map (s/map-of keyword? any?))
+(s/def :reitit.core.coercion/kw-map (s/or :map (s/map-of keyword? any?) :spec s/spec?))

 (s/def :reitit.core.coercion/query :reitit.core.coercion/kw-map)
 (s/def :reitit.core.coercion/body :reitit.core.coercion/kw-map)


offset phase by a half to ensure the min point is start and end of phase

--- etc/synthdefs/synth-designs.clj
+++ etc/synthdefs/synth-designs.clj
@@ -1655,6 +1655,7 @@
           res                 (lag res res_slide)
           cutoff_min          (midicps cutoff_min)
           cutoff_max          (midicps cutoff_max)
+          phase_offset        (+ phase_offset 0.5)
           double_phase_offset (* 2 phase_offset)
           ctl-wave            (select:kr wave [(lf-saw:kr rate double_phase_offset)
                                                (- (* 2 (lf-pulse:kr rate phase_offset pulse_width)) 1)


divide model-building into multiple-stages

--- src/babel/italiano/grammar.cljc
+++ src/babel/italiano/grammar.cljc
@@ -731,7 +731,7 @@
         debug (log/info "  indices..")
         indices (create-indices lexicon-for-generation index-lexicon-on-paths)
         debug (log/info "  finalizing..")
-        retval
+        stage-1
         {:index-fn (fn [spec] (lookup-spec spec indices index-lexicon-on-paths))
          :default-fn default-fn
          :name "model"
@@ -746,35 +746,39 @@
          :morph-ps fo-ps
          :rules rules
          :rule-map (zipmap rules grammar)
-         :tenses tenses}]
-    (merge retval
-           {:generate-fn (fn [spec] (generate/generate spec retval))
-            :bolts
-            (merge
-             (let [depth 2
-                   spec
-                   {:synsem {:subcat []
-                             :cat :verb
-                             :sem {:tense :present
-                                   :reflexive :top
-                                   :aspect :perfect}}}]
-               {(merge {:depth depth}
-                       spec)
-                (lightning-bolts retval
-                                 spec
-                                 0 depth)})
-             (let [depth 3
-                   spec
-                   {:synsem {:subcat []
-                             :cat :verb
-                             :sem {:tense :present
-                                   :reflexive :top
-                                   :aspect :perfect}}}]
-               {(merge {:depth depth}
-                       spec)
-                (lightning-bolts retval
-                                 spec
-                                 0 depth)}))})))
+         :tenses tenses}
+        stage-2
+        (merge stage-1
+               {:generate-fn (fn [spec] (generate/generate spec stage-1))})]
+
+    (merge
+     stage-2
+     {:bolts
+      (merge
+       (let [depth 2
+             spec
+             {:synsem {:subcat []
+                       :cat :verb
+                       :sem {:tense :present
+                             :reflexive :top
+                             :aspect :perfect}}}]
+         {(merge {:depth depth}
+                 spec)
+          (lightning-bolts stage-2
+                           spec
+                           0 depth)})
+       (let [depth 3
+             spec
+             {:synsem {:subcat []
+                       :cat :verb
+                       :sem {:tense :present
+                             :reflexive :top
+                             :aspect :perfect}}}]
+         {(merge {:depth depth}
+                 spec)
+          (lightning-bolts stage-2
+                           spec
+                           0 depth)}))})))

 (defn model-with-vocab-items [vocab-items filter-lexicon-fn model]
   (let [input-lexicon (map vocab-entry-to-lexeme vocab-items)


added partire

added partire

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -1632,6 +1632,9 @@

       (unify common2 intransitive intransitive-unspecified-obj)))

+    "partire" {:synsem {:essere true
+                            :cat :verb
+                            :sem {:pred :leave}}}

     "pensare"
     {:synsem {:cat :verb


spacing

spacing

--- src/babel/italiano/lexicon.cljc
+++ src/babel/italiano/lexicon.cljc
@@ -1057,28 +1057,28 @@
          (unify essere-common {:notes "be"
                                :synsem {:sem {:pred :be}}})

-           ;; essere: copula ;; note that we don't enforce agreement the same here as we do in essere-adjective: TODO: try to make more consistent.
-           (let [gender (atom :top)
-                 number (atom :top)
-                 human (atom :top)]
-             (unify
-              transitive
-              essere-common
-              {:notes "copula" ;; significant only for debugging.
-               :synsem {:cat :verb
-                        :subcat {:1 {:cat :noun
-                                     :agr {:gender gender
-                                           :number number}}
-                                 :2 {:cat :noun
-                                     :pronoun {:not true} ;; accusative pronouns cause unbounded depth-first searches on the subject side. (TODO: not sure if this problem is still present)
-                                     :def {:not :demonstrativo}
-                                     :agr {:gender gender
-                                           :number number}}}
-                        :sem {:pred :be
-                              :activity false
-                              :discrete false
-                              :subj {:human human}
-                              :obj {:human human}}}}))
+         ;; essere: copula ;; note that we don't enforce agreement the same here as we do in essere-adjective: TODO: try to make more consistent.
+         (let [gender (atom :top)
+               number (atom :top)
+               human (atom :top)]
+           (unify
+            transitive
+            essere-common
+            {:notes "copula" ;; significant only for debugging.
+             :synsem {:cat :verb
+                      :subcat {:1 {:cat :noun
+                                   :agr {:gender gender
+                                         :number number}}
+                               :2 {:cat :noun
+                                   :pronoun {:not true} ;; accusative pronouns cause unbounded depth-first searches on the subject side. (TODO: not sure if this problem is still present)
+                                   :def {:not :demonstrativo}
+                                   :agr {:gender gender
+                                         :number number}}}
+                      :sem {:pred :be
+                            :activity false
+                            :discrete false
+                            :subj {:human human}
+                            :obj {:human human}}}}))

            ;; essere: intensifier
            ;; this is for e.g "essere più alto di quelle donne belle (to be taller than those beautiful women)"