Update deps & turn off logging in tests

Update deps & turn off logging in tests


Update clojure to 1.9.0 release

Update clojure to 1.9.0 release

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


Update PostgreSQL driver to latest version (9.4-1205-jdbc42)

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/vincentstorme/clojureme.git/'


Default warn-on-reflection to false

Default warn-on-reflection to false

--- project.clj
+++ project.clj
@@ -4,7 +4,7 @@
   :license {:name "The MIT License"
             :url "http://opensource.org/licenses/mit-license.php"
             :distribution :repo}
-  :global-vars {*warn-on-reflection* true}
+  :global-vars {*warn-on-reflection* false}
   :min-lein-version "2.0.0"
   :exclusions [org.clojure/clojure]
   :dependencies [[org.apache.httpcomponents/httpcore "4.4.1"]


LightTable nREPL.

LightTable 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/knishimu/blinkclj.git/'


bump teller

bump teller

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


Reproduce percentage-multi-job-test #348

error: pathspec 'test/onyx/log/percentage_multi_job_generative_test.clj' did not match any file(s) known to git

--- test/onyx/log/percentage_multi_job_generative_test.clj
+++ test/onyx/log/percentage_multi_job_generative_test.clj
@@ -0,0 +1,82 @@
+(ns onyx.log.percentage-multi-job-generative-test
+  (:require [onyx.messaging.dummy-messenger :refer [dummy-messenger]]
+            [onyx.log.generators :as log-gen]
+            [onyx.extensions :as extensions]
+            [onyx.api :as api]
+            [onyx.static.planning :as planning]
+            [onyx.test-helper :refer [job-allocation-counts get-counts]]
+            [clojure.set :refer [intersection]]
+            [clojure.test.check :as tc]
+            [clojure.test.check.generators :as gen]
+            [clojure.test.check.properties :as prop]
+            [clojure.test :refer :all]
+            [onyx.log.replica-invariants :refer [standard-invariants]]
+            [com.gfredericks.test.chuck :refer [times]]
+            [com.gfredericks.test.chuck.clojure-test :refer [checking]]))
+
+(deftest percentage-multi-job-test
+  (let [percentages-peer-config {:onyx/id #uuid "9fd09779-749b-4668-b373-bdf3eeb98a8f"
+                                 :onyx.messaging/impl :dummy-messenger
+                                 :onyx.peer/job-scheduler :onyx.job-scheduler/percentage}
+        job-1-id #uuid "f55c14f0-a847-42eb-81bb-0c0390a88608"
+        job-1 {:workflow [[:a :b]]
+               :percentage 70
+               :catalog [{:onyx/name :a
+                          :onyx/plugin :onyx.plugin.core-async/input
+                          :onyx/type :input
+                          :onyx/medium :core.async
+                          :onyx/batch-size 20
+                          :onyx/doc "Reads segments from a core.async channel"}
+
+                         {:onyx/name :b
+                          :onyx/plugin :onyx.plugin.core-async/output
+                          :onyx/type :output
+                          :onyx/medium :core.async
+                          :onyx/batch-size 20
+                          :onyx/doc "Writes segments to a core.async channel"}]
+               :task-scheduler :onyx.task-scheduler/balanced}
+
+        job-2-id #uuid "5813d2ec-c486-4428-833d-e8373910ae14"
+        job-2 {:workflow [[:c :d]]
+               :percentage 30
+               :catalog [{:onyx/name :c
+                          :onyx/plugin :onyx.plugin.core-async/input
+                          :onyx/type :input
+                          :onyx/medium :core.async
+                          :onyx/batch-size 20
+                          :onyx/doc "Reads segments from a core.async channel"}
+
+                         {:onyx/name :d
+                          :onyx/plugin :onyx.plugin.core-async/output
+                          :onyx/type :output
+                          :onyx/medium :core.async
+                          :onyx/batch-size 20
+                          :onyx/doc "Writes segments to a core.async channel"}]
+               :task-scheduler :onyx.task-scheduler/balanced}]
+    (checking
+      "Checking percentage multi job test, replicates onyx.log.percentage-multi-job-test"
+      (times 50)
+      [{:keys [replica log peer-choices]}
+       (log-gen/apply-entries-gen
+         (gen/return
+           {:replica {:job-scheduler :onyx.job-scheduler/percentage
+                      :messaging {:onyx.messaging/impl :dummy-messenger}}
+            :message-id 0
+            :entries (assoc (log-gen/generate-join-queues (log-gen/generate-peer-ids 20))
+                            :job-1 {:queue [(api/create-submit-job-entry
+                                              job-1-id
+                                              percentages-peer-config
+                                              job-1
+                                              (planning/discover-tasks (:catalog job-1) (:workflow job-1)))]}
+                            :job-2 {:queue [(api/create-submit-job-entry
+                                              job-2-id
+                                              percentages-peer-config
+                                              job-2
+                                              (planning/discover-tasks (:catalog job-2) (:workflow job-2)))]})
+            :log []
+            :peer-choices []}))]
+      (standard-invariants replica)
+      (is (= #{:active} (set (vals (:peer-state replica)))))
+      (is (= [14 6]
+             (map (partial apply +)
+                  (get-counts replica [{:job-id job-1-id} {:job-id job-2-id}])))))))


Company list authorization tests.

Company list authorization tests.

error: pathspec 'test/open_company/integration/authorization/company_list_auth.clj' did not match any file(s) known to git

--- test/open_company/integration/authorization/company_list_auth.clj
+++ test/open_company/integration/authorization/company_list_auth.clj
@@ -0,0 +1,59 @@
+(ns open-company.integration.authorization.company-list-auth
+  "Authorization tests for the company listing API."
+  (:require [midje.sweet :refer :all]
+            [open-company.lib.test-setup :as ts]
+            [open-company.lib.rest-api-mock :as mock]
+            [open-company.lib.hateoas :as hateoas]
+            [open-company.api.common :as common]))
+
+;; ----- Test Cases -----
+
+;; OPTIONS
+;; fail - invalid JWToken - 401 Unauthorized
+;; success - no JWToken - 204 No Content
+;; success - with JWToken - 204 No Content
+
+;; GET
+;; fail - invalid JWToken - 401 Unauthorized
+;; success - no JWToken - 200 OK
+;; success - with JWToken - 200 OK
+
+;; ----- Tests -----
+
+(def options (hateoas/options-response [:options :get]))
+
+(with-state-changes [(before :contents (ts/setup-system!))
+                     (after :contents (ts/teardown-system!))]
+
+  (facts "about failing to access the API entry point"
+
+    (doseq [method [:options :get]]
+
+      (fact "with a bad JWToken"
+        (let [response (mock/api-request method "/" {:auth mock/jwtoken-bad})]
+          (:status response) => 401
+          (:body response) => common/unauthorized))))
+
+  (fact "about OPTIONS access on the API entry point"
+
+    (fact "with no JWToken"
+      (let [response (mock/api-request :options "/" {:skip-auth true})]
+        (:status response) => 204
+        (:body response) => ""
+        ((:headers response) "Allow") => options))
+
+    (fact "with a valid JWToken"
+      (let [response (mock/api-request :options "/")]
+        (:status response) => 204
+        (:body response) => ""
+        ((:headers response) "Allow") => options)))
+
+  (fact "about GET access on the API entry point"
+
+    (fact "with no JWToken"
+      (let [response (mock/api-request :get "/" {:skip-auth true})]
+        (:status response) => 200))
+
+    (fact "with a valid JWToken"
+      (let [response (mock/api-request :get "/")]
+        (:status response) => 200))))


start working on email invite

start working on email invite

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

--- src/chat/server/invite.clj
+++ src/chat/server/invite.clj
@@ -0,0 +1,79 @@
+(ns chat.server.invite
+  (:require [org.httpkit.client :as http]
+            [taoensso.carmine :as car]
+            [clojure.string :as string]
+            [taoensso.timbre :as timbre]
+            [environ.core :refer [env]])
+  (:import java.security.SecureRandom
+           [org.apache.commons.codec.binary Base64]))
+
+(defn random-nonce
+  "url-safe random nonce"
+  [size]
+  (let [rand-bytes (let [seed (byte-array size)]
+                     (.nextBytes (SecureRandom. ) seed)
+                     seed)]
+    (-> rand-bytes
+        Base64/encodeBase64
+        String.
+        (string/replace "+" "-")
+        (string/replace "/" "_")
+        (string/replace "=" ""))))
+
+(defn constant-comp
+  "Compare two strings in constant time"
+  [a b]
+  (loop [a a b b match (= (count a) (count b))]
+    (if (and (empty? a) (empty? b))
+      match
+      (recur
+        (rest a)
+        (rest b)
+        (and match (= (first a) (first b)))))))
+
+; same as conf in handler, but w/e
+(def redis-conn {:pool {}
+                 :spec {:host "127.0.0.1"
+                        :port 6379}})
+
+(defmacro wcar* [& body] `(car/wcar redis-conn ~@body))
+
+(defn make-invite-link
+  [invite]
+  (let [secret-nonce (random-nonce 20)]
+    (wcar* (car/set (str (invite :id)) secret-nonce)
+           (car/expire (str (invite :id)) (* 3600 2)))
+    (str (env :site-url)
+         "/accept?tok=" secret-nonce
+         "&?invite=" (invite :id))))
+
+(defn verify-invite-nonce
+  "Verify that the given nonce is valid for the invite"
+  [invite nonce]
+  (if-let [stored-nonce (wcar* (car/get (str (invite :id))))]
+    (if (constant-comp stored-nonce nonce)
+      (do (wcar* (car/del (str (invite :id))))
+          true)
+      {:error "Invalid token"})
+    (do (timbre/warnf "Expired nonce %s for invite %s" nonce invite)
+        {:error "Expired token"})))
+
+(defn invite-message
+  [invite]
+  (let [accept-link ""]
+    {:text (str (invite :inviter-email) " has invited to join the " (invite :group-name)
+                " group on chat.leanpixel.com.\n\n"
+                "Go to " accept-link " to accept.")
+     :html (str ""
+                (invite :inviter-email) " has invited to join the " (invite :group-name)
+                " group on chat.leanpixel.com."
+                "
"
+                "Click here to accept."
+                "")}))
+
+(defn send-invite
+  [invite]
+  (http/post "https://api.mailgun.net/v3/chat.leanpixel.com/messages"
+             {:basic-auth ["api" (env :mailgun-password)]
+              :form-params (merge {:to (invite :invitee-email)}
+                                  (invite-message invite))}))


Added partially implemented Assembly Language classes.

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

--- src/clj/minijava/assem.clj
+++ src/clj/minijava/assem.clj
@@ -0,0 +1,26 @@
+(ns minijava.assem
+  "Assembly code classes")
+
+(defprotocol Instr
+  (use [this])
+  (def [this])
+  (jumps [this])
+  (format [this]))
+
+(deftype AssemOper [fmt, dsts, srcs, jmps]
+  (use [] srcs)
+  (def [] dsts)
+  (jumps [] jmps)
+  (format [] "unimplemented"))
+
+(deftype AssemMove [fmt, dst, src]
+  (use [] (list src))
+  (def [] (list dst))
+  (jumps [] '())
+  (format [] "unimplemented"))
+
+(deftype AssemLabel [fmt, lbl]
+  (use [] '())
+  (def [] '())
+  (jumps [] '())
+  (format [] "unimplemented"))


formatting

formatting

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


args -> & args

args -> & args


punt -> punted

punt -> punted


CMR-563: Moved supported types to umm project.

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

--- src/cmr/umm/mime_types.clj
+++ src/cmr/umm/mime_types.clj
@@ -0,0 +1,9 @@
+(ns cmr.umm.mime-types
+  "Provides a mapping of all supported mime-types.")
+
+;; body element (metadata) of a request arriving at ingest app should be in xml format and mime type
+;; should be of the items in this def.
+(def CMR_VALID_CONTENT_TYPES
+  #{"application/echo10+xml", "application/iso_prototype+xml", "application/iso:smap+xml",
+    "application/iso19115+xml", "application/dif+xml"})
+


Hookup commands to the ring web forms

Hookup commands to the ring web forms

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

--- src/rill/web.clj
+++ src/rill/web.clj
@@ -0,0 +1,18 @@
+(ns rill.web
+  (:require [clojure.tools.logging :as log]
+            [rill.handler :as rill-handler]
+            [rill.message :as message]))
+
+(defn wrap-command-handler
+  "Given a ring handler that returns a command (or nil), execute the
+  command with the given event store and return status 500 or 200"
+  [ring-handler event-store]
+  (fn [request]
+    (when-let [command (ring-handler request)]
+      (log/info ["Executing command" command])
+      (let [[status events] (rill-handler/try-command event-store command)]
+        (case status
+            :rejected {:status 422 :body {:status :command-rejected}} ; HTTP 422 Unprocessable Entity
+            :conflict {:status 409 :body {:status :command-conflict}} ; HTTP 409 Conflict
+            :ok {:status 200 :body {:status :command-accepted, :events events}}
+            {:status 500 :body {:status :internal-error}})))))


formatting

formatting


rev comment

rev comment


Add initial leininen project definition.

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

--- project.clj
+++ project.clj
@@ -0,0 +1,8 @@
+;; Wonderdome project definition
+(defproject com.mvxcvi/wonderdome "1.0.0-SNAPSHOT"
+  :description "Control and rendering software for driving an LED strip art project with various visualizations."
+  :url "https://github.com/mvxcvi/wonderdome"
+  :license {:name "MIT License"
+            :url "http://opensource.org/licenses/MIT"}
+
+  :dependencies [[org.clojure/clojure "1.5.1"]])


Update postgresql to address CVE-2022-26520, CVE-2022-21724

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


Update project map with required SCM information

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


Some final changes before attempting cortex integration

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/thinktopic/netlib-ccm.git/'


Add junk-drawer to module list.

Add junk-drawer to module list.

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


Added deps back to clj-sql-up.

Added deps back to clj-sql-up.

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/inchingforward/clojurians.git/'


Update to use internal core.async lib with support for invoke protocols

Signed-off-by: selmeci <bb938fc7591901d0e874df22e3ae174886bcb931@infones.com>

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


release version 2.5.0

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


[WM] bump clojure to 1.7.0

[WM] bump clojure to 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/democracyworks/election-notification-works.git/'


Version 56

Version 56

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clojars-web "56-SNAPSHOT"
+(defproject clojars-web "56"
   :min-lein-version "2.0.0"
   :dependencies [[org.clojure/clojure "1.8.0"]
                  [org.clojure/tools.cli "0.2.1"]


more helpful error if unable to read fighweel.edn

--- plugin/src/leiningen/figwheel.clj
+++ plugin/src/leiningen/figwheel.clj
@@ -212,7 +212,20 @@

 (defn figwheel-edn []
   (and (figwheel-edn-exists?)
-       (read-string (slurp (io/file "figwheel.edn")))))
+       (try
+         (read-string (slurp (io/file "figwheel.edn")))
+         (catch Throwable e
+           (main/abort
+            (str "---- Bad figwheel.edn File! ----\n"
+                 "You have a malformed figwheel.edn file at the root of your\n"
+                 "of your project directory.\n\n"
+
+                 "While reading this file we encountered the following error:\n"
+                 " --->  " (.getMessage e)
+                 "\n\n"
+                 "Either remove this file to revert to reading the Figwheel config\n"
+                 "from the project.clj or fix the reader errors in this file.\n"
+                 "---- Bad figwheel.edn File! ----\n"))))))

 (defn cljs-builds [data]
   (map-to-vec-builds


Short UUID generation.

Short UUID generation.

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

--- src/posthere/util/uuid.clj
+++ src/posthere/util/uuid.clj
@@ -0,0 +1,14 @@
+(ns posthere.util.uuid
+  "UUIDs and the heat death of the Universe..."
+  (:require [clojure.string :as s]))
+
+(defn uuid []
+  "Simple wrapper for Java's UUID"
+  (str (java.util.UUID/randomUUID)))
+
+(defn short-uuid []
+  "Take the middle 3 sections of a Java UUID to make a shorter UUID.
+
+  Ex: f6f7-499f-b805
+  "
+  (s/join "-" (take 3 (rest (s/split (uuid) #"-")))))


Update deps

Update deps


Update dependency to resolve https://github.com/clj-commons/ordered/issues/40

fatal: unable to access 'https://github.com/HealthUnlocked/lein-docker-compose.git/': The requested URL returned error: 403


[WM] add desc & url to project.clj; update langhor

Langhor 3.1.0 is out now.

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


add clj-time

add clj-time

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


main definitu

main definitu

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


[WM] update pedestal-toolbox to 0.6.2

[WM] update pedestal-toolbox to 0.6.2

Fixes a problem with Content-Type regexes where we weren't matching some valid ones when they e.g. had a charset appended to the MIME type string. Firefox likes to send them this way, and we should be handling them correctly regardless. H/T to Chris for the fix in pedestal-toolbox.

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


bump dependencies

bump dependencies

--- project.clj
+++ project.clj
@@ -65,7 +65,7 @@
                              [lein-ancient "0.6.5"]                   ; Check project for outdated dependencies + plugins w/ 'lein ancient'
                              [lein-bikeshed "0.2.0"]                  ; Linting
                              [lein-expectations "0.0.8"]              ; run unit tests with 'lein expectations'
-                             [lein-instant-cheatsheet "2.0.0"]        ; use awesome instant cheatsheet created by yours truly w/ 'lein instant-cheatsheet'
+                             [lein-instant-cheatsheet "2.1.0"]        ; use awesome instant cheatsheet created by yours truly w/ 'lein instant-cheatsheet'
                              [lein-marginalia "0.8.0"]]               ; generate documentation with 'lein marg'
                    :jvm-opts ["-Dlogfile.path=target/log"
                               "-Xms1024m"                             ; give JVM a decent heap size to start with


Version 28-SNAPSHOT

Version 28-SNAPSHOT

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject clojars-web "27"
+(defproject clojars-web "28-SNAPSHOT"
   :min-lein-version "2.0.0"
   :dependencies [[org.clojure/clojure "1.7.0"]
                  [org.clojure/tools.cli "0.2.1"]


[WM] update kehaar to 0.4.0

[WM] update kehaar to 0.4.0

This doesn't move the project to the wire-up fns yet, though. That should probably be its own PR.


Increment version to 0.3.0.

Increment version to 0.3.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/croeder/clojure-koans-work.git/'


Added repl runner script

Added repl runner script

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

--- script/repl.clj
+++ script/repl.clj
@@ -0,0 +1,3 @@
+(use 'figwheel-sidecar.repl-api)
+(start-figwheel!) ;; <-- fetches configuration
+(cljs-repl)


chore(core): update restQL-clojure to 2.8.2

fatal: unable to access 'https://github.com/B2W-BIT/restQL-server.git/': The requested URL returned error: 403


New default port.

New default port.

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/dillius/peak-tolerable-stupidity.git/'


small copy change to test emails.

small copy change to test emails.

--- src/metabase/api/email.clj
+++ src/metabase/api/email.clj
@@ -74,7 +74,7 @@
                    :subject      "Metabase Test Email"
                    :recipients   [(:email @*current-user*)]
                    :message-type :text
-                   :message      "The Metabase emails are working, hooray!")]
+                   :message      "Your Metabase emails are working — hooray!")]
     (if (= :SUCCESS (:error response))
       {:ok true}
       {:status 500


Delete outdated iface component cardS file


Saioa hasi: eremuak bete direla egiaztatu

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


Add aeron protocol tests.

Add aeron protocol tests.

error: pathspec 'test/onyx/messaging/protocol_aeron_test.clj' did not match any file(s) known to git

--- test/onyx/messaging/protocol_aeron_test.clj
+++ test/onyx/messaging/protocol_aeron_test.clj
@@ -0,0 +1,53 @@
+(ns onyx.messaging.protocol-aeron-test
+  (:require [onyx.messaging.protocol-aeron :as protocol]
+            [onyx.compression.nippy :refer [compress decompress]]
+            [onyx.types :refer [map->Leaf map->Ack]]
+            [midje.sweet :refer :all]))
+
+(defn read-aux-buf [buf]
+  (let [msg-type ^byte (protocol/read-message-type buf 0)]
+    (cond (= msg-type protocol/ack-msg-id)
+          (protocol/read-acker-message buf 1)
+          (= msg-type protocol/completion-msg-id)
+          (protocol/read-completion buf 1)
+          (= msg-type protocol/retry-msg-id)
+          (protocol/read-retry buf 1))))
+
+(let [message #uuid "11837bd7-2de5-4b62-888d-171c4c47845c"]
+  (fact message =>
+        (read-aux-buf (protocol/build-completion-msg-buf message))))
+
+(let [message (map->Ack {:id #uuid "e2ba38dd-b523-4e63-ba74-645fb91c231a"
+                         :completion-id #uuid "b57f7be1-f2f9-4d0f-aa02-939b3d48dc23"
+                         :ack-val 3323130347050513529})]
+  (fact message =>
+        (read-aux-buf (protocol/build-acker-message (:id message) (:completion-id message) (:ack-val message)))))
+
+(let [messages [(map->Leaf {:id #uuid "ac39bc62-8f06-46a0-945e-3a17642a619f"
+                            :acker-id #uuid "11837bd7-2de5-4b62-888d-171c4c47845c"
+                            :completion-id #uuid "b57f7be1-f2f9-4d0f-aa02-939b3d48dc23"
+                            :message {:n 1}
+                            :ack-val 8892143382010058362})
+                (map->Leaf {:id #uuid "010a1688-47ff-4055-8da5-1f02247351e1"
+                            :acker-id #uuid "bf8fd5fc-30fd-424c-af6a-0b32568581a4"
+                            :completion-id #uuid "7ad37c45-ce67-4fd4-8850-f3ec58ede0bf"
+                            :message {:n 2}
+                            :ack-val 729233382010058362})]]
+
+  (let [[size buf] (protocol/build-messages-msg-buf compress messages)]
+    (fact messages =>
+          (protocol/read-messages-buf decompress buf 0 size))))
+
+(let [messages []]
+  (let [[size buf] (protocol/build-messages-msg-buf compress messages)]
+    (fact messages =>
+          (protocol/read-messages-buf decompress buf 0 size))))
+
+(let [messages [(map->Leaf {:id #uuid "010a1688-47ff-4055-8da5-1f02247351e1"
+                   :acker-id #uuid "bf8fd5fc-30fd-424c-af6a-0b32568581a4"
+                   :completion-id #uuid "7ad37c45-ce67-4fd4-8850-f3ec58ede0bf"
+                   :message {}
+                   :ack-val 729233382010058362})]]
+  (let [[size buf] (protocol/build-messages-msg-buf compress messages)]
+    (fact messages =>
+          (protocol/read-messages-buf decompress buf 0 size))))


:self-rf-nometa is on the meta of rf* not rf* itself

fatal: unable to access 'https://github.com/michaelsbradleyjr/transwarp.git/': The requested URL returned error: 403


Remove redundant type hint

Remove redundant type hint

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/leif47/immutabledb-experimental.git/'


Use keyword for ns import (#116)

Use keyword for ns import (#116)

--- src/yada/resources/sse.clj
+++ src/yada/resources/sse.clj
@@ -9,7 +9,7 @@
    clojure.core.async.impl.channels
    clojure.core.async.impl.protocols
    manifold.stream.async)
-  (import [clojure.core.async.impl.protocols ReadPort]))
+  (:import [clojure.core.async.impl.protocols ReadPort]))

 (extend-protocol ResourceCoercion
   ReadPort


Adding docstring

Adding docstring

fatal: unable to access 'https://github.com/xcthulhu/clj-bitauth.git/': The requested URL returned error: 403


Also name-mangle schema `:type` fields.

Also name-mangle schema `:type` fields.

fatal: unable to access 'https://github.com/damballa/abracad.git/': The requested URL returned error: 403


Got started on our attache namespace to reprepsent our external endpoints.

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

--- src/attache.clj
+++ src/attache.clj
@@ -0,0 +1,18 @@
+(ns attache)
+
+(def endpoints
+  {:moodle {:format :json
+            :http-method :post}
+   :moodle {:format :json :post}})
+
+;;; Two-level hash map with the first level key being an endpoint and the
+;;; second level key is the flare event that is being transformed. All values
+;;; should be fns that take a single argument, a payload for the specified
+;;; event.
+(def outgoing-transformations
+  {:moodle {:flare.event/flare.ping identity}
+   :showevidence {:flare.event/flare.ping identity}})
+
+;;; ??
+(def incoming-transformations
+  {})


Add support for working with colors. Refs #24.

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

--- src/lib/cljs/one/color.cljs
+++ src/lib/cljs/one/color.cljs
@@ -0,0 +1,89 @@
+(ns ^{:doc "Provide support for working with colors. Wraps Google
+  Closure's color support.  The goog.color namespace provides support for
+  additional color formats."}
+  one.color
+  (:require [goog.string :as gstring]
+            [goog.style :as style]
+            [goog.color :as gcolor]
+            [goog.color.alpha :as alpha]))
+
+(defprotocol IColor
+  (rgb [this] "Returns a vector [r g b].")
+  (rgba [this] "Returns a vector [r g b a].")
+  (hex [this] "Returns a hex string for this color.")
+  (hex-rgba [this] "Returns a hex rgba string for this color.")
+  (alpha [this] "Returns the alpha for this color, a number in the range [0 1]."))
+
+(defrecord Color [r g b a]
+  IColor
+  (rgb [_] [r g b])
+  (rgba [_] [r g b a])
+  (hex [_]
+    (gcolor/rgbArrayToHex (array r g b)))
+  (hex-rgba [_]
+    (alpha/rgbaArrayToHex (array r g b a)))
+  (alpha [_] a))
+
+(defn- make-color
+  ([r g b]
+     (make-color r g b 1))
+  ([r g b a]
+     (Color. r g b a)))
+
+(comment ;; Color examples
+
+  (def red (make-color 200 0 0))
+  (rgb red)
+  (rgba red)
+  (hex red)
+  (hex-rgba red)
+  (alpha red)
+  )
+
+(defprotocol IColorSource
+  (color [this] "Get the color from the passed object. Return a Color object.")
+  (bg-color [this] "Get the background color from the passed
+  object. Returns a Color object."))
+
+(extend-protocol IColorSource
+
+  nil
+  (color [this] (make-color 0 0 0))
+  (bg-color [this] (make-color 0 0 0))
+
+  Color
+  (color [this] this)
+  (bg-color [this] this)
+
+  cljs.core.Vector
+  (color [this] (apply make-color this))
+  (bg-color [this] (apply make-color this))
+
+  js/String
+  (color [this]
+    (color (js->clj (cond (gstring/startsWith this "#")
+                          (cond (= (count this) 7) (gcolor/hexToRgb this)
+                                (= (count this) 9) (alpha/hexToRgba this))
+
+                          (gstring/startsWith this "rgba(")
+                          (alpha/parse this)
+
+                          (gstring/startsWith this "rgb(") (gcolor/parseRgb this))
+                    :keywordize-keys true)))
+  (bg-color [this] (color this))
+
+  cljs.core.ObjMap
+  (color [this] (color (:hex this)))
+  (bg-color [this] (color this))
+
+  js/HTMLElement
+  (color [this]
+    (color (js->clj (gcolor/parse (style/getComputedStyle this "color"))
+                    :keywordize-keys true)))
+  (bg-color [this]
+    (color (js->clj (let [c (style/getBackgroundColor this)]
+                      (try
+                        (gcolor/parse c)
+                        (catch js/Error e (alpha/parse c))))
+                    :keywordize-keys true))))
+


Add config.clj for configuration of beebster.

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

--- src/beebster_clj/config.clj
+++ src/beebster_clj/config.clj
@@ -0,0 +1,8 @@
+(ns beebster-clj.config)
+
+(def config {:terminal "gnome-terminal"
+             :download-folder (apply str "--working-directory=" (System/getenv "HOME") "/Videos")})
+
+
+
+


Testings hashes too now

Testings hashes too now

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/xcthulhu/clj-bitauth.git/'


Add election-mail-subscription to tv-signup

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


Add is-node?.

Add is-node?.

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

--- src/datomish/js_util.cljs
+++ src/datomish/js_util.cljs
@@ -0,0 +1,14 @@
+;; This Source Code Form is subject to the terms of the Mozilla Public
+;; License, v. 2.0. If a copy of the MPL was not distributed with this
+;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+(ns datomish.js-util)
+
+(defn is-node? []
+  (try
+    (= "[object process]"
+       (.toString (aget js/global "process")))
+    (catch js/ReferenceError e
+      false)
+    (catch js/TypeError e
+      false)))


Prevent temp filename leak in multipart uploads

The deleteOnExit hook adds files to a LinkedHashSet, which continues to
grow even when those files are periodically deleted. This causes a slow
memory leak, which can be solved by replacing deleteOnExit with a custom
shutdown hook.

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


permissions check on user listing endpoint.

--- src/metabase/api/user.clj
+++ src/metabase/api/user.clj
@@ -9,8 +9,9 @@

 (defendpoint GET "/" []
-  ;; TODO - permissions check
-  (sel :many User :is_active true))
+  ; user must be a superuser to proceed
+  (check-403 (:is_superuser @*current-user*))
+  (sel :many User))

 (defendpoint GET "/current" []


minor tooltip tweak

minor tooltip tweak

--- cljs-cheatsheet/cljs_cheatsheet/html.cljs
+++ cljs-cheatsheet/cljs_cheatsheet/html.cljs
@@ -924,7 +924,8 @@

   [:div#tooltip-sets.tooltip-53dde {:style "display:none"}
     [:i.fa.fa-thumb-tack.pin-0ad63]
-    [:p.info-2e4f9 "Sets are collections of unique values."]]
+    [:p.info-2e4f9 "Sets are collections of unique values, just like in "
+      "mathematics."]]

   [:div#tooltip-set-as-fn.tooltip-53dde {:style "display:none"}
     [:i.fa.fa-thumb-tack.pin-0ad63]


add test (init commit)

add test (init commit)

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/sbondaryev/cljs-worker.git/'


Arranged apps in grid of 3 cols

Arranged apps in grid of 3 cols

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/uris77/6pedos-web.git/'


add :external-config

add :external-config

--- sidecar/src/figwheel_sidecar/config_check/validate_config.clj
+++ sidecar/src/figwheel_sidecar/config_check/validate_config.clj
@@ -124,7 +124,9 @@
           :ups-libs                  [string?]
           :ups-externs               [string?]
           :ups-foreign-libs          [(ref-schema 'ForeignLib)]
-          :closure-output-charset    string?})
+          :closure-output-charset    string?
+
+          :external-config           {keyword? map?}})
     (spec 'ForeignLib {:file string?
                        :provides [string?]
                        :file-min string?


Moving the check for special symbols to the right place

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


Revert "Remove connect test, unsupported"

This reverts commit 035ee05d

error: pathspec 'src/com/wsscode/pathom/connect/test.cljc' did not match any file(s) known to git

--- src/com/wsscode/pathom/connect/test.cljc
+++ src/com/wsscode/pathom/connect/test.cljc
@@ -0,0 +1,435 @@
+(ns com.wsscode.pathom.connect.test
+  (:require
+    [clojure.data :as data]
+    [clojure.set :as set]
+    [clojure.spec.alpha :as s]
+    [clojure.walk :as walk]
+    [com.fulcrologic.guardrails.core :refer [>def >defn >fdef => | <- ?]]
+    [#?(:clj  com.wsscode.async.async-clj
+        :cljs com.wsscode.async.async-cljs) :refer [go-catch]]
+    [com.wsscode.common.combinatorics :as combo]
+    [com.wsscode.pathom.connect :as pc]
+    [com.wsscode.pathom.core :as p]
+    [com.wsscode.pathom.misc :as p.misc]
+    [com.wsscode.pathom.test :as pt])
+  #?(:clj
+     (:import
+       (java.util
+         Date))))
+
+;; EXPERIMENTAL
+
+;; generative test helpers
+
+(def parser-env
+  {:async-reader    pt/async-reader
+   ::pt/depth-limit 10
+   ::p/reader       pt/reader
+   ::p/union-path   pt/union-test-path})
+
+(def parser (p/parser {:mutate pt/mutate-fn}))
+
+(defn resolve-fn
+  [{{::pc/keys [output]} ::pc/resolver-data} _]
+  (parser (assoc parser-env ::pt/include-nils? false) output))
+
+(defn async-resolve-fn
+  [{{::pc/keys [output]} ::pc/resolver-data :as env} _]
+  (if (-> env :ast :key (pt/hash-mod? 3))
+    (go-catch
+      (parser (assoc parser-env ::pt/include-nils? false) output))
+    (parser (assoc parser-env ::pt/include-nils? false) output)))
+
+;; auto-test
+
+(>def ::values set?)
+(>def ::error any?)
+(>def ::depth nat-int?)
+(>def ::error-box (s/keys :req [::error]))
+(>def ::data-bank any?)
+(>def ::data-bank-raw (s/map-of ::pc/attribute ::values))
+(>def ::input-arguments (s/map-of ::pc/attribute any?))
+(>def ::call-result (s/or :error (s/keys :req [::error]) :value any?))
+(>def ::call-event (s/map-of ::input-arguments ::call-result))
+(>def ::call-history (s/map-of symbol? ::call-event))
+(>def ::calls (s/coll-of map? :kind set?))
+(>def ::log (s/tuple inst? symbol? map? map?))
+(>def ::call-log (s/coll-of ::log :kind vector?))
+(>def ::multi-args (s/coll-of ::pc/attributes-set :kind set?))
+
+(>def ::event-type #{::report-seek
+                     ::report-resolver-start
+                     ::report-resolver-discover
+                     ::report-resolver-call})
+
+(>def ::report-fn any?)
+
+(>def ::resolver-out
+  (s/or :failed (s/or :simple #{::unreachable ::end-of-input}
+                      :error (s/keys :req [::error]))
+        :success map?))
+
+(declare test-resolver* discover-data)
+
+(defn reduce-first [col] (reduce #(reduced %2) nil col))
+
+(defn add-subsets [{::keys [multi-args] :as a} b]
+  (let [b-keys (set (keys b))]
+    (reduce
+      (fn [m args]
+        (if (set/subset? args b-keys)
+          (update m args (fnil conj #{}) (select-keys b (set/intersection args b-keys)))
+          m))
+      a
+      multi-args)))
+
+(defn dissoc-stats-keys [data-bank]
+  (dissoc data-bank ::call-history ::call-log ::out-shape-mismatch ::unreachable))
+
+(defn bank-add
+  "Adds new information to a data bank, the data bank is feed by resolver outputs
+  and is used to feed in as input to call other resolvers."
+  [{::keys [bank-ignore] :as env
+    :or    {bank-ignore #{::p/not-found}}} a b]
+  (let [bank-add' (partial bank-add env)]
+    (if (map? b)
+      (-> (reduce-kv
+            (fn [m k v]
+              (if v
+                (cond-> (if (contains? bank-ignore v)
+                          m
+                          (update m k (fnil conj #{}) v))
+                  (map? v) (bank-add' v)
+                  (sequential? v) (as-> <> (reduce bank-add' <> v)))
+                m))
+            a
+            (dissoc b ::pc/env))
+          (add-subsets b))
+      a)))
+
+(defn unreachable
+  "Mark attribute k as unreachable on db. Returns ::unreachable."
+  [{::keys [data-bank]} k]
+  (swap! data-bank update ::unreachable (fnil conj #{}) k)
+  {::error ::unreachable})
+
+(defn report [{::keys [report-fn] :as env} event data]
+  (if report-fn
+    (let [env' (update env ::depth #(or % 0))]
+      (report-fn env' event data))))
+
+(defn seek-attr
+  "Try to run more resolvers to get more attributes of type `attr`."
+  [{::keys    [data-bank resolver-trace depth]
+    ::pc/keys [indexes]
+    :or       {depth 0}
+    :as       env}
+   attr]
+  (let [db      @data-bank
+        db-keys (set (keys db))
+        {::pc/keys [index-oir index-resolvers]} indexes]
+    (report env ::report-seek {::pc/attribute attr})
+    (if-let [attr-resolvers (get index-oir attr)]
+      (or (->> attr-resolvers
+               (mapcat (fn [[attrs syms]]
+                         (let [missing (set/difference attrs db-keys)]
+                           (for [s syms]
+                             {:sym     s
+                              :data    (get index-resolvers s)
+                              :attrs   attrs
+                              :missing missing}))))
+               (sort-by (comp count :missing))
+               (eduction
+                 (remove (comp (or resolver-trace #{}) :sym))
+                 (keep (fn [{:keys [sym data]}]
+                         (let [env' (-> env
+                                        (assoc ::depth (inc depth))
+                                        (update ::resolver-trace (fnil conj #{}) sym))]
+                           (test-resolver* env' data)
+                           (when (not= (get db attr) (get @data-bank attr))
+                             (get @data-bank attr))))))
+               (reduce-first))
+          (unreachable env attr))
+      (unreachable env attr))))
+
+(defn resolve-attr
+  "Find a value for an attribute."
+  [{::keys [data-bank force-seek?] :as env} attr]
+  (let [db @data-bank]
+    (if force-seek?
+      (seek-attr (dissoc env ::force-seek?) attr)
+      (or (get db attr)
+          (seek-attr env attr)))))
+
+(defn discover-data
+  "Pick a new input for a resolver from the data bank."
+  [env {::pc/keys [input]}]
+  (zipmap input (map #(resolve-attr env %) input)))
+
+(defn call-add [env a b]
+  (-> (bank-add env a b)
+      (update ::calls (fnil conj #{}) b)))
+
+(defn now []
+  #?(:clj  (Date.)
+     :cljs (js/Date.)))
+
+(defn log!
+  [{::keys [data-bank]}
+   {::pc/keys [sym]}
+   {:keys [in out]}]
+  (swap! data-bank update ::call-log (fnil conj []) [(now) sym in out])
+  out)
+
+(defn collect-multi-args
+  "Collect inputs with more than one attribute from the index."
+  [indexes]
+  (->> indexes ::pc/index-resolvers vals
+       (map ::pc/input)
+       (filter #(> (count %) 1))
+       (set)))
+
+(defn expand-output-tree
+  "Connect normaly only indexes the direct root attributes for scan fetching.
+  But for test discovery we also want the nested to be available as options
+  during parsing. This function brings the nested items to top level."
+  [indexes]
+  (let [resolvers (->> indexes ::pc/index-resolvers)]
+    (reduce-kv
+      (fn add-output [idx _ {::pc/keys [sym output input] :as res}]
+        (reduce
+          (fn [idx attr]
+            (let [attr' (if (map? attr) (ffirst attr) attr)]
+              (cond-> (update-in idx [::pc/index-oir attr' input] (fnil conj #{}) sym)
+                (map? attr)
+                (add-output nil (assoc res ::pc/output (first (vals attr)))))))
+          idx
+          output))
+      indexes
+      resolvers)))
+
+(defn input-list
+  [{::keys [data-bank]} {::pc/keys [input]} in-data]
+  (let [db @data-bank]
+    (cond
+      (zero? (count input))
+      [{}]
+
+      (= 1 (count input))
+      (let [[k inputs] (first in-data)]
+        (map #(hash-map k %) inputs))
+
+      :else
+      (concat (get db input)
+              (->> (apply combo/cartesian-product (vals in-data))
+                   (map #(zipmap (keys in-data) %))
+                   (remove (get db input #{})))))))
+
+(defn vector->set
+  "Recursively converts all vectors in sets."
+  [x]
+  (walk/prewalk
+    (fn [x]
+      (if (and (vector? x) (not (map-entry? x)))
+        (set x)
+        x))
+    x))
+
+(defn find-join-value [q k]
+  (some (fn [i]
+          (if (and (map? i)
+                   (= k (ffirst i)))
+            (-> i first second))) q))
+
+(defn diff-data-shapes
+  "Return the query shape differece."
+  [a b]
+  (let [a (->> (vector->set a)
+               (into #{} (remove #(and (keyword? %)
+                                       (find-join-value b %)))))
+        b (vector->set b)
+        [missing] (data/diff a b)
+        post-missing
+        (some->> missing
+                 (into []
+                       (keep (fn [x]
+                               (if (map? x)
+                                 (let [[k v] (first x)
+                                       val-diff (diff-data-shapes v (find-join-value b k))]
+                                   (if val-diff
+                                     {k val-diff}))
+                                 x)))))]
+    (if (seq post-missing)
+      post-missing)))
+
+(defn return-extra-attributes [{::pc/keys [output]} out]
+  (-> (pc/data->shape out)
+      (diff-data-shapes output)))
+
+(defn merge-mismatch
+  [{::keys [out-cumulative]}
+   {::pc/keys [output]}
+   out]
+  (let [out-shape (pc/data->shape out)
+        out-c     (p/merge-queries (or out-cumulative output) out-shape)]
+    {::out-base       output
+     ::out-cumulative out-c
+     ::out-missing    (diff-data-shapes out-c output)}))
+
+(defn inc* [x] (if x (inc x) 1))
+
+(defn test-resolver*
+  "Test a resolver."
+  ([{::keys [data-bank force-seek?] :as env} {::pc/keys [sym] :as resolver}]
+   (report env ::report-resolver-start resolver)
+   (let [db      @data-bank
+         env     (update env ::depth inc*)
+         in-data (discover-data env resolver)]
+     (report env ::report-resolver-discover (assoc resolver ::data-bank in-data))
+     (if (some ::error (vals in-data))
+       (if force-seek?
+         (log! env resolver {:in in-data :out ::unreachable})
+         (recur (assoc env ::force-seek? true) resolver))
+       (if-let [input' (->> (input-list env resolver in-data)
+                            (remove (get-in db [::call-history sym] {}))
+                            (first))]
+         (test-resolver* env resolver input')
+         (if force-seek?
+           (log! env resolver {:in in-data :out ::end-of-input})
+           (recur (assoc env ::force-seek? true) resolver))))))
+
+  ([{::keys [data-bank] :as env}
+    {::pc/keys [sym] :as resolver}
+    input]
+   (report env ::report-resolver-call (assoc resolver ::input-arguments input))
+   (let [out (try
+               (some-> (pc/call-resolver (assoc env ::pc/resolver-data resolver) input)
+                       (dissoc ::pc/env))
+               (catch #?(:clj Throwable :cljs :default) e
+                 {::error e}))]
+     (swap! data-bank update-in [::call-history sym] assoc input out)
+     (log! env resolver {:in input :out out})
+     (if-not (::error out)
+       (do
+         (when (return-extra-attributes resolver out)
+           (swap! data-bank update-in [::out-shape-mismatch sym]
+             merge-mismatch resolver out))
+         (swap! data-bank (partial bank-add env) out)
+         env)
+       out))))
+
+(defn success-call? [x] (not (contains? x ::error)))
+
+(defn resolver-calls [{::keys [data-bank]} s]
+  (get-in @data-bank [::call-history s]))
+
+(defn count-success-calls [env s]
+  (->> (resolver-calls env s) vals (filter success-call?) count))
+
+(defn count-failed-calls [env s]
+  (->> (resolver-calls env s) vals (remove success-call?) count))
+
+(defn process-multi-run!
+  [{::keys [data-bank target-call-count max-error-retry]
+    :or    {target-call-count 5
+            max-error-retry   10}
+    :as    env} sym]
+  (let [mark-done (fn [sym reason]
+                    (swap! data-bank update-in [::call-history sym] (fn [x] (vary-meta (or x {}) assoc ::resolver-finished-by reason))))
+        {::pc/keys [input]} (pc/resolver-data env sym)
+        [kind res] (->> (test-resolver* env (pc/resolver-data env sym))
+                        (s/conform ::resolver-out))]
+    (case kind
+      :success
+      (if (seq input)
+        (if (>= (count-success-calls env sym) target-call-count)
+          (mark-done sym ::resolver-done))
+        (mark-done sym ::resolver-done))
+
+      :failed
+      (let [[type value] res]
+        (case type
+          :simple
+          (case value
+            ::end-of-input
+            (mark-done sym ::end-of-input)
+
+            ::unreachable
+            (mark-done sym ::unreachable))
+
+          :error
+          (if (>= (count-failed-calls env sym) max-error-retry)
+            (mark-done sym ::max-error)))))))
+
+(defn test-index*
+  [{::pc/keys [indexes]
+    :as       env}]
+  (let [resolvers (-> indexes ::pc/index-resolvers)
+        res-keys  (set (keys resolvers))
+        sym-calls #(resolver-calls env %)]
+    (loop []
+      (let [missing (->> res-keys
+                         (remove (comp ::resolver-finished-by meta sym-calls))
+                         (sort-by (juxt #(count-success-calls env %)
+                                        #(-> (pc/resolver-data env %) ::pc/input count))))]
+        (if (seq missing)
+          (do
+            (process-multi-run! env (first missing))
+            (recur))
+          env)))))
+
+(declare console-print-reporter)
+
+(defn prepare-environment [{::pc/keys [indexes]
+                            ::keys    [data-bank]
+                            :as       env}]
+  (assert (s/valid? (s/keys :req [::pc/indexes]) env)
+    (s/explain-str (s/keys :req [::pc/indexes]) env))
+  (let [data-bank (if data-bank
+                    (do (swap! data-bank assoc ::multi-args (collect-multi-args indexes)))
+                    (atom {::multi-args (collect-multi-args indexes)}))]
+    (-> (merge {::data-bank data-bank
+                ::report-fn console-print-reporter} env)
+        (update ::pc/indexes expand-output-tree))))
+
+(defn test-resolver
+  "Test a single resolver."
+  [env {::pc/keys [sym]}]
+  (let [env' (prepare-environment env)]
+    (loop [_ nil]
+      (if (-> (resolver-calls env' sym) meta ::resolver-finished-by)
+        env'
+        (recur (process-multi-run! env' sym))))))
+
+(defn test-index [env]
+  (test-index* (prepare-environment env)))
+
+;; reporter
+
+(defn depth-print [{::keys [depth]} & more]
+  (apply println
+    (apply str (repeat depth "  "))
+    "- " more))
+
+(defmulti console-print-reporter (fn [env event data] event))
+
+(defmethod console-print-reporter ::report-seek
+  [env _ {:keys [::pc/attribute]}]
+  (depth-print env "seeking" ::pc/attribute))
+
+(defmethod console-print-reporter ::report-resolver-start
+  [env _ {:keys [::pc/sym]}]
+  (depth-print env "test resolver" ::pc/sym))
+
+(defmethod console-print-reporter ::report-resolver-discover
+  [env _ {:keys [::pc/sym ::data-bank]}]
+  (depth-print env "discovered input" ::pc/sym (pr-str data-bank)))
+
+(defmethod console-print-reporter ::report-resolver-call
+  [env _ {:keys [::pc/sym ::input-arguments]}]
+  (depth-print env "call resolver" (pr-str ::pc/sym) (pr-str input-arguments)))
+
+(defmethod console-print-reporter :default
+  [_ _ _] nil)
+
+(defn silent-reporter "I report nothing!" [_ _ _])


midje unit test

midje unit test

error: pathspec 'cljx/plongeur-clj/test/kierros/sente_server_diver_test.clj' did not match any file(s) known to git

--- cljx/plongeur-clj/test/kierros/sente_server_diver_test.clj
+++ cljx/plongeur-clj/test/kierros/sente_server_diver_test.clj
@@ -0,0 +1,67 @@
+(ns kierros.sente-server-diver-test
+  (use midje.sweet)
+  (:require [clojure.core.async :as a :refer [<! <!! >! chan close!]]
+            [kierros.sente-server-driver :refer :all]))
+
+(defn pause
+  ([] (pause 100))
+  ([n] (<!! (a/timeout n))))
+
+(facts
+
+  "about the sente server driver"
+
+  (facts
+
+    "init smoke tests"
+
+    (make-sente-server-driver) => truthy
+    (make-sente-server-driver {}) => truthy
+    (make-sente-server-driver {:sente {}}) => truthy
+    (make-sente-server-driver {:http-kit {}}) => truthy
+
+    )
+
+  (facts
+
+    "driver call smoke tests"
+
+    (let [driver      (make-sente-server-driver)
+          sink-proxy  (chan)
+          _           (driver sink-proxy)]
+      (close! sink-proxy) (pause)) => nil
+
+    (let [driver      (make-sente-server-driver {})
+          sink-proxy  (chan)
+          _           (driver sink-proxy)]
+      (close! sink-proxy) (pause)) => nil
+
+    (let [driver      (make-sente-server-driver {:sente {}})
+          sink-proxy  (chan)
+          _           (driver sink-proxy)]
+      (close! sink-proxy) (pause)) => nil
+
+    (let [driver      (make-sente-server-driver {:http-kit {:port 3000}})
+          sink-proxy  (chan)
+          _           (driver sink-proxy)]
+      (close! sink-proxy) (pause)) => nil
+
+    )
+
+  (facts
+
+    "calling two sente drivers on different ports"
+
+    (let [driver-0     (make-sente-server-driver {:http-kit {:port 3000}})
+          sink-proxy-0 (chan)
+          _            (driver-0 sink-proxy-0)
+          driver-1     (make-sente-server-driver {:http-kit {:port 3001}})
+          sink-proxy-1 (chan)
+          _            (driver-1 sink-proxy-1)]
+      (close! sink-proxy-0)
+      (close! sink-proxy-1)
+      (pause)) => nil
+
+    )
+
+  )


Cleanup

Cleanup


Fix sms-form schema

Fix sms-form schema


Zero was not a valid value for :send-after


Minor test cleanup

Minor test cleanup

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


fix test formatting

fix test formatting


Require ns before protocol

Require ns before protocol

--- pigpen-core/src/main/clojure/pigpen/extensions/core_async.clj
+++ pigpen-core/src/main/clojure/pigpen/extensions/core_async.clj
@@ -17,7 +17,8 @@
 ;;

 (ns pigpen.extensions.core-async
-  (:require [clojure.core.async :as a])
+  (:require [clojure.core.async :as a]
+            [clojure.core.async.impl.protocols])
   (:import [clojure.core.async.impl.protocols Channel]))

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


Adds an example of how to capture the keyboard output in an applet

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

--- examples/key_capture.clj
+++ examples/key_capture.clj
@@ -0,0 +1,34 @@
+(ns key-capture
+	(:use quil.core))
+
+(def current-text-size (atom 20))
+
+(def params {:big-text-size 30
+	:background-color 25
+	:foreground-color 200})
+
+(defn setup []
+  (smooth)
+  (no-stroke)
+  (set-state! :message (atom "Click on screen and type a key")))
+
+(defn draw
+  []
+  (background-float (params :background-color))
+  (stroke-weight 20)
+  (stroke-float 10)
+  (fill (params :foreground-color))
+  (text-size @current-text-size)
+  (text @(state :message) 20 60))
+
+(defn key-press []
+	(let [big-text-size (params :big-text-size)]
+	(if (< @current-text-size big-text-size) (reset! current-text-size big-text-size))
+	(reset! (state :message) (str "Key pressed: " (raw-key)))))
+
+(defsketch key-listener
+  :title "Keyboard listener example"
+  :size [400 100]
+  :setup setup
+  :draw draw
+  :key-typed key-press)


Fix typo (raven -> sentry)

Fix typo (raven -> sentry)

--- src/clojars/main.clj
+++ src/clojars/main.clj
@@ -28,7 +28,7 @@
 (defn -main [& args]
   (try
     (configure args)
-    (println "clojars-web: enabling raven-clj client dsn:project-id:" (:project-id (raven-clj/parse-dsn (:raven-dsn @config))))
+    (println "clojars-web: enabling raven-clj client dsn:project-id:" (:project-id (raven-clj/parse-dsn (:sentry-dsn @config))))
     (let [dsn (:sentry-dsn @config)]
       (if (not dsn)
         (throw (Exception. (str "No :sentry-dsn key value found in config - " @config))))


Versuche Wahrheitstafel

Versuche Wahrheitstafel

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

--- src/logic/tt_alt.clj
+++ src/logic/tt_alt.clj
@@ -0,0 +1,109 @@
+;   Copyright (c) Burkhardt Renz THM. All rights reserved.
+;   The use and distribution terms for this software are covered by the
+;   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;   which can be found in the file epl-v10.html at the root of this distribution.
+;   By using this software in any fashion, you are agreeing to be bound by
+;   the terms of this license.
+;   You must not remove this notice, or any other, from this software.
+
+(ns mpa.core
+  (:use mpa.util)
+  (:use [clojure.math.combinatorics :only [selections]]))
+
+; unary operator
+; (not ...) see clojure.core
+
+; binary operators
+
+; (and ...) see clojure.core
+
+(defn nand [p q]
+  (not (and p q)))
+
+; (or ...) see clojure.core
+
+(defn nor [p q]
+  (not (or p q)))
+
+(defn impl [p q]
+  (or (not p) q))
+
+(defn nimpl [p q]
+  (not (impl p q)))
+
+; converse implication aka if
+(defn cimpl [p q]
+  (impl q p))
+
+(defn ncimpl [p q]
+  (not (cimpl p q)))
+
+(defn iff [p q]
+  (=  p q))
+
+(defn xor [p q]
+  (not (iff p q)))
+
+; helper
+(defn- error [type s]
+  (throw (IllegalArgumentException. (format "- %s: '%s'." type s))))
+
+; global set of operators
+(def phiops #{'not 'and 'nand 'or 'nor 'impl 'nimpl 'cimpl 'ncimpl 'iff 'xor})
+
+; phivar? decides whether a symbol is a propositional variable
+(defn phivar? [item]
+    (and (symbol? item) (not-any? #(= item %) phiops)))
+
+; besser zwei Funktionen, die eine mit Fehlerprüfung, die andere ohne
+; dann muss bei phival normalerweise nicht der dispatch-mechanismus
+; verwendet werden
+(defn phival-dispatch [phi _]
+  (cond
+    (and (list? phi) (not (empty? phi))) :valid
+    (phivar? phi) :valid
+    :else :invalid))
+
+(defmulti phival phival-dispatch)
+
+; value of a formula phi under a given valuation vmap
+(defmethod phival :valid [phi valuation]
+  (try
+    (eval `(let ~valuation ~phi))
+    (catch Exception e (error "Valuation not possible" (str phi " with " valuation)))
+    ))
+
+(defmethod phival :invalid [phi valuation]
+  (error "Not a valid formula" (str phi)))
+
+; the set of atoms of formula phi
+(defn- phivar-set [phi]
+  (apply sorted-set (filter phivar? (flatten phi))))
+
+(defn- get-atom-set-old [phi]
+  (set (filter keyword? (flatten phi))))
+
+; print header of truth table
+(defn- print-tt-head [vset]
+  (do
+    (doseq [item vset]
+      (print (format "%-6s" item))))
+    (println "phi"))
+
+; print line of truth table
+(defn- print-tt-line [valuation phival]
+  (do
+    (doseq [aval (take-nth 2 (next valuation))]
+      (print (format "%-6s" aval)))
+    (println phival)))
+
+; print truth table of formula phi
+(defn print-tt [phi]
+  (let [vset (phivar-set phi), vset-cnt (count vset)]
+    (do
+      (print-tt-head vset)
+      (doseq [comb (selections [false true] vset-cnt)]
+        (let [valuation (vec (interleave vset comb))]
+          (print-tt-line valuation (phival phi valuation))))
+    )))
+


Cell labeling script

Cell labeling script

error: pathspec 'src/plugins/Scripts/Funimage/Morphology/Cell_Labeler.clj' did not match any file(s) known to git

--- src/plugins/Scripts/Funimage/Morphology/Cell_Labeler.clj
+++ src/plugins/Scripts/Funimage/Morphology/Cell_Labeler.clj
@@ -0,0 +1,258 @@
+; @ImagePlus(label="Target image",description="Input image (expects channel1 is Nuclei channel2 is CellSurface)") input-imp
+; @Integer(label="Cell surface channel index",description="Index of the cell surface channel",value=0) cell-surface-channel-index
+; @Integer(label="Nuclei channel index",description="Index of the nuclei channel",value=1) nuclei-channel-index
+; @Integer(label="Signal channel index",description="Index of the cell surface channel",value=2) signal-channel-index
+; @Integer(label="Surface threshold",description="Threshold for creating a mask from cellsurface channel",value=500) surface-threshold
+; @Boolean(label="Show all steps",description="Show all processing steps",value=false) show-all-steps
+; @OUTPUT ImagePlus output-imp
+
+(use '[funimage img imp project conversion]
+     '[funimage.segmentation utils imp]
+     '[funimage.imp calibration roi threshold calculator statistics])
+
+; @Parameter(visibility = ItemVisibility.MESSAGE) to write a message
+
+(import '[mpicbg.imglib.image Image]
+        '[mpicbg.imglib.cursor Cursor]
+        '[script.imglib ImgLib]
+        '[mpicbg.imglib.type.numeric NumericType]
+        '[mcib3d.image3d.regionGrowing Watershed3D]
+        '[ij IJ ImagePlus WindowManager ImageStack]
+        '[ij.measure ResultsTable]
+        '[ij.gui WaitForUserDialog PointRoi NewImage PolygonRoi Roi GenericDialog NonBlockingGenericDialog Line]
+        '[ij.plugin ImageCalculator Duplicator]
+        '[ij.plugin.frame RoiManager]
+        '[ij.process ImageConverter FloatProcessor ByteProcessor])
+
+(println "Show all steps: " show-all-steps)
+
+(defn dilate-erode-filter
+  "Filter by dilate then erode."
+  [imp num-dilate num-erode]
+  (loop [k num-erode
+         imp (loop [k num-dilate
+                    imp imp]
+               (if (zero? k)
+                 imp
+                 (recur (dec k)
+                        (dilate imp))))]
+    (if (zero? k)
+      imp
+      (recur (dec k)
+             (erode imp)))))
+
+(defn split-imp
+  "Testing imp splitting."
+  [imp]
+  (for [k (range (get-num-channels imp))]
+    (let [new-stack ^ImageStack (ImageStack. (get-width imp) (get-height imp) #_(get-stack-depth imp))]
+      (.setC imp (inc k))
+      (dotimes [idx (get-num-slices imp)]
+        (.setSlice imp (inc (+ k (* 4 idx))))
+        (.addSlice new-stack ^ImageProcessor (.duplicate (.getProcessor imp))))
+      (ImagePlus. (str "C" k "-" (.getTitle imp)) new-stack))))
+
+(defn watershed-3d
+  "Do a 3D watershed."
+  [spot-imp seed-imp voxel-threshold seed-threshold]
+  (let [water ^Watershed3D (Watershed3D. (.getStack spot-imp) (.getStack seed-imp) voxel-threshold seed-threshold)
+        image-short (.getWatershedImage3D water)]
+    (mcib3d.image3d.ImageShort/getImagePlus (.getArray1D image-short) (get-width spot-imp) (get-height spot-imp) (get-num-slices spot-imp) false)
+    ))
+
+(defn label-3d
+  "Label segments in 3D"
+  [imp]
+  (let [labeler (mcib3d.image3d.ImageLabeller.)
+        minthresh 0]
+    (.setMinSize labeler minthresh)
+    (.setMaxsize labeler -1)
+    (let [img (mcib3d.image3d.ImageInt/wrap imp)
+          bin (.thresholdAboveInclusive img minthresh)
+          res (.getLabels labeler bin)]
+      #_(println "Num objects:" (.getNbObjectsTotal labeler bin)); there is a count for within size range too, but we count all for now
+      (mcib3d.image3d.ImageShort/getImagePlus (.getArray1D res) (get-width imp) (get-height imp) (get-num-slices imp) false))))
+
+(defn relabel-in-8bit
+  "Relabel a 16-bit labeled image in 8-bit to start at 1."
+  [imp]
+  (let [img (imp->img imp)
+        idxs (atom {})]
+    (map-imgs
+      (fn [^Cursor cur]
+        (when-not (get @idxs (.getRealFloat (.get cur)))
+          (swap! idxs assoc (.getRealFloat (.get cur)) (inc (count @idxs))))
+        (.set (.get cur) (get @idxs (.getRealFloat (.get cur)))))
+      img)
+    (img->imp img)))
+
+(defn find-centroids-3d
+  "Find the 3D centroids of each segment."
+  [imp]
+  (let [stack ^ImageStack (.getStack imp)
+        segs (atom {})]
+    (dotimes [z (get-num-slices imp)]
+      (dotimes [x (get-width imp)]
+        (dotimes [y (get-height imp)]
+          (when-not (zero? (.getVoxel stack x y z))
+            (swap! segs assoc (.getVoxel stack x y z) (conj (get @segs (.getVoxel stack x y z)) [x y z]))))))
+    (for [[k points] @segs]
+      (let [sumx (reduce + (map first points))
+            sumy (reduce + (map second points))
+            sumz (reduce + (map last points))]
+        [k [(float (/ sumx (count points)))
+            (float (/ sumy (count points)))
+            (float (/ sumz (count points)))]]))))
+
+(defn analyze-by-label
+  "Analyze an image based on a label image."
+  [labels signal]
+  (let [label-stack ^ImageStack (.getStack labels)
+        signal-stack ^ImageStack (.getStack signal)
+        centroids (atom {})
+        label-signals (atom {})
+        label-counts (atom {})
+        signal-sum (atom 0)
+        labeled-signal-sum (atom 0)]; just keep track of the total signal to know how much is lost
+    (dotimes [z (get-num-slices labels)]
+      (dotimes [x (get-width labels)]
+        (dotimes [y (get-height labels)]
+          (swap! signal-sum #(+ % (.getVoxel signal-stack x y z)))
+          (when-not (zero? (.getVoxel label-stack x y z))
+            (swap! labeled-signal-sum #(+ % (.getVoxel signal-stack x y z)))
+            (swap! centroids assoc (.getVoxel label-stack x y z)
+                   (conj (get @centroids (.getVoxel label-stack x y z)) [x y z]))
+            (swap! label-signals assoc (.getVoxel label-stack x y z)
+                   (conj (get @label-signals (.getVoxel label-stack x y z))
+                         (.getVoxel signal-stack x y z)))
+            (swap! label-counts assoc (.getVoxel label-stack x y z)
+                   (if-not (get @label-counts (.getVoxel label-stack x y z))
+                     1
+                     (inc (get @label-counts (.getVoxel label-stack x y z)))))
+            ))))
+    #_(println "Total signal:" @signal-sum)
+    #_(println "Total labeled signal:" @labeled-signal-sum)
+    (for [k (keys @centroids)]
+      (let [points (get @centroids k)
+            signal (get @label-signals k)
+            counts (get @label-counts k)
+            sumx (reduce + (map first points))
+            sumy (reduce + (map second points))
+            sumz (reduce + (map last points))]
+        [k {:x (float (/ sumx (count points)))
+            :y (float (/ sumy (count points)))
+            :z (float (/ sumz (count points)))
+            :total-signal (reduce + signal)
+            :avg-signal (float (/ (reduce + signal) counts))
+            :count counts}]))))
+
+(defn color-labeled-by-map
+   "Color a label image using a map."
+   [labels m]
+   (let [;imp (create-imp :width (get-width labels) :height (get-height labels) :depth (get-stack-depth labels) :type "32-bit")
+         imp (convert-to-float (create-imp-like labels))
+         label-stack (.getImageStack labels)
+         stack (.getImageStack imp)
+         m (assoc m 0 0)]
+     (dotimes [z (get-num-slices labels)]
+       ;(println (sort (distinct (.getPixels label-stack (inc z)))))
+       ;(println (sort (keys m)))
+       (.setPixels stack (float-array
+                           (map m (.getPixels label-stack (inc z))))
+         (inc z))
+       #_(dotimes [x (get-width labels)]
+          (dotimes [y (get-height labels)]
+            (when-not (zero? (.getVoxel label-stack x y z))
+              (.setVoxel stack x y z (get m (.getVoxel label-stack x y z)))))))
+     imp))
+
+
+#_(def channels (doall (map #(open-imp (str "/Volumes/Amnes/Claudia/ERG_Dll4_VEcad_IsoB4/07-06-2015/Ctl_P5_IsoB4594_ERG405_Dll4647_VEcad488b_Stitch/" % ".tif"))
+                             ["VEcad" "Dll4" "ERG" "IsoB4"])))
+
+(def channels (split-channels input-imp))
+;(show-imp (first channels))
+(def nuclei (blur-gaussian (copy-imp (nth channels nuclei-channel-index)) 5))
+(def backup (copy-imp nuclei))
+(IJ/run nuclei "Auto Threshold" "method=RenyiEntropy white stack use_stack_histogram"); for the vecad batch
+;(IJ/run nuclei "Auto Threshold" "method=Huang white stack use_stack_histogram"); for the vecad batch
+;(show-imp (autothreshold nuclei :renyi-entropy false false false false false true))
+(def clean-nuclei (convert-to-8bit nuclei #_(dilate-erode-filter nuclei 0 3)))
+(imp-multiply clean-nuclei (invert (nth channels nuclei-channel-index)))
+(.setTitle clean-nuclei "CleanNuclei")
+;(copy-calibration imp clean-nuclei)
+(copy-calibration (first channels) clean-nuclei)
+(when show-all-steps
+  (show-imp clean-nuclei))
+
+;(IJ/run "3D Watershed" (str "seeds_threshold=25 image_threshold=25 image=" (.getTitle clean-nuclei) " seeds=" (.getTitle clean-nuclei) " radius=2"))
+;(def labeled-nuclei (label-3d (watershed-3d clean-nuclei clean-nuclei 25 25)))
+(def labeled-nuclei (watershed-3d clean-nuclei clean-nuclei 25 25))
+(.setTitle labeled-nuclei "LabeledNuclei")
+;(copy-calibration imp labeled-nuclei)
+(copy-calibration (first channels) labeled-nuclei)
+(when show-all-steps
+  (show-imp labeled-nuclei))
+(def all-centroids (find-centroids-3d labeled-nuclei))
+#_(doseq [[k centroid] all-centroids]
+   (println "Segment" k ": " centroid))
+
+(.close clean-nuclei)
+;(def clean-nuclei ((comp erode erode erode) (convert-to-8bit (threshold-stack labeled-nuclei 1)))) ;(show-imp clean-nuclei)
+;(def clean-nuclei (convert-to-8bit (threshold-stack labeled-nuclei 1))) ;(show-imp clean-nuclei)
+;(def clean-nuclei (threshold-stack (convert-to-8bit (threshold-stack labeled-nuclei 1)) 1)) ;(show-imp clean-nuclei)
+(def clean-nuclei (threshold-stack labeled-nuclei 1)) ;(show-imp clean-nuclei)
+;(IJ/run clean-nuclei "Erode (3D)" "iso=1")
+(.setTitle clean-nuclei "CleanNuclei")
+(when show-all-steps
+  (show-imp clean-nuclei))
+
+; Split nuclei on size
+
+;(def boundaries (watershed-3d (second channels) clean-nuclei 10000 25))
+;(def boundaries (watershed-3d (first channels) clean-nuclei 10000 25))
+;(def boundaries (watershed-3d (first channels) clean-nuclei 10000 25))
+(def boundaries (watershed-3d (nth channels cell-surface-channel-index) clean-nuclei surface-threshold 1))
+;(def boundaries (watershed-3d (nth channels 2) clean-nuclei 10000 25))
+(.setTitle boundaries "Boundaries")
+;(copy-calibration imp boundaries)
+(copy-calibration (first channels) boundaries)
+(when show-all-steps
+  (show-imp boundaries))
+
+(def mask (copy-imp (nth channels cell-surface-channel-index)))
+(copy-calibration (first channels) mask)
+(convert-to-8bit (threshold-stack mask surface-threshold))
+(.setTitle mask "Mask")
+(when show-all-steps
+  (show-imp mask))
+
+#_(def cell-shape (watershed-3d (imp-subtract (copy-imp mask)
+                                             (threshold-stack (copy-imp (first channels)) 9252)) clean-nuclei 25 25))
+(def cell-shape (watershed-3d (copy-imp mask)
+                              clean-nuclei 25 25))
+(.setTitle cell-shape "CellShape")
+(copy-calibration (first channels) cell-shape)
+(when show-all-steps
+  (show-imp cell-shape))
+;(IJ/run cell-shape "16 ramps" "")
+
+;(.setMinAndMax cell-shape 0 128)
+#_(def merged-labels (imp-subtract (copy-imp cell-shape)
+                                  clean-nuclei))
+;(show-imp merged-labels)
+
+#_(def cell-results (analyze-by-label cell-shape (nth channels signal-channel-index)))
+
+#_(when show-all-steps
+   (doseq [[k v] cell-results]
+     (println k v))
+   (print (sort (map (comp :avg-signal second) cell-results))))
+
+;(def dll4-cells (color-labeled-by-map cell-shape (zipmap (keys cell-results) (map (comp :avg-signal second) cell-results))))
+#_(def dll4-cells (color-labeled-by-map cell-shape (zipmap (map (comp int first) cell-results) (map (comp :avg-signal second) cell-results))))
+#_(.setTitle dll4-cells "Dll4Labeling")
+#_(when show-all-steps
+   (show-imp dll4-cells))
+
+(def output-imp (autocontrast (zconcat-imps (concat channels [cell-shape]))))


Fixed permissions API via manual testing

Need to add a ::token for the bearer token to :identity

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/physion/ovation-webapi.git/'


Add summary cache to config

Add summary cache to config

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/leif47/immutabledb-experimental.git/'


Use durable subscriptions.

Use durable subscriptions.

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


Testing arity for restart-subscription-by-phone


Understand variadic inputs

Understand variadic inputs

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/kkroening/jackal.git/'


Trying to find existing paths that need to be updated.

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


[CS NH] Process tests

[CS NH] Process tests

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

--- test/vip/data_processor/pipeline_test.clj
+++ test/vip/data_processor/pipeline_test.clj
@@ -0,0 +1,47 @@
+(ns vip.data-processor.pipeline-test
+  (:require [clojure.test :refer :all]
+            [vip.data-processor.pipeline :refer :all]))
+
+(defn incrementor [ctx]
+  (update-in ctx [:input] inc))
+(defn thrower [ctx]
+  (throw (Throwable. "Boom!")))
+
+(deftest try-validation-test
+  (let [ctx {:input 0}]
+    (testing "Without an exception"
+      (let [result (try-validation incrementor ctx)]
+        (is (= 1 (:input result)))
+        (is (not (contains? result :stop)))
+        (is (not (contains? result :exception)))))
+    (testing "With an exception"
+      (let [result (try-validation thrower ctx)]
+        (is (:stop result))
+        (is (:exception result))))))
+
+(deftest run-pipeline-test
+  (testing "Without an exception"
+    (let [ctx {:input 0 :pipeline [incrementor
+                                   incrementor
+                                   incrementor]}
+          result (run-pipeline ctx)]
+      (is (= 3 (:input result)))
+      (is (empty? (:pipeline result)))
+      (is (not (contains? result :stop)))
+      (is (not (contains? result :exception)))))
+  (testing "With an exception"
+    (let [ctx {:input 0 :pipeline [incrementor
+                                   thrower
+                                   incrementor]}
+          result (run-pipeline ctx)]
+      (is (:stop result))
+      (is (:exception result))
+      (is (= 1 (:input result)))
+      (is (= [thrower incrementor] (:pipeline result))))))
+
+(deftest process-test
+  (testing "Builds the context and executes the pipeline"
+    (let [intial-input 0
+          pipeline [incrementor incrementor incrementor]
+          result (process pipeline intial-input)]
+      (is (= {:input 3 :pipeline []} result)))))


add endpoint request logging middleware

add endpoint request logging middleware

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


Add migration generation script

Add migration generation script

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

--- adressverzeichnis/migrate.clj
+++ adressverzeichnis/migrate.clj
@@ -0,0 +1,182 @@
+#!/usr/bin/env bb
+
+(ns migrate
+  (:require
+   [babashka.deps :as deps]
+   [clojure.pprint :as pprint]
+   [clojure.string :as str]
+   [clojure.set :as set]
+   [clojure.java.io :as io])
+  (:import java.util.Date))
+
+(deps/add-deps
+ '{:deps
+   {honeysql/honeysql {:mvn/version "1.0.444"}
+    org.clojure/data.csv {:mvn/version "1.0.0"}}})
+
+(require '[clojure.data.csv :as csv]
+         '[honeysql.core :as sql]
+         '[honeysql.helpers :as helpers])
+
+(def path-to-csv (first *command-line-args*))
+
+(defn csv-data->maps [csv-data]
+  (map zipmap
+       (->> (first csv-data) ;; First row is the header
+            (map keyword) ;; Drop if you want string keys instead
+            repeat)
+       (rest csv-data)))
+
+(def old
+  (csv-data->maps
+   (with-open [reader (io/reader path-to-csv)]
+    (doall
+     (csv/read-csv reader)))))
+
+(def rename-keys
+  {:Anrede :anrede
+   :Titel :titel
+   :Vorname :vorname
+   :Nachname :nachname
+   :Fahrtenname :fahrtenname
+   :Email :email
+   :NRW :nrw
+   :Stand :stand
+   :NichtAbdrucken :nicht_abdrucken
+   :Anmerkung :anmerkung
+   :Geburtsdatum :geburtstag
+   :Todesdatum :todestag
+   :ID :alte_id})
+
+(def stand-map
+  {"OR" "Ordensritter"
+   "P" "Pilgerin"
+   "StGR" "St.-Georgs-Ritter"
+   "GM" "Gildenmeisterin"
+   "Gim" "Gildenmädchen"
+   "Gil" "Gildin"})
+
+(defn parse-date [s]
+  (when-not (str/blank? s)
+    (let [[_ date year month day] (re-find #"^((\d\d\d\d)-(\d\d)-(\d\d))" s)]
+      date)))
+
+(defn get-adress [{:keys [Straße Zusatz Postleitzahl Ort]}]
+  (when-not (every? str/blank? [Straße Zusatz Postleitzahl Ort])
+    {:label ""
+     :strasse Straße
+     :zusatz Zusatz
+     :plz Postleitzahl
+     :stadt Ort}))
+
+(defn build-number [vorwahl nummer]
+  (str vorwahl nummer))
+
+(defn get-numbers [{:keys [Vorwahl1 Telefonnummer1 Telefonbezeichner1
+                           Vorwahl2 Telefonnummer2 Telefonbezeichner2
+                           Vorwahl3 Telefonnummer3 Telefonbezeichner3]}]
+  (let [not-blank? (complement str/blank?)]
+    (cond-> []
+      (not-blank? Telefonnummer1)
+      (conj {:label Telefonbezeichner1
+             :nummer (build-number Vorwahl1 Telefonnummer1)})
+
+      (not-blank? Telefonnummer2)
+      (conj {:label Telefonbezeichner2
+             :nummer (build-number Vorwahl2 Telefonnummer2)})
+
+      (not-blank? Telefonnummer3)
+      (conj {:label Telefonbezeichner3
+             :nummer (build-number Vorwahl3 Telefonnummer3)}))))
+
+(defn parse-out-tel [person]
+  (-> person
+      (assoc :numbers (get-numbers person))
+      (dissoc :Vorwahl1 :Telefonnummer1 :Telefonbezeichner1
+              :Vorwahl2 :Telefonnummer2 :Telefonbezeichner2
+              :Vorwahl3 :Telefonnummer3 :Telefonbezeichner3)))
+
+(defn parse-out-adress [person]
+  (-> person
+      (assoc :address (get-adress person))
+      (dissoc :Straße :Zusatz :Postleitzahl :Ort)))
+
+(defn get-permissions [{:keys [Bundesthing Bundesrat Bundesjungenrat Bundesmädchenrat]
+                        :as person}]
+  {"Bundesthing"
+   {:bekommt_einladung (Boolean/parseBoolean Bundesthing)
+    :bekommt_protokoll (Boolean/parseBoolean (get person (keyword "Protokoll Bundesthing")))}
+   "Bundesrat"
+   {:bekommt_einladung (Boolean/parseBoolean Bundesrat)
+    :bekommt_protokoll (Boolean/parseBoolean (get person (keyword "Protokoll Bundesrat")))}
+   "Bundesmädchenrat"
+   {:bekommt_einladung (Boolean/parseBoolean Bundesmädchenrat)
+    :bekommt_protokoll (Boolean/parseBoolean (get person (keyword "Protokoll Bundesmädchenrat")))}
+   "Bundesjungenrat"
+   {:bekommt_einladung (Boolean/parseBoolean Bundesjungenrat)
+    :bekommt_protokoll (Boolean/parseBoolean (get person (keyword "Protokoll Bundesjungenrat")))}})
+
+(defn parse-out-permissions [person]
+  (-> person
+      (assoc :permissions (get-permissions person))
+      (dissoc
+       :Bundesthing (keyword "Protokoll Bundesthing") (keyword "Stimmberechtigung Bundesthing")
+       :Bundesrat (keyword "Protokoll Bundesrat") (keyword "Stimmberechtigung Bundesrat")
+       :Bundesjungenrat (keyword "Protokoll Bundesjungenrat") (keyword "Stimmberechtigung Bundesjungenrat")
+       :Bundesmädchenrat (keyword "Protokoll Bundesmädchenrat") (keyword "Stimmberechtigung Bundesmädchenrat"))))
+
+(defn parse-person [person]
+  (-> person
+      parse-out-tel
+      parse-out-adress
+      parse-out-permissions
+      (set/rename-keys rename-keys)
+      (update :geburtstag parse-date)
+      (update :todestag parse-date)
+      (update :nrw #(Boolean/parseBoolean %))
+      (update :nicht_abdrucken #(Boolean/parseBoolean %))
+      (update :stand #(get stand-map % ""))))
+
+(defmulti format-value type)
+(defmethod format-value String [value]
+  (str "'" value "'"))
+(defmethod format-value Boolean [value] value)
+(defmethod format-value nil [_] "NULL")
+
+(defn adress-sql [address old-id]
+  (let [fields (keys address)
+        values (map #(format-value (get address %)) fields)]
+    (if (every? str/blank? values)
+      ""
+      (str
+       "INSERT INTO public.adressverzeichnis_adresse (" (str/join "," (map name fields)) ",erstellt,veraendert,land,person_id) VALUES ("
+       (str/join "," values)
+       ",'now','now', 'Deutschland', (SELECT id FROM public.adressverzeichnis_person WHERE adressverzeichnis_person.alte_id = " old-id "));"))))
+
+(defn phone-sql [phone old-id]
+  (let [fields (keys phone)
+        values (map #(format-value (get phone %)) fields)]
+    (str
+      "INSERT INTO public.adressverzeichnis_telefon (" (str/join "," (map name fields)) ",erstellt,veraendert,person_id) VALUES ("
+      (str/join "," values)
+      ",'now','now', (SELECT id FROM public.adressverzeichnis_person WHERE adressverzeichnis_person.alte_id = " old-id "));")))
+
+(defn phones-sql [phones old-id]
+  (str/join "\n" (map #(phone-sql % old-id) phones)))
+
+(defn person-sql [person]
+  (let [person (dissoc person :Gruppe :Älterengemeinschaft :Ordensgruppe :Amt :Ordensamt :Übergeordnetegruppe :Änderungsdatum :Hilfsgruppe
+                       :permissions)
+        fields (keys (dissoc person :address :numbers))
+        old-id (:alte_id person)]
+    (str
+     "INSERT INTO adressverzeichnis_person (" (str/join "," (map name fields)) ",erstellt,veraendert) VALUES (" (str/join "," (map #(format-value (get person %)) fields)) ",'now','now');"
+     (adress-sql (:address person) old-id)
+     (phones-sql (:numbers person) old-id))))
+
+(defn persons-sql [persons]
+  (let [persons (map #(dissoc % :Gruppe :ID :Älterengemeinschaft :Ordensgruppe :Amt :Ordensamt :Übergeordnetegruppe :Änderungsdatum :Hilfsgruppe
+                              :address :permissions :numbers) persons)]
+    []))
+
+(print (str/join "\n" (map (comp person-sql parse-person) old)))


Beer-song in clojure, first version passing tests.

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

--- clojure/beer-song/beer.clj
+++ clojure/beer-song/beer.clj
@@ -0,0 +1,37 @@
+(ns beer
+  (:require [clojure.string :as str]))
+
+(defn- count-string [count]
+  (cond
+    (= count 0) "no more bottles"
+    (= count 1) "1 bottle"
+    :else (str/join [count, " bottles"])))
+
+(defn- beer-string [count]
+  (if (= count 1)
+    "it"
+    "one"))
+
+(defn- first-strophe [count]
+  (str/capitalize
+    (str/join [(count-string count),
+      " of beer on the wall, ",
+      (count-string count),
+      " of beer."])))
+
+(defn- second-strophe [count]
+  (if (= 0 count)
+    "Go to the store and buy some more, 99 bottles of beer on the wall.\n"
+    (str/join ["Take ",
+      (beer-string count),
+      " down and pass it around, ",
+      (count-string (- count 1)),
+      " of beer on the wall.\n"])))
+
+(defn verse [count]
+  (str/join "\n" [(first-strophe count), (second-strophe count)]))
+
+(defn sing
+  ([begin] (sing begin 0))
+  ([begin,end]
+    (str/join [(str/join "\n" (map verse (range begin (- end 1) -1))) "\n"])))


Part 1 of Clojure complete

Part 1 of Clojure complete

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

--- palindrome.clj
+++ palindrome.clj
@@ -0,0 +1,3 @@
+(def input (seq (char-array (first *command-line-args*))))
+(defn palindrome? [s] (= s (reverse s)))
+(printf "%s%n" (palindrome? input))


send broadcast currently is a side-effect. There should be a better way to treat this as a pure function...

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


statsd reported

statsd reported

error: pathspec 'trackit-statsd/src/samsara/trackit/reporter_statsd.clj' did not match any file(s) known to git

--- trackit-statsd/src/samsara/trackit/reporter_statsd.clj
+++ trackit-statsd/src/samsara/trackit/reporter_statsd.clj
@@ -0,0 +1,98 @@
+(ns samsara.trackit.reporter
+  (:import  [java.util.concurrent TimeUnit]
+            [com.codahale.metrics MetricFilter])
+  (:require [metrics.reporters.console :as console]
+            #_[metrics.reporters.ganglia :as ganglia])
+  #_(:require [metrics.reporters.graphite :as graphite]
+            #_[metrics.reporters.ganglia :as ganglia])
+  #_(:import  [com.codahale.metrics.ganglia GangliaReporter]
+            [info.ganglia.gmetric4j.gmetric GMetric GMetric$UDPAddressingMode])
+  #_(:import  [com.codahale.metrics.riemann RiemannReporter Riemann]
+            [com.aphyr.riemann.client RiemannClient TcpTransport])
+
+  #_(:import  [com.bealetech.metrics.reporting StatsdReporter Statsd]))
+
+(defmulti start-reporting (fn [registry cfg] (:type cfg)))
+
+
+
+(defmethod start-reporting :default [registry cfg]
+  (println "TRACKit!: no reporting method selected."))
+
+
+
+(defmethod start-reporting :console
+  [registry
+   {:keys [reporting-frequency-seconds stream rate-unit duration-unit]
+    :or  {reporting-frequency-seconds 300, stream (System/err)
+          rate-unit TimeUnit/SECONDS, duration-unit TimeUnit/MILLISECONDS} :as cfg}]
+  (console/start
+   (console/reporter registry cfg)
+   reporting-frequency-seconds))
+
+
+(comment
+  (defmethod start-reporting :graphite
+    [registry
+     {:keys [reporting-frequency-seconds host port prefix rate-unit duration-unit]
+      :or  {reporting-frequency-seconds 10, host "localhost", port 2003, prefix "trackit"
+            rate-unit TimeUnit/SECONDS, duration-unit TimeUnit/MILLISECONDS} :as cfg}]
+    (require 'metrics.reporters.graphite)
+    (graphite/start
+     (graphite/reporter registry cfg)
+     reporting-frequency-seconds)))
+
+(comment
+  (defmethod start-reporting :statsd
+    [registry
+     {:keys [reporting-frequency-seconds host port prefix rate-unit duration-unit]
+      :or  {reporting-frequency-seconds 10, host "localhost", port 8125, prefix "trackit"
+            rate-unit TimeUnit/SECONDS, duration-unit TimeUnit/MILLISECONDS} :as cfg}]
+
+    (-> (StatsdReporter/forRegistry registry)
+        (.prefixedWith prefix)
+        (.convertDurationsTo duration-unit)
+        (.convertRatesTo rate-unit)
+        (.filter MetricFilter/ALL)
+        (.build (Statsd. host port))
+        (.start reporting-frequency-seconds TimeUnit/SECONDS))))
+
+
+(comment
+  (defmethod start-reporting :riemann
+    [registry
+     {:keys [reporting-frequency-seconds host port prefix rate-unit duration-unit]
+      :or  {reporting-frequency-seconds 10, host "localhost", port 5555, prefix "trackit"
+            rate-unit TimeUnit/SECONDS, duration-unit TimeUnit/MILLISECONDS} :as cfg}]
+
+    (let [;; tell Riemann client to do not cache the dns name
+          rc (Riemann.
+              (RiemannClient.
+               (doto
+                   (TcpTransport. host (int port))
+                 (-> .-cacheDns (.set false)))))]
+      (-> (RiemannReporter/forRegistry registry)
+          (.prefixedWith prefix)
+          (.convertDurationsTo duration-unit)
+          (.convertRatesTo rate-unit)
+          (.useSeparator ".")
+          (.filter MetricFilter/ALL)
+          (.build rc)
+          (.start reporting-frequency-seconds TimeUnit/SECONDS))))
+
+
+
+  (defmethod start-reporting :ganglia
+    [registry
+     {:keys [reporting-frequency-seconds host port prefix rate-unit duration-unit]
+      :or  {reporting-frequency-seconds 60, host "localhost", port 8649, prefix "trackit"
+            rate-unit TimeUnit/SECONDS, duration-unit TimeUnit/MILLISECONDS} :as cfg}]
+
+    (-> (GangliaReporter/forRegistry registry)
+        (.prefixedWith prefix)
+        (.convertDurationsTo duration-unit)
+        (.convertRatesTo rate-unit)
+        (.filter MetricFilter/ALL)
+        (.build (GMetric. host (int port) GMetric$UDPAddressingMode/MULTICAST 1))
+        (.start reporting-frequency-seconds TimeUnit/SECONDS)))
+  )


Clojure Collector: bump metrics-clojure to 2.10.0 (closes #3781)

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/liveintent-berlin/snowplow.git/'


Verifies all modules load outside the container [IMMUTANT-103]

The namespaces/immutant module serves two purposes: 1) as a convenient
way to pull in all the immutant namespaces and b) a means to test that
all modules can be loaded, albeit less functional, outside the
container.

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

--- namespaces/immutant/src/test/clojure/immutant/test/everything.clj
+++ namespaces/immutant/src/test/clojure/immutant/test/everything.clj
@@ -0,0 +1,28 @@
+;; Copyright 2008-2012 Red Hat, Inc, and individual contributors.
+;;
+;; This is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU Lesser General Public License as
+;; published by the Free Software Foundation; either version 2.1 of
+;; the License, or (at your option) any later version.
+;;
+;; This software is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+;; Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this software; if not, write to the Free
+;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+;; 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+
+(ns immutant.test.everything
+  (:require immutant.web
+            immutant.messaging
+            immutant.cache
+            immutant.jobs
+            immutant.daemons
+            immutant.xa)
+  (:use clojure.test))
+
+(deftest everything "Confirm all namespaces load when not running inside Immutant"
+  (is true "everything loaded"))


improve geocoding by reformatting intersections

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


New sample

New sample

error: pathspec '2016/multiple-dispatch/clojure/multi/src/multi/single_dispatch_mapkey.clj' did not match any file(s) known to git

--- 2016/multiple-dispatch/clojure/multi/src/multi/single_dispatch_mapkey.clj
+++ 2016/multiple-dispatch/clojure/multi/src/multi/single_dispatch_mapkey.clj
@@ -0,0 +1,25 @@
+; Eli Bendersky [http://eli.thegreenplace.net]
+; This code is in the public domain.
+(ns multi.single-dispatch-mapkey)
+
+; Single-dispatch multimethod, dispatching on the value of a key in a map.
+(defmulti promotion-due :position)
+
+(defmethod promotion-due :engineer
+  [emp] (> (:lines-of-code emp) 100000))
+
+(defmethod promotion-due :manager
+  [emp] (> (:num-reports emp) 10))
+
+; Works with records
+(defrecord Employee [name position num-reports lines-of-code])
+
+(promotion-due (Employee. "jim" :manager 12 0))
+(promotion-due (Employee. "sue" :engineer 0 98000))
+
+; And works with maps!
+(def joe {:name "joe", :position :manager, :num-reports 9})
+(def tim {:name "tim", :position :engineer, :lines-of-code 124000})
+
+(promotion-due joe)
+(promotion-due tim)


run database migrations on application startup.

--- src/metabase/core.clj
+++ src/metabase/core.clj
@@ -39,7 +39,9 @@
   [& args]
   (log/info "Launching Metabase in STANDALONE mode")

-  ;; TODO - startup database.  validates connection & runs any necessary migrations
+  ;; startup database.  validates connection & runs any necessary migrations
+  ;; TODO - allow for env configuration regarding migrations process
+  (db/setup true)

   ;; startup webserver
   ;; TODO - allow for env configuration


Add an index on the jars table.

Add an index on the jars table.

This time as a migration.

--- src/clojars/db/migrate.clj
+++ src/clojars/db/migrate.clj
@@ -13,6 +13,11 @@

 (defn add-promoted-field []
   (sql/do-commands "ALTER TABLE jars ADD COLUMN promoted_at DATE"))
+
+(defn add-jars-index []
+  ;; speed up the front page and selects for jars by name
+  (sql/do-commands (str "CREATE INDEX IF NOT EXISTS jars_idx0 "
+                        "ON jars (group_name, jar_name, created DESC)")))

 ;; migrations mechanics

@@ -44,4 +49,5 @@

 (defn -main []
   (migrate #'initial-schema
-           #'add-promoted-field))
+           #'add-promoted-field
+           #'add-jars-index))