more utils

more utils

error: pathspec 'src/clj/bluebell/utils.clj' did not match any file(s) known to git

--- src/clj/bluebell/utils.clj
+++ src/clj/bluebell/utils.clj
@@ -0,0 +1,199 @@
+(ns bluebell.utils
+  (:require [clojure.spec.alpha :as spec]))
+
+(defmacro check [& args]
+  (cond
+    (empty? args) (throw (ex-info "No arguments to check" {}))
+    #_(= 1 (count args)) #_(let [[c] args]
+                         `(if (not ~c)
+                            (throw (ex-info "Check failed"
+                                            {:value ~c
+                                             :str ~(str c)}))))
+    :default
+    (let [[pred & data] args
+          asyms (repeatedly (count data) gensym)]
+      `(let [pred# ~pred
+             ~@(reduce into [] (map vector asyms data))]
+         (if (pred# ~@asyms)
+           ~(first asyms)
+           (throw (ex-info "Check failed"
+                           {:pred-expr (quote ~pred)
+                            :pred-value pred#
+                            :value-expr (quote ~data)
+                            :value ~(vec asyms)})))))))
+
+(defn non-conforming-error [sp x]
+  (throw (ex-info "Does not conform to spec"
+                  {:spec sp
+                   :value x
+                   :explanation (spec/explain-str sp x)})))
+
+(defn validate [sp x]
+  (if (spec/valid? sp x)
+    x
+    (non-conforming-error sp x)))
+
+(defn validate-conform [sp x]
+  (let [c (spec/conform sp x)]
+    (if (= c ::spec/invalid)
+      (non-conforming-error sp x)
+      c)))
+
+(defn map-with-keys?
+  ([ks]
+   #(map-with-keys? % ks))
+  ([x ks]
+   (check coll? ks)
+   (and (map? x)
+        (every? (partial contains? x) ks))))
+
+(defn classify
+  ([classifier data]
+   (classify classifier [] data))
+  ([classifier empty-dst data]
+   (reduce
+    (fn [dst item]
+      (update dst (classifier item) (fn [dst] (conj (or dst empty-dst) item))))
+    {}
+    data)))
+
+(defn int-floor [x]
+  (int (Math/floor x)))
+
+(defn int-ceil [x]
+  (int (Math/ceil x)))
+
+(defn greater [x]
+  (inc (int-floor x)))
+
+(defn greater-or-equal [x]
+  (let [y (int-floor x)]
+    (if (< y x)
+      (inc y)
+      y)))
+
+(defn less [x]
+  (dec (int-ceil x)))
+
+(defn less-or-equal [x]
+  (let [y (int-ceil x)]
+    (if (< x y)
+      (dec y)
+      y)))
+
+(defn rotate [src steps]
+  (let [src (vec src)
+        n (count src)]
+    (mapv (fn [index] (nth src (mod (+ steps index) n)))
+          (range n))))
+
+(defn check-arg-map [arg-spec arg-map]
+  (check map? arg-spec)
+  (check map? arg-map)
+  (doseq [[k checker] arg-spec]
+    (if (contains? arg-map k)
+      (let [v (get arg-map k)]
+        (cond
+          (keyword? checker) (validate checker v)
+          (not (checker v)) (throw (ex-info "Failed arg-spec"
+                                            {:key k
+                                             :value v}))))
+      (throw (ex-info "Missing key"
+                      {:key k}))))
+  ::success)
+
+(defmacro check-arg-list [predicates args-expr]
+  (check sequential? predicates)
+  (let [n (count predicates)
+        syms (take n (repeatedly gensym))]
+    `(let [args# ~args-expr]
+       (if (= ~n (count args#))
+         (let [[~@syms] args#]
+           ~@(map (fn [i pred sym]
+                    `(if (not (~pred ~sym))
+                       (throw (ex-info "Bad argument"
+                                       {:index ~i
+                                        :predicate (quote ~pred)
+                                        :value ~sym}))))
+                  (range) predicates syms)
+           args#)
+         (throw (ex-info "Wrong length of arguments"
+                         {:expected (quote ~predicates)
+                          :provided args#}))))))
+
+(defn clamp [x lower upper]
+  (min upper (max x lower)))
+
+
+(defn maximize [ordered-items0 valid-fn]
+  (let [ordered-items (vec ordered-items0)
+        n (count ordered-items)]
+    (if (< 0 n)
+      (let [mid (int (/ n 2))
+            item (nth ordered-items mid)]
+        (if (valid-fn item)
+          (if (= 1 n)
+            item
+            (maximize (subvec ordered-items mid n) valid-fn))
+          (maximize (subvec ordered-items 0 mid) valid-fn))))))
+
+(defn assign-indices
+  ([values]
+   (assign-indices values :index))
+  ([values index-key]
+   (map (fn [dst i] (assoc dst index-key i))
+        values
+        (range))))
+
+(defn interpolate [x [x0 x1] [y0 y1]]
+  (let [lambda (/ (- x x0) (- x1 x0))]
+    (+ (* (- 1 lambda) y0)
+       (* lambda y1))))
+
+(defn repeat-cat [s]
+  (let [v (vec s)
+        n (count s)]
+    (map #(nth v (mod % n)) (range))))
+
+(defn butlast-vec [v]
+  (let [v (vec v)]
+    (subvec v 0 (dec (count v)))))
+
+
+(defn- solve-key-indirection [m k]
+  (let [v (get m k)]
+    (if (contains? m v)
+      (let [m (solve-key-indirection m v)]
+        (assoc m k (get m v)))
+      m)))
+
+(defn solve-key-indirections [m]
+  (reduce
+   solve-key-indirection
+   m
+   (keys m)))
+
+(defn map-vals [f m]
+  (into (empty m)
+        (for [[k v] m]
+          [k (f v)])))
+
+(defn check-get [m k]
+  (if (contains? m k)
+    (get m k)
+    (throw (ex-info "Missing key"
+                    {:map m
+                     :key k}))))
+
+(defmacro dout [& args]
+  `(do
+     ~@(for [arg args]
+         `(let [arg# ~arg]
+            (println ~(str arg) "=" arg#)
+            arg#))))
+
+(defn nested-map [f data]
+  (for [x data]
+    (if (coll? x)
+      (nested-map f x)
+      (f x))))


inline map-or-abort, only used in one place and does much more than mapping and aborting

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tobiasbayer/lambdacd.git/'


use namespace alias to refer to clojure.string functions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Yleisradio/yle-api-template.git/'


Always re-dispatch the route on page load

This makes development easier as the current files list will always be reloaded,
and doesn't change anything at all for the (forthcoming, presumably...) live
version.

--- ui/src/bucket/routes.cljs
+++ ui/src/bucket/routes.cljs
@@ -57,6 +57,5 @@

 ;; listen for state change events and dispatch when they happen
 (defonce setup
-  (do
-    (.addEventListener js/window "popstate" dispatch-current-path!)
-    (dispatch-current-path!)))
+  (.addEventListener js/window "popstate" dispatch-current-path!))
+(dispatch-current-path!)


Some documentation.

Some documentation.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/couragelabs/coachbot.git/'


added json-html css

added json-html css

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Zallin/fhirvc.git/'


make create-order-params more concise

make create-order-params more concise

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/starcity-properties/odin.git/'


Add asciicast model ns

Add asciicast model ns

error: pathspec 'src/asciinema/model/asciicast.clj' did not match any file(s) known to git

--- src/asciinema/model/asciicast.clj
+++ src/asciinema/model/asciicast.clj
@@ -0,0 +1,13 @@
+(ns asciinema.model.asciicast)
+
+(defn json-store-path [{:keys [id file stdout_frames]}]
+  (cond
+    file (str "asciicast/file/" id "/" file)
+    stdout_frames (str "asciicast/stdout_frames/" id "/" stdout_frames)))
+
+(def default-theme "asciinema")
+
+(defn theme-name [asciicast user]
+  (or (:theme_name asciicast) ; ensure we don't store empty strings in db
+      (:theme_name user)
+      default-theme))


Minor formatting experiment

Minor formatting experiment

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/aneeshpu/pms.git/'


Add classifier tests

Add classifier tests

error: pathspec 'test/bejeweled_bot/gem_classifier_test.clj' did not match any file(s) known to git

--- test/bejeweled_bot/gem_classifier_test.clj
+++ test/bejeweled_bot/gem_classifier_test.clj
@@ -0,0 +1,26 @@
+(ns bejeweled-bot.gem-classifier-test
+  (:require [clojure.test :refer :all]
+            [bejeweled-bot.gem-classifier :refer :all]))
+
+
+(deftest classify-test
+  (testing "classies correctly"
+    (let
+      [rgb {:red 230, :green 101, :blue 33}
+       gem :sapphire]
+      (is (= gem (classify rgb))))
+    (let
+      [rgb {:red 254, :green 245, :blue 35}
+       gem :topaz]
+      (is (= gem (classify rgb))))))
+
+(deftest classify-test-non-exact-match
+  (testing "classies correctly even with close enough but not exact rgb"
+    (let
+      [rgb {:red 250, :green 101, :blue 33}
+       gem :sapphire]
+      (is (= gem (classify rgb))))
+    (let
+      [rgb {:red 254, :green 205, :blue 35}
+       gem :topaz]
+      (is (= gem (classify rgb))))))


Add seaport terrain info

Add seaport terrain info

--- src/cljs/zetawar/data.cljs
+++ src/cljs/zetawar/data.cljs
@@ -94,7 +94,9 @@
      :deep-water    {:description "Deep Water"
                      :image "tilesets/elite-command/terrains/deep-water.png"}
      :base          {:description "Base"
-                     :image "tilesets/elite-command/terrains/base-COLOR.png"}}
+                     :image "tilesets/elite-command/terrains/base-COLOR.png"}
+     :seaport       {:description "Seaport"
+                     :image "tilesets/elite-command/terrains/seaport-COLOR.png"}}

     :unit-state-maps
     {:move-attack


fixes for loinc VS expansions

fixes for loinc VS expansions

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/fhirbase/fhirterm.git/'


Anagram in clojure, first attempt.

Anagram in clojure, first attempt.

error: pathspec 'clojure/anagram/anagram.clj' did not match any file(s) known to git

--- clojure/anagram/anagram.clj
+++ clojure/anagram/anagram.clj
@@ -0,0 +1,11 @@
+(ns anagram
+  (:require [clojure.string :as str]))
+
+(defn- normalizeWord [word]
+  (sort (str/upper-case word)))
+
+(defn anagrams-for [word, candidates]
+  (let [normWord (normalizeWord word)]
+    (filter (fn [candidate]
+      (= normWord (normalizeWord candidate)))
+      candidates)))


Feature - appId now consists of hostname, initialising/main class and pid

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ChallenHB/samsara.git/'


Adjust with of content to match designAdjust with of content to match designss


using aero on config.edn file, if no params are passed

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/maoo/bot-unfurl.git/'


add comment to document/create-multi: does not work yet; and make private

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/colophon/clarango.git/'


refactoring

refactoring


Adding spec style registry for keyword documentation

error: pathspec 'src/cljc/zetawar/doc.cljc' did not match any file(s) known to git

--- src/cljc/zetawar/doc.cljc
+++ src/cljc/zetawar/doc.cljc
@@ -0,0 +1,23 @@
+(ns zetawar.doc
+  (:refer-clojure :exclude [def]))
+
+(defonce ^:private registry-ref (atom {}))
+
+(defn def
+  "Given a namespace-qualified keyword k and a docstring, makes an entry in the
+  registry mapping k to the docstring."
+  [k docstring]
+  (c/assert (c/and (keyword? k) (namespace k)) "k must be namespaced keyword")
+  (swap! registry-ref assoc k docstring)
+  k)
+
+(defn registry
+  "Returns the registry map, prefer 'get-docstring' to lookup a docstring by
+  name."
+  []
+  @registry-ref)
+
+(defn get-doc
+  "Returns docstring registered for keyword or nil."
+  [k]
+  (get (registry) k))


Make the wiped hashes login message more descriptive

People seeing that message might not immediately realise that the hashes
were wiped long ago, and the message is probably not relevant to them.

--- src/clojars/web/login.clj
+++ src/clojars/web/login.clj
@@ -15,7 +15,7 @@

     (when login_failed
       [:div [:p.error "Incorrect username and/or password."]
-       [:p.hint "If you have not logged in since "
+       [:p.hint "If you have not logged in since April 2012 when "
         [:a {:href "https://groups.google.com/group/clojure/browse_thread/thread/5e0d48d2b82df39b"}
          "the insecure password hashes were wiped"]
         ", please use the " [:a {:href "/forgot-password"} "forgot password"]


Add `take-while-ascending` stuff.

Add `take-while-ascending` stuff.

error: pathspec 'test/com/nomistech/clojure_the_language/take_while_ascending_etc_test.clj' did not match any file(s) known to git

--- test/com/nomistech/clojure_the_language/take_while_ascending_etc_test.clj
+++ test/com/nomistech/clojure_the_language/take_while_ascending_etc_test.clj
@@ -0,0 +1,42 @@
+(ns com.nomistech.clojure-the-language.take-while-ascending-etc-test
+  (:require [midje.sweet :refer :all]))
+
+
+;; Or was what you did at the Citi interview better?
+;; - partition into pairs...
+
+(defn take-while-binary-pred
+  [pred coll]
+  (letfn [(helper [[x & xs]]
+            (lazy-seq
+             (cons x (when (and (seq xs)
+                                (pred x (first xs)))
+                       (helper xs)))))]
+    (let [s (seq coll)]
+      (if (seq s)
+        (helper s)
+        s))))
+
+(def take-while-strictly-ascending
+  (partial take-while-binary-pred <))
+
+;; --------
+
+(fact (take-while-strictly-ascending [1 3 6 4 9])
+  => [1 3 6])
+
+(fact (take-while-strictly-ascending [1 3 6 6 9])
+  => [1 3 6])
+
+(fact (take-while-strictly-ascending [1 0])
+  => [1])
+
+(fact (take-while-strictly-ascending [1])
+  => [1])
+
+(fact
+  (take-while-strictly-ascending [])
+  => nil)
+
+(fact (take-while-strictly-ascending [1 3 6 10])
+  => [1 3 6 10])


Improve docsite tool.

Improve docsite tool.

--- dev-resources/utils/docsite.clj
+++ dev-resources/utils/docsite.clj
@@ -4,7 +4,8 @@
             [hiccup
              [core :as h]
              [page :as p]
-             [element :as e]]
+             [element :as e]
+             [util :as u]]
             garden.core
             [garden.units :refer [px]]
             [garden.arithmetic :as ga]
@@ -95,6 +96,11 @@
                                  "," ""
                                  "&" "and"})))

+(defn- as-id [str]
+  (-> str
+      (string/lower-case)
+      (string/replace "?" "_q")))
+
 (defn- as-filename [& path]
   (->> path (map as-url) (string/join "/")))

@@ -109,9 +115,9 @@
   ([text to anchor]
      (let [page (if to (as-filename-ext to) "")]
       (e/link-to (if anchor
-                   (str page "#" (as-url anchor))
+                   (str page "#" (as-url (as-id anchor)))
                    page)
-                 text))))
+                 (u/escape-html text)))))

 (defn trim-docstring
   "Removes extra spaces in the begginning of dostringing lines."
@@ -133,7 +139,7 @@
                                                  [:code processing-name])
                                                "None. It is present only in Quil.")
                 "Added in" added)]
-    [:div.function {:id name}
+    [:div.function {:id (as-id name)}
      [:h3 name]
      [:dl (for [[key val] fields]
             (list [:dt key] [:dd val]))]]))
@@ -145,8 +151,8 @@
         function->html (comp function->html fn-metas)
         subcat->html (fn [subcat]
                        (cons [:h3.subcategory
-                              {:id (subcat-id subcat)}
-                              (:name subcat)]
+                              {:id (as-id (subcat-id subcat))}
+                              (u/escape-html (:name subcat))]
                              (map function->html (:fns subcat))))
         subcat->toc (fn [subcat]
                       (cons [:h4.subcategory (link (:name subcat) nil (subcat-id subcat))]
@@ -187,7 +193,7 @@
           (column->html [column]
             [:div.column (map (comp category->html find-category) column)])]
     [:div.wrapper
-     [:h1#title "Quil 2.1.0 API"]
+     [:h1#title "Quil 2.2.0 API"]
      [:div#description
       [:p "Quil is a clojure animation library for creating interactive sketches. "]
       [:p


monte-carlo-simulations:: solving the monty-hall problem in clojure

error: pathspec 'src/clojure_learning/monte_carlo/monty_hall_problem.clj' did not match any file(s) known to git

--- src/clojure_learning/monte_carlo/monty_hall_problem.clj
+++ src/clojure_learning/monte_carlo/monty_hall_problem.clj
@@ -0,0 +1,116 @@
+(ns clojure-learning.monte-carlo.monty-hall-problem)
+
+;; Monty Hall in Monte Carlo
+;; https://data-sorcery.org/2009/06/23/monty-hall-in-monte-carlo/
+
+;; each room has a weight of 1/3 chances of wining. Once a room has been selected,
+;; before opening it, Monty will then OPEN the door of another room. That room
+;; is DEFINETELLY NOT the winner, leaving you the choosing option to select the LAST
+;; maybe winner door(switching the already selected room). Monty will NOT provide
+;; the door-openining for the winner room by any means. So the thing concludes whether
+;; the chances of switching between the already selected(but not opened door)
+;; and the last-room.
+
+;; for a range of generated 1000 attempts -> check what are the chances of winning
+;; if choosing the already-selected door
+;; for a range of generated 1000 attempts -> check what are the chances of wining
+;; if choosing the last door(not the one selected, not the one opened by Monty)
+
+;; Set a simulation sample size, generate samples of initial-guesses, prize-doors,
+;; and switch decisions with the sample function. The probability that the prize is
+;; behind any of the three doors is 1/3, as is the probability that you select a particular
+;; door as an initial guess, while the probability that you switch doors is 1/2.
+
+(defrecord Door [door-idx prize])
+
+(defn doors-generator []
+  "will generate 3 rooms guarded by doors and will place a prize inside a
+   randomly chose room, leaving the other 2 rooms with some goats inside"
+  (let [doors-idxs (take 3 (iterate inc 1))
+        rand-prize-room (rand-nth doors-idxs)]
+    (map (fn [door-idx]
+           (if (= rand-prize-room door-idx)
+               (Door. door-idx :win)
+               (Door. door-idx :goat)))
+          doors-idxs)
+))
+
+(doors-generator)
+#_({:door 1, :prize :goat}
+  {:door 2, :prize :win}
+  {:door 3, :prize :goat})
+#_({:door 1, :prize :win}
+  {:door 2, :prize :goat}
+  {:door 3, :prize :goat})
+
+(defn select-door-nmber [] (rand-nth (take 3 (iterate inc 1))))
+(select-door-nmber) ;; randomly chose rooom-number between 1..3
+
+(defn get-selected-door [doors selected-door-nmber]
+  (first (filter #(= selected-door-nmber (.door-idx %)) doors)))
+
+(get-selected-door [(Door. 1 :goat)] 1) ;; {:door-idx 1, :prize :goat}
+(get-selected-door [(Door. 1 :goat)] 2) ;; nil
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; final function that computes the probabilities a user has to WIN, if staying to
+;; the initial decision or switching the door for monte-carlo simulation::monty-hall problem
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defn monte-carlo-monty-problem [doors-number attempts]
+  "decision should be [:stay] or [:reconsider]"
+  (letfn[(select-door-number [] (rand-nth (take doors-number (iterate inc 1))))
+
+         (doors-generator [doors-num]
+           "will generate n rooms guarded by doors and will place a prize inside a
+            randomly chose room, leaving the other 2 rooms with some goats inside"
+           (let [doors-idxs (take doors-num (iterate inc 1))
+                 rand-prize-door (select-door-number)]
+             (map (fn [door-idx]
+                    (if (= rand-prize-door door-idx)
+                        (Door. door-idx :win)
+                        (Door. door-idx :goat)))
+                   doors-idxs)))
+
+         (door-excluding [doors-to-exclude doors]
+           (first ;; realize from seq
+             (remove doors-to-exclude doors)))
+
+         (get-selected-door [doors selected-door-nmber]
+           (first ;; realize from seq
+             (filter #(= selected-door-nmber (.door-idx %)) doors)))
+
+         (find-winner-door [doors]
+           (first (filter #(= :win (.prize %)) doors)))
+
+         (probabilities [doors-number attempts-bound]
+           (repeatedly attempts-bound
+             (fn[]
+               (let [doors (doors-generator doors-number)
+                     selected-door (get-selected-door doors (select-door-number))
+                     monty-non-winner-door (door-excluding
+                                             (set [selected-door (find-winner-door doors)])
+                                             doors)
+                     switch-door (door-excluding (set [selected-door monty-non-winner-door]) doors)]
+                 [selected-door switch-door]
+              ))
+         ))
+
+         (winner-door-occurences [doors]
+           (count (filter (fn [door] (= :win (.prize door))) doors)))
+
+         (to->percentage [win-result attempts]
+           (str (/ (* (double win-result) 100)
+                   attempts) "%"
+         ))]
+    (let [generated-probabilities (probabilities doors-number attempts)
+          win-by-select-door (winner-door-occurences
+                               (map first generated-probabilities))
+          win-by-switch-door (winner-door-occurences
+                               (map second generated-probabilities))]
+
+      {:win-by-stay (to->percentage win-by-select-door attempts)
+       :win-by-switch (to->percentage win-by-switch-door attempts)}
+)))
+
+;; exercising monte-carlo monty-hall problem::
+(monte-carlo-monty-problem 3 10000)


Test utilities

Test utilities

error: pathspec 'src/flatgui/testsuite.clj' did not match any file(s) known to git

--- src/flatgui/testsuite.clj
+++ src/flatgui/testsuite.clj
@@ -0,0 +1,51 @@
+; Copyright (c) 2015 Denys Lebediev and contributors. All rights reserved.
+; The use and distribution terms for this software are covered by the
+; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+; which can be found in the file LICENSE at the root of this distribution.
+; By using this software in any fashion, you are agreeing to be bound by
+; the terms of this license.
+; You must not remove this notice, or any other, from this software.
+
+(ns flatgui.testsuite
+  (:require [flatgui.widgets.componentbase])
+  (:import (java.awt.event MouseEvent KeyEvent)
+           (java.awt Container)))
+
+
+(def dummy-source (Container.))
+
+(defn simulate-mouse-left [container id target]
+  (flatgui.widgets.componentbase/evolve-container
+    container
+    target
+    (MouseEvent. dummy-source id 0 0 0 0 0 0 1 false MouseEvent/BUTTON1)))
+
+(defn simulate-mouse-click [container target]
+  (-> (simulate-mouse-left container MouseEvent/MOUSE_PRESSED target)
+      (simulate-mouse-left MouseEvent/MOUSE_RELEASED target)
+      (simulate-mouse-left MouseEvent/MOUSE_CLICKED target)))
+
+(defn simulate-key-event [container id key-code char-code target]
+  (flatgui.widgets.componentbase/evolve-container
+    container
+    target
+    (KeyEvent. dummy-source id 0 0 (if (= id KeyEvent/KEY_TYPED) KeyEvent/VK_UNDEFINED key-code) char-code)))
+
+(defn simulate-key-type [container key-code char-code target]
+  (-> (simulate-key-event container KeyEvent/KEY_PRESSED key-code char-code target)
+      (simulate-key-event KeyEvent/KEY_TYPED key-code char-code target)
+      (simulate-key-event KeyEvent/KEY_RELEASED key-code char-code target)))
+
+(defn simulate-string-type [container str target]
+  (let [len (.length str)]
+    (loop [c container
+           i 0]
+      (if (< i len)
+        (recur
+          (simulate-key-type
+            c
+            (int (.charAt (clojure.string/upper-case (String/valueOf (.charAt str i))) 0))
+            (.charAt str i)
+            target)
+          (inc i))
+        c))))


Add Overtone source for synth designs.

Add Overtone source for synth designs.

error: pathspec 'etc/synthdefs/synth-designs.clj' did not match any file(s) known to git

--- etc/synthdefs/synth-designs.clj
+++ etc/synthdefs/synth-designs.clj
@@ -0,0 +1,232 @@
+(ns sp
+  (:use [overtone.live])
+  (:require [clojure.string :as str]))
+
+(defn save-synthdef [sdef folder]
+  (let [path (str folder "/" (last (str/split (-> sdef :sdef :name) #"/")) ".scsyndef") ]
+    (overtone.sc.machinery.synthdef/synthdef-write (:sdef sdef) path)
+    path))
+
+(defn save-to-pi [sdef]
+  (save-synthdef sdef "/Users/sam/Dropbox/lab/code/defining-pi/etc/synthdefs/"))
+
+(do
+  (defsynth space_organ [note 24 amp 1 x 0 y 0 out-bus 0]
+    (let [freq-shift (/ x 100)
+          delay (* -1 (/ x 10000))]
+      (out out-bus (pan2  (g-verb (* 0.2 (mix (map #(blip (+ freq-shift (* (midicps (duty:kr % 0 (dseq [note (+ 3 note) (+ 7 note) (+ 12 note) (+ 17 note)] INF))) %2)) (mul-add:kr (lf-noise1:kr 1/2) 3 4)) (+ delay [1 1/4]) [1  8]))) 200 8)))))
+
+
+  (save-to-pi space_organ)
+
+  (defsynth saws [note 52 x 0 y 0 out-bus 0]
+    (let [x    (abs x)
+          x    (min x 10000)
+          x    (max x 50)
+          y    (abs y)
+          y    (/ y 10000)
+          y    (min y 0.3)
+          y    (max y 0)
+          freq (midicps note)]
+      (out out-bus (mix (* 0.15 (normalizer (lpf (saw [freq (+ freq (* freq y))]) x)))))))
+
+  (save-to-pi saws))
+
+
+(do
+  (defsynth trig))
+
+(do
+  (defsynth beep [note 52 attack 0.1 release 0.3 out-bus 0]
+    (let [freq (midicps note)]
+      (out out-bus (* (sin-osc freq)
+                      (env-gen (perc attack release) :action FREE)))))
+
+  (save-to-pi beep))
+
+(do
+  (defsynth saw_beep [note 52 attack 0.1 release 0.3 out-bus 0]
+    (let [freq (midicps note)]
+      (out out-bus (* 0.3
+                      (saw [freq (+ freq (* freq 0.01))])
+                      (env-gen (perc attack release) :action FREE)))))
+
+  (save-to-pi saw_beep))
+
+(do
+  (defsynth loop-synth [buf 0 vol 1 rate 1 out-bus 0]
+    (let [src (play-buf 1 buf rate 1.0 0.0 1.0 1)]
+      (out out-bus (pan2 (* src vol)))))
+  (save-to-pi loop-synth))
+
+(do
+  (defsynth mixer [in-bus 0 amp 1 pan 0]
+    (let [src (in:ar in-bus 1)
+          src (lpf src 20000)]
+      (out 0 (pan2 (* (lag-ud amp 0 0.02) src) pan))))
+
+  (save-to-pi mixer))
+
+(do
+  ;;TODO FIXME!
+  (defsynth babbling [out-bus 0 x 0 y 50]
+    (let [x      (abs x)
+          x      (/ x 100000)
+          x      (min x 0.05)
+          x      (max x 0.005)
+          y      (abs y)
+          y      (min y 10000)
+          y      (max y 200)
+          noise  (* 0.003
+                    (rhpf (one-pole (* 0.99 (brown-noise)))
+                          (+ 500 (* 400 (lpf (* (brown-noise) 14))))
+                          x))
+          noise  [noise noise]
+          noise2 (* 0.005
+                    (rhpf (one-pole (* 0.99 (brown-noise)))
+                          (+ 1000 (* 800 (lpf (* (brown-noise) 20))))
+                          x))
+          noise2 [noise2 noise2]
+          mixed  (+ noise noise2)
+          mixed  (lpf mixed y)]
+      (out out-bus (* 0 (mix (* 3 mixed))))))
+  (save-to-pi babbling))
+
+(do
+  (defsynth fm [note 52 divisor 2.0 depth 1.0 out-bus 0]
+    (let [carrier   (midicps note)
+          modulator (/ carrier divisor)
+          mod-env   (env-gen (lin-env 1 0 1))
+          amp-env   (env-gen (lin-env 0 1 1) :action FREE)]
+      (out out-bus (* 0.25 (* amp-env
+                             (sin-osc (+ carrier
+                                         (* mod-env  (* carrier depth) (sin-osc modulator)))))))))
+
+  (save-to-pi fm))
+
+(do
+
+  (save-to-pi stereo-player)
+  (save-to-pi mono-player)
+ )
+
+
+(do
+  (defsynth woah [note 52 out-bus 0 x 0 y 0]
+    (let [freq (midicps note)
+          x    (abs x)
+          x    (/ x 700)
+          x    (min x 15)
+          x    (max x 0.5)
+          snd  (lpf (sync-saw
+                     freq
+                     (* (* freq 1.5) (+ 2 (sin-osc:kr x))))
+                    1000)]
+      (out out-bus (* 0.25 snd))))
+
+  (save-to-pi woah))
+
+
+(do
+  (defsynth arpeg-click [x 10 buf 0 arp-div 2 beat-div 1 out-bus 0]
+    (let [x (abs x)
+          x (/ x 70)
+          x (min x 200)
+          x (max x 1)
+          tik   (impulse x)
+          a-tik (pulse-divider tik arp-div)
+          b-tik (pulse-divider tik beat-div)
+          cnt   (mod (pulse-count a-tik) (buf-frames 1))
+          note  (buf-rd:kr 1 1 cnt)
+          freq  (midicps note)
+          snd   (white-noise)
+          snd   (rhpf snd 2000 0.4)
+          snd   (normalizer snd)
+          b-env (env-gen (perc 0.01 0.1) b-tik)
+          a-env (env-gen (perc 0.01 0.4) a-tik)]
+      (out out-bus (* 0.20 (pan2 (+ (* 0.5 snd b-env)
+                                    (* (sin-osc freq) a-env)
+                                    (* (sin-osc (* 2 freq)) a-env)))))))
+
+  (save-to-pi arpeg-click))
+
+(do
+  ;;http://computermusicresource.com/Simple.bell.tutorial.html
+(def dull-partials
+  [
+   0.56
+;;   1.19
+;;   1.71
+;;   2.74
+   3
+;;   3.76
+   ])
+
+;; http://www.soundonsound.com/sos/Aug02/articles/synthsecrets0802.asp
+;; (fig 8)
+(def partials
+  [
+   1
+   4
+;;   3
+;;   4.2
+;;   5.4
+;;   6.8
+   ])
+
+;; we make a bell by combining a set of sine waves at the given
+;; proportions of the frequency. Technically not really partials
+;; as for the 'pretty bell' I stuck mainly with harmonics.
+;; Each partial is mixed down proportional to its number - so 1 is
+;; louder than 6. Higher partials are also supposed to attenuate
+;; quicker but setting the release didn't appear to do much.
+
+(defcgen bell-partials
+  "Bell partial generator"
+  [freq {:default 440 :doc "The fundamental frequency for the partials"}
+   attack {:default 0.01}
+   release  {:default 1.0 :doc "Duration multiplier. Length of longest partial will
+                            be dur seconds"}
+   partials {:default [0.5 1 2 4] :doc "sequence of frequencies which are
+                                        multiples of freq"}]
+  "Generates a series of progressively shorter and quieter enveloped sine waves
+  for each of the partials specified. The length of the envolope is proportional
+  to dur and the fundamental frequency is specified with freq."
+  (:ar
+   (apply +
+          (map
+           (fn [partial proportion]
+             (let [env      (env-gen (perc attack (* release proportion)))
+                   vol      (/ proportion 2)
+                   overtone (* partial freq)]
+               (* env vol (sin-osc overtone))))
+           partials ;; current partial
+           (iterate #(/ % 2) 1.0)  ;; proportions (1.0  0.5 0.25)  etc
+           ))))
+
+
+(defsynth dull_bell [note 52 attack 0.01 release 1.0 vol 1.0 out-bus 0]
+  (let [freq (midicps note)
+        snd (* vol (bell-partials freq attack release dull-partials))]
+    (detect-silence snd :action FREE)
+    (out out-bus snd)))
+
+(defsynth pretty_bell [note 52 attack 0.01 release 1 vol 1.0 out-bus 0]
+  (let [freq (midicps note)
+        snd (* vol (bell-partials freq attack release partials))]
+    (detect-silence snd :action FREE)
+    (out out-bus snd)))
+
+(save-to-pi dull_bell)
+(save-to-pi pretty_bell))
+
+
+;; SynthDef(\babblingbrook_jmc, { |out=0, amp=0.1|
+;;      var son;
+
+;;      son = ({RHPF.ar(OnePole.ar(BrownNoise.ar, 0.99), LPF.ar(BrownNoise.ar, 14)
+;;              * 400 + 500, 0.03, 0.003)}!2)
+;;              + ({RHPF.ar(OnePole.ar(BrownNoise.ar, 0.99), LPF.ar(BrownNoise.ar, 20)
+;;              * 800 + 1000, 0.03, 0.005)}!2)  * 4;
+;;      Out.ar(out, son * (amp * 20))
+;; },


Added beginnings of servlet unit tests

Added beginnings of servlet unit tests

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/meowcakes/ring.git/'


Added mouse example

Added mouse example

error: pathspec 'examples/mouse.clj' did not match any file(s) known to git

--- examples/mouse.clj
+++ examples/mouse.clj
@@ -0,0 +1,35 @@
+;; processing example
+
+(ns mouse-example
+  (:use [rosado.processing]
+        [rosado.processing.applet]))
+
+(def mouse-position (atom [0 0]))
+
+(defn draw
+  []
+  (background-float 125)
+  (stroke-weight 20)
+  (stroke-float 10)
+  (let [[x y] @mouse-position]
+    (point x y)))
+
+(defn setup []
+  (smooth)
+  (no-stroke))
+
+
+(defn mouse-moved [evt]
+  (let [x (.getX evt) y (.getY evt)]
+    (reset! mouse-position [x y])))
+
+;; Now we just need to define an applet:
+
+(defapplet mouse-example :title "Mouse example."
+  :size [200 200]
+  :setup setup :draw draw
+  :mouse-moved mouse-moved)
+
+(run mouse-example)
+
+;; (stop mouse-example)


[#674] Collection backend tests

[#674] Collection backend tests

error: pathspec 'backend/test/akvo/lumen/endpoint/collection_test.clj' did not match any file(s) known to git

--- backend/test/akvo/lumen/endpoint/collection_test.clj
+++ backend/test/akvo/lumen/endpoint/collection_test.clj
@@ -0,0 +1,109 @@
+(ns akvo.lumen.endpoint.collection-test
+  (:require [akvo.lumen.component.tenant-manager :refer [tenant-manager]]
+            [akvo.lumen.component.transformation-engine :refer [transformation-engine]]
+            [akvo.lumen.fixtures :refer [test-tenant-spec
+                                         migrate-tenant
+                                         rollback-tenant]]
+            [akvo.lumen.import.csv-test :refer [import-file]]
+            [akvo.lumen.lib.collection :as collection]
+            [akvo.lumen.lib.dashboard :as dashboard]
+            [akvo.lumen.lib.dataset :as dataset]
+            [akvo.lumen.lib.visualisation :as visualisation]
+            [clojure.test :refer :all]
+            [com.stuartsierra.component :as component]
+            [duct.component.hikaricp :refer [hikaricp]]))
+
+(def test-system
+  (->
+   (component/system-map
+    :transformation-engine (transformation-engine {})
+    :tenant-manager (tenant-manager {})
+    :db (hikaricp {:uri (:db_uri test-tenant-spec)}))
+   (component/system-using
+    {:transformation-engine [:tenant-manager]
+     :tenant-manager [:db]})))
+
+(def ^:dynamic *tenant-conn*)
+
+(defn fixture [f]
+  (migrate-tenant test-tenant-spec)
+  (alter-var-root #'test-system component/start)
+  (binding [*tenant-conn* (:spec (:db test-system))]
+    (f)
+    (alter-var-root #'test-system component/stop)
+    (rollback-tenant test-tenant-spec)))
+
+(use-fixtures :once fixture)
+
+(defn visualisation-body [dataset-id]
+  {"datasetId" dataset-id
+   "visualisationType" ""
+   "name" ""
+   "spec" {}})
+
+(defn create-visualisation [tenant-conn dataset-id]
+  (-> (visualisation/create *tenant-conn* (visualisation-body dataset-id) {})
+      (get-in [:body "id"])))
+
+(defn create-dashboard [tenant-conn]
+  (-> (dashboard/create tenant-conn {"title" ""})
+      (get-in [:body :id])))
+
+(deftest ^:functional collection-test
+  (let [;; Import a few datasets
+        ds1 (import-file "GDP.csv" {})
+        ds2 (import-file "dates.csv" {})
+        vs1 (create-visualisation *tenant-conn* ds1)
+        vs2 (create-visualisation *tenant-conn* ds2)
+        db1 (create-dashboard *tenant-conn*)
+        db2 (create-dashboard *tenant-conn*)]
+    (testing "Create an empty collection"
+      (let [response (collection/create *tenant-conn* {"title" "col1"})]
+        (is (= 201 (:status response)))
+        (is #{:id :title :modified :created :entities}
+            (-> response :body keys set))
+        (is (= 409 (:status (collection/create *tenant-conn* {"title" "col1"}))))
+        (is (= 400 (:status (collection/create *tenant-conn* {"title" nil}))))
+        (is (= 400 (:status (collection/create *tenant-conn* {"title" (apply str (repeat 129 "a"))}))))))
+    (testing "Create a collection with entities"
+      (let [response (collection/create *tenant-conn* {"title" "col2"
+                                                       "entities" [ds1 vs1 db1]})]
+        (is (= 201 (:status response)))
+        (is (= #{ds1 vs1 db1} (-> response :body :entities set)))))
+
+    (testing "Fetch collection"
+      (let [id (-> (collection/create *tenant-conn* {"title" "col3" "entities" [ds2 vs2 db2]})
+                   :body :id)
+            coll (-> (collection/fetch *tenant-conn* id) :body)]
+        (is #{ds2 vs2 db2} (-> coll :entities set))))
+
+    (testing "Update collection"
+      (let [id (-> (collection/create *tenant-conn* {"title" "col4" "entities" [ds2 vs2 db2]})
+                   :body :id)]
+        (let [coll (-> (collection/update *tenant-conn* id {"title" "col4 renamed"}) :body)]
+          (is (= (:title coll) "col4 renamed"))
+          (is (= (-> coll :entities set) #{ds2 vs2 db2}))
+          (collection/update *tenant-conn* id {"entities" []})
+          (is (= [] (-> (collection/fetch *tenant-conn* id) :body :entities)))
+          (collection/update *tenant-conn* id {"entities" [ds1 vs1]})
+          (is (= #{ds1 vs1} (-> (collection/fetch *tenant-conn* id) :body :entities set)))
+          (collection/update *tenant-conn* id {"entities" [vs1 vs2]})
+          (is (= #{vs1 vs2} (-> (collection/fetch *tenant-conn* id) :body :entities set))))))
+
+    (testing "Delete collection"
+      (let [id (-> (collection/create *tenant-conn* {"title" "col5"}) :body :id)]
+        (collection/delete *tenant-conn* id)
+        (is (= 404 (:status (collection/fetch *tenant-conn* id))))))
+
+    (testing "Delete collection entities"
+      (let [id (-> (collection/create *tenant-conn* {"title" "col6"
+                                                     "entities" [ds1 ds2 vs1 vs2 db1 db2]})
+                   :body :id)]
+        (dashboard/delete *tenant-conn* db1)
+        (is (= #{ds1 ds2 vs1 vs2 db2}
+               (-> (collection/fetch *tenant-conn* id)
+                   :body :entities set)))
+        (dataset/delete *tenant-conn* ds1)
+        (is (= #{ds2 vs2 db2}
+               (-> (collection/fetch *tenant-conn* id)
+                   :body :entities set))) ))))


Add ticket model

Add ticket model

error: pathspec 'src/checkin_halake/models/ticket.clj' did not match any file(s) known to git

--- src/checkin_halake/models/ticket.clj
+++ src/checkin_halake/models/ticket.clj
@@ -0,0 +1,19 @@
+(ns checkin-halake.models.ticket
+  (:require [monger.core :as mg]
+            [monger.collection :as mc]
+            [monger.operators :as mo]
+            [environ.core :refer [env]])
+  (:use [crypto.password.bcrypt :only [encrypt check]]
+        checkin-halake.models.core))
+
+(def ticket-types {:1day {:id :1day :nama "1日利用権"}})
+
+(defn add-ticket-to-user [user ticket-type count]
+  (let [ticket-key (str "tickets." ticket-type)]
+    (mc/update db "users" {:_id (:id user)} {mo/$inc {ticket-key count}})))
+
+(defn use-ticket [user ticket-type]
+  (let [ticket-key (str "tickets." ticket-type)]
+    (mc/update db "users" {:_id (:id user) mo/$gt {ticket-type 0}} {mo/$inc {ticket-key -1}})))
+
+


Add generic mac engine abstraction for low level but clojure idiomatic access to mac.

error: pathspec 'src/clojure/buddy/core/mac/proto.clj' did not match any file(s) known to git

--- src/clojure/buddy/core/mac/proto.clj
+++ src/clojure/buddy/core/mac/proto.clj
@@ -0,0 +1,34 @@
+;; Copyright (c) 2013-2015 Andrey Antukh <niwi@niwi.be>
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License")
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
+;;
+;;     http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
+
+(ns buddy.core.mac.proto
+  "Hash-based Message Authentication Codes
+  low level protocol definition.")
+
+(defprotocol IMac
+  (^:private update [_ bytes offset length] "Update bytes in a current instance.")
+  (^:private end [_] "Return the computed mac and reset the engine."))
+
+(defn update!
+  ([engine input]
+   (update engine input 0 (count input)))
+  ([engine input offset]
+   (update engine input offset (count input)))
+  ([engine input offset length]
+   (update engine input offset length)))
+
+(defn end!
+  [engine]
+  (end engine))
+


add some missing glyphs

add some missing glyphs

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/clojurecup/cc2014-frontend.git/'


implement autopay? resolver

implement autopay? resolver

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/starcity-properties/odin.git/'


Comment out :paredit-close-round-and-newline

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bsmr-clojure/Nightcode.git/'


Added count

Added count

error: pathspec 'src/clojurebyexample/code/count.clj' did not match any file(s) known to git

--- src/clojurebyexample/code/count.clj
+++ src/clojurebyexample/code/count.clj
@@ -0,0 +1,7 @@
+;; count
+(ns count)
+
+;; Takes a vector and returns the number of elements in it
+(count [1 2 3 4 5 6])
+
+;; Returns 6


Update notification signers

Update notification signers

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-notification-works.git/'


Fixed to remove empty/broken URL in feed

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ananthmv/stream.git/'


Corrected env variables in rabbit

Corrected env variables in rabbit

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/acessocard/microscope.git/'


Add more repl no-prompt tests and rework other repl tests.

--- test/cli4clj/test/cli_tests.clj
+++ test/cli4clj/test/cli_tests.clj
@@ -174,12 +174,12 @@
 (test/deftest clojure-repl-stdout-no-op-test
   (let [in-cmds [""]
         out (cli-tests/test-cli-stdout clojure.main/repl in-cmds)]
-    (test/is (= (cli-tests/expected-string ["user=> user=>"]) out))))
+    (test/is (= "user=> user=>" out))))

 (test/deftest clojure-repl-stderr-no-op-test
   (let [in-cmds [""]
         out (cli-tests/test-cli-stderr clojure.main/repl in-cmds)]
-    (test/is (= (cli-tests/expected-string [""]) out))))
+    (test/is (= "" out))))

 (test/deftest clojure-repl-stdout-inc-test
   (let [in-cmds ["(inc 1)"]
@@ -196,8 +196,18 @@
         out (cli-tests/test-cli-stderr clojure.main/repl in-cmds)]
     (test/is (.startsWith out "ArithmeticException Divide by zero"))))

+(test/deftest clojure-repl-stdout-no-op-no-prompt-test
+  (let [in-cmds [""]
+        out (cli-tests/test-cli-stdout #(clojure.main/repl :prompt str) in-cmds)]
+    (test/is (= "" out))))
+
+(test/deftest clojure-repl-stdout-inc-no-prompt-test
+  (let [in-cmds ["(inc 1)"]
+        out (cli-tests/test-cli-stdout #(clojure.main/repl :prompt str) in-cmds)]
+    (test/is (= "2" out))))
+
 (test/deftest clojure-repl-stdout-let-inc-println-no-prompt-test
   (let [in-cmds ["(def x 21)" "(inc x)" "(println x)"]
-        out (cli-tests/test-cli-stdout #(clojure.main/repl :prompt (fn [] "")) in-cmds)]
+        out (cli-tests/test-cli-stdout #(clojure.main/repl :prompt str) in-cmds)]
     (test/is (= (cli-tests/expected-string ["#'user/x" "22" "21" "nil"]) out))))


4clojure:: impl 1st draft of words-chain? for a set of words(hard)

error: pathspec 'src/clojure_learning/word_chains.clj' did not match any file(s) known to git

--- src/clojure_learning/word_chains.clj
+++ src/clojure_learning/word_chains.clj
@@ -0,0 +1,108 @@
+;;Word Chains
+;;Difficulty:	Hard
+;;Topics:	seqs
+;;A word chain consists of a set of words ordered so that each word differs by only one letter
+;;from the words directly before and after it.
+;;The one letter difference can be either an insertion, a deletion, or a substitution.
+;;Here is an example word chain:
+;;cat -> cot -> coat -> oat -> hat -> hot -> hog -> dog
+;;
+;;Write a function which takes a sequence of words, and returns true if they can be arranged
+;;into one continous word chain, and false if they cannot.
+;;test not run
+(ns clojure-learning.word-chains
+  (use (clojure [repl] test)))
+
+;; #{"hat" "coat" "dog" "cat" "oat" "cot" "hot" "hog"}
+
+;; thinking: take each element and reduce with rest to find if there's a matching word
+;; the matching func should take two words -> and return truthy if the words seem to match
+(defn words-chain? [source-str target-str]
+  (let [intersected (clojure.set/intersection (set source-str) (set target-str))
+        identify-by #(apply % [(count %2) (count %3)])
+        smallest (identify-by min source-str target-str)
+        greatest (identify-by max source-str target-str)]
+     (and (<= (- greatest smallest) 1)
+         (or (= intersected (set source-str))
+             (= intersected (set target-str))))))
+
+(words-chain? "tackli" "tackl") ;; true
+(words-chain? "clau" "claud")   ;; true
+(words-chain? "clau" "clua")    ;; true
+(words-chain? "cos" "cosar")    ;; false
+
+(defn all-words-chain?
+  ([xset]
+   (all-words-chain? (vec xset) (rest (vec xset)) []))
+  ([[head-inner sec-inner & tail-inner] [head-rest & tail-rest]  matches-vec]
+   (if (nil? head-rest) matches-vec
+    (if (nil? sec-inner)
+     (recur tail-rest tail-rest matches-vec)
+     (if (words-chain? head-inner sec-inner)
+       (recur (cons sec-inner tail-inner) (cons head-rest tail-rest) (conj matches-vec :link))
+       (recur (cons sec-inner tail-inner) (cons head-rest tail-rest) matches-vec))))))
+
+(all-words-chain? #{"hat" "coat" "dog" "cat" "oat" "cot" "hot" "hog"}) ;; true
+(all-words-chain? #{"cot" "hot" "bat" "fat"})                 ;; false
+(all-words-chain? #{"to" "top" "stop" "tops" "toss"})         ;; false
+(all-words-chain? #{"spout" "do" "pot" "pout" "spot" "dot"})  ;; true
+(all-words-chain? #{"share" "hares" "shares" "hare" "are"})   ;; true
+(all-words-chain? #{"share" "hares" "hare" "are"})            ;; false
+
+(defn words-chain? [source-str target-str]
+  (let [intersected (clojure.set/intersection (set source-str) (set target-str))
+        identify-by #(apply % [(count %2) (count %3)])
+        smallest (identify-by min source-str target-str)
+        greatest (identify-by max source-str target-str)]
+     (when (and (<= (- greatest smallest) 1)
+                (or (= intersected (set source-str))
+                    (= intersected (set target-str))))
+       source-str)))
+;; unfortunatelly this function is not helping too much as it's using sets as values and not words stricly comparisons
+
+(words-chain? "share" "hares") ;; -> fix this func and the algorithm is ok!
+(words-chain? "tops" "toss")
+
+;; if count a - count b = 1 -> then leading-padding & trailing padding of-smaller with 0
+(interleave "tops" "toss")
+(interleave "toss" "to")
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "0hare" "hares"))) ;; (false false false false false)
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "hare0" "hares"))) ;; (true true true true false)
+
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "0top" "stop")))   ;; (false true true true)
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "top0" "stop")))   ;; (false false false false)
+
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "0pout" "spout"))) ;; (false true true true true)
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "pout0" "spout"))) ;; (false false false false false)
+
+;; check for false in both vec-results -> if a vec contains only one false -> words-chaining-match!
+(defn words-chain? [source-str target-str]
+    (letfn [(difference [& words]
+              (let [[smallest greatest] (sort-by count words)]
+                (- (count greatest) (count smallest))))
+            (pair-compared-chars [& words]
+              (let [[smallest greatest] (sort-by count words)]
+                 (assoc
+                    (assoc {} :left-padded-vals (map (fn [[a b]] (= a b)) (partition 2 (interleave (apply str (cons "$" smallest)) greatest))))
+                      :right-padded-vals (map (fn [[a b]] (= a b)) (partition 2 (interleave (apply str (conj (vec smallest) "$")) greatest))))))]
+      (if (<= (difference source-str target-str) 1)
+        (if-let [{:keys [left-padded-vals right-padded-vals]} (pair-compared-chars source-str target-str)]
+          (if (or (= 1 (count (filter false? left-padded-vals)))
+                  (= 1 (count (filter false? right-padded-vals))))
+            :linked
+            :not-linked)))))
+
+("abcde" "abvde")
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "abcde" "abvde"))) ;; (true true false true true)
+(map (fn [[a b]] (= a b)) (partition 2 (interleave "abcdef" "abvde0"))) ;; (true true false true true false)
+
+(sort-by count ["clojure" "this"])
+(apply str  (cons "$" "this"))
+(filter false? [true true false])
+
+(words-chain? "share" "hares") ;; -> fix this func and the algorithm is ok!
+(words-chain? "tops" "toss")
+(words-chain? "top" "tops")
+
+(assoc {} :left-padded (map (fn [[a b]] (= a b)) (partition 2 (interleave (apply str (cons "$" "thi")) "cthi"))))
+(conj "$" (vec "this"))


Make sure errors get logged.

Make sure errors get logged.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mtravers/incidents.git/'


fixed namespace in syntax rules functions for macros.clj

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/parenode/clojure-cup-2015.git/'


automatically open setup URL when installing metabase :heart_eyes_cat:

--- src/metabase/core.clj
+++ src/metabase/core.clj
@@ -1,6 +1,8 @@
 (ns metabase.core
   (:gen-class)
   (:require [clojure.tools.logging :as log]
+            [clojure.java.browse :refer [browse-url]]
+            [colorize.core :as color]
             [medley.core :as medley]
             [metabase.config :as config]
             [metabase.db :as db]
@@ -37,6 +39,23 @@
       wrap-session            ; reads in current HTTP session and sets :session/key
       wrap-gzip))             ; GZIP response if client can handle it

+(defn- -init-create-setup-token
+  "Create and set a new setup token, and open the setup URL on the user's system."
+  []
+  (let [setup-token (setup/token-create)
+        hostname    (or (config/config-str :mb-jetty-host) "localhost")
+        port        (config/config-int :mb-jetty-port)
+        setup-url   (str "http://"
+                         (or hostname "localhost")
+                         (when-not (= 80 port) (str ":" port))
+                         "/setup/init/"
+                         setup-token)]
+    (log/info (color/green "Please use the following url to setup your Metabase installation:\n\n"
+                           setup-url
+                           "\n\n"))
+    ;; Attempt to browse URL on user's system; this will just fail silently if we can't do it
+    (browse-url setup-url)))
+

 (defn init
   "General application initialization function which should be run once at application startup."
@@ -51,17 +70,7 @@
   ;; the test we are using is if there is at least 1 User in the database
   (when-not (db/sel :one :fields [User :id])
     (log/info "Looks like this is a new installation ... preparing setup wizard")
-    (let [setup-token (setup/token-create)
-          hostname (or (config/config-str :mb-jetty-host) "localhost")
-          port (config/config-int :mb-jetty-port)
-          setup-url (str "http://"
-                         (or hostname "localhost")
-                         (when-not (= 80 port) (str ":" port))
-                         "/setup/init/"
-                         setup-token)]
-      (log/info (str "Please use the following url to setup your Metabase installation:\n\n"
-                     setup-url
-                     "\n\n"))))
+    (-init-create-setup-token))

   ;; Now start the task runner
   (task/start-task-runner!)


Neaten.

Neaten.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cstorey/nrod.git/'


Pull out meta-functions specific test

Pull out meta-functions specific test

error: pathspec 'test/clj/clojure/lang/meta_test.clj' did not match any file(s) known to git

--- test/clj/clojure/lang/meta_test.clj
+++ test/clj/clojure/lang/meta_test.clj
@@ -0,0 +1,50 @@
+(ns clojure.lang.meta-test
+  (:refer-clojure :only [apply cons deftype let select-keys])
+  (:require [clojure.test           :refer :all]
+            [clojure.lang.protocols :refer [IMeta -reset-meta!]]
+            [clojure.next           :refer :all :exclude [cons]]))
+
+(deftype TestMeta [^:unsynchronized-mutable -meta]
+  IMeta
+  (-meta [this] -meta)
+
+  (-with-meta [this new-meta]
+    (TestMeta. new-meta))
+
+  (-reset-meta! [this new-meta]
+    (set! -meta new-meta)
+    new-meta)
+
+  (-alter-meta! [this f args]
+    (let [meta-args (cons -meta args)
+          new-meta (apply f meta-args)]
+      (-reset-meta! this new-meta))))
+
+(deftest meta-test
+  (testing "meta returns the meta of an object"
+    (let [mta {:so :meta}
+          obj (TestMeta. mta)]
+      (is (= mta (meta obj)))))
+
+  (testing "with-meta returns a new instance with the specified meta"
+    (let [obj1 (TestMeta. {})
+          obj2 (with-meta obj1 {:so :meta})]
+      (is (not== obj1 obj2))
+      (is (= {:so :meta} (meta obj2)))))
+
+  (testing "reset-meta! will reset the meta on the object"
+    (let [obj (TestMeta. {})]
+      (reset-meta! obj {:so :meta})
+      (is (= {:so :meta} (meta obj)))))
+
+  (testing "alter-meta! will reset the meta on the object by applying the given function with the given arguments"
+    (let [obj (TestMeta. {:a 1 :b 2 :c 3})]
+      (alter-meta! obj select-keys '(:b))
+      (is (= {:b 2} (meta obj)))))
+
+  (testing "vary-meta will apply a function and given arguments to with-meta"
+    (let [obj1 (TestMeta. {:a 1 :b 2 :c 3})
+          obj2 (vary-meta obj1 select-keys '(:b))]
+      (is (= {:a 1 :b 2 :c 3} (meta obj1)))
+      (is (= {:b 2} (meta obj2))))))
+


Display delete routes by default in Swagger UI (#770)

--- src/ctia/http/routes/crud.clj
+++ src/ctia/http/routes/crud.clj
@@ -43,7 +43,7 @@
            can-patch?
            can-search?
            can-get-by-external-id?]
-    :or {hide-delete? true
+    :or {hide-delete? false
          can-post? true
          can-update? true
          can-patch? false


Minor functions for determining the cutoff points for switching from set to HLL.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/screen6/cardinality.git/'


Add utils module.

Add utils module.

error: pathspec 'src/clojure/buddy/auth/utils.clj' did not match any file(s) known to git

--- src/clojure/buddy/auth/utils.clj
+++ src/clojure/buddy/auth/utils.clj
@@ -0,0 +1,28 @@
+;; Copyright 2013-2015 Andrey Antukh <niwi@niwi.be>
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License")
+;; you may not use this file except in compliance with the License.
+;; You may obtain a copy of the License at
+;;
+;;     http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS,
+;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+;; See the License for the specific language governing permissions and
+;; limitations under the License.
+
+(ns buddy.auth.utils
+  (:require [cuerdas.core :as str]
+            [clojure.walk :refer [postwalk]]))
+
+(defn lowercase-headers
+  [headers]
+  (postwalk (fn [form]
+              (if (vector? form)
+                (cond
+                  (string? (first form)) [(str/lower (first form)) (second form)]
+                  (keyword? (first form)) [(keyword (str/lower (name (first form)))) (second form)]
+                  :else form)
+                form))
+            headers))


implement POST /api/emailreport/:id which executes a given email report.

--- src/metabase/api/emailreport.clj
+++ src/metabase/api/emailreport.clj
@@ -12,6 +12,7 @@
                              [emailreport-executions :refer [EmailReportExecutions]]
                              [org :refer [Org]]
                              [user :refer [users-for-org]])
+            [metabase.tasks.email-report :as report]
             [metabase.util :as util]))

 (defannotation EmailReportFilterOption [symb value :nillable]
@@ -100,9 +101,10 @@
   (del EmailReport :id id))

-;; TODO
-;; (defendpoint POST "/:id" [id]
-;;   {:TODO "TODO"})
+(defendpoint POST "/:id" [id]
+  (read-check EmailReport id)
+  (->> (report/execute-and-send id)
+       (sel :one EmailReportExecutions :id)))

 (defendpoint GET "/:id/executions" [id]


(PE-4982) Rename puppetserver config file

error: pathspec 'configs/puppetserver/puppetserver.clj' did not match any file(s) known to git

--- configs/puppetserver/puppetserver.clj
+++ configs/puppetserver/puppetserver.clj
@@ -0,0 +1,18 @@
+(defproject puppetlabs.packages/puppetserver "{{{puppet-server-version}}}"
+  :description "Release artifacts for puppet-server"
+  :pedantic? :abort
+  :dependencies [[puppetlabs/puppet-server "{{{puppet-server-version}}}"]
+                 [puppetlabs/trapperkeeper-webserver-jetty9 "0.5.2"]]
+
+  :uberjar-name "puppet-server-release.jar"
+
+  :repositories [["releases" "http://nexus.delivery.puppetlabs.net/content/repositories/releases/"]
+                 ["snapshots" "http://nexus.delivery.puppetlabs.net/content/repositories/snapshots/"]]
+  :main puppetlabs.trapperkeeper.main
+
+  :ezbake { :user "puppet"
+            :group "puppet"
+            :build-type "foss"
+            :java-args "-Xmx1g"
+            }
+  )


comment out previous smart errors

comment out previous smart errors

--- sidecar/src/figwheel_sidecar/config_check/type_check.clj
+++ sidecar/src/figwheel_sidecar/config_check/type_check.clj
@@ -404,7 +404,7 @@

 ;; this could be improved by considering the type of the
 ;; current parent value by considering the parents other keys
-(defn misspelled-key [parent-type bad-key value error]
+#_(defn misspelled-key [parent-type bad-key value error]
   (take 1
    (sort-by
     #(-> % :distance-score -)
@@ -422,7 +422,7 @@
           :distance-score (+ score (key-distance bad-key ky))
           :confidence :high}))))))

-(defn misplaced-key [root-type parent-type bad-key value]
+#_(defn misplaced-key [root-type parent-type bad-key value]
   (let [parent-type-set
         (set (cons parent-type (decendent-types *schema-rules* parent-type)))]
     (for [[ky _ [other-parent-type _ typ]] (*schema-rules* [:- bad-key])
@@ -435,7 +435,7 @@
        :correct-paths (get-paths-for-key root-type typ ky)
        :confidence :high})))

-(defn misspelled-misplaced-key [root-type parent-type bad-key value]
+#_(defn misspelled-misplaced-key [root-type parent-type bad-key value]
   (let [parent-type-set
         (set (cons parent-type (decendent-types *schema-rules* parent-type)))]
     (sort-by
@@ -454,7 +454,7 @@
         :correct-paths (get-paths-for-key root-type typ ky)
         :confidence :high}))))

-(defn unknown-key-error-help [root-type parent-type bad-key value error]
+#_(defn unknown-key-error-help [root-type parent-type bad-key value error]
   (first
    (filter
     not-empty


add in missing utils file

add in missing utils file

git-svn-id: 03a8048b5ee8463be5048a3801110fb50f378627@10704 d0ab736e-dc22-4aeb-8dc9-08def0aa14fd

error: pathspec 'plugins/SlideExplorer2/src/slide_explorer/utils.clj' did not match any file(s) known to git

--- plugins/SlideExplorer2/src/slide_explorer/utils.clj
+++ plugins/SlideExplorer2/src/slide_explorer/utils.clj
@@ -0,0 +1,3 @@
+(ns slide-explorer.utils)
+
+(def test (atom false))


[STORM-2056] - Bugs in logviewer

[STORM-2056] - Bugs in logviewer

--- storm-core/src/clj/org/apache/storm/daemon/logviewer.clj
+++ storm-core/src/clj/org/apache/storm/daemon/logviewer.clj
@@ -371,27 +371,27 @@
     (drop-down "file" log-files)
     [:input {:type "submit" :value "Switch file"}]]])

-(defn pager-links [fname start length file-size]
+(defn pager-links [fname start length file-size type]
   (let [prev-start (max 0 (- start length))
         next-start (if (> file-size 0)
                      (min (max 0 (- file-size length)) (+ start length))
                      (+ start length))]
     [[:div
       (concat
-          [(to-btn-link (url "/log"
+          [(to-btn-link (url (str "/" type)
                           {:file fname
                            :start (max 0 (- start length))
                            :length length})
                           "Prev" :enabled (< prev-start start))]
-          [(to-btn-link (url "/log"
+          [(to-btn-link (url (str "/" type)
                            {:file fname
                             :start 0
                             :length length}) "First")]
-          [(to-btn-link (url "/log"
+          [(to-btn-link (url (str "/" type)
                            {:file fname
                             :length length})
                         "Last")]
-          [(to-btn-link (url "/log"
+          [(to-btn-link (url (str "/" type)
                           {:file fname
                            :start (min (max 0 (- file-size length))
                                        (+ start length))
@@ -452,7 +452,7 @@
                           (filter #(.contains % grep))
                           (string/join "\n"))
                      log-string)])
-            (let [pager-data (if (is-txt-file fname) (pager-links fname start length file-length) nil)]
+            (let [pager-data (if (is-txt-file fname) (pager-links fname start length file-length "log") nil)]
               (html (concat (search-file-form fname "no")
                             (log-file-selection-form reordered-files-str "log") ; list all files for this topology
                             pager-data
@@ -496,7 +496,7 @@
                         (filter #(.contains % grep))
                         (string/join "\n"))
                    log-string)])
-          (let [pager-data (if (is-txt-file fname) (pager-links fname start length file-length) nil)]
+          (let [pager-data (if (is-txt-file fname) (pager-links fname start length file-length "daemonlog") nil)]
             (html (concat (search-file-form fname "yes")
                           (log-file-selection-form reordered-files-str "daemonlog") ; list all daemon logs
                           pager-data
@@ -506,11 +506,13 @@
       (-> (resp/response "Page not found")
           (resp/status 404)))))

-(defn download-log-file [fname req resp user ^String root-dir]
+(defnk download-log-file [fname req resp user ^String root-dir :is-daemon false]
   (let [file (.getCanonicalFile (File. root-dir fname))]
     (if (.exists file)
-      (if (or (blank? (*STORM-CONF* UI-FILTER))
-              (authorized-log-user? user fname *STORM-CONF*))
+
+      (if (or is-daemon
+            (or (blank? (*STORM-CONF* UI-FILTER))
+              (authorized-log-user? user fname *STORM-CONF*)))
         (-> (resp/response file)
             (resp/content-type "application/octet-stream"))
         (unauthorized-user-html user))
@@ -830,8 +832,9 @@
   [fname user ^String root-dir is-daemon search num-matches offset callback origin]
   (let [file (.getCanonicalFile (File. root-dir fname))]
     (if (.exists file)
-      (if (or (blank? (*STORM-CONF* UI-FILTER))
-            (authorized-log-user? user fname *STORM-CONF*))
+      (if (or is-daemon
+            (or (blank? (*STORM-CONF* UI-FILTER))
+              (authorized-log-user? user fname *STORM-CONF*)))
         (let [num-matches-int (if num-matches
                                 (try-parse-int-param "num-matches"
                                   num-matches))
@@ -1106,7 +1109,7 @@
     (try
       (.mark logviewer:num-download-log-daemon-file-http-requests)
       (let [user (.getUserName http-creds-handler servlet-request)]
-        (download-log-file file servlet-request servlet-response user daemonlog-root))
+        (download-log-file file servlet-request servlet-response user daemonlog-root :is-daemon true))
       (catch InvalidRequestException ex
         (log-error ex)
         (ring-response-from-exception ex))))


oops, make sure to call fn we're testing in unit tests :unamused:

--- test/metabase/driver/h2_test.clj
+++ test/metabase/driver/h2_test.clj
@@ -9,8 +9,8 @@
 ;; ## new-style
 (expect {:db
          "file:/Users/cam/birdly/bird_sightings.db;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1"}
-    {:details {:db "file:/Users/cam/birdly/bird_sightings.db;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1"}})
+  (database->connection-details {:details {:db "file:/Users/cam/birdly/bird_sightings.db;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1"}}))

 ;; ## legacy
 (expect {:db "file:/Users/cam/birdly/bird_sightings.db;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1"}
-  {:details {:conn_str "file:/Users/cam/birdly/bird_sightings.db;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1"}})
+  (database->connection-details {:details {:conn_str "file:/Users/cam/birdly/bird_sightings.db;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1"}}))


lein ring kendu

lein ring kendu

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lnmnd/magnet.zer.git/'


project: bump deps to avoid warnings

project: bump deps to avoid warnings

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/pyr/bundes.git/'


upgrade to 0.7.3

upgrade to 0.7.3

--- project.clj
+++ project.clj
@@ -14,7 +14,7 @@
                  [org.twitter4j/twitter4j-stream "2.2.6-SNAPSHOT"]
                  ]

-  :dev-dependencies [[storm "0.7.2"]
+  :dev-dependencies [[storm "0.7.3"]
                      [org.clojure/clojure "1.4.0"]
                      ])


version upgrade

version upgrade

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/meandor/aim-pipeline.git/'


Version 109

Version 109

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tobias/clojars-web.git/'


Bumped Clojure version

Bumped Clojure version

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/hudren/ebook-novel.git/'


adding a min lein version to the project

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/nilenso/finenso-time-tracker.git/'


Clojure 1.5.0-RC4

Clojure 1.5.0-RC4

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/shen.clj.git/'


Replicate a Sequence

Replicate a Sequence

error: pathspec 'src/4clojure/replicate-seq.clj' did not match any file(s) known to git

--- src/4clojure/replicate-seq.clj
+++ src/4clojure/replicate-seq.clj
@@ -0,0 +1,37 @@
+;; Replicate a Sequence
+;; http://www.4clojure.com/problem/33
+
+(defn __ [coll n]
+  (mapcat #(take n (iterate identity %)) coll))
+
+;; (take 2 (iterate identity 1))
+
+(= (__ [1 2 3] 2) '(1 1 2 2 3 3))
+(= (__ [:a :b] 4) '(:a :a :a :a :b :b :b :b))
+(= (__ [4 5 6] 1) '(4 5 6))
+(= (__ [[1 2] [3 4]] 2) '([1 2] [1 2] [3 4] [3 4]))
+(= (__ [44 33] 2) [44 44 33 33])
+
+;; 4Clojure solution:
+(fn [coll n] (mapcat #(take n (iterate identity %)) coll))
+
+
+;; _artem_uv's solution:
+;; (fn f
+;;   ([s t]
+;;    (f s t '()))
+;;   ([s t r]
+;;    (if (empty? s)
+;;      (reverse r)
+;;      (recur (rest s) t (into r (repeat t (first s)))))))
+;;
+;; _pcl's solution:
+;; (fn [xs n] (mapcat #(repeat n %) xs))
+
+;; aceeca1's solution:
+;; (fn [x t] (mapcat (partial repeat t) x))
+
+;; adereth's solution:
+;; (fn [s n]
+;;   (if (= n 1) s
+;;     (apply interleave (repeat n s))))


[WM] deal with more optional nil values in tx data

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/election-authority-works.git/'


Bump deps

Bump deps

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/zk/rx.git/'


Kehaar 0.7.0 with bounded thread pools

Kehaar 0.7.0 with bounded thread pools

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/voting-method-http-api.git/'


Update core.async and test.check dependencies.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tcsavage/cats.git/'


Releasing v0.9.3

Releasing v0.9.3


Update dependencies

Update dependencies

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/vote-by-mail-works.git/'


lein-release plugin: preparing 0.2.1 release

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject sablono "0.2.1-SNAPSHOT"
+(defproject sablono "0.2.1"
   :description "Lisp style templating for Facebook's React."
   :url "http://github.com/r0man/sablono"
   :author "Roman Scherer"


Increase version number for dev

Increase version number for dev

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tobiasbayer/eureka-client.git/'


explicit :resource-paths

explicit :resource-paths

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/ply.git/'


move :aot under :uberjar profile

move :aot under :uberjar profile


jvm opts

jvm opts

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/transwarp.git/'


release test

release test

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/janraasch/esigrate.git/'


Guess this should be another version

Guess this should be another version


Upgrade to latest cognitect aws libs

Upgrade to latest cognitect aws libs


will use inner loop rather than recur on core func


default state

default state

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/kenichirow/recipes.git/'


more comments, cleaned up code

more comments, cleaned up code

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/talexand/velcro-notes.git/'


Better docstring

Better docstring

--- src/cljx/cats/monad/maybe.cljx
+++ src/cljx/cats/monad/maybe.cljx
@@ -320,6 +320,7 @@

 (defn map-maybe
   "Given a maybe-returning function and a collection, map the function over
-  the collection returning the values contained in the just values."
+  the collection returning the values contained in the just values of the
+  resulting collection."
   [mf coll]
   (cat-maybes (map mf coll)))


[load-module] allow absolute paths

[load-module] allow absolute paths

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/blandinw/cherry.git/'


Delete vestigial code in partner-site entity

Nothing was using this any more.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/partner-works.git/'


CMR-1030: Pulled in refactoring for routes.

error: pathspec 'common-lib/src/cmr/common/routes.clj' did not match any file(s) known to git

--- common-lib/src/cmr/common/routes.clj
+++ common-lib/src/cmr/common/routes.clj
@@ -0,0 +1,51 @@
+(ns cmr.common.routes
+  "Provides common routes."
+  (:require [compojure.handler :as handler]
+            [compojure.route :as route]
+            [compojure.core :refer :all]
+            [clojure.string :as str]
+            [clojure.java.io :as io]
+            [ring.util.response :as r]
+            [ring.util.request :as request]
+            [ring.util.codec :as codec]
+            [ring.middleware.json :as ring-json]
+            [cheshire.core :as json]
+            [cmr.common.cache :as cache]
+            [cmr.acl.core :as acl]))
+
+(def cache-api-routes
+  "Create routes for the cache querying/management api"
+  (context "/caches" []
+    ;; Get the list of caches
+    (GET "/" {:keys [params request-context headers]}
+      (let [context (acl/add-authentication-to-context request-context params headers)
+            caches (map name (keys (get-in context [:system :caches])))]
+        (acl/verify-ingest-management-permission context :read)
+        {:status 200
+         :body (json/generate-string caches)}))
+    ;; Get the keys for the given cache
+    (GET "/:cache-name" {{:keys [cache-name] :as params} :params
+                         request-context :request-context
+                         headers :headers}
+      (let [context (acl/add-authentication-to-context request-context params headers)
+            cache (cache/context->cache context (keyword cache-name))]
+        (acl/verify-ingest-management-permission context :read)
+        (when cache
+          (let [result (cache/cache-keys cache)]
+            (println "RESULT....")
+            (println result)
+            {:status 200
+             :body (json/generate-string result)}))))
+
+    ;; Get the value for the given key for the given cache
+    (GET "/:cache-name/:cache-key" {{:keys [cache-name cache-key] :as params} :params
+                                    request-context :request-context
+                                    headers :headers}
+      (let [cache-key (keyword cache-key)
+            context (acl/add-authentication-to-context request-context params headers)
+            cache (cache/context->cache context (keyword cache-name))
+            result (cache/cache-lookup cache cache-key)]
+        (acl/verify-ingest-management-permission context :read)
+        (when result
+          {:status 200
+           :body (pr-str result)})))))


Create separate namespace for multiple libs

error: pathspec 'src/discuss/lib/views.cljs' did not match any file(s) known to git

--- src/discuss/lib/views.cljs
+++ src/discuss/lib/views.cljs
@@ -0,0 +1,38 @@
+(ns discuss.lib.views
+  (:require [om.core :as om :include-macros true]
+            [om.dom :as dom :include-macros true]))
+
+(defn fa-icon
+  "Wrapper for font-awesome icons."
+  ([class]
+   (dom/i #js {:className (str "fa " class)}))
+  ([class f]
+   (dom/i #js {:className (str "pointer fa " class)
+               :onClick   f})))
+
+(defn logo
+  "If no function is provided, show logo as is. Else bind function to onClick-event and add
+   pointer-class."
+  ([]
+   (fa-icon "fa-comments"))
+  ([f]
+   (fa-icon "fa-comments" f)))
+
+(defn safe-html
+  "Creates DOM element with interpreted HTML."
+  [string]
+  (dom/span #js {:dangerouslySetInnerHTML #js {:__html string}}))
+
+(defn commit-target-value
+  "Set local state of view, parse the value of the target of val."
+  [key val owner]
+  (om/set-state! owner key (.. val -target -value)))
+
+(defn display
+  "Toggle display view."
+  [show]
+  (if show
+    #js {}
+    #js {:display "none"}))
+
+(defn toggle-show [show] (if show false true))


added initial uce solution

added initial uce solution

error: pathspec 'src/main/cljc/clojure_club/x121_universal_computation_engine/jstrength.cljc' did not match any file(s) known to git

--- src/main/cljc/clojure_club/x121_universal_computation_engine/jstrength.cljc
+++ src/main/cljc/clojure_club/x121_universal_computation_engine/jstrength.cljc
@@ -0,0 +1,14 @@
+(ns clojure-club.x121-universal-computation-engine.jstrength)
+
+(defn uce [l]
+  (fn [m]
+    (let [m (merge m {'/ / '+ + '- - '* *})]
+      (letfn [(calc [[f & r] ret]
+                (if f
+                  (if (list? f)
+                    (let [[fun & args] (calc f [])]
+                      (recur r (conj ret (apply fun args))))
+                    (calc r (conj ret (get m f f))))
+                  ret))]
+        (let [[fun & args] (calc l [])]
+          (apply fun args))))))


testing Samza config reader.

testing Samza config reader.

error: pathspec 'kappaql-core/test/clojure/org/pathirage/kappaql/config_test.clj' did not match any file(s) known to git

--- kappaql-core/test/clojure/org/pathirage/kappaql/config_test.clj
+++ kappaql-core/test/clojure/org/pathirage/kappaql/config_test.clj
@@ -0,0 +1,15 @@
+(ns org.pathirage.kappaql.config-test
+  (:import [org.apache.samza.config MapConfig])
+  (:require [clojure.test :refer :all]
+            [clojure.java.io :as io]))
+
+
+(deftest properties-file-map-value-test
+  (testing "Map as a value of a property in propeties file"
+    (with-open [^java.io.Reader reader (-> "config-test.properties" io/resource io/file io/reader)]
+    (let [props (java.util.Properties.)]
+      (.load props reader)
+      (let [map-config (MapConfig. props)
+            stream-defs (.subset map-config "org.pathirage.kappaql.input")]
+        (is (= "name=String,age=Integer" (.get stream-defs ".stream1")))
+        (is (= "orderId=String,Quantity=Integer" (.get stream-defs ".stream2"))))))))


First working version of re-index

First working version of re-index

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mstang/pathdatabase.git/'


Add buffer to incoming events

Add buffer to incoming events

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/democracyworks/electorate-works.git/'


added

added

error: pathspec 'src/promises.clj' did not match any file(s) known to git

--- src/promises.clj
+++ src/promises.clj
@@ -0,0 +1,32 @@
+(ns promises)
+
+(def f
+  (future (Thread/sleep 10000) (println "done") 100))
+
+;; @f
+
+(future-cancel f)
+(future-cancelled? f)
+(future-done? f)
+
+;; Create a promise
+(def p (promise))
+
+;; Check if was delivered/realized
+(realized? p)
+
+;; Delivering the promise
+(deliver p 42)
+
+;; Check again if it was delivered
+(realized? p)
+
+;; Deref to see what has been delivered
+;;@p
+;;(deref p)
+
+
+(let
+    [sum (future (apply + (range 1e7)))]
+    (println "Started...")
+    (println "Done: " @sum))


Add an example of testing streams with exceptions

error: pathspec 'test/as_documentation/prerequisites/streaming_with_exceptions.clj' did not match any file(s) known to git

--- test/as_documentation/prerequisites/streaming_with_exceptions.clj
+++ test/as_documentation/prerequisites/streaming_with_exceptions.clj
@@ -0,0 +1,106 @@
+(ns as-documentation.prerequisites.streaming-with-exceptions
+  (:use midje.sweet))
+
+;; By treating the correctness of functions as facts depending on
+;; prerequisites, we can test handling of a stream of values that
+;; includes exceptions without a *whole* lot of fuss. This style will
+;; be explained more fully in https://leanpub.com/utpov by Fields,
+;; Feathers, and Marick.
+
+;; 1: Turn function calls into data.
+
+;; See chapter 12 of https://leanpub.com/fp-oo for the idea behind
+;; this function.
+(defn value-stream
+  "Convert on-demand calls of a function into a lazy seq of values.
+   Note that the stream is assumed to be infinite - there is no
+   'out of values' indicator."
+  [stream-fn]
+  (cons (stream-fn) (lazy-seq (value-stream stream-fn))))
+
+(def source-of-values-fn)
+
+(fact "`value-stream` converts a function into a lazy seq of values"
+  (take 3 (value-stream (constantly 1))) => [1 1 1]
+
+  (fact "works with Midje's =streams=>"
+    (take 3 (value-stream #'source-of-values-fn)) => [1 2 3]
+    (provided
+      (source-of-values-fn) =streams=> [1 2 3])))
+
+
+;; 2: Independently, handle exceptions.
+
+(defn value-or-sentinel
+  "Return value of a function, except in the case of an exception.
+   For exception, return the value `sentinel-function`, which is
+   given the exception"
+  [f sentinel-fn]
+     (try (f)
+     (catch Exception ex
+       (sentinel-fn ex))))
+
+(fact "`value-or-sentinel returns a sentinel value upon exception"
+  (value-or-sentinel (constantly 2) ..unused..) => 2
+
+  (value-or-sentinel #'source-of-values-fn (constantly ::sentinel)) => ::sentinel
+  (provided
+    (source-of-values-fn) =throws=> (new Exception))
+
+  (value-or-sentinel #'source-of-values-fn #(.getMessage %)) => "hi"
+  (provided
+    (source-of-values-fn) =throws=> (new Exception "hi")))
+
+
+;; 3: Compose the two ideas.
+
+(defn sentinelized-stream
+  "Convert stream into a lazy sequence of values, with
+   ::sentinel replacing any exceptions."
+  [stream-fn]
+  (value-stream #(value-or-sentinel stream-fn (constantly ::sentinel))))
+
+(facts "about sentinelized streams"
+  (fact "no exceptions => no problem"
+    (take 3 (sentinelized-stream source-of-values-fn)) => [1 2 3]
+    (provided
+     (source-of-values-fn) =streams=> [1 2 3]))
+
+  (fact "exceptions are converted into sentinel"
+    (take 2 (sentinelized-stream source-of-values-fn)) => [::sentinel ::sentinel]
+    (provided
+      (source-of-values-fn) =throws=> (new Exception))))
+
+;; Per J.B. Rainsberger, "test until fear turns to boredom". I'm confident that the above
+;; will work for a mixture of real values and exceptions, but let's see!
+;;
+;; Note: my first thought was to construct a lazy stream like this:
+;;
+;;   (source-of-values-fn) =streams=> (cons 1
+;;                                          (lazy-seq (cons (throw (new Exception "boom!"))
+;;                                                          [3])))))
+;;
+;; That doesn't work - when the `throw happens`, the `cons` is bypassed as the exception goes
+;; up the stack. Thereafter, the next value is always an exception because the cached sequence
+;; never changes. So we have to resort to explicit state.
+
+(defn mkfn:fail-on [fail-set]
+  (let [count (atom 0)]
+    (fn []
+      (let [retval (swap! count inc)]
+        (if (fail-set retval)
+          (throw (new Exception))
+          retval)))))
+
+(def fail-on-first (mkfn:fail-on #{1}))
+(def fail-on-second (mkfn:fail-on #{2}))
+(def fail-on-third (mkfn:fail-on #{3}))
+(def fail-on-bounds (mkfn:fail-on #{1 3}))
+
+
+(facts "end-to-end-like"
+  (take 3 (sentinelized-stream fail-on-first)) => [::sentinel 2 3]
+  (take 3 (sentinelized-stream fail-on-second)) => [1 ::sentinel 3]
+  (take 3 (sentinelized-stream fail-on-third)) => [1 2 ::sentinel]
+  (take 3 (sentinelized-stream fail-on-bounds)) => [::sentinel 2 ::sentinel])
+


Ensure goimports is installed

Ensure goimports is installed

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/shaunstanislaus/cljs2go.git/'


WIP: tests

WIP: tests

error: pathspec 'test/vip/data_processor/db/translations/v5_0/ballot_measure_contests_test.clj' did not match any file(s) known to git

--- test/vip/data_processor/db/translations/v5_0/ballot_measure_contests_test.clj
+++ test/vip/data_processor/db/translations/v5_0/ballot_measure_contests_test.clj
@@ -0,0 +1,52 @@
+(ns vip.data-processor.db.translations.v5-0.ballot-measure-contests-test
+  (:require [clojure.test :refer [deftest testing is]]
+            [vip.data-processor.db.translations.v5-0.ballot-measure-contests :as bmc]))
+
+(deftest index-generator-test
+  (testing "repeatedly calling a generator yields new values"
+    (let [idx (bmc/index-generator 13)
+          values (into [] (take 5 (repeatedly idx)))]
+      (is (= [13 14 15 16 17] values))))
+
+  (testing "values increase monotonicly"
+    (let [idx (bmc/index-generator 0)
+          values (into [] (take 5 (repeatedly idx)))]
+      (is (every? > values)))))
+
+(def bmc
+  {:ballot_title "BALLOT_TITLE",
+   :pro_statement "PRO_STATEMENT",
+   :ballot_sub_title "BALLOT_SUB_TITLE",
+   :results_id 1,
+   :con_statement "CON_STATEMENT",
+   :name "NAME",
+   :external_identifier_value "EXTERNAL_IDENTIFIER_VALUE",
+   :summary_text "SUMMARY_TEXT",
+   :type "TYPE",
+   :effect_of_abstain "EFFECT_OF_ABSTAIN",
+   :electoral_district_id "ELECTORAL_DISTRICT_ID",
+   :has_rotation "HAS_ROTATION",
+   :full_text "FULL_TEXT",
+   :id "bmc001",
+   :external_identifier_othertype "EXTERNAL_IDENTIFIER_OTHERTYPE",
+   :vote_variation "VOTE_VARIATION",
+   :info_uri "INFO_URI",
+   :other_type "OTHER_TYPE",
+   :other_vote_variation "OTHER_VOTE_VARIATION",
+   :passage_threshold "PASSAGE_THRESHOLD",
+   :abbreviation "ABBREVIATION",
+   :electorate_specification "ELECTORATE_SPECIFICATION",
+   :external_identifier_type "EXTERNAL_IDENTIFIER_TYPE",
+   :sequence_order "SEQUENCE_ORDER"})
+
+(deftest abbreviation-ltree-test
+  (let [idx-fn (bmc/index-generator 0)
+        bmc-path "VipObject.0.BallotMeasureContest.0"
+        index-path "VipObject.0.BallotMeasureContest.0.id"]
+    (testing "creating an abbreviation entity"
+      (is (= (list
+              {:simple_path "VipObject.BallotMeasureContest.Abbreviation"
+               :path "VipObject.0.BallotMeasureContest.0.Abbreviation.0"
+               :parent_with_id index-path
+               :value "ABBREVIATION"})
+             (bmc/abbreviation->ltree idx-fn bmc-path bmc))))))


add demo namespace

add demo namespace

error: pathspec 'src/test/clojure/trellis/demo.clj' did not match any file(s) known to git

--- src/test/clojure/trellis/demo.clj
+++ src/test/clojure/trellis/demo.clj
@@ -0,0 +1,2 @@
+(ns trellis.demo)
+


additionally test for jar in target/

additionally test for jar in target/

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/michaelsbradleyjr/shen.clj.git/'


add a :debug option to print req map and HttpRequest object to stdout on request

--- src/clj_http/core.clj
+++ src/clj_http/core.clj
@@ -37,7 +37,7 @@
    the clj-http uses ByteArrays for the bodies."
   [{:keys [request-method scheme server-name server-port uri query-string
            headers content-type character-encoding body socket-timeout
-           conn-timeout]}]
+           conn-timeout debug] :as req}]
   (let [http-client (DefaultHttpClient.)]
     (try
       (doto http-client
@@ -76,6 +76,11 @@
         (when body
           (let [http-body (ByteArrayEntity. body)]
             (.setEntity #^HttpEntityEnclosingRequest http-req http-body)))
+        (when debug
+          (println "Request:")
+          (clojure.pprint/pprint req)
+          (println "HttpRequest:")
+          (clojure.pprint/pprint (bean http-req)))
         (let [http-resp (.execute http-client http-req)
               http-entity (.getEntity http-resp)
               resp {:status (.getStatusCode (.getStatusLine http-resp))


Check for changed content in resources.

Check for changed content in resources.

--- src/clj_stan/core.clj
+++ src/clj_stan/core.clj
@@ -68,6 +68,11 @@

 (defn file-last-modified [fname] (.lastModified (io/file fname)))

+(defn changed-content?
+  [fname content]
+  (or (not (.exists (io/file fname)))
+      (not= (slurp fname) content)))
+
 (defmacro make-step
   [in out & body]
   `(do (if (.exists (io/file ~in))
@@ -81,6 +86,8 @@
   necessary by writing out the data to a new file in the `target`
   directory. Returns `nil` if this is not possible."
   type)
+
+(defmethod model-path :default [_] nil)

 (defmethod model-path java.lang.String
   [filename]
@@ -97,8 +104,10 @@
   (if (.exists (io/file (.getPath url)))
     (.getPath url)
     (let [filename (str "target/stan/" (last (str/split (.getPath url) #"/")))
-          _ (io/make-parents filename)]
-      (spit filename (slurp (.getContent url)))
+          _ (io/make-parents filename)
+          content (slurp url)]
+      (when (changed-content? filename content)
+        (spit filename (slurp url)))
       filename)))

 (defn make