error logging when connection fails

error logging when connection fails

--- src/metabase/driver/generic_sql/connection.clj
+++ src/metabase/driver/generic_sql/connection.clj
@@ -1,15 +1,16 @@
 (ns metabase.driver.generic-sql.connection
-  (:require [korma.core :as k]
-            [metabase.driver :refer [connection]]))
+  (:require [clojure.tools.logging :as log]
+            [korma.core :as k]
+            [metabase.driver :as driver]))

 (defn can-connect?
   "Check whether we can connect to a DATABASE and perform a very simple SQL query.

     (can-connect? (sel :one Database ....)) -> true"
   [database]
-  (try (= (-> (k/exec-raw (connection database) "SELECT 1 AS ONE" :results)
-              first
-              :one)
-          1)
-       (catch Throwable _
+  (try (= 1 (-> (k/exec-raw (driver/connection database) "SELECT 1 AS ONE" :results)
+                first
+                :one))
+       (catch Throwable e
+         (log/error "Failed to connect to database:" (.getMessage e))
          false)))


:sparkles: Add empty file for cljs.user ns.

error: pathspec 'frontend/dev/cljs/user.cljs' did not match any file(s) known to git

--- frontend/dev/cljs/user.cljs
+++ frontend/dev/cljs/user.cljs
@@ -0,0 +1 @@
+(ns cljs.user)


Add web_repl namespace containing functions available to users in the web app

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

--- src/todo_repl_webapp/web_repl.clj
+++ src/todo_repl_webapp/web_repl.clj
@@ -0,0 +1,29 @@
+(ns todo-repl-webapp.web-repl
+  (:require [todo-repl.core :as todo]))
+
+(def ^:dynamic *tasks-ref* (ref []))
+
+(defn tasks [] (deref *tasks-ref*))
+
+(defn add-new-task [x]
+  (dosync (alter *tasks-ref* #(conj
+                                %1
+                                (todo/new-task-better x)))))
+
+(defn complete-task [index]
+  "Sets the :status of task at index to :complete"
+  (dosync (alter *tasks-ref* assoc-in [index :status] :complete)))
+
+(defn init-tasks [& _]
+  (do
+    (dosync (ref-set *tasks-ref*  []))
+    (add-new-task {:name "Go get some milk"
+                   :context "shopping"
+                   :due "tomorrow"})
+    (add-new-task {:name "Go get new shoes"
+                   :context "shopping"
+                   :due "friday"})
+    (add-new-task {:name "Clean the kitchen sink"
+                   :context "cleaning"})))
+
+(init-tasks)


change prn to log/info

change prn to log/info

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/amedw/mud-server.git/'


static work

static work

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/CraZySacX/scene.git/'


add board transwormers

add board transwormers

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

--- stuf/src/sandbox/sudoku_logic.clj
+++ stuf/src/sandbox/sudoku_logic.clj
@@ -0,0 +1,29 @@
+(ns sandbox.sudoku-logic
+  (require [clojure.core.logic :as logic]))
+
+(def b1 '[3 - - - - 5 - 1 -
+          - 7 - - - 6 - 3 -
+          1 - - - 9 - - - -
+          7 - 8 - - - - 9 -
+          9 - - 4 - 8 - - 2
+          - 6 - - - - 5 - 1
+          - - - - 4 - - - 6
+          - 4 - 7 - - - 2 -
+          - 2 - 6 - - - - 3])
+
+(defn rowify [board]
+  (->> board
+       (partition 9)
+       (map vec)
+       vec))
+
+(defn colify [rows]
+  (apply map vector rows))
+
+(defn subgrid [rows]
+  (partition 9
+             (for [row (range 0 9 3)
+                   col (range 0 9 3)
+                   x (range row (+ row 3))
+                   y (range col (+ col 3))]
+               (get-in rows [x y]))))


Modified tests because of changes in 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/DajanaStiberova/green-recipes.git/'


Rename valid subscription transducer

Rename valid subscription transducer

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/'


Added tests for checking processing level 3.

error: pathspec 'test/cmr/opendap/tests/system/app/ous/core.clj' did not match any file(s) known to git

--- test/cmr/opendap/tests/system/app/ous/core.clj
+++ test/cmr/opendap/tests/system/app/ous/core.clj
@@ -0,0 +1,93 @@
+(ns ^:system cmr.opendap.tests.system.app.ous.core
+  "Note: this namespace is exclusively for system tests; all tests defined
+  here will use one or more system test fixtures.
+
+  Definition used for system tests:
+  * https://en.wikipedia.org/wiki/Software_testing#System_testing"
+  (:require
+    [clojure.test :refer :all]
+    [cmr.opendap.http.request :as request]
+    [cmr.opendap.testing.system :as test-system]
+    [cmr.opendap.testing.util :as util]
+    [org.httpkit.client :as httpc]
+    [ring.util.codec :as codec]))
+
+(use-fixtures :once test-system/with-system)
+
+(deftest processing-level-1-and-2-no-spatial)
+
+(deftest processing-level-1-and-2-with-spatial)
+
+(deftest processing-level-3+-no-spatial
+  (let [collection-id "C1200267318-HMR_TME"
+          granule-id "G1200267320-HMR_TME"
+          variable-id "V1200267322-HMR_TME"]
+    (testing "GET with bounding box ..."
+      (let [response @(httpc/get
+                       (format (str "http://localhost:%s"
+                                    "/opendap/ous/collection/%s"
+                                    "?granules=%s"
+                                    "&variables=%s")
+                               (test-system/http-port)
+                               collection-id
+                               granule-id
+                               variable-id)
+                       (request/add-token-header {} (util/get-sit-token)))]
+        (is (= 200 (:status response)))
+        (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A,Latitude,Longitude"]
+               (util/parse-response response)))))
+    (testing "GET with subset ..."
+      (let [response @(httpc/get
+                       (format (str "http://localhost:%s"
+                                    "/opendap/ous/collection/%s"
+                                    "?coverage=%s"
+                                    "&rangesubset=%s")
+                               (test-system/http-port)
+                               collection-id
+                               granule-id
+                               variable-id)
+                       (request/add-token-header {} (util/get-sit-token)))]
+        (is (= 200 (:status response)))
+        (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A,Latitude,Longitude"]
+               (util/parse-response response)))))))
+
+(deftest processing-level-3+-with-spatial
+  (let [collection-id "C1200267318-HMR_TME"
+          granule-id "G1200267320-HMR_TME"
+          variable-id "V1200267322-HMR_TME"]
+    (testing "GET with bounding box ..."
+      (let [response @(httpc/get
+                       (format (str "http://localhost:%s"
+                                    "/opendap/ous/collection/%s"
+                                    "?granules=%s"
+                                    "&variables=%s"
+                                    "&bounding-box="
+                                    "-9.984375,56.109375,19.828125,67.640625")
+                               (test-system/http-port)
+                               collection-id
+                               granule-id
+                               variable-id)
+                       (request/add-token-header {} (util/get-sit-token)))]
+        (is (= 200 (:status response)))
+        (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A[0:1:23][22:1:34][169:1:200],Latitude[22:1:34],Longitude[169:1:200]"]
+               (util/parse-response response)))))
+    (testing "GET with subset ..."
+      (let [response @(httpc/get
+                       (format (str "http://localhost:%s"
+                                    "/opendap/ous/collection/%s"
+                                    "?coverage=%s"
+                                    "&rangesubset=%s"
+                                    "&subset=lat(56.109375,67.640625)"
+                                    "&subset=lon(-9.984375,19.828125)")
+                               (test-system/http-port)
+                               collection-id
+                               granule-id
+                               variable-id)
+                       (request/add-token-header {} (util/get-sit-token)))]
+        (is (= 200 (:status response)))
+        (is (= ["https://acdisc.gesdisc.eosdis.nasa.gov/opendap/Aqua_AIRS_Level3/AIRX3STD.006/2002/AIRS.2002.09.04.L3.RetStd001.v6.0.9.0.G13208020620.hdf.nc?CH4_VMR_A[0:1:23][22:1:34][169:1:200],Latitude[22:1:34],Longitude[169:1:200]"]
+               (util/parse-response response)))))))
+
+(deftest processing-level-not-provided-no-spatial)
+
+(deftest processing-level-not-provided-with-spatial)


Remove chime dependency

Remove chime dependency

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/scheduled-message-works.git/'


Update versions of deps & base Docker image


Version 0.3.0-SNAPSHOT

Version 0.3.0-SNAPSHOT

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/nathanielksmith/trapperkeeper-status.git/'


Bump tools.cli version

Bump tools.cli 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/terrancesnyder/engulf.git/'


Added list queries and resources

Added list queries and resources

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/B2W-BIT/restQL-server.git/'


Added midje unit testing framework and lein-midje.

--- project.clj
+++ project.clj
@@ -30,9 +30,10 @@
   :dev-dependencies
   [
    [ring/ring-devel "1.0.1"]
+   [midje "1.3.1"]
+   [lein-midje "1.0.8"]
    ]
   :ring {:handler ruuvi-tracker.core/dev-app}
-  ;;  :repositories {"sonatype-oss-public" "https://oss.sonatype.org/content/groups/public/"}
   )


Update deps

Update deps

These are fairly well-tested updates in other components.

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-http-api.git/'


updated project file

updated project file

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/jchli/jepsen-aurora.git/'


Release 0.12.5.

Release 0.12.5.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clojars-web "0.12.4"
+(defproject clojars-web "0.12.5"
   :dependencies [[org.clojure/clojure "1.4.0"]
                  [org.clojure/tools.cli "0.2.1"]
                  [org.apache.maven/maven-model "3.0.4"


Version 1.7.0

Version 1.7.0

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/'


tuturial

tuturial

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

--- examples/tuturial.clj
+++ examples/tuturial.clj
@@ -0,0 +1,414 @@
+(require '[glasses :as lens])
+(require '[glasses.traversals :as travers])
+(require '[glasses.tree :as tree])
+
+;; #######################################
+;; basic lens
+
+(def user
+  {:first-name "tobias"
+   :last-name "funke"
+   :email "tobias.funke@gmail.com"})
+
+;; this is the raw way to define a lense
+;; you call lens/lens and give it a function
+;; that takes a root value in this case a user
+;; and returns a pair where the first value
+;; is the field. And the second value is a function
+;; that takes a function of the name and returns a new user
+
+(def first-name
+  (lens/lens
+   (fn [user]
+     (let [name (:first-name user)]
+       [name
+        (fn [f] (assoc user :first-name (f name)))]))))
+
+(require '[clojure.string :as string])
+(use 'clojure.pprint)
+
+;; you can get the field from the root value
+;; by calling view on it with the lens
+
+(pprint (lens/view user first-name))
+;; => "tobias"
+
+;; you can also update the field with the update function
+
+(pprint (lens/update user first-name string/capitalize))
+;; => {:last-name "funke",
+;;     :first-name "Tobias", <-- capitalized
+;;     :email "tobias.funke@gmail.com"}
+
+;; you can also write to the field with lens/write
+;; this is the same as doing (update root lens (fn [_] new-value))
+
+(pprint (lens/write user first-name "Newname"))
+;; => {:last-name "funke",
+;;     :first-name "Newname",
+;;     :email "tobias.funke@gmail.com"}
+
+;; you can also define lenses using lens/getter-setter-lens
+;; wich makes a lens from a getter and a setter function
+
+(def first-name2
+  (lens/getter-setter-lens
+   (fn [user] (:first-name user))
+   (fn [user new-first-name] (assoc user :first-name new-first-name))))
+
+;; this will make you the same lens
+(= (lens/write user first-name  "Newname")
+   (lens/write user first-name2 "Newname"))
+
+;; since using keywords to reference fields in maps is so commen
+;; you can use them directly as lenses
+
+(= (lens/write user first-name  "Newname")
+   (lens/write user first-name2 "Newname")
+   (lens/write user :first-name "Newname"))
+
+(= (lens/view user first-name)
+   (lens/view user first-name2)
+   (lens/view user :first-name))
+
+;; ========================================================
+;; composition
+
+;; a critical feture of lenses are that they compose
+;; you can do this with the lens/comp-lenses
+;; this function takse a seq of lenses and combines them
+
+(def user2
+  {:first-name "tobias"
+   :last-name "funke"
+   :address {:city "bluethwill"
+             :address_line "sudden valy street 23"
+             :postcode "56321"}})
+
+(def user-city (lens/comp-lenses [:address :city]))
+
+(= (lens/view user2 user-city) "bluethwill")
+
+;; if you use a vector of lenses as a lens
+;; you will get the same result as calling lens/comp-lenses on the lenses
+
+(= (lens/view user2 [:address :postcode])
+   "56321")
+
+;; so basicly you can use lenses just like you use
+;; the clojure *-in funcitons
+
+(= (get-in user2 [:address :city])
+   (lens/view user2 [:address :city]))
+
+(= (update-in user2 [:address :city] string/capitalize)
+   (lens/update user2 [:address :city] string/capitalize))
+
+;; =====================================================
+;; iso-lens
+
+;; the postcode in the nested structure is a string atm
+;; but we can write a lens that lets us treat it as a number
+
+(def str->num (lens/iso-lens #(Integer/parseInt %) str))
+
+;; iso-lens takes 2 functions one to convert it to a integer in this case
+;; and anather one to convert it back to a string
+
+(lens/update user2 [:address :postcode str->num] inc)
+;; {:last-name "funke",
+;;  :first-name "tobias",
+;;  :address {:address_line "sudden valy street 23",
+;;            :postcode "56322",
+;;            :city "bluethwill"}}
+
+;; the result after incrementing the postcode is still a string
+
+;; =====================================================
+;; extract
+
+;; extract is a function that lets you transform a structure
+;; to a map of a diferent shape and later write back changes
+;; that are done to the new map
+
+(def user-view
+  {:first-name   :first-name
+   :last-name    :last-name
+   :address_line [:address :address_line]
+   :address_city [:address :city]})
+
+(= (lens/view user2 user-view)
+   {:address_line "sudden valy street 23",
+    :last-name "funke",
+    :first-name "tobias",
+    :address_city "bluethwill"})
+
+(defn take-ower-town
+  "clame the town as you own"
+  [user] ;; user in the user-view shape
+  (assoc user :address_city (:first-name user)))
+
+(= (lens/update user2 user-view take-ower-town)
+   {:last-name "funke", :first-name "tobias",
+    :address {:address_line "sudden valy street 23",
+              :postcode "56321",
+              :city "tobias"}})
+
+;; =================================================
+;; traversals
+
+;; traversals lets you dig into collections (or any thing that can be "traversed")
+
+(def user3
+  {:first-name "tobias"
+   :last-name  "funke"
+   :languages ["clojure" "ruby" "elixir"]})
+
+(= (lens/update user3 [:languages travers/mapped] string/capitalize)
+   {:last-name "funke",
+    :first-name "tobias",
+    :languages '("Clojure" "Ruby" "Elixir")})
+
+;; travers/mapped treats the items as seqs. so all results will be
+;; converted to lists
+;; but a traversal can create whatever structure it wants
+
+;; lets write a vector travers
+
+(def mapped-vec
+  (lens/traversal
+   (fn [collection]
+     [collection
+      (fn [f] (mapv f collection))])))
+
+;; traversals are built a lot like lenses
+;; its a function that takes the structure
+;; in this case a collection
+;; it returns a pair that where the first item is
+;; all the items it "traverses" as a seq.
+;; and the second item is a function
+;; that builds a new value after applying the function
+;; to every item it traverses. IE a mapping
+
+(= (lens/update user3 [:languages mapped-vec] string/capitalize)
+   {:last-name "funke",
+    :first-name "tobias",
+    :languages ["Clojure" "Ruby" "Elixir"]})
+
+;; this version keeps the languages in a vector
+
+;; traversals can be composed with lenses in any way you want
+
+(def deep-data
+  {:a [{:b [{:c [1 2 3]}
+            {:c [3 4 5]}]}
+       {:b [{:c [9 8 7]}
+            {:c []}]}
+       {:b [{:c [1 3]}
+            {:c [3]}]}]})
+
+(def cs-lens [:a mapped-vec :b mapped-vec :c mapped-vec])
+
+(= (lens/update deep-data cs-lens * 2)
+   {:a [{:b [{:c [2 4 6]}
+             {:c [6 8 10]}]}
+        {:b [{:c [18 16 14]}
+             {:c []}]}
+        {:b [{:c [2 6]}
+             {:c [6]}]}]})
+
+;; you can take a traversal and shrink the result your working with
+
+(def even-cs-lens [cs-lens (travers/shrink even?)])
+
+(= (lens/write deep-data even-cs-lens 0)
+   {:a [{:b [{:c [1 0 3]}
+             {:c [3 0 5]}]}
+        {:b [{:c [9 0 7]}
+             {:c []}]}
+        {:b [{:c [1 3]}
+             {:c [3]}]}]})
+
+;; this will only write to even values
+
+;; if you view a traversed lens you get all
+;; values it points to as a flattened seq
+
+(= (lens/view deep-data even-cs-lens)
+   [2 4 8])
+
+;; this returns all even values in the :c fields of the deep-data
+
+;; ===========================================
+
+;; tree
+;; ok! lets work with some tree data
+;; courtesy of http://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx
+
+(def xml-string
+  "<?xml version=\"1.0\"?>
+   <catalog>
+   <book id=\"bk101\">
+      <author>Gambardella, Matthew</author>
+      <title>XML Developer's Guide</title>
+      <genre>Computer</genre>
+      <price>44.95</price>
+      <publish_date>2000-10-01</publish_date>
+      <description>An in-depth look at creating applications
+      with XML.</description>
+   </book>
+   <book id=\"bk102\">
+      <author>Ralls, Kim</author>
+      <title>Midnight Rain</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2000-12-16</publish_date>
+      <description>A former architect battles corporate zombies,
+      an evil sorceress, and her own childhood to become queen
+      of the world.</description>
+   </book>
+   <book id=\"bk103\">
+      <author>Corets, Eva</author>
+      <title>Maeve Ascendant</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2000-11-17</publish_date>
+      <description>After the collapse of a nanotechnology
+      society in England, the young survivors lay the
+      foundation for a new society.</description>
+   </book>
+   <book id=\"bk104\">
+      <author>Corets, Eva</author>
+      <title>Oberon's Legacy</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2001-03-10</publish_date>
+      <description>In post-apocalypse England, the mysterious
+      agent known only as Oberon helps to create a new life
+      for the inhabitants of London. Sequel to Maeve
+      Ascendant.</description>
+   </book>
+   <book id=\"bk105\">
+      <author>Corets, Eva</author>
+      <title>The Sundered Grail</title>
+      <genre>Fantasy</genre>
+      <price>5.95</price>
+      <publish_date>2001-09-10</publish_date>
+      <description>The two daughters of Maeve, half-sisters,
+      battle one another for control of England. Sequel to
+      Oberon's Legacy.</description>
+   </book>
+   <book id=\"bk106\">
+      <author>Randall, Cynthia</author>
+      <title>Lover Birds</title>
+      <genre>Romance</genre>
+      <price>4.95</price>
+      <publish_date>2000-09-02</publish_date>
+      <description>When Carla meets Paul at an ornithology
+      conference, tempers fly as feathers get ruffled.</description>
+   </book>
+   <book id=\"bk107\">
+      <author>Thurman, Paula</author>
+      <title>Splish Splash</title>
+      <genre>Romance</genre>
+      <price>4.95</price>
+      <publish_date>2000-11-02</publish_date>
+      <description>A deep sea diver finds true love twenty
+      thousand leagues beneath the sea.</description>
+   </book>
+   <book id=\"bk108\">
+      <author>Knorr, Stefan</author>
+      <title>Creepy Crawlies</title>
+      <genre>Horror</genre>
+      <price>4.95</price>
+      <publish_date>2000-12-06</publish_date>
+      <description>An anthology of horror stories about roaches,
+      centipedes, scorpions  and other insects.</description>
+   </book>
+   <book id=\"bk109\">
+      <author>Kress, Peter</author>
+      <title>Paradox Lost</title>
+      <genre>Science Fiction</genre>
+      <price>6.95</price>
+      <publish_date>2000-11-02</publish_date>
+      <description>After an inadvertant trip through a Heisenberg
+      Uncertainty Device, James Salway discovers the problems
+      of being quantum.</description>
+   </book>
+   <book id=\"bk110\">
+      <author>O'Brien, Tim</author>
+      <title>Microsoft .NET: The Programming Bible</title>
+      <genre>Computer</genre>
+      <price>36.95</price>
+      <publish_date>2000-12-09</publish_date>
+      <description>Microsoft's .NET initiative is explored in
+      detail in this deep programmer's reference.</description>
+   </book>
+   <book id=\"bk111\">
+      <author>O'Brien, Tim</author>
+      <title>MSXML3: A Comprehensive Guide</title>
+      <genre>Computer</genre>
+      <price>36.95</price>
+      <publish_date>2000-12-01</publish_date>
+      <description>The Microsoft MSXML3 parser is covered in
+      detail, with attention to XML DOM interfaces, XSLT processing,
+      SAX and more.</description>
+   </book>
+   <book id=\"bk112\">
+      <author>Galos, Mike</author>
+      <title>Visual Studio 7: A Comprehensive Guide</title>
+      <genre>Computer</genre>
+      <price>49.95</price>
+      <publish_date>2001-04-16</publish_date>
+      <description>Microsoft Visual Studio 7 is explored in depth,
+      looking at how Visual Basic, Visual C++, C#, and ASP+ are
+      integrated into a comprehensive development
+      environment.</description>
+   </book>
+</catalog>")
+
+(require '[clojure.xml :as xml])
+
+(defn parse-xml-str [xml-text]
+  (xml/parse
+   (java.io.ByteArrayInputStream.
+    (.getBytes xml-text))) )
+
+(def xml-catalog (parse-xml-str xml-string))
+
+;; first task! something simple
+;; Lets change the name of all the authors to tobias funke in this xml document.
+;; This culd be accomplished by diggin down to the right elements and updating them
+;; appropriately... but a lazier way would be to just walk all of the tree
+;; and replace the contents of the elements with the author tag
+
+;; we can use tree/pre-tree to accomplish this
+;; it is a function that takes a traversal of all sub nodes of a node
+;; and gives you a traversal of all nodes in the tree
+;; EXAMPLE:
+
+;; sinse nodes in the
+
+(def xml-nodes (tree/pre-tree
+                [:content
+                 (travers/filtered map?) ; we dont want to list the strings
+                                         ; in the tree as nodes
+                                         ; so we filter them here
+                 ]))
+
+;; xml nodes here is a lens/traversal that lets you view and modify
+;; nodes of the tree in a pre-walk fassion.
+;; (there is also a post-tree that lets you do it in a post-walk fassion)
+
+;; ok so lets shrink the nodes we are working with to only the nodes
+;; with the tag author
+
+(def authors [xml-nodes (travers/shrink #(= (:tag %) :author))])
+
+;; and change the contents of these nodes to be "tobias funke"
+
+(pprint
+ (-> xml-catalog
+     (lens/write [authors :content] ["tobias funke"])))
+
+;; perfect all the authors are now tobias funke


Added elementary cellular automata example

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

--- examples/automata.clj
+++ examples/automata.clj
@@ -0,0 +1,176 @@
+(ns clj-automata.core
+  "This module visualizes elementary cellular automata. It's primarily intended
+   to show off the fun aspects of functional programming and lazy-sequences in clojure to those who are coming from an OO background.
+
+   If you're interested in how elementary cellular automata work, see:
+   http://mathworld.wolfram.com/ElementaryCellularAutomaton.html and
+   http://en.wikipedia.org/wiki/Elementary_cellular_automaton
+
+   Also, I highly recommend reading this source file bottom to top in order to understand it best.
+
+   In particular, the code here makes heavy use of lazy-sequences, both directly through
+   `lazy-seq` and also through functions like map, for, partition, and other functions that
+   in clojure return lazy sequences. In some cases, we force lazy-evaluation for side-effects with
+   (dorun).
+
+   Since the visualization is of a stream of states for the automata, lazy-sequences are a very apt model.
+   We can define a sequence of all future results, and simply iterate our way toward where we'd like to be.
+   At a high level this library revolves around a single lazy seq that represents all future states.
+
+   The rendering model here is quite simple, we use pure clojure to fill a 2D array of 1s and 0s that contains
+   the current on-screen state. This 2D buffer is, itself, a partition (e.g. slice) of the lazy sequence of all
+   future states. See the run-rule function for more detail.
+
+   The core functions behind the laziness are (run-rule) which sets up the initial state and UI,
+   (simulation), which returns a lazy sequence of results,
+   and (simulate) which does the legwork of applying the automaton's rules.
+
+   There are other functional aspects here at play. The (rule) function for instance, is a higher-order function,
+   meaning that it returns a brand new function. The function it returns implements a given rule, matching the patterns
+   of the rule to outputs"
+  (:gen-class)
+  (:require [quil.core :as qc])
+  (:use clojure.pprint)
+  (:import java.lang.Math))
+
+;; Colors for each cell
+(def live-color [242 233 99])
+(def dead-color [64 37 27])
+
+;; Elementary automata use a clever trick to allow us to describe an entire rule with only a few numbers.
+;; Since the automata are essentially pattern matchers, describing what a trio of living / dead cells evaluate to
+;; we can effeciently encode their behaviour as a sequence of 1s and 0s. A good visualization of this can be found
+;; here, at wolfram math world: http://mathworld.wolfram.com/ElementaryCellularAutomaton.html
+(defn int->bdigits
+  "Gets the binary digits that comprise an integer as a seq of ints."
+  [number]
+  (for [c (Integer/toBinaryString number)] (Integer/valueOf (str c))))
+
+(defn zero-pad
+  "Forward pads a seq with 0s to match a given length. Used for making sure int->bdigits hits byte boundaries"
+  [x len]
+  (let [shortage (- len (count x))]
+    (if (< shortage 1)
+      x
+      (concat (repeat shortage 0) x))))
+
+(def input-patterns
+  "The list of possible input sequences for elementary cellular automata, which are easily generated
+   by counting down from 8 in binary, and making sure we have at least three digits.
+   This should produce a list like: ((111 110 ...))"
+  (map #(zero-pad (int->bdigits %1) 3) (range 8)))
+
+(defn rule-mappings
+  "Returns a mapping of patterns to new states. Returns a structure like:
+   {(0 1 1) 1
+    ...}"
+  [number]
+  ;; Zipmap combines two sequences into a map, much like a real-life zipper!
+  ;; The key here is that the magic rule numbers are not numbers at all
+  ;; but a sequence rather (their individual binary digits) that get mapped
+  ;; onto the list of possible inputs described in input-patterns.
+  ;; The heart of the generic solution here is really just checking
+  ;; equality of a sequence, which we can do via a lookup in the hashmap
+  ;; this generates
+  (zipmap input-patterns
+          (reverse (zero-pad (int->bdigits number) 8))))
+
+(defn rule
+  "Returns a function that will process a triad of input values according to a given rule #.
+   Since rules are simple lookup tables, this maps to nothing more than a get really.
+   We use a function here only to be able to close over the rule-mappings and only evaluate those once."
+  [number]
+  ;; Applying a rule is really simple, since we've reduced the problem to pattern matching, and
+  ;; clojrue can match lists well (e.g. (= [1 2 3] [1 2 3]) => true even though they're separate
+  ;; objects), can simply see which pattern the 3 given values match with a map lookup via get.
+  (let [mappings (rule-mappings number)]
+    (fn [triad] (get mappings triad))))
+
+;; Since we assume cells that are off the grid are zeroes, and the far left and far
+;; right calculatoins both require these cells, we make our calculation a bit easier by
+;; simply pretending the previous row has two extra 0s on either side
+(defn bookend
+  "Pads a seq with a given value on both sides."
+  [x v]
+  (concat [v] x [v]))
+
+(defn simulate
+  "Runs a single iteration of a given rule-fn on a given-state"
+  [rule-fn state]
+  (let [rule (rule-mappings 110)]
+    ;; We bookend the value below to add a 0 on both sides of the previous state
+    ;; as it makes calculations simpler
+    (for [triad (partition 3 1 (bookend state 0))]
+      (rule-fn triad))))
+
+(defn simulation
+  "Returns a lazy-seq of future states for a given rule-fn and state"
+  [rule-fn state]
+  (let [new-state (simulate rule-fn state)]
+    ;; This is an infinitely recursive lazy sequence! Notice how we start
+    ;; by considing (prepending) to a new-state onto the head of a not-yet extant
+    ;; lazy sequence.
+    ;; You'll notice that the lazy sequence is declared with a
+    ;; body that will recurse from the present state, passing the current state into
+    ;; itself. Lazy sequences such as this are inherently tail-recursive, so they won't
+    ;; blow the stack.
+    (cons new-state (lazy-seq (simulation rule-fn new-state)))))
+
+(defn draw-buffer
+  "Redraw what's on screen given a buffer of cell data at a given scale"
+  [buffer scale]
+  ;; We use letfn here because we want both of these functions to
+  ;; have access to the variables `buffer` and `scale`. Closing over them
+  ;; here rather than defining them separately is simply a stylistic choice.
+  ;;
+  ;; We use two nested `map-index` calls to iterated over the canvas row by row,
+  ;; cell by cell, rendering each to the UI
+  (letfn [(draw-row [y row]
+            (dorun (map-indexed (fn [x col] (draw-cell x y col)) row)))
+          (draw-cell [x y col]
+            (apply qc/fill (if (= 1 col) live-color dead-color))
+            (qc/rect (* scale x) (* scale y) scale scale))]
+    (dorun (map-indexed draw-row buffer))))
+
+(defn setup
+  "Setup the UI"
+  []
+  (qc/smooth) ;; Enable AA
+  (qc/frame-rate 24))
+
+(defn run-rule [rule-num {:keys [width height scale]}]
+  (let [width (or width 100)
+        height (or height 100)
+        scale (or scale 5) ; Scale factor for rendering
+        ;; Our initial state is a single row of random 0s and 1s
+        initial (repeatedly height #(rand-int 2))
+        sim (simulation (rule rule-num) initial)
+        ;; We use partition as a sliding wintdow here. Since sim is
+        ;; an infinite lazy sequence of future rows we use the 3-arity
+        ;; version of partition here to create a 2D view of the visible range
+        ;; of results. Since this is the 3-arity version of partition, with 1
+        ;; specified as the second parameter, each time we grab the next item from
+        ;; the sim sequence we wind up with the same 2D view as before, but shifted ahead
+        ;; one row. This is how the simulation scrolls down!
+        time-slices (atom (partition height 1 sim))]
+    (println "Rule " rule-num " mappings:")
+    (pprint (rule-mappings rule-num))
+    ;; Initialize the graphics
+    (qc/defsketch automata
+      :title (str "Rule " rule-num)
+      :setup setup
+      :draw (fn drawfn [] ;; Named anonymous functions are easier to stacktrace
+              ;; Lazy sequences can also re-integrate into a more imperitive style
+              ;; What follows below is convenient, but not quite functional.
+              ;; Since the :draw callback is inherently not recursive I went with a
+              ;; more imperitive approach here. We use an atom to maintain the current position
+              ;; within our infinite sequence. This could also have been archieved with a
+              ;; tail recursive loop and not-utilizing the draw callback, but that's left
+              ;; as an excercise for the reader.
+              (draw-buffer (first @time-slices) scale)
+              (swap! time-slices (fn [_] (rest @time-slices))))
+      :size [(* scale width) (* scale height)])))
+
+(defn -main [rule-num & args]
+  (run-rule (Integer/valueOf rule-num)
+            {:width 100 :height 100 :scale 4}))


copy tweak

copy tweak


extract/pdf.clj: move pdf-to-html code from ohm1 jobs to here

error: pathspec 'src/org/altlaw/extract/pdf.clj' did not match any file(s) known to git

--- src/org/altlaw/extract/pdf.clj
+++ src/org/altlaw/extract/pdf.clj
@@ -0,0 +1,22 @@
+(ns org.altlaw.extract.pdf
+  (:require [clojure.contrib.singleton :as sing]
+            [org.altlaw.util.log :as log])
+  (:import (org.altlaw.util RunProgramOnFile)
+           (org.apache.commons.exec ExecuteException)
+           (java.io File)))
+
+(def *pdf-to-html-executable* (File. "/usr/local/bin/altlaw_parse_pdf"))
+
+(def #^{:private true} get-runner
+     (sing/per-thread-singleton
+      (fn []
+        (doto (RunProgramOnFile.)
+          (.setExecutable *pdf-to-html-executable*)))))
+
+
+(defn pdf-to-html [filename bytes]
+  (try
+   (String. (.exec (get-runner) bytes))
+   (catch ExecuteException e
+     (log/warn "altlaw_parse_pdf failed on " filename ": " e)
+     nil)))


define our Korma relationship from Session to User.

--- src/metabase/models/session.clj
+++ src/metabase/models/session.clj
@@ -1,11 +1,13 @@
 (ns metabase.models.session
   (:require [korma.core :refer :all]
             [metabase.db :refer :all]
-            [metabase.models.common :refer :all]
+            (metabase.models [common :refer :all]
+              [user :refer [User]])
             [metabase.util :as util]))

 (defentity Session
-  (table :core_session))
+  (table :core_session)
+  (belongs-to User {:fk :user_id}))

 (defmethod pre-insert Session [_ session]


Add @imrekoszo's json test suite

Add @imrekoszo's json test suite

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

--- test/yada/transit_json_test.clj
+++ test/yada/transit_json_test.clj
@@ -0,0 +1,72 @@
+(ns yada.transit-json-test
+  (:require [clojure.test :refer :all]
+            [schema.core :as s]
+            [yada.body :as sut]))
+
+(s/defschema TestSchema
+  {:a s/Str
+   :b s/Keyword
+   :c [s/Int]})
+
+(def ^:private test-map {:a "Hello" :b :foo :c [4 5 6]})
+
+(defmacro is-coercing-correctly?
+  ([expected value content-type schema]
+   `(is (= ~expected
+           (sut/coerce-request-body ~value ~content-type ~schema))))
+  ([expected value content-type]
+   `(is (= ~expected
+           (sut/coerce-request-body ~value ~content-type)))))
+
+#_(deftest reading-transit-json-from-body
+  (let [content-type "application/transit+json"
+        json "[\"^ \",\"~:a\",\"Hello\",\"~:b\",\"~:foo\",\"~:c\",[4,5,6]]"
+        json-verbose "{\"~:a\":\"Hello\",\"~:b\":\"~:foo\",\"~:c\":[4,5,6]}"]
+    (testing (str "coercing " content-type)
+      (is-coercing-correctly? test-map json content-type)
+      (is-coercing-correctly? test-map json content-type TestSchema)
+      (is-coercing-correctly? test-map json-verbose content-type)
+      (is-coercing-correctly? test-map json-verbose content-type TestSchema))))
+
+#_(deftest rendering-to-transit-json
+  (let [basic {:media-type {:name       "application/transit+json"
+                            :parameters {"pretty" false}}}
+        pretty (assoc-in basic [:media-type :parameters "pretty"] true)
+
+        test-map {:a "Hello" :b :foo :c [4 5 6]}
+        map-json "[\"^ \",\"~:a\",\"Hello\",\"~:b\",\"~:foo\",\"~:c\",[4,5,6]]"
+        map-json-verbose "{\"~:a\":\"Hello\",\"~:b\":\"~:foo\",\"~:c\":[4,5,6]}"]
+
+    (testing "render-map"
+      (is (= map-json
+             (sut/render-map test-map basic)))
+
+      (is (= map-json-verbose
+             (sut/render-map test-map pretty))))
+
+    (testing "render-seq"
+      (is (= "[4,5,6]"
+             (sut/render-seq [4 5 6] basic)
+             (sut/render-seq [4 5 6] pretty))))
+
+    (testing "render-error"
+      (is (= {:status  503
+              :message "Service Unavailable"
+              :id      12345
+              :error   {:some :error-happened}}
+
+             (sut/render-error 503
+                               {:some :error-happened}
+                               basic
+                               {:id 12345})
+
+             (sut/render-error 503
+                               {:some :error-happened}
+                               pretty
+                               {:id 12345})
+
+             (sut/render-error 503
+                               {:some :error-happened}
+                               (assoc-in basic [:media-type :name] "application/json")
+                               {:id 12345}))))
+    ))


Initial implementation of tree-seq

Initial implementation of tree-seq

error: pathspec 'lambdalf-lib/src/main/clojure/alfresco/seq.clj' did not match any file(s) known to git

--- lambdalf-lib/src/main/clojure/alfresco/seq.clj
+++ lambdalf-lib/src/main/clojure/alfresco/seq.clj
@@ -0,0 +1,18 @@
+(ns alfresco.seq
+  (:require [alfresco.nodes :as n]
+            [alfresco.model :as m]
+            [alfresco.auth :as a]))
+
+(defn ts
+  "Returns a lazy seq of the nodes representing the repository branch
+having the given root. Uses the currently authenticated user to realize
+the seq."
+  [root]
+  ;; store the currently authenticated user, needed by the following closures
+  (let [user (a/whoami)
+        branch? (fn [x] (a/run-as user
+                                 (m/qname-isa? (n/type-qname x)
+                                               (m/qname "cm:folder"))))
+        children (fn [x] (a/run-as user
+                                  (n/children x)))]
+    (tree-seq branch? children root)))


Fix close-all!

Fix close-all!


Make create-and-broadcast return electorate

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/'


Rename helper function in quadtree.

Rename helper function in quadtree.

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/'


attach orders to the fees incurred by those orders


Solución en Clojure.

Solución en Clojure.

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

--- desafio3/clojure/project.clj
+++ desafio3/clojure/project.clj
@@ -0,0 +1,6 @@
+(defproject ordenar-vector "0.1.0-SNAPSHOT"
+  :description "ordenar/vector"
+  :dependencies [[org.clojure/clojure "1.8.0"]]
+  :main ^:skip-aot ordenar-vector.core
+  :target-path "target/%s"
+  :profiles {:uberjar {:aot :all}})


Removed sqlite-memory

Removed sqlite-memory

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/'


remove unused code

remove unused code

--- test/metabase/driver/query_processor_test.clj
+++ test/metabase/driver/query_processor_test.clj
@@ -59,12 +59,7 @@
 (def driver-name->driver-dataset
   {:mongo       (MongoDriverData.)
    :generic-sql (GenericSqlDriverData.)})
-
-(def driver-name->db-delay
-  "Map of `driver-name` to a delay that will return the corresponding `Database`."
-  {:mongo       mongo-data/mongo-test-db
-   :generic-sql generic-sql-data/test-db})
-(def valid-driver-names (set (keys driver-name->db-delay)))
+(def valid-driver-names (set (keys driver-name->driver-dataset)))

 (defmacro with-driver
   "Execute BODY with `*db*` and `*db-id*` bound to appropriate places for "


start geometry function test

start geometry function test

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

--- src/test/clojure/zana/test/geometry/huber.clj
+++ src/test/clojure/zana/test/geometry/huber.clj
@@ -0,0 +1,19 @@
+(set! *warn-on-reflection* true)
+(set! *unchecked-math* :warn-on-boxed)
+(ns ^{:author "wahpenayo at gmail dot com"
+      :date "2018-02-24"
+      :doc
+      "Tests for zana.java.geometry.Huber and HuberQR." }
+
+    zana.test.geometry.huber
+
+  (:require [clojure.test :as test])
+
+  (:import [zana.java.geometry Huber HuberQR]))
+;;------------------------------------------------------------------------------
+#_(test/deftest Huber
+     (let [i (z1/interval 0 1)
+           [i0 i1] i]
+       (test/is (= i0 (z1/lower i)))
+       (test/is (= i1 (z1/upper i)))))
+;;------------------------------------------------------------------------------


Removed unused function

Removed unused function

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

--- src/trumpet_server/domain/trumpet_service.clj
+++ src/trumpet_server/domain/trumpet_service.clj
@@ -0,0 +1,19 @@
+(ns trumpet-server.domain.trumpet-service
+  (:require [clojure.core.async :refer [go >! chan close!]]
+            [ninjudd.eventual.server :refer [edn-events]]))
+
+(defn trumpet [trumpeters]
+
+  )
+
+
+;(defn sse-handler [request]
+;  (let [events (chan)]
+;    (go (loop [...]
+;          (if ...
+;            (>! events event)
+;            (recur ...)))
+;        (close! events))
+;    (edn-events events)))
+
+


transact-async the :scheduled-message/create-identifiers bit

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/scheduled-message-works.git/'


implement order resolver

implement order resolver


Payments, formatting numbers

Payments, formatting numbers

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/snichme/expenses-cljs.git/'


Remove some boilerplate.

Remove some boilerplate.

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/'


Fix doc string.

Fix doc string.

--- src/clojure/abracad/avro.clj
+++ src/clojure/abracad/avro.clj
@@ -187,8 +187,9 @@
 Whenever an Avro record is deserialized, the Clojure datum reader will
 check this map for a key matching the Avro record name represented as
 a namespace-qualified symbol.  When found, the datum reader will
-invoke the associated value as a function on the map-form deserialized
-record and use the return value as the deserialization result."
+invoke the associated value as a function on the deserialized record's
+fields as positional arguments.  The datum reader will use the return
+value as the deserialization result."
   {})

 (defn ^:private avro-reader-urls


fix signup date

fix signup date

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/'


Update cider nrepl

Update cider nrepl

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/jamesleonis/dotfiles.git/'


CMR-1580: Added code for converting a UMM record to JSON.

error: pathspec 'umm-spec-lib/src/cmr/umm_spec/umm_to_json.clj' did not match any file(s) known to git

--- umm-spec-lib/src/cmr/umm_spec/umm_to_json.clj
+++ umm-spec-lib/src/cmr/umm_spec/umm_to_json.clj
@@ -0,0 +1,43 @@
+(ns cmr.umm-spec.umm-to-json
+  "Contains functions for converting a UMM record into JSON"
+  (:require [cheshire.core :as json]
+            [cheshire.generate :as json-gen]))
+
+;; Adds the ability for Joda DateTimes to be converted to JSON.
+(json-gen/add-encoder
+  org.joda.time.DateTime
+  (fn [c jsonGenerator]
+    (.writeString jsonGenerator (str c))))
+
+
+(defprotocol ToJsonAble
+  "A function for converting data into data that can easily be converted to JSON"
+  (to-jsonable
+    [o]
+    "Takes in object and returns a new object that can be converted to JSON"))
+
+
+(extend-protocol ToJsonAble
+
+  ;; Records contain every key with a value of nil. We don't want the JSON to contain that.
+  ;; This converts them into a standard map without the nil keys.
+  clojure.lang.IRecord
+  (to-jsonable
+    [r]
+    (into {}
+          (for [[k v] r
+                :when (some? v)]
+            [(to-jsonable k) (to-jsonable v)])))
+
+
+  ;; Default implementations
+  Object
+  (to-jsonable [o] o)
+
+  nil
+  (to-jsonable [o] o))
+
+(defn umm->json
+  "Converts the UMM record to JSON."
+  [umm-record]
+  (json/generate-string (to-jsonable umm-record)))


oops remove debug code

oops remove debug code

--- src/metabase/driver/generic_sql/util.clj
+++ src/metabase/driver/generic_sql/util.clj
@@ -29,9 +29,7 @@
                                 :ttl/threshold (* 60 1000))]
     ;; only :engine and :details are needed for driver/connection so just pass those so memoization works as expected
     (fn [database]
-      (let [r (-db->korma-db (select-keys database [:engine :details]))]
-        (println "R:\n" (metabase.util/pprint-to-str 'green r))
-        r))))
+      (-db->korma-db (select-keys database [:engine :details])))))

 (def ^:dynamic ^java.sql.DatabaseMetaData *jdbc-metadata*
   "JDBC metadata object for a database. This is set by `with-jdbc-metadata`."


Amend json text to match requirements

Amend json text to match requirements

--- frameworks/Clojure/pedestal/src/pedestal/service.clj
+++ frameworks/Clojure/pedestal/src/pedestal/service.clj
@@ -14,7 +14,7 @@

 (defn json-test
   [request]
-  (ring-resp/response (json/write-str {:hello "world"})))
+  (ring-resp/response (json/write-str {:message "Hello, World!"})))

 (defroutes routes
   [[["/json" {:get json-test}]]])


Added computer.clj

Added computer.clj

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

--- src/emm_ess_pee/computer.clj
+++ src/emm_ess_pee/computer.clj
@@ -0,0 +1,176 @@
+(ns emm-ess-pee.computer
+  (:use emm-ess-pee.binary-utils))
+
+(defn get-reg
+  "Returns value register reg from a computer"
+  [computer i]
+  (get-in computer [:registers i]))
+
+(defn set-reg
+  "Sets register i to value in computer"
+  [computer reg val]
+  (assoc-in computer [:registers reg] val))
+
+(defn inc-reg
+  "Increments register by delta (default 2)"
+  ([computer reg] (inc-reg computer reg 2))
+  ([computer reg delta] (let [val (get-reg computer reg)]
+                          (set-reg computer reg (+w val delta)))))
+
+(defn dec-reg
+  "Decrements register by delta (default 2)"
+  ([computer reg] (dec-reg computer reg 2))
+  ([computer reg delta] (let [val (get-reg computer reg)]
+                      (set-reg computer reg (-w val delta)))))
+
+(defn inc-pc
+  "Increments PC by delta (default 2)"
+  ([computer] (inc-reg computer 0 2))
+  ([computer delta] (inc-reg computer 0 delta)))
+
+(defn PC [computer]
+  (get-reg computer 0))
+
+(defn SP [computer]
+  (get-reg computer 1))
+
+(defn SR [computer]
+  (get-reg computer 2))
+
+(defn set-PC [computer val]
+  (set-reg computer 0 val))
+
+(defn set-SP [computer val]
+  (get-reg computer 1 val))
+
+(defn set-SR [computer]
+  (get-reg computer 2 val))
+
+(defn C [computer]
+  (bit-get (SR computer) 0))
+
+(defn Z [computer]
+  (bit-get (SR computer) 1))
+
+(defn N [computer]
+  (bit-get (SR computer) 2))
+
+(defn GIE [computer]
+  (bit-get (SR computer 3)))
+
+(defn CPUOFF [computer]
+  (bit-get (SR computer 4)))
+
+(defn OSCOFF [computer]
+  (bit-get (SR computer 5)))
+
+(defn SCG0 [computer]
+  (bit-get (SR computer 6)))
+
+(defn SCG1 [computer]
+  (bit-get (SR computer 7)))
+
+(defn V [computer]
+  (bit-get (SR computer 8)))
+
+(defn set-C [computer val]
+  (set-bit (SR computer) 0) val)
+
+(defn set-Z [computer val]
+  (set-bit (SR computer) 1) val)
+
+(defn set-N [computer val]
+  (set-bit (SR computer) 2) val)
+
+(defn set-GIE [computer val]
+  (set-bit (SR computer 3)) val)
+
+(defn set-CPUOFF [computer val]
+  (set-bit (SR computer 4)) val)
+
+(defn set-OSCOFF [computer val]
+  (set-bit (SR computer 5)) val)
+
+(defn set-SCG0 [computer val]
+  (set-bit (SR computer 6)) val)
+
+(defn set-SCG1 [computer val]
+  (set-bit (SR computer 7)) val)
+
+(defn set-V [computer val]
+  (set-bit (SR computer 8)) val)
+
+(defn get-word
+  "Returns a (little-endian) word from memory at index i"
+  [computer i]
+  (apply make-word (subvec (:memory computer) i (+ i 2))))
+
+(defn set-word
+  "Sets a (little-endian) word in memory to value"
+  [computer i val]
+  (let [val (little-endian val) ; not sure if I should be flipping the bytes twice here
+        hb (high-byte val)
+        lb (low-byte val)]
+    (-> computer
+        (assoc-in [:memory i] lb)
+        (assoc-in [:memory (inc i)] hb))))
+
+
+(defn get-word-indirect
+  "Returns a word at the address contained in a register (i.e. @Rn)"
+  [computer reg]
+  (let [i (int (get-reg computer reg))]
+    (get-word computer i)))
+
+(defn set-word-indirect
+  "Sets a word at the address contained in a register to val (i.e. @Rn)"
+  [computer reg val]
+  (let [i (int (get-reg computer reg))]
+    (set-word computer i val)))
+
+(defn get-word-indexed
+  "Returns a word at the address contained in a register at offset (i.e. offset(Rn))"
+  [computer reg offset]
+  (let [r (int (get-reg computer reg))
+        i (int (+w r offset))]
+    (get-word computer i)))
+
+(defn set-word-indexed
+  "Sets a word at the address contained in a register at offset (i.e. offset(Rn))"
+  [computer reg offset val]
+  (let [r (int (get-reg computer reg))
+        i (int (+w r offset))]
+    (set-word computer i val)))
+
+(defn get-word-indirect-increment
+  "Returns a word at the address contained in a register and increments the register (i.e. @Rn+)"
+  [computer reg]
+  (let [i (int (get-reg computer reg))]
+    (-> (get-word computer i)
+        (assoc-in [:registers reg] (+w i 2)))))
+
+(defn stack-push
+  "Pushes a value onto the stack"
+  ;; TODO: handle byte/word mode
+  [computer value]
+  (-> computer
+      (set-word-indirect (named-register :sp) value)
+      (dec-reg (named-register :sp))))
+
+(defn stack-pop
+  "Pops a value off the stack. Returns [value, computer]"
+  ;; TODO: handle byte/word mode
+  [computer]
+  (let [value (get-word-indirect (named-register :sp))]
+    [value (dec-reg computer (named-register :sp))]))
+
+;;; maybe I don't need these
+
+(def register-names [:pc :sp :sr :r3 :r4 :r5 :r6 :r7 :r8 :r9 :r10 :r11 :r12 :r13 :r14 :r15])
+
+(def named-register (zipmap register-names (range)))
+
+(def status-bit-names [:gc :z :n :gie :cpuoff :oscoff :scg0 :scg1 :v])
+
+(def status-bit-index (zipmap status-bit-names (range)))
+


also check for the referendum type

also check for the referendum type

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/'


See #15. Add ClojureScript sample. Previewer not yet implemented.

error: pathspec 'spec/samples/example.clj' did not match any file(s) known to git

--- spec/samples/example.clj
+++ spec/samples/example.clj
@@ -0,0 +1,6 @@
+;; ClojureScript does not hoist variables
+;; this function will issue a warning
+
+(defn print-name []
+  (println "Hello, " name)
+  (let [name "Bob"]))


Clean up chained maps in search-by-identifiers*


.t pu.

.t pu.

error: pathspec 'demo/core.cljs' did not match any file(s) known to git

--- demo/core.cljs
+++ demo/core.cljs
@@ -0,0 +1,5 @@
+(ns ^:figwheel-always demo.core
+  (:require [klang.core as k]))
+
+(k/demo!)
+


Vorbereitung 10.12.

Vorbereitung 10.12.

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

--- src/fpc/vl09.clj
+++ src/fpc/vl09.clj
@@ -0,0 +1,409 @@
+; Funktionale Programmierung (in Clojure) Vorlesung 9
+; Folgen (Sequences, kurz Seqs)
+; (c) 2014 by Burkhardt Renz, THM
+
+(ns fpc.vl09
+  (:require [clojure.repl :refer :all]))
+
+stop
+
+;; 1 Folgen (als Abstraktion von zusammengesetzten Datenstrukturen)
+
+(comment
+  Wir haben eine ganze Reihe von Datenstrukturen gesehen, wie Listen, Vektoren,
+  Mengen, Hash-Maps usw.
+  Clojure hat eine einheitliche Art und Weise mit solchen Datenstrukturen als Ganzen
+  elementweise umzugehen, die Abstraktion "sequence" (Folge), alle solche Datenstrukturen
+  sind "seqable"
+)
+
+(comment
+  Seqs haben eine gewisse Ähnlichkeit zu Iteratoren, haben aber ein funktionales Konzept.
+  "Seqs differ from iterators in that they are persistent and immutable, not stateful
+   cursors into a collection. As such, they are useful for much more than foreach -
+   functions can consume and produce seqs, they are thread safe, they can share structure
+   etc." Aus der Dokumentation von Clojure
+)
+
+(comment
+  Das Konzept von Sequences kommt von LISP, dort aber ist die Sequence definiert auf einer
+  konkreten Datenstruktur, der Liste.
+  In Clojure ist die sequence ein logisches Konzept, das auf Basis verschiedener konkreter
+  Datenstrukturen funktioniert.
+  "A sequence is a sequential _view_ on a collection, it is not the collection itself."
+  (Meikel Brandmeyer)
+)
+
+
+; seq macht aus einer konkreten Datenstruktur eine sequence
+(seq '(1 2 3 4 5))
+;=> (1 2 3 4 5)
+
+(seq? (seq '(1 2 3 4 5)))
+;=> true
+
+(seq [1 2 3 4 5])
+;=> (1 2 3 4 5)
+
+(seq? [1 2 3 4 5])
+;=> false
+
+(seq? (seq [1 2 3 4 5]))
+;=> true
+
+(instance? clojure.lang.Seqable (seq [1 2 3 4 5]))
+;=> true
+
+(seq #{1 2 3 4 5})
+;=> (1 4 3 2 5)
+
+(seq {:a 1, :b 2, :c 3, :d 4, :e 5})
+;=> ([:e 5] [:c 3] [:b 2] [:d 4] [:a 1])
+
+; seq geht auch mit Java!
+(seq "12345")
+;=> (\1 \2 \3 \4 \5)
+; Ein String ist eine Folge von Buchstaben
+
+(comment
+  Man muss beachten, dass die einheitliche Behandlung der konkreten Datenstrukturen
+  einen Preis hat. Verwendet man einen Vektor als Folge, dann hat man hinterher eine
+  Folge in der Hand, nicht mehr den Vektor, will man daraus wieder einen Vektor machen,
+  dann muss man das explizit tun.
+
+  Wir werden später sehen, dass viele Funktionen "automatisch" konkrete Datenstrukturen
+  in Folgen verwandeln, damit man Funktionen schachteln kann. Das funktioniert nur,
+  weil alle diese Funktionen mit sequences funktionieren. Deshalb kann man nicht unbedingt
+  erwarten, dass der ursprüngliche Typ erhalten bleibt.
+ )
+
+(instance? clojure.lang.PersistentVector (seq [1 2]))
+;=> false
+
+(instance? clojure.lang.PersistentVector (vector (seq [1 2])))
+;=> true
+
+;; 2 Verzögerte und unendliche Folgen
+
+(comment
+  Das Auswertungsmodell, das wir bisher bei Clojure kennengelernt haben, ist _strikte_ Auswertung,
+  d.h. zuerst werden die Parameter ausgewertet, dann die Werte an die Funktion
+  übergeben. Man nennt diese Auswertungsstrategi auch "eager".
+
+  Dem steht gegenüber die verzögerte Auswertung ("lazy"), die einen Wert erst dann erzeugt,
+  wenn er auch wirklich gebraucht wird.
+
+  Clojure verwendet diese Strategie bei den sogenannten "lazy sequences", wobei eine Sequenz
+  nicht wirklich realisiert wird. Man muss sich das so vorstellen: Bei der Definition der
+  Folge wird nicht die Folge selbst erzeugt, sondern eine Funktion, die die Folge erzeugen
+  kann. Wird ein Element der Folge benötigt, dann wird diese Funktion aufgerufen
+  (Clojure tut dies nicht einzeln pro Element, sondern in Blöcken (chunks)).
+)
+
+; Beispiel für eine verzögerte Folge
+
+(range 10)
+;=> (0 1 2 3 4 5 6 7 8 9)
+
+(type (range 10))
+;=> clojure.lang.LazySeq
+
+; In der REPL wird die verzögerte Folge ausgegeben, deshalb muss sie realisiert werden
+; aber wenn wir sie in einer Var merken, dann ist sie nicht realisiert
+
+(def r (range  10))
+;=> #'fpc.vl09/r
+
+(realized? r)
+;=> false
+
+r
+;=> (0 1 2 3 4 5 6 7 8 9)
+
+(realized? r)
+;=> true
+
+; Wir wollen nun an einem Beispiel eine lazy sequence selbst programmieren und
+; ihr Verhalten untersuchen (aus Clojure Programming S. 93)
+
+(defn random-ints
+  "Erzeugt eine verzögerte Folge von Zufallszahlen und protokolliert die Erzeugung"
+  [limit]
+  (lazy-seq
+    (println "ich erzeuge eine Zufallszahl")
+    (cons (rand-int limit) (random-ints limit))))
+;=> #'fpc.vl09/random-ints
+
+(doc cons)
+;-------------------------
+;clojure.core/cons
+;([x seq])
+;  Returns a new seq where x is the first element and seq is
+;    the rest.
+
+;=> Vorsicht: dauert auf meinem neuen Mac sehr lange!!
+(random-ints 49)
+;=> OutOfMemoryError Java heap space  java.util.Arrays.copyOf (:-1)
+
+; Dieser Aufruf war keine gute Idee: random-ints erzeugt Zufallszahlen ohne Ende!
+
+; Zwei Möglichkeiten:
+; Die Funktion (take n ...) gibt die ersten n Elemente der Folge aus
+; Die dynamische Var *print-length* sorgt dafür, dass die REPL nach dieser Zahl aufhört
+
+(take 10 (random-ints 49))
+
+(set! *print-length* 10)
+(random-ints 49)
+
+; Nun wollen wir beobachten, wie die Zufallszahlen erzeugt werden:
+
+(def rands (random-ints 49))
+;=> #'fpc.vl09/rands
+
+; es gibt keine Meldung, dass eine Zufallszahl erzeugt wurde
+; wir sehen also, dass keine Auswertung der Funktion erfolgt ist
+
+(first rands)
+;=> ich erzeuge eine Zufallszahl
+;=> 24
+
+; eine Zufallszahl wurde erzeugt
+
+(nth rands 3)
+;=> ich erzeuge eine Zufallszahl
+;=> ich erzeuge eine Zufallszahl
+;=> ich erzeuge eine Zufallszahl
+;=> 10
+
+; man sieht wie die verzögerte Auswertung erfolgt
+
+
+(comment
+  Eine schöne Eigenschaft der verzögerten Auswertung haben wir an diesem
+  Beispiel schon gesehen:
+  Verzögerte Folgen erlaube es _unendliche_ Folgen zu programmieren.
+)
+
+; Das Musterbeispiel - unendliche Folge von ganzen Zahlen beginnend bei start
+
+(defn numbers
+  [start]
+  (lazy-seq
+    (cons start (numbers (inc start)))))
+;=> #'fpc.vl09/numbers
+
+(numbers 0)
+;=> (0 1 2 3 4 5 6 7 8 9 ...)
+;=> die ... stehen da, weil wir die Zahl der Werte für die Ausgabe beschränkt haben
+
+(numbers 1)
+;=>  (1 2 3 4 5 6 7 8 9 10 ...)
+
+(class (numbers 0))
+;=> clojure.lang.LazySeq
+
+; Nun aber wollen wir endlich sehen, was man mit Folgen alles tun kann:
+
+;; 3 Funktionen mit und für Folgen
+
+; Die Abstraktion "sequence" hat folgende Funktionen:
+; seq erzeugt eine Folge aus einer konkreten Datenstruktur
+; first, rest und next verwendet man um die Folge zu durchlaufen
+; lazy-seq erzeugt eine verzögerte Folge
+
+; seq und lazy-seq haben wir schon gesehen
+
+(def bis3 (seq [1 2 3]))
+
+(first bis3)
+;=> 1
+
+(defn durchlauf
+  [seq]
+  (if (= seq nil)
+    (println "Folge ist zuende")
+    (do
+      (println (first seq))
+      (durchlauf (next seq)))))
+
+(durchlauf bis3)
+;=> 1
+;=> 2
+;=> 3
+;=> Folge ist zuende
+
+; Was ist der Unterschied zwischen rest und next?
+
+(next [1 2])
+;=> (2)
+
+(next [1])
+;=> nil
+
+(next [])
+;=> nil
+
+(rest [1 2])
+;=> (2)
+
+(rest [1])
+;=> ()
+
+(rest [])
+;=> ()
+
+; next realisiert das nächste Element der Folge, wenn keines mehr da ist ergibt sich nil
+
+; rest realisiert das nächste Element _nicht_, gibt immer eine leere Folge zurück
+; Grund: rest erlaubt "mehr" Verzögerung
+
+; Man kann den Unterschied mit random-ints sehen
+(def r (next (random-ints 49)))
+;=> ich erzeuge eine Zufallszahl
+;=> ich erzeuge eine Zufallszahl
+; Die Meldung kommt zweimal: 1. für das erste Element und 2. für den Anfang der restlichen Folge
+
+(def r (rest (random-ints 49)))
+;=> ich erzeuge eine Zufallszahl
+; Die Meldung kommt nur einmal für das erste Element, die restliche Folge wird nicht ausgewertet
+
+; wie bricht man mit "rest" ab?
+(empty? (rest [1]))
+;=> true
+
+(empty? (rest [1 2]))
+;=> false
+
+;; Folgen sind die zentrale Abstraktion in Clojure und es gibt eine Menge Funktionen, die mit
+;; Folgen arbeiten
+
+;; Funktionen, die Folgen erzeugen -----------------------------------
+
+; Folge aus konkreter Datenstruktur
+(seq [1 2 3 4])
+;=> (1 2 3 4)
+
+; Folge in umgekehrter Ordnung aus geordneter Datenstruktur
+(rseq [1 2 3 4])
+;=> (4 3 2 1)
+
+; Folge der Werte einer Hash-Map
+(vals {:a 1, :b 2})
+;=> (2 1)
+
+; Folge der Schlüssel einer Hash-Map
+(keys {:a 1, :b 2})
+;=> (:b :a)
+
+; Folge durch die Iteration einer Funktion
+(iterate inc 0)
+;=> (0 1 2 3 4 5 6 7 8 9 ...)
+; Vergleiche mit numbers oben
+
+; Folge durch Wiederholung einer Funktion
+(repeatedly #(rand-int 49))
+;=> (28 10 18 44 4 29 24 40 46 39 ...)
+; Vergleiche mit random-ints oben
+
+; Folge aus Konstanten
+(repeat 1)
+;=> (1 1 1 1 1 1 1 1 1 1 ...)
+
+; Folge aus Zahlenbereich
+(range)
+;=> (0 1 2 3 4 5 6 7 8 9 ...)
+
+(range 5)
+;=> (0 1 2 3 4)
+
+(range 2 5)
+;=> (2 3 4)
+
+(range 2 10 2)
+;=> (2 4 6 8)
+
+; Folge durch zyklische Wiederholung von Werten
+(cycle [1 2 3])
+;=> (1 2 3 1 2 3 1 2 3 1 ...)
+
+; Folgen durch aneinanderhängen
+(concat [1 2] [3 4] [5 6])
+;=> (1 2 3 4 5 6)
+
+; Folge durch Mischen von Folgen
+(interleave [:a :b :c] [1 2 3 4])
+;=> (:a 1 :b 2 :c 3)
+
+
+;; Funktionen, die Folgen manipulieren --------------------------------------------------
+
+; Folge filtern
+(filter even? (range 20))
+;=> (0 2 4 6 8 10 12 14 16 18)
+
+; geht auch andersrum
+(remove even? (range 20))
+;=> (1 3 5 7 9 11 13 15 17 19)
+
+; Folge elementweise "ändern"
+(map inc (range 20))
+;=> (1 2 3 4 5 6 7 8 9 10 ...)
+
+; Folge sukzessive zusammenfalten
+(reduce + [1 2 3 4])
+;=> 10
+
+; Man kann sich auch alle Zwischenergebnisse ansehen
+(reductions + [1 2 3 4])
+;=> (1 3 6 10)
+
+; alle diese Funktionen kann man kombinieren und dadurch erreicht man extrem eleganten Stil,
+; wie wir gleich sehen werden.
+
+; Es gibt "tons of functions for seqs", siehe Dokumentation von Clojure
+
+;; 4 Rekursion mit Folgen neu gesehen
+
+; wir haben schon Beispiele gesehen
+
+; Erzeugen von Zufallszahlen
+(defn random-ints
+  [limit]
+  (lazy-seq
+    (cons (rand-int limit) (random-ints limit))))
+
+(random-ints 49)
+;=> (23 28 19 32 32 1 18 23 28 48 ...)
+
+; geht schöner mit Folge
+(defn random-ints'
+  [limit]
+  (repeatedly #(rand-int limit)))
+
+(random-ints' 49)
+;=> (6 1 26 35 23 25 41 31 28 6 ...)
+
+; noch ein Beispiel Berechnung der Fakultät
+; so sah factorial mit Endrekursion aus
+(defn factorial
+  "Fakultät von n"
+  [n]
+  (loop [cur n, acc 1]
+    (if (= cur 0)
+      acc
+      (recur (dec cur) (* acc cur)))))
+
+(factorial 12)
+;=> 479001600
+
+; geht das auch einfacher??
+(defn factorial'
+  "Fakultät von n"
+  [n]
+  (reduce * (range 1 (inc n))))
+
+(factorial' 12)
+;=> 479001600
+
+; Folgen statt Rekursion wollen wir im Praktikum ausprobieren


fix silly throttler test failure :unamused:

--- test/metabase/api/common/throttle_test.clj
+++ test/metabase/api/common/throttle_test.clj
@@ -3,7 +3,7 @@
             [metabase.api.common.throttle :as throttle]
             [metabase.test.util :refer [resolve-private-fns]]))

-(def ^:private test-throttler (throttle/make-throttler :test, :initial-delay-ms 2, :attempts-threshold 3, :delay-exponent 2, :attempt-ttl-ms 10))
+(def ^:private test-throttler (throttle/make-throttler :test, :initial-delay-ms 2, :attempts-threshold 3, :delay-exponent 2, :attempt-ttl-ms 25))

 ;;; # tests for calculate-delay
 (resolve-private-fns metabase.api.common.throttle calculate-delay)
@@ -111,6 +111,6 @@
        (count @(:attempts test-throttler)))
    (do (attempt 3)
        (count @(:attempts test-throttler)))
-   (do (Thread/sleep 10)
+   (do (Thread/sleep 25)
        (attempt 1)
        (count @(:attempts test-throttler)))])


#1. tests

#1. 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/james-mcelwain/vielheit-clj.git/'


changed comment

changed comment

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/kjsnd/tln.git/'


changed-files seems to be vector

changed-files seems to be vector

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -255,14 +255,14 @@
 (def empty-commit
   [:empty-commit
    (fn [{:keys [changed-files author time]}]
-     (when (= changed-files 0)
+     (when (= (count changed-files) 0)
        {:username author
         :time time}))])

 (def wrecking-ball
   [:wrecking-ball
    (fn [{:keys [changed-files author time]}]
-     (when (>= changed-files 100)
+     (when (>= (count changed-files) 100)
        {:username author
         :time time}))])


Parsing query timeout

Parsing query timeout

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/B2W-BIT/restQL-server.git/'


Add missing web.env namespace

Add missing web.env namespace

error: pathspec 'src/web/env.cljs' did not match any file(s) known to git

--- src/web/env.cljs
+++ src/web/env.cljs
@@ -0,0 +1,4 @@
+(ns web.env
+  (:require-macros [adzerk.env :as aenv]))
+
+(aenv/def BACKEND_URL "http://localhost:3001")


Moire circles

Moire circles

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

--- src/art/moire_circles_00.clj
+++ src/art/moire_circles_00.clj
@@ -0,0 +1,70 @@
+(ns art.moire-circles-00
+  (:require [quil.core :as q]
+            [quil.middleware]))
+
+; en.wikipedia.org/wiki/Moir%C3%A9_pattern#/media/File:Moire_Circles.svg
+
+; (def width  810)
+; (def height 540)
+(def width 1080)
+(def height 720)
+
+(def step-size 33)
+
+
+(defn circles [max-size]
+  (let [sizes (->> (range)
+                   (map #(* step-size %))
+                   (drop 1)
+                   (take-while #(< % max-size)))]
+    (doseq [size sizes]
+      (q/ellipse 0 0 size size))))
+
+
+(defn render []
+  (q/stroke 240)
+  (q/stroke-weight 5)
+
+  (q/translate 0 (/ (q/height) 2))
+  (q/background 0)
+
+  (let [left 64.5
+        right (* left 2)
+        max-size (* 1.6 (q/height))]
+
+    (-> (q/height)
+        (/ 2)
+        (+ left)
+        (q/translate 0))
+    (circles max-size)
+
+    (-> (q/height)
+        (/ 2)
+        (- right)
+        (q/translate 0))
+    (circles max-size)
+    ))
+
+(defn setup []
+  (q/fill 0 0)
+  (render)
+  (q/save "moire.png")
+  )
+
+(defn step [state] state)
+
+(defn draw [state]
+  (render)
+  )
+
+(defn run []
+  (q/defsketch example
+    :title "Art!"
+    :middleware [quil.middleware/fun-mode]
+    :settings #(q/smooth 2)
+    :setup setup
+    :update step
+    :draw draw
+    :size [width height]
+    ))
+; (run)


Factor out routes to own file.

Factor out routes to own file.

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

--- src/beebster_clj/routes.clj
+++ src/beebster_clj/routes.clj
@@ -0,0 +1,18 @@
+;; routes.clj
+
+
+(ns beebster-clj.routes
+  (:use beebster-clj.core beebster-clj.views compojure.core)
+  (:require [compojure.handler :as handler]
+            [compojure.route :as route]))
+
+(defroutes app-routes
+  (route/resources "/")
+  (GET "/" [] (index-page))
+  (GET "/about" [] (about-page)))
+
+
+(def app
+  (handler/site app-routes))
+
+


Change capitalization of results reporter

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/aaronlahey/coconut.git/'


add samples/repl/repl.clj to simplify browser REPL testing

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

--- samples/repl/repl.clj
+++ samples/repl/repl.clj
@@ -0,0 +1,9 @@
+(require '[cljs.closure :as cljsc])
+(require '[cljs.repl :as repl])
+(require '[cljs.repl.browser :as brepl])
+
+(repl/repl
+  (brepl/repl-env)
+  :init (fn []
+          (cljsc/build "src" {:output-to "main.js"}))
+  :repl-verbose true)


Reverted application config back to enabled vsync and limited foreground (focused) fps

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/Yoshiyuka/cthulhu.git/'


add error logging to handle-errors

add error logging to handle-errors

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/mail-works.git/'


add missing declare

add missing declare

--- src/metabase/api/common.clj
+++ src/metabase/api/common.clj
@@ -37,6 +37,8 @@
      (case (when @*current-user*
              ((:perms-for-org @*current-user*) org-id#))
        ~@body)))
+
+(declare check-403)

 (defn check-org-admin
   "Check that `*current-user*` is an admin (i.e., `can_write`) of `Org` with ORG-ID, or return a 403."


[WM] Revert 2nd attempt at NewRelic wrapper

Sigh...

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/'


Add lein config and profiles.clj.

Add lein config and profiles.clj.

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

--- lein/profiles.clj
+++ lein/profiles.clj
@@ -0,0 +1,2 @@
+{:user {:plugins [[cider/cider-nrepl "0.9.0-SNAPSHOT"]]
+        :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}}


Add example of putting functions on channels

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

--- test/com/nomistech/clojure_the_language/c_800_libraries/s_300_core_async/ss_010_core_async_functions_on_channels.clj
+++ test/com/nomistech/clojure_the_language/c_800_libraries/s_300_core_async/ss_010_core_async_functions_on_channels.clj
@@ -0,0 +1,22 @@
+(ns com.nomistech.clojure-the-language.c-800-libraries.s-300-core-async.ss-010-core-async-functions-on-channels
+  (:require [clojure.core.async :as a]
+            [midje.sweet :refer :all]))
+
+;;;; You can put functions on channels.
+;;;; - That's cool.
+;;;; - But should you?
+;;;;   - Maybe it makes debugging harder.
+;;;;     - You read something about this.
+;;;; - You could use an agent instead.
+
+(defn put-and-take-n-funs [n]
+  (let [c (a/chan 10)]
+    (dotimes [i n]
+      (a/>!! c (fn [] i)))
+    (for [i (range n)]
+      (let [f (a/<!! c)]
+        (f)))))
+
+(fact
+  (put-and-take-n-funs 10)
+  => (range 10))


Add tests for str->safe-for-email-attachments

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/voter-registration-works.git/'


Shut down the finagle-clojure/thrift test server after tests run

otherwise the server stays bound to a port which prevents tests
from running again (e.g. with lein midje :autotest)

--- thrift/test/clj/finagle_clojure/thrift_test.clj
+++ thrift/test/clj/finagle_clojure/thrift_test.clj
@@ -35,3 +35,6 @@
 (fact "this all works"
   (f/await (beautiful-dog? "pit bull")) =>  true
   (f/await (beautiful-dog? "pomeranian")) =>  false)
+
+;; shut down the thrift server so midje :autorun will work
+(f/await (.close dog-breed-server))


Use the latest handle-errors

Use the latest handle-errors


Use %0d for time display on console final disp

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/terrancesnyder/engulf.git/'


impl verify-bank-account!

impl verify-bank-account!

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 defcard to print source sample code

Add defcard to print source sample code


Add tracing to the entity ns functions

Add tracing to the entity ns 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/democracyworks/scheduled-message-works.git/'


Added Even Squares problem

Added Even Squares problem

error: pathspec 'src/clojush/problems/software/even_squares.clj' did not match any file(s) known to git

--- src/clojush/problems/software/even_squares.clj
+++ src/clojush/problems/software/even_squares.clj
@@ -0,0 +1,162 @@
+;; even_squares.clj
+;; Tom Helmuth, thelmuth@cs.umass.edu
+;;
+;; Problem Source: iJava (http://ijava.cs.umass.edu/)
+;;
+;; Given an integer 0 < n < 10000, print all of the positive even perfect
+;; squares < n on separate lines.
+;;
+;; input stack has input integer n
+
+(ns clojush.problems.software.even-squares
+  (:use clojush.pushgp.pushgp
+        [clojush pushstate interpreter random util globals]
+        clojush.instructions.tag
+        [clojure.math numeric-tower]
+        ))
+
+; Atom generators
+(def even-squares-atom-generators
+  (concat (list
+            ;;; end ERCs
+            (tag-instruction-erc [:integer :boolean :exec] 1000)
+            (tagged-instruction-erc 1000)
+            ;;; end tag ERCs
+            'in1
+            ;;; end input instructions
+            )
+          (registered-for-stacks [:integer :boolean :exec :print])))
+
+
+;; A list of data domains for the problem. Each domain is a vector containing
+;; a "set" of inputs and two integers representing how many cases from the set
+;; should be used as training and testing cases respectively. Each "set" of
+;; inputs is either a list or a function that, when called, will create a
+;; random element of the set.
+(def even-squares-data-domains
+  [[(list 1 2 3 4 5 6 15 16 17 18) 10 0] ;; Small edge cases
+   [(list 9600 9700 9999) 3 0] ;; Large edge cases
+   [(fn [] (+ 20 (lrand-int 9980))) 87 1000] ;; Random cases
+   ])
+
+
+(defn test-and-train-data-from-domains
+  "Takes a list of domains and creates a set of (random) train inputs and a set of test
+   inputs based on the domains. Returns [train test]. A program should not
+   be considered a solution unless it is perfect on both the train and test
+   cases."
+  [domains]
+  (apply mapv concat (map (fn [[input-set n-train n-test]]
+                            (if (fn? input-set)
+                              (vector (repeatedly n-train input-set)
+                                      (repeatedly n-test input-set))
+                              (vector (if (>= n-train (count input-set))
+                                        input-set
+                                        (take n-train (shuffle input-set)))
+                                      (if (>= n-test (count input-set))
+                                        input-set
+                                        (take n-test (shuffle input-set))))))
+                          domains)))
+
+;;Can make Even Squares test data like this:
+;(test-and-train-data-from-domains even-squares-data-domains)
+
+; Helper function for error function
+(defn even-squares-test-cases
+  "Takes a sequence of inputs and gives IO test cases of the form
+   [input output]."
+  [inputs]
+  (map (fn [in] (vector in
+                        (apply str (interpose \newline
+                                              (rest (take-while #(< % in)
+                                                                (map #(* 4 % %)
+                                                                     (range))))))))
+       inputs))
+
+; Define error function. For now, each run uses different random inputs
+(defn even-squares-error-function
+  "Returns the error function for the Even Squares problem. Takes as
+   input Even Squares data domains."
+  [data-domains]
+  (let [[train-cases test-cases] (map even-squares-test-cases
+                                      (test-and-train-data-from-domains data-domains))]
+    (when true ;; Change to false to not print test cases
+      (doseq [[i case] (map vector (range) train-cases)]
+        (println (format "Train Case: %3d | Input/Output: %s" i (str case))))
+      (doseq [[i case] (map vector (range) test-cases)]
+        (println (format "Test Case: %3d | Input/Output: %s" i (str case)))))
+    (fn the-actual-even-squares-error-function
+      ([program]
+        (the-actual-even-squares-error-function program :train))
+      ([program data-cases] ;; data-cases should be :train or :test
+        (the-actual-even-squares-error-function program data-cases false))
+      ([program data-cases print-outputs]
+        (let [behavior (atom '())
+              errors (doall
+                       (for [[input1 correct-output] (case data-cases
+                                                                  :train train-cases
+                                                                  :test test-cases
+                                                                  [])]
+                         (let [final-state (run-push program
+                                                     (->> (make-push-state)
+                                                       (push-item input1 :input)
+                                                       (push-item "" :output)))
+                               result (stack-ref :output 0 final-state)]
+                           (when print-outputs
+                             (println (format "| Correct output: %s\n| Program output: %s\n" (pr-str correct-output) (pr-str result))))
+                           ; Record the behavior
+                           (when @global-print-behavioral-diversity
+                             (swap! behavior conj result))
+                           ; Error is Levenshtein distance of printed strings
+                           (levenshtein-distance correct-output result))))]
+          (when @global-print-behavioral-diversity
+            (swap! population-behaviors conj @behavior))
+          errors)))))
+
+(defn even-squares-report
+  "Custom generational report."
+  [best population generation error-function report-simplifications]
+  (let [best-program (not-lazy (:program best))
+        best-test-errors (error-function best-program :test)
+        best-total-test-error (apply +' best-test-errors)]
+    (println ";;******************************")
+    (printf ";; -*- Even Squares problem report - generation %s\n" generation)(flush)
+    (println "Test total error for best:" best-total-test-error)
+    (println (format "Test mean error for best: %.5f" (double (/ best-total-test-error (count best-test-errors)))))
+    (when (zero? (:total-error best))
+      (doseq [[i error] (map vector
+                             (range)
+                             best-test-errors)]
+        (println (format "Test Case  %3d | Error: %d" i error))))
+    (println ";;------------------------------")
+    (println "Outputs of best individual on training cases:")
+    (error-function best-program :train true)
+    (println ";;******************************")
+    )) ;; To do validation, could have this function return an altered best individual
+       ;; with total-error > 0 if it had error of zero on train but not on validation
+       ;; set. Would need a third category of data cases, or a defined split of training cases.
+
+
+; Define the argmap
+(def argmap
+  {:error-function (even-squares-error-function even-squares-data-domains)
+   :atom-generators even-squares-atom-generators
+   :max-points 300
+   :max-points-in-initial-program 150
+   :evalpush-limit 600
+   :population-size 1000
+   :max-generations 300
+   :parent-selection :lexicase
+   :genetic-operator-probabilities {:alternation 0.2
+                                    :uniform-mutation 0.2
+                                    :uniform-close-mutation 0.1
+                                    [:alternation :uniform-mutation] 0.5
+                                    }
+   :alternation-rate 0.01
+   :alignment-deviation 10
+   :uniform-mutation-rate 0.01
+   :problem-specific-report even-squares-report
+   :print-behavioral-diversity true
+   :report-simplifications 0
+   :final-report-simplifications 5000
+   })


bump http client and commons dependencies

--- project.clj
+++ project.clj
@@ -8,10 +8,10 @@
   :warn-on-reflection false
   :min-lein-version "2.0.0"
   :dependencies [[org.clojure/clojure "1.4.0"]
-                 [org.apache.httpcomponents/httpclient "4.1.3"]
-                 [org.apache.httpcomponents/httpmime "4.1.3"]
-                 [commons-codec "1.5"]
-                 [commons-io "2.1"]
+                 [org.apache.httpcomponents/httpclient "4.2.1"]
+                 [org.apache.httpcomponents/httpmime "4.2.1"]
+                 [commons-codec "1.6"]
+                 [commons-io "2.4"]
                  [slingshot "0.10.3"]
                  [cheshire "4.0.1"]]
   :profiles {:dev {:dependencies [[ring/ring-jetty-adapter "1.1.0"]


Bump to 1.0.0-SNAPSHOT

Bump to 1.0.0-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clj-http "0.7.9"
+(defproject clj-http "1.0.0-SNAPSHOT"
   :description "A Clojure HTTP library wrapping the Apache HttpComponents client."
   :url "https://github.com/dakrone/clj-http/"
   :license {:name "The MIT License"


I mean update newrelic *agent*

I mean update newrelic *agent*


bump version to 3.2.3

bump version to 3.2.3

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/B2W-Digital/pdg-core.git/'


use slim clojure.jar in :uberjar profile.

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/runoshun/syncat.git/'


Update deps

Update 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/democracyworks/turbovote-http-api.git/'


start of tests for transactional topologies

error: pathspec 'test/clj/backtype/storm/transactional_test.clj' did not match any file(s) known to git

--- test/clj/backtype/storm/transactional_test.clj
+++ test/clj/backtype/storm/transactional_test.clj
@@ -0,0 +1,56 @@
+(ns backtype.storm.transactional-test
+  (:use [clojure test])
+  (:import [backtype.storm.topology TopologyBuilder])
+  (:import [backtype.storm.transactional TransactionalSpoutCoordinator ITransactionalSpout
+            ITransactionalSpout$Coordinator])
+  (:use [backtype.storm bootstrap testing])
+  (:use [backtype.storm.daemon common])
+  )
+
+(bootstrap)
+
+(defn mk-coordinator-state-changer [atom]
+  (TransactionalSpoutCoordinator.
+    (reify ITransactionalSpout
+      (getComponentConfiguration [this]
+        nil)
+      (getCoordinator [this conf context]
+        (reify ITransactionalSpout$Coordinator
+          (initializeTransaction [this txid prevMetadata]
+            @atom )
+          (close [this]
+            )))
+    )))
+
+(defn mk-spout-capture [capturer]
+  (SpoutOutputCollector.
+    (reify ISpoutOutputCollector
+      (emit [this stream-id tuple message-id]
+        (swap! capturer update-in [stream-id]
+          (fn [oldval] (concat oldval [{:tuple tuple :id message-id}])))
+        []
+        ))))
+
+(deftest test-coordinator
+  (let [zk-port (available-port 2181)
+        coordinator-state (atom nil)
+        emit-capture (atom nil)]
+    (with-inprocess-zookeeper zk-port
+      (letlocals
+        (bind coordinator
+              (mk-coordinator-state-changer coordinator-state))
+        (.open coordinator
+               (merge (read-default-config)
+                       {TOPOLOGY-MAX-SPOUT-PENDING 4
+                       TOPOLOGY-TRANSACTIONAL-ID "abc"
+                       STORM-ZOOKEEPER-PORT 2181
+                       STORM-ZOOKEEPER-SERVERS ["localhost"]
+                       })
+               nil
+               (mk-spout-capture emit-capture))
+        (reset! coordinator-state 10)
+        (.nextTuple coordinator)
+        (.nextTuple coordinator)
+        (.nextTuple coordinator)
+        (println @emit-capture)
+        ))))


core_test

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

--- test/Watchlist/core_test.clj
+++ test/Watchlist/core_test.clj
@@ -0,0 +1,7 @@
+(ns Watchlist.core-test
+  (:use clojure.test
+        Watchlist.core))
+
+(deftest a-test
+  (testing "Something went wrong"
+    (is (= 0 1))))


thought of a few more!

thought of a few 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/election-notification-works.git/'


delete connection map comment from core

delete connection map comment from core

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/'


Optimise nearest neighbour by avoiding unneeded allocations.

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/'


validate params and return the appropo status code if validation fails

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/'


changing duration between runs to random 60-70

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/jchli/jepsen-aurora.git/'


Added new boot module.

Added new boot module.

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

--- src/clj/io/cogitat/boot.clj
+++ src/clj/io/cogitat/boot.clj
@@ -0,0 +1,22 @@
+(ns io.cogitat.boot
+  (:require [tailrecursion.boot.core :refer [deftask mkdir! mk!]]))
+
+
+(deftask process-hlx
+  "A custom pre-processor for use with Hoplon.
+
+  This task does the following:
+   * compiles boilerplate .hlx files to .hl files (in a temp dir)
+   * adds the temp dir to the boot env's src-paths so that they will get
+     compiled
+   *
+
+  Called as:
+      $ boot watch process-hlx hoplon
+  "
+  [boot]
+  (fn [continue]
+    (fn [event]
+      ; XXX do the stuffs
+      ; see doc/notex.rst, "Remove the need to create HEAD boilerplate"
+      (continue event))))


First work on new experimental items-view.

error: pathspec 'src-cljs/freactive/experimental/items-view.cljs' did not match any file(s) known to git

--- src-cljs/freactive/experimental/items-view.cljs
+++ src-cljs/freactive/experimental/items-view.cljs
@@ -0,0 +1,71 @@
+(ns freactive.experimental.items-view
+  (:require
+   [freactive.dom :as dom]
+   [clojure.data.avl :as avl]))
+
+(defn- create-cursor [k v])
+
+(defn- get-node [nodes k v view-fn]
+  (loop [node (get nodes k)]
+    (if node
+      (if (instance? dom/ReactiveElement node)
+        (recur (.-cur-element node))
+        node)
+      (view-fn (create-cursor k v)))))
+
+(deftype ItemsView [container items view-fn
+                    ^:mutable projection nodes
+                    lower-index upper-index
+                    range-test
+                    filter
+                    disposed]
+  Object
+  (withinBounds [this idx k v]
+    (if range-test
+      (range-test idx k v)
+      (and (or (not lower-index) (>= idx lower-index))
+           (or (not upper-index) (<= idx upper-index)))))
+
+  (removeItemNode [this k]
+    (when-let [node (get nodes k)]
+      (dom/remove! node)))
+
+  (insertAt [this node idx])
+
+  (moveOrCreateAt [this k v idx])
+
+  (updateItem [this k v]
+    ;; update cursor
+    (if (and filter (not (filter v)))
+      (.removeItemNode this k)
+      (let [projection (assoc projection k v)
+            new-idx (avl/rank-of projection k)]
+        (if (not (.withinBounds new-idx k v))
+          (.removeItemNode this k)
+          (.moveOrCreateAt this k v new-idx)))))
+
+  (disposed-callback [this]))
+
+(defn- sort-items [items-seq sort-by]
+  (let [projection
+        (into
+         (if sort-by (avl/sorted-map-by sort-by) (avl/sorted-map))
+         items-seq)]))
+
+(defn items-view [{:keys [items container view-fn
+                          header footer
+                          sort-by sort-order
+                          filter
+                          lower-index upper-index
+                          range-test
+                          placeholder placeholder-idx]}]
+  (let [container (dom/build container)
+        start-offset (or (when header (count header)) 0)
+        end-offset (or (when footer (count footer)) nil)
+        projection nil
+        nodes {}]
+    (doseq [h header] (dom/append-child! container h))
+    (doseq [f footer] (dom/append-child! container f))))
+
+
+