remove conversations with only one status

--- src/statuses/backend/core.clj
+++ src/statuses/backend/core.clj
@@ -84,23 +84,29 @@
   [db]
   (count (:posts db)))

-(defn remove-from-conv
-  "Returns db with the update removed from a conversation"
-  [db id conv-id]
-  (let [conversation (get-in db [:conversations conv-id])
-        new-conversation (pop conversation)]
-    (if (seq new-conversation)
-      (assoc-in db [:conversations conv-id] new-conversation)
-      (assoc db :conversations (dissoc (:conversations db) conv-id)))))
-
 (defn remove-update
   "Returns db with the update with id removed"
   [db id]
-  (-> (if-let [conversation-id (get-in db [:posts id :conversation])]
-        (remove-from-conv db id conversation-id)
-        db)
-    (assoc :posts (dissoc (:posts db) id))
-    (assoc :timeline (remove #(= id %) (:timeline db)))))
+  (letfn [(rm-single [db id]
+            (-> db
+              (assoc :posts (dissoc (:posts db) id))
+              (assoc :timeline (remove #(= id %) (:timeline db)))))
+          (update-conv [db id conv-id]
+            (let [conv (get-in db [:conversations conv-id])
+                  new-conv (pop conv)
+                  conv-remains? (seq (pop new-conv))]
+              (if conv-remains?
+                (assoc-in db [:conversations conv-id] new-conv)
+                (let [last-status (peek new-conv)]
+                  (-> db
+                    (update-in [:conversations] dissoc conv-id)
+                    (update-in [:posts last-status] dissoc :conversation))))))]
+    (if-let [conv-id (get-in db [:posts id :conversation])]
+      (-> db
+        (update-conv id conv-id)
+        (rm-single id))
+      (-> db
+        (rm-single id)))))

 (defn add-testdata [db n]
   "Create a DB with a set of n test updates"


bump version and core version to 3.5.1

bump version and core version to 3.5.1

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


Upgrade to Clojure 1.8.0

Upgrade to Clojure 1.8.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/vincentstorme/clojureme.git/'


Update to latest NewRelic agent version

Update to latest NewRelic agent version

fatal: unable to access 'https://github.com/democracyworks/turbovote-http-api.git/': The requested URL returned error: 403


Log form filling errors

Log form filling errors

... but continue to fill the form

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


ensure our IO matches ttt protocol

ensure our IO matches ttt protocol

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/jassa/web-ttt.git/'


Adds a test for serialized exceptions.

Adds a test for serialized exceptions.

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

--- test/onyx/peer/serialized_exception_test.clj
+++ test/onyx/peer/serialized_exception_test.clj
@@ -0,0 +1,79 @@
+(ns onyx.peer.serialized-exception-test
+  (:require [clojure.core.async :refer [chan >!! <!! close! sliding-buffer]]
+            [clojure.test :refer [deftest is testing]]
+            [onyx.plugin.core-async :refer [take-segments!]]
+            [onyx.test-helper :refer [load-config with-test-env add-test-env-peers!]]
+            [onyx.extensions :as extensions]
+            [onyx.api]))
+
+(def n-messages 100)
+
+(def in-chan (atom nil))
+
+(def out-chan (atom nil))
+
+(defn inject-in-ch [event lifecycle]
+  {:core.async/chan @in-chan})
+
+(defn inject-out-ch [event lifecycle]
+  {:core.async/chan @out-chan})
+
+(def in-calls
+  {:lifecycle/before-task-start inject-in-ch})
+
+(def out-calls
+  {:lifecycle/before-task-start inject-out-ch})
+
+(defn my-inc [{:keys [n] :as segment}]
+  (throw (ex-info "Exception message" {:exception-data 42})))
+
+(deftest min-peers-test
+  (let [id (java.util.UUID/randomUUID)
+        config (load-config)
+        env-config (assoc (:env-config config) :onyx/id id)
+        peer-config (assoc (:peer-config config) :onyx/id id)]
+    (with-test-env [test-env [3 env-config peer-config]]
+      (let [batch-size 20
+            catalog [{:onyx/name :in
+                      :onyx/plugin :onyx.plugin.core-async/input
+                      :onyx/type :input
+                      :onyx/medium :core.async
+                      :onyx/batch-size batch-size
+                      :onyx/max-peers 1
+                      :onyx/doc "Reads segments from a core.async channel"}
+
+                     {:onyx/name :inc
+                      :onyx/fn ::my-inc
+                      :onyx/type :function
+                      :onyx/batch-size batch-size}
+
+                     {:onyx/name :out
+                      :onyx/plugin :onyx.plugin.core-async/output
+                      :onyx/type :output
+                      :onyx/medium :core.async
+                      :onyx/batch-size batch-size
+                      :onyx/max-peers 1
+                      :onyx/doc "Writes segments to a core.async channel"}]
+            workflow [[:in :inc] [:inc :out]]
+            lifecycles [{:lifecycle/task :in
+                         :lifecycle/calls ::in-calls}
+                        {:lifecycle/task :in
+                         :lifecycle/calls :onyx.plugin.core-async/reader-calls}
+                        {:lifecycle/task :out
+                         :lifecycle/calls ::out-calls}
+                        {:lifecycle/task :out
+                         :lifecycle/calls :onyx.plugin.core-async/writer-calls}]
+            _ (reset! in-chan (chan (inc n-messages)))
+            _ (reset! out-chan (chan (sliding-buffer (inc n-messages))))
+            _ (doseq [n (range n-messages)]
+                (>!! @in-chan {:n n}))
+            job-id (:job-id (onyx.api/submit-job
+                             peer-config
+                             {:catalog catalog
+                              :workflow workflow
+                              :lifecycles lifecycles
+                              :task-scheduler :onyx.task-scheduler/balanced}))]
+        (onyx.api/await-job-completion peer-config job-id)
+        (let [e (extensions/read-chunk (:log (:env test-env)) :exception job-id)]
+          (is (= "Exception message" (.getMessage e)))
+          (is (= {:exception-data 42} (ex-data e))))))))


Added package task to project.clj

Added package task to project.clj

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


Removed 0 as division candidate.

Removed 0 as division candidate.

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


mangos

mangos

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

--- src/hackerrank/lambda_calculi_jun14/mango.clj
+++ src/hackerrank/lambda_calculi_jun14/mango.clj
@@ -0,0 +1,34 @@
+(ns hackerrank.lambda-calculi-jun14.mango)
+
+;https://www.hackerrank.com/contests/lambda-calculi-jun14/challenges/mango
+
+(defn eaten
+  [invited appetite happiness]
+  (+' appetite (* (dec invited) happiness)))
+
+(defn min-mangos-k-friends
+  [k appetites happiness]
+  (reduce +' (take k (sort (map (partial eaten k) appetites happiness)))))
+
+(defn max-friends
+  [num-friends mangos appetites happinesses]
+  (loop [low 1 high num-friends]
+    (let [k (int (/ (+ high low) 2))
+          min-mangos-eaten (min-mangos-k-friends k appetites happinesses)]
+      (cond
+        (= mangos min-mangos-eaten) k
+        (and (= k high) (> mangos min-mangos-eaten))  k
+        (and (= k low) (< mangos min-mangos-eaten)) (dec k)
+        :else (let [[nl nh] (cond
+                              (> mangos min-mangos-eaten) [(inc k) high]
+                              :else [low k])]
+                (recur nl nh))))))
+
+(defn parse-vec [] (read-string (str "[" (read-line) "]")))
+
+(defn -main
+  []
+  (let [[num-friends mangos] (parse-vec)
+        appetites (parse-vec)
+        happinesses (parse-vec)]
+    (println (max-friends num-friends mangos appetites happinesses))))


Cache all upcoming elections

Cache all upcoming elections

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


Typos.

Typos.

--- src/sablono/util.cljx
+++ src/sablono/util.cljx
@@ -18,7 +18,7 @@
   (apply str (map to-str xs)))

 (defn camel-case
-  "Returns camelcased version of the key, e.g. :http-equiv becomes :httpEquiv."
+  "Returns camel case version of the key, e.g. :http-equiv becomes :httpEquiv."
   [k]
   (if k
     (let [[first-word & words] (split (name k) #"-")]
@@ -48,7 +48,7 @@
    m (keys m)))

 (defn merge-with-class
-  "Like clojure.core/merge but concat :class entries."
+  "Like clojure.core/merge but concatenate :class entries."
   [& maps]
   (let [classes (->> (mapcat #(cond
                                (list? %1) [%1]
@@ -65,7 +65,7 @@
   [s] (if s (replace s #"^[.#]" "")))

 (defn match-tag
-  "Match `s` as a CSS tag and return a vecotr of tag name, CSS id and
+  "Match `s` as a CSS tag and return a vector of tag name, CSS id and
   CSS classes."
   [s]
   (let [[tag-name & matches] (re-seq #"[#.]?[^#.]+" (name s))]


Increased ArrayBlockingQueue timeout value from 1 minute to 10 minutes.

fatal: unable to access 'https://github.com/mschmele/Common-Metadata-Repository.git/': The requested URL returned error: 403


Use ReactDOM.render in benchmark to remove warning

--- test/sablono/benchmark.cljs
+++ test/sablono/benchmark.cljs
@@ -1,5 +1,7 @@
 (ns sablono.benchmark
   (:require [cljsjs.jquery]
+            [cljsjs.react]
+            [cljsjs.react.dom]
             [cljs.test :refer-macros [is deftest testing]]
             [crate.core :as crate]
             [goog.dom :as gdom]
@@ -76,7 +78,7 @@
   (let [render-fn #(this-as this (html [:ul children]))
         component (js/React.createFactory
                    (js/React.createClass #js {:render render-fn}))]
-    (js/React.render (component) root)))
+    (js/ReactDOM.render (component) root)))

 (defn time-test [data]
   (for [[key li-fn render-fn]


clojure algorithm

clojure algorithm

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


Add tests for cljam.dict

Add tests for cljam.dict

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


warning handlers

warning handlers

--- sidecar/src/figwheel_sidecar/config_check/validate_config.clj
+++ sidecar/src/figwheel_sidecar/config_check/validate_config.clj
@@ -206,7 +206,9 @@
             :notify-command  [string?]
             :jar             (ref-schema 'Boolean)
             :incremental     (ref-schema 'Boolean)
-            :assert          (ref-schema 'Boolean) })
+            :assert          (ref-schema 'Boolean)
+            :warning-handlers [anything?]
+           })
     (assert-not-empty 'BuildOptionsMap :source-paths)
     (requires-keys 'BuildOptionsMap :source-paths :compiler)
     (or-spec 'FigwheelClientOptions
@@ -310,25 +312,11 @@

 #_ (with-color
      (validate-project-config
-   {:cljsbuild
-    {:builds { :source-paths ["src" ]
-              :fighweel true
-              :compiler {}}
-
-                                        }
-    :figwheel {}
-                            }
-                           ))
-
-#_(defn tester [conf]
-    (with-schema (validate-regular-rules {:figwheel {}})
-      (tc/tc-with-parent 'RootMap conf)
-      #_(doall (tc/document-all 'BuildOptionsMap [:compiler]))
-      (doall (tc/get-example-for-key 'RootMap :cljsbuild))
-      #_(doall (tc/docs-for 'BuildOptionsMap :compiler))
-    ))
-
-#_(tester {:fighweel {:css-dirs []}})
+      {:cljsbuild
+       {:builds { :source-paths ["src" ]
+                 :fighweel true
+                 :compiler {}}}
+       :figwheel {}}))

 (defn validate-figwheel-edn-file [config]
   (print-one-error (validate-figwheel-edn-rules config)


don't say too much in the comments

don't say too much in the comments

--- src/metabase/driver/h2.clj
+++ src/metabase/driver/h2.clj
@@ -121,16 +121,14 @@
 (defn- wrap-process-query-middleware [_ qp]
   (fn [{query-type :type, :as query}]
     {:pre [query-type]}
-    ;; For :native queries check to make sure the DB in question has a NAME property specified in the connection string.
-    ;; We don't want to allow SQL queries on DBs connected with the default H2 admin account because they have access
-    ;; to potentially unsafe functions like FILEREAD and FILEWRITE.
-    ;; Assume any specified non-default USER for this H2 database doesn't have admin privs
+    ;; For :native queries check to make sure the DB in question has a (non-default) NAME property specified in the connection string.
+    ;; We don't allow SQL execution on H2 databases for the default admin account for security reasons
     (when (= (keyword query-type) :native)
       (let [{:keys [db]}   (db/sel :one :field [Database :details] :id (:database query))
             _              (assert db)
             [_ options]    (connection-string->file+options db)
             {:strs [USER]} options]
-        (when (or (not USER)
+        (when (or (s/blank? USER)
                   (= USER "sa")) ; "sa" is the default USER
           (throw (Exception. "Running SQL queries against H2 databases using the default (admin) database user is forbidden.")))))
     (qp query)))


Now debug-prn does not print to error but just calls println

fatal: unable to access 'https://github.com/Lambda-X/replumb.git/': The requested URL returned error: 403


Update reup

Update reup

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


remove TODO about what we just did

remove TODO about what we just did

--- src/metabase/db.clj
+++ src/metabase/db.clj
@@ -172,9 +172,6 @@
 ;; TODO - It would be good to allow custom types by just inserting the `{:in fn :out fn}` inline with the
 ;; entity definition

-;; TODO - It would be nice to be able to say an entity is "timestamped" and have created_at / updated_at taken
-;; care of automatically
-
 ;; TODO - hydration-keys should be an entity function for the sake of prettiness


Add allow headers to CORS middleware

Add allow headers to CORS 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/physion/ovation-webapi.git/'


remove exception handling

remove exception handling

fatal: unable to access 'https://github.com/starcity-properties/odin.git/': The requested URL returned error: 403


STORM-1925 Remove Nimbus thrift call from Nimbus itself

* Nimbus fails to start in secure mode since authrization is not passed
* Extract the logic of getClusterInfo to new function 'get-cluster-info'
  * and let both of callers call this function instead

fatal: unable to access 'https://github.com/hmcl/storm-apache.git/': The requested URL returned error: 403


doc-generator: add cljs special-form parsing

--- scripts/cljs-api-parser/src/core.clj
+++ scripts/cljs-api-parser/src/core.clj
@@ -29,7 +29,8 @@
 (def cljs-ns-paths
   ; NS                        REPO             FILE               PATH IN REPO
   {"cljs.core"              {"clojurescript" {"core.cljs"        "src/cljs/cljs"
-                                              "core.clj"         "src/clj/cljs"}
+                                              "core.clj"         "src/clj/cljs"
+                                              "analyzer.clj"     "src/clj/cljs"}
                              "clojure"       {"core.clj"         "src/clj/clojure"
                                               "core_deftype.clj" "src/clj/clojure"
                                               "core_print.clj"   "src/clj/clojure"
@@ -298,6 +299,26 @@
           final (update-in merged [:source] try-remove-docs (:expected-docs specific))]
       final)))

+(defn parse-special*
+  "Parse cljs special forms of the form:
+  (defmethod parse 'symbol ...)"
+  [form]
+  (when (and (list? form)
+             (= 'defmethod (first form))
+             (= 'parse (second form)))
+    (let [quoted-name (nth form 2)
+          name- (second quoted-name)]
+      {:name name-})))
+
+(defn parse-special
+  [form ns- repo]
+  (when-let [special (parse-special* form)]
+    (let [location (parse-location form ns- repo)
+          extras {:full-name (str ns- "/" (:name special))
+                  :type "special form"}
+          final (merge special location extras)]
+      final)))
+
 (defn parse-api
   "Parse the functions and macros from the given repo file"
   [ns- repo file]
@@ -325,6 +346,7 @@
 (defmulti parse-ns-api (fn [ns-] ns-))

 (defn parse-extra-macros-from-clj
+  "cljs.core uses some macros from clojure.core, so find those here"
   []
   (let [clj-api (concat (parse-api "cljs.core" "clojure" "core.clj")
                         (parse-api "cljs.core" "clojure" "core_deftype.clj")
@@ -334,15 +356,26 @@
         cljs-forms   (get-forms "cljs.core" "clojurescript" "core.clj")
         imports      (get-imported-macro-api     cljs-forms clj-api)
         non-excludes (get-non-excluded-macro-api cljs-forms clj-api)]
-    (println "   " (count imports) "imported clojure.core macros")
-    (println "   " (count non-excludes) "non-excluded clojure.core macros")
+    (println "   " (count imports) "macros imported from clojure.core")
+    (println "   " (count non-excludes) "macros non-excluded clojure.core")
     (concat imports non-excludes)))
+
+(defn parse-cljs-special-forms
+  "cljs.core has some special forms defined in analyzer.clj, so find those here"
+  []
+  (let [ns- "cljs.core"
+        repo "clojurescript"
+        forms (get-forms ns- repo "analyzer.clj")
+        specials (keep #(parse-special % ns- repo) forms)]
+    (println "   " (count specials) "special forms in cljs.analyzer")
+    specials))

 (defmethod parse-ns-api "cljs.core" [ns-]
   (let [clj-api  (parse-api ns- "clojurescript" "core.clj")
         cljs-api (parse-api ns- "clojurescript" "core.cljs")
-        extra-macro-api (parse-extra-macros-from-clj)]
-    (concat extra-macro-api clj-api cljs-api)))
+        extra-macro-api (parse-extra-macros-from-clj)
+        special-forms (parse-cljs-special-forms)]
+    (concat extra-macro-api clj-api cljs-api special-forms)))

 (defmethod parse-ns-api "cljs.reader" [ns-]
   (parse-api ns- "clojurescript" "reader.cljs"))


chore: set pool-max-queue-size default to 100

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


create schema and test it

create schema and test it

error: pathspec 'datomic-dsl/create_test.clj' did not match any file(s) known to git

--- datomic-dsl/create_test.clj
+++ datomic-dsl/create_test.clj
@@ -0,0 +1,29 @@
+;;lein test :only datomic-dsl.create-test
+(ns datomic-dsl.create-test
+  (:require [clojure.test :refer :all]
+            [datomic-dsl.create :refer :all]
+            [datomic-dsl.common-test :refer :all]
+            [clojure.pprint :refer :all]
+            [datomic.api :as d]))
+
+(def book-schema
+  "Use the API to create some Datomic schema syntax.
+  Add a pprint to see what this looks like."
+  (vec
+   (create-schema "book"
+                  "title" "string"
+                  "author" "string")))
+
+;; (pprint book-schema)
+
+(def trans-result
+  "Add the schema to the database. Save the result in a symbol if we need to look at it."
+  (d/transact conn book-schema))
+
+(def book-schema-query-result
+  "Query the schema to see if it exists - schemas are entities too"
+  (d/touch (d/entity (d/db conn) :book/title)))
+
+(deftest schema-created-test
+  (testing "Is the schema created with a book title?"
+    (is book-schema-query-result)))


Refactor for clarity

Refactor for clarity


clojure

clojure

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/luoxing91/elcc.git/'


Programmes space & redundancy tidy up.

Programmes space & redundancy tidy up.

--- src/kixi/hecuba/api/programmes.clj
+++ src/kixi/hecuba/api/programmes.clj
@@ -39,11 +39,11 @@
       {::programme_id programme_id})))

 (defn index-handle-created [ctx]
-    (let [request (:request ctx)
-          location (format programme-resource (::programme_id ctx))]
-      (ring-response {:headers {"Location" location}
-                      :body (json/encode {:location location
-                                          :status "OK" :version "4"})})))
+  (let [request  (:request ctx)
+        location (format programme-resource (::programme_id ctx))]
+    (ring-response {:headers {"Location" location}
+                    :body (json/encode {:location location
+                                        :status "OK" :version "4"})})))

 (defn resource-exists? [store ctx]
   (db/with-session [session (:hecuba-session store)]
@@ -55,12 +55,10 @@

 (defn resource-handle-ok [ctx]
   (let [request (:request ctx)]
-      (util/render-item request
-                        (as-> (::item ctx) item
-                              (dissoc item :user_id)
-                              (assoc item
-                                :projects (format programme-projects-index (:id item)))
-                              (dissoc item :user_id)))))
+    (util/render-item request
+                      (as-> (::item ctx) item
+                            (dissoc item :user_id)
+                            (assoc item :projects (format programme-projects-index (:id item)))))))

 (defresource index [store]
   :allowed-methods #{:get :post}


add internal name to service creation resolver

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


递归的问题,交给王垠的模式匹配和递归

递归的问题,交给王垠的模式匹配和递归

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


don’t need to pass the id in the create slot route

fatal: unable to access 'https://github.com/nilenso/finenso-time-tracker.git/': The requested URL returned error: 403


Add lib for shared test functions

Add lib for shared test functions

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


removed print

removed print

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/m1dnight/clojbot.git/'


Added fuzzy sets

Added fuzzy sets

Signed-off-by: Daniel Borchmann <25857343a15bf1edafebc2912e82ecf775c585c1@mailbox.tu-dresden.de>

error: pathspec 'src/conexp/contrib/fuzzy/sets.clj' did not match any file(s) known to git

--- src/conexp/contrib/fuzzy/sets.clj
+++ src/conexp/contrib/fuzzy/sets.clj
@@ -0,0 +1,83 @@
+;; Copyright (c) Daniel Borchmann. All rights reserved.
+;; The use and distribution terms for this software are covered by the
+;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;; which can be found in the file LICENSE at the root of this distribution.
+;; By using this software in any fashion, you are agreeing to be bound by
+;; the terms of this license.
+;; You must not remove this notice, or any other, from this software.
+
+(ns conexp.contrib.fuzzy.sets
+  (:use conexp.main))
+
+(ns-doc "Basic definitions for fuzzy sets")
+
+(set! *warn-on-reflection* true)
+
+;;;
+
+(deftype Fuzzy-Set [^clojure.lang.PersistentHashMap hashmap]
+  ;;
+  Object
+  (equals [this other]
+    (boolean (or (identical? this other)
+                 (when (= (class this) (class other))
+                   (let [ohashmap (.hashmap ^Fuzzy-Set other)]
+                     (and (forall [k (keys hashmap)]
+                            (=> (not (zero? (hashmap k)))
+                                (= (hashmap k) (ohashmap k))))
+                          (forall [k (keys ohashmap)]
+                            (=> (not (zero? (ohashmap k)))
+                                (= (hashmap k) (ohashmap k))))))))))
+  (hashCode [this]
+    (hash-combine-hash Fuzzy-Set hashmap))
+  (toString [this]
+    (str hashmap))
+  ;;
+  clojure.lang.ISeq
+  (first [this]
+    (first hashmap))
+  (next [this]
+    (next hashmap))
+  (more [this]
+    (if-let [n (next hashmap)]
+      n
+      ()))
+  (cons [this o]
+    (if (zero? (second o))
+      this
+      (Fuzzy-Set. (conj hashmap o))))
+  (seq [this]
+    (seq hashmap))
+  (count [this]
+    (count hashmap))
+  (empty [this]
+    (Fuzzy-Set. {}))
+  (equiv [this other]
+    (.equals ^Fuzzy-Set this other))
+  ;;
+  clojure.lang.IFn
+  (invoke [this thing]
+    (let [result (hashmap thing)]
+      (or result 0)))
+  (applyTo [this seq]
+    (if (= 1 (count seq))
+      (.applyTo hashmap seq)
+      (illegal-argument "Cannot apply fuzzy sets to non-singleton sequences."))))
+
+(defn make-fuzzy-set
+  "Constructs a fuzzy set from a given hashmap. The values must be
+  numbers between 0 (exclusive) and 1 (inclusive)."
+  [hashmap]
+  (assert (forall [[k v] hashmap]
+            (and (number? v)
+                 (< 0 v)
+                 (<= v 1))))
+  (Fuzzy-Set. hashmap))
+
+(defmethod print-method Fuzzy-Set [set out]
+  (.write ^java.io.Writer out
+          ^String (str "#F" set)))
+
+;;;
+
+nil


Allow :form-params for :put requests also.

--- src/clj_http/client.clj
+++ src/clj_http/client.clj
@@ -251,7 +251,7 @@

 (defn wrap-form-params [client]
   (fn [{:keys [form-params request-method] :as req}]
-    (if (and form-params (= :post request-method))
+    (if (and form-params (#{:post :put} request-method))
       (client (-> req
                   (dissoc :form-params)
                   (assoc :content-type (content-type-value


GM: Add forms-state and utilities

GM: Add forms-state and utilities

fatal: unable to access 'https://github.com/onaio/zebra-lite.git/': The requested URL returned error: 403


handlers registered with name

handlers registered with name


works for a simple single strand DNA.

works for a simple single strand DNA.

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

--- clojure/rna-transcription/dna.clj
+++ clojure/rna-transcription/dna.clj
@@ -0,0 +1,6 @@
+(ns dna)
+
+(defn to-rna [dna-seq]
+  (let
+      [dna-to-rna {"G" "C", "C" "G", "T" "A", "A" "U"}]
+    (dna-to-rna dna-seq)))


day 21 not working

day 21 not working

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

--- src/adventofcode/day21.clj
+++ src/adventofcode/day21.clj
@@ -0,0 +1,75 @@
+(ns adventofcode.day21
+  (:require [clojure.math.combinatorics :as combo]))
+
+(def boss {:hp 103
+           :damage 9
+           :armor 2})
+
+(def me {:hp 100
+         :damage 0
+         :armor 0
+         :cost 0})
+
+(def shop {:weapons [{:name "dagger" :cost 8 :damage 4 :armor 0}
+                     {:name "shortsword" :cost 10 :damage 5 :armor 0}
+                     {:name "warhammer" :cost 25 :damage 6 :armor 0}
+                     {:name "longsword" :cost 40 :damage 7 :armor 0}
+                     {:name "greataxe" :cost 74 :damage 8 :armor 0}]
+           :armor [{:name "shirt" :cost 0 :damage 0 :armor 0}
+                   {:name "leather" :cost 13 :damage 0 :armor 1}
+                   {:name "chainmail" :cost 31 :damage 0 :armor 2}
+                   {:name "splintmail" :cost 53 :damage 0 :armor 3}
+                   {:name "bandedmail" :cost 75 :damage 0 :armor 4}
+                   {:name "platemail" :cost 102 :damage 0 :armor 5}]
+           :rings [{:name "damage +1" :cost 25 :damage 1 :armor 0}
+                   {:name "damage +2" :cost 50 :damage 2 :armor 0}
+                   {:name "damage +3" :cost 100 :damage 3 :armor 0}
+                   {:name "defence +1" :cost 20 :damage 0 :armor 1}
+                   {:name "defence +2" :cost 40 :damage 0 :armor 2}
+                   {:name "defence +3" :cost 80 :damage 0 :armor 3}]})
+
+(defn win? [me boss]
+  (<= (/ (:hp boss) (max 1 (- (:damage me) (:armor boss))))
+      (/ (:hp me) (max 1 (- (:damage boss) (:armor me))))))
+
+(defn win-2? [me boss]
+  (let [my-damage (max 1 (- (:damage me) (:armor boss)))
+        boss-damage (max 1 (- (:damage boss) (:armor me)))]
+    (loop [my-hp (:hp me)
+           boss-hp (:hp boss)]
+      (if (> 0 (- boss-hp my-damage))
+        true
+        (if (> 0 (- my-hp boss-damage))
+          false
+          (recur (- my-hp boss-damage) (- boss-hp my-damage)))))))
+
+(comment (win-2? {:hp 8 :damage 5 :armor 5}
+                 {:hp 12 :damage 7 :armor 2}))
+
+(comment (win-2? {:hp 100 :damage 7 :armor 4}
+                 boss))
+
+(defn apply-items [items]
+  (reduce #(-> %1
+               (update :cost + (:cost %2))
+               (update :damage + (:damage %2))
+               (update :armor + (:armor %2)))
+          me
+          items))
+
+(comment (apply-items [{:cost 10 :damage 10 :armor 10}
+                       {:cost 1 :damage 1 :armor 1}]))
+
+(comment (->>
+          (for [weapon (:weapons shop)
+                armor (:armor shop)
+                rings (filter #(<= (count %) 2) (combo/subsets (:rings shop)))
+                :let [items (concat [weapon armor] rings)
+                      new-me (apply-items items)]
+                :when (win-2? new-me boss)]
+            [new-me items])
+          (sort-by (comp :cost first))
+          first
+          clojure.pprint/pprint
+          #_(map :cost)
+          #_(apply min)))


Factored out harvest-handler, added failure logic

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


Solved problem 1 in Clojure.

Solved problem 1 in Clojure.

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/tokyo-jesus/university.git/'


alternative locally-nameless term implementation (faster ?)

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

--- src/latte/kernel/nsyntax.clj
+++ src/latte/kernel/nsyntax.clj
@@ -0,0 +1,377 @@
+
+(ns latte.kernel.nsyntax
+  "This is an alternative representation of terms
+using a locally-nameless approach."
+  (:require [clj-by.example :refer [example do-for-example]]
+            [clojure.set :as set]))
+
+(def +examples-enabled+ true)
+
+(defn kind? [t]
+  (= t '□))
+
+(defn type? [t]
+  (= t '✳))
+
+(defn sort? [t]
+  (or (kind? t)
+      (type? t)))
+
+(defn variable? [t]
+  (symbol? t))
+
+(defprotocol Term
+  "The generic functions for terms."
+  (free-vars [t]
+    "The free variable symbols of term `t`.")
+  (open-term [t k x]
+    "Open the term `t` at level `k` with variable `x` ")
+  (close-term [t k x]
+    "Close the term `t` at level `k` for free variable named `x`")
+  (subst-term [t s]
+    "Apply substitution `s` to type `t`.")
+  (apply-to-term [t k u]
+    "Apply term `u` to term `t` at level `k` (in beta-reduction)")
+  (unparse-term [t k bmap forbid]
+    "Unparse term `t` at level `k` with `bmap` map of bound variable and `forbid`den names.")
+  (unparse-ln-term [t]
+    "Unparse as locally-nameless term `t`."))
+
+(defn open
+  "Open term `t` with variable `x`."
+  [t x]
+  (open-term t 0 x))
+
+(defn close
+  "Close term `t` for free variable named `x`."
+  [t x]
+  (close-term t 0 x))
+
+(defn subst
+  "Apply substitution `s` to type `t`."
+  ([t x u] (subst-term t {x u}))
+  ([t s] (subst-term t s)))
+
+(defn apply-term
+  "Apply term `u` to term `t` at level `k` (in beta-reduction)."
+  ([t u] (apply-to-term t 0 u))
+  ([t k u] (apply-to-term t k u)))
+
+(defn unparse
+  "Unparse term `t`."
+  [t]
+  (unparse-term t 0 {} (free-vars t)))
+
+(defn unparse-ln
+  "Unparse term `t` in a locally-nameless way."
+  [t]
+  (unparse-ln-term t))
+
+(extend-type Object
+  Term
+  ;; no free variables by default
+  (free-vars [_] #{})
+  ;; the default opening and closing are identity
+  (open-term [t _ _] t)
+  (close-term [t _ _] t)
+  (subst-term [t _] t)
+  (apply-to_term [t _ _] t)
+  ;; the default unparse is identity
+  (unparse-term [t _ _ _] t)
+  (unparse-ln-term [t] t))
+
+(defn mk-fresh
+  ([base forbid] (mk-fresh base 0 forbid))
+  ([base level forbid]
+   (if-not (contains? forbid base)
+     base
+     (let [suffix (case level
+                    0 ""
+                    1 "'"
+                    2 "''"
+                    3 "'''"
+                    (str "-" level))
+           candidate (symbol (str base suffix))]
+       (if (contains? forbid candidate)
+         (recur base (inc level) forbid)
+         candidate)))))
+
+(example
+ (mk-fresh 'x '#{x1 x2}) => 'x)
+
+(example
+ (mk-fresh 'x '#{x x' x''}) => 'x''')
+
+(example
+ (mk-fresh 'x '#{x x' x'' x'''}) => 'x-4)
+
+(defrecord FVar [name]
+  Term
+  (free-vars [t] #{(:name t)})
+  (open-term [t _ _] t)
+  (close-term [t k x] (if (= (:name t) x)
+                        (mk-bvar k)
+                        t))
+  (subst-term [t s] (if-let [u (get s (:name t))]
+                      u
+                      t))
+  (unparse-term [t _ _ _] (:name t))
+  (unparse-ln-term [t] (:name t)))
+
+(defn mk-fvar [x] (->FVar x))
+
+(example
+ (open-term (mk-fvar 'x) 2 'y)
+ => (mk-fvar 'x))
+
+(example
+ (close-term (mk-fvar 'x) 2 'x)
+ => (mk-bvar 2))
+
+(example
+ (close-term (mk-fvar 'x) 2 'y)
+ => (mk-fvar 'x))
+
+(example
+ (unparse (mk-fvar 'x)) => 'x)
+
+(defrecord BVar [index]
+  Term
+  (free-vars [t] #{})
+  (open-term [t k x]
+    (if (= (:index t) k)
+      (mk-fvar x)
+      t))
+  (close-term [t _ _] t)
+  (apply-to-term [t k u]
+    (if (= k (:index t))
+      u
+      t))
+  (unparse-term [t _ bmap _]
+    (if-let [bname (get bmap (:index t))]
+      bname
+      (keyword (str (:index t)))))
+  (unparse-ln-term [t]
+    (keyword (str (:index t)))))
+
+(defn mk-bvar [index]
+  (->BVar index))
+
+(example
+ (open-term (mk-bvar 2) 2 'y)
+ => (mk-fvar 'y))
+
+(example
+ (open-term (mk-bvar 1) 2 'y)
+ => (mk-bvar 1))
+
+(example
+ (close-term (mk-bvar 1) 1 'x)
+ => (mk-bvar 1))
+
+(example
+ (unparse (mk-bvar 1)) => :1)
+
+(defrecord Lambda [name type body]
+  Term
+  (free-vars [t] (free-vars (:body t)))
+  (open-term [t k x]
+    (->Lambda (mk-fresh (:name t) #{x}) (open-term (:type t) k x)
+              (open-term (:body t) (inc k) x)))
+  (close-term [t k x]
+    (->Lambda (:name t) (close-term (:type t) k x)
+              (close-term (:body t) (inc k) x)))
+  (subst-term [t s]
+    (->Lambda (:name t) (subst-term (:type t) s)
+              (subst-term (:body t) s)))
+  (apply-to-term [t k u]
+    (->Lambda (:name t) (apply-to-term (:type t) k u)
+              (apply-to-term (:body t) (inc k) u)))
+  (unparse-term [t k bmap forbid]
+    (let [name (mk-fresh (:name t) forbid)])
+    (list 'λ [name (unparse-term (:type t) k bmap forbid)]
+          (unparse-term (:body t)
+                        (inc k)
+                        (assoc bmap k name)
+                        (conj forbid name))))
+  (unparse-ln-term [t]
+    (list 'λ [(unparse-ln-term (:type t))]
+          (unparse-ln-term (:body t)))))
+
+(defn mk-lambda [name type body]
+  (->Lambda name type body))
+
+(example
+ (open-term (mk-lambda 'x '□ (mk-bvar 3)) 2 'y)
+ => (mk-lambda 'x '□ (mk-fvar 'y)))
+
+(example
+ (close-term (mk-lambda 'x '□ (mk-fvar 'y)) 2 'y)
+ => (mk-lambda 'x '□ (mk-bvar 3)))
+
+(example
+ (unparse (mk-lambda 'x '□ (mk-bvar 0)))
+ => '(λ [x □] x))
+
+(example
+ (unparse (mk-lambda 'x '□ (mk-bvar 1)))
+ => '(λ [x □] :1))
+
+(defrecord Prod [name type body]
+  Term
+  (free-vars [t] (free-vars (:body t)))
+  (open-term [t k x]
+    (->Prod (mk-fresh (:name t) #{x}) (open-term (:type t) k x)
+              (open-term (:body t) (inc k) x)))
+  (close-term [t k x]
+    (->Prod (:name t) (close-term (:type t) k x)
+            (close-term (:body t) (inc k) x)))
+  (subst-term [t s]
+    (->Prod (:name t) (subst-term (:type t) s)
+              (subst-term (:body t) s)))
+  (apply-to-term [t k u]
+    (->Prod (:name t) (apply-to-term (:type t) k u)
+              (apply-to-term (:body t) (inc k) u)))
+  (unparse-term [t k bmap forbid]
+    (let [name (mk-fresh (:name t) forbid)])
+    (list 'Π [name (unparse-term (:type t) k bmap forbid)]
+          (unparse-term (:body t)
+                        (inc k)
+                        (assoc bmap k name)
+                        (conj forbid name))))
+  (unparse-ln-term [t]
+    (list 'Π [(unparse-ln-term (:type t))]
+          (unparse-ln-term (:body t)))))
+
+(defn mk-prod [name type body]
+  (->Prod name type body))
+
+(example
+ (open-term (mk-prod 'x '□ (mk-bvar 3)) 2 'y)
+ => (mk-prod 'x '□ (mk-fvar 'y)))
+
+(example
+ (close-term (mk-prod 'x '□ (mk-fvar 'y)) 2 'y)
+ => (mk-prod 'x '□ (mk-bvar 3)))
+
+(example
+ (unparse (mk-prod 'x '□ (mk-bvar 0)))
+ => '(Π [x □] x))
+
+(example
+ (unparse (mk-prod 'x '□ (mk-bvar 1)))
+ => '(Π [x □] :1))
+
+(declare app?)
+(defrecord App [left right]
+  Term
+  (free-vars [t]
+    (clojure.set/union (free-vars (:left t))
+                       (free-vars (:right t))))
+  (open-term [t k x]
+    (->App (open-term (:left t) k x)
+           (open-term (:right t) k x)))
+  (close-term [t k x]
+    (->App (close-term (:left t) k x)
+           (close-term (:right t) k x)))
+  (subst-term [t s]
+    (->App (subst-term (:left t) s)
+           (subst-term (:right t) s)))
+  (apply-to-term [t k u]
+    (->App (apply-to-term (:left t) k u)
+           (apply-to-term (:right t) k u)))
+  (unparse-term [t k bmap forbid]
+    (let [left (unparse-term (:left t) k bmap forbid)
+          right (unparse-term (:right t) k bmap forbid)]
+      (if (app? (:left t))
+        (concat left (list right))
+        (list left right))))
+  (unparse-ln-term [t]
+    (let [left (unparse-ln-term (:left t))
+          right (unparse-ln-term (:right t))]
+      (if (app? (:left t))
+        (concat left (list right))
+        (list left right)))))
+
+(defn mk-app
+  ([right] right)
+  ([left right & others]
+   (let [app (->App left right)]
+     (if (seq others)
+       (apply mk-app app others)
+       app))))
+
+(example (mk-app 'x) => 'x)
+
+(example
+ (mk-app 'a 'b) => '#latte.kernel.nsyntax.App{:left a, :right b})
+
+(example
+ (mk-app 'a 'b 'c)
+ => '#latte.kernel.nsyntax.App{:left #latte.kernel.nsyntax.App{:left a, :right b},
+                               :right c})
+
+(example
+ (mk-app 'a 'b 'c 'd)
+ => '#latte.kernel.nsyntax.App{:left #latte.kernel.nsyntax.App{:left #latte.kernel.nsyntax.App{:left a, :right b},
+                                                               :right c},
+                               :right d})
+
+(defn app? [v]
+  (instance? App v))
+
+(example
+ (app? (mk-app 'x 'y)) => true)
+
+(example
+ (app? (mk-lambda 'x 'ty 'x)) => false)
+
+(example
+ (app? '(1 2)) => false)
+
+(example
+ (free-vars (mk-app (mk-fvar 'x)
+                    (mk-fvar 'y)))
+ => '#{x y})
+
+(example
+ (unparse
+  (open (mk-app (mk-lambda 'x '□ (mk-app (mk-bvar 1)
+                                         (mk-bvar 0)))
+                (mk-bvar 0)) 'z))
+ => '((λ [x □] (z x)) z))
+
+(example
+ (unparse
+  (open (mk-app (mk-lambda 'x '□ (mk-app (mk-bvar 1)
+                                         (mk-bvar 0)))
+                (mk-bvar 0)) 'x))
+ => '((λ [x' □] (x x')) x))
+
+(example
+ (unparse
+  (close (mk-app (mk-lambda 'x '□ (mk-app (mk-fvar 'x)
+                                          (mk-fvar 'x)))
+                 (mk-bvar 0)) 'x))
+ => '((λ [x □] (:1 :1)) :0))
+
+(example
+ (unparse
+  (close (mk-app (mk-lambda 'x '□ (mk-app (mk-fvar 'x)
+                                          (mk-fvar 'z)))
+                 (mk-bvar 0)) 'z))
+ => '((λ [x □] (x :1)) :0))
+
+(example
+ (unparse
+  (mk-app 'x 'y (mk-app 'z 't)))
+ => '(x y (z t)))
+
+
+(defn alpha-eq? [t1 t2]
+  (= (unparse-ln-term t1)
+     (unparse-ln-term t2)))
+
+(example
+ (alpha-eq? (mk-lambda 'x '✳ (mk-bvar 0))
+            (mk-lambda 'y '✳ (mk-bvar 0))) => true)


better wiring of modal, persist selections, prepare for svc card


add optimise namespace

add optimise namespace

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

--- src/cortex/optimise.clj
+++ src/cortex/optimise.clj
@@ -0,0 +1,6 @@
+(ns cortex.optimise
+  "Namespace for optimisation algorithms and optimiser objects"
+  (:require [cortex.protocols :as cp])
+  (:require [cortex.util :as util :refer [error]])
+  (:require [clojure.core.matrix :as m]))
+


[TH] fix log string spacing

[TH] fix log string spacing

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


RFC6979 Deterministic signatures, BitCoin recovery bytes

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


v/wmeta-fn macros

v/wmeta-fn macros

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


Remove :data from schema validation errors

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


Support setting bar colors

Support setting bar colors

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/dignati/om-charts.git/'


added compilation file

added compilation file

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

--- src/paredit/compile.clj
+++ src/paredit/compile.clj
@@ -0,0 +1,8 @@
+(ns paredit.compile)
+
+(defn all []
+  (compile 'paredit.loc-utils)
+  (compile 'paredit.text-utils)
+  (compile 'paredit.parser)
+  (compile 'paredit.core-commands)
+  (compile 'paredit.core))


Add mailgun output

Add mailgun output

Add mailer to send email via the mailgun http api. This will allow users
to send emails alerts, without having to configure sendmail or some
equivalent.

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

--- src/riemann/mailgun.clj
+++ src/riemann/mailgun.clj
@@ -0,0 +1,90 @@
+;(ns riemann.mailgun
+  ;"Forwards events to Mailgun"
+  ;(:require [clj-http.client :as client]))
+(use 'aleph.http)
+(use '[riemann.common :only [body subject]])
+
+(def ^:private event-url
+  "https://api.mailgun.net/v2/%s/messages")
+
+(defn- post
+  "POST to the Mailgun events API."
+  [mgun-opts msg-opts]
+  (sync-http-request
+    {:method :post
+     :url (format event-url (:sandbox mgun-opts))
+     :basic-auth ["api" (:service-key mgun-opts)]
+     :form-params
+     {:from (format (:from msg-opts) (:sandbox mgun-opts))
+      :to (:to msg-opts)
+      :subject (:subject msg-opts)
+      :text (:body msg-opts)}
+     :socket-timeout 5000
+     :conn-timeout 5000
+     :accept :json
+     :throw-entire-message? true}))
+
+
+(defn mailgun-event
+  "Send an event, or a sequence of events, with the given smtp and msg
+  options."
+  [mgun-opts msg-opts events]
+  ;TODO: error checking to ensure sandbox and service-key are set
+  (let [events  (flatten [events])
+        subject ((get msg-opts :subject subject) events)
+        body    ((get msg-opts :body body) events)]
+    (post
+      mgun-opts
+      (merge msg-opts {:subject subject :body body}))))
+
+
+(defn mailgun
+  "Returns a mailer, which is a function invoked with an address or a sequence
+  of addresses and returns a stream. That stream is a function which takes a
+  single event, or a sequence of events, and sends email about them.
+
+  (def mailer (mailgun))
+  (def email (mailer \"xerxes@trioptimum.org\" \"shodan@trioptimum.org\"))
+
+  This mailer sends email out via mailgun using the mailgun http api. When used
+  it outputs the http response recieved from mailgun.
+
+  (changed :state
+    #(info \"mailgun response\" (email %)))
+
+  The first argument is a map of the mailgun options :sandbox and :service-key.
+  The second argument is a map of default message options, like :from,
+  :subject, or :body.
+
+  (def email (mailgun {:sandbox \"mail.relay\" :service-key \"key\"}
+                     {:from \"riemann@trioptimum.com\"}))
+
+  If you provide a single map, the mailer will split the mailgun options out
+  for you.
+
+  (def email (mailgun {:sandbox \"mail.relay\"
+                      :service-key \"foo\"
+                      :from \"riemann@trioptimum.com\"}))
+
+  By default, riemann uses (subject events) and (body events) to format emails.
+  You can set your own subject or body formatter functions by including
+  :subject or :body in msg-opts. These formatting functions take a sequence of
+  events and return a string.
+
+  (def email (mailgun {} {:body (fn [events]
+                                 (apply prn-str events))}))"
+  ([] (mailgun {}))
+  ([opts]
+        (let [mg-keys #{:sandbox :service-key}
+              mgun-opts (select-keys opts mg-keys)
+              msg-opts  (select-keys opts (remove mg-keys (keys opts)))]
+          (mailgun mgun-opts msg-opts)))
+  ([mgun-opts msg-opts]
+   (let [msg-opts (merge {:from "Riemann <riemann@%s>"} msg-opts)]
+     (fn make-stream [& recipients]
+       (fn stream [event]
+         (let [msg-opts (if (empty? recipients)
+                          msg-opts
+                          (merge msg-opts {:to recipients}))]
+           (mailgun-event mgun-opts msg-opts event)))))))
+


Remove println when LOGGIN_HOST available

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


Create/delete repo

Create/delete repo

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

--- src/runbld/util/git.clj
+++ src/runbld/util/git.clj
@@ -0,0 +1,21 @@
+(ns runbld.util.git
+  (:require [clj-jgit.porcelain :as git]
+            [clojure.java.io :as io]))
+
+(defn make-repo [dir]
+  (git/git-init dir))
+
+(defn make-tmp-repo [dir]
+  (let [basename "build.sh"
+        f (io/file dir basename)
+        repo (make-repo dir)]
+    (spit f "echo building... done")
+    (git/git-add repo basename)
+    (git/git-commit repo "Add build")
+    repo))
+
+(defn delete-repo [dir]
+  (let [pb (ProcessBuilder. ["rm" "-r" dir])
+        p (.start pb)]
+    (assert (= 0 (.waitFor p))
+            (-> p .getErrorStream io/reader slurp .trim))))


Stub for new test: test-json-renderer

Stub for new test: test-json-renderer

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

--- test/clouseau/test_json_renderer.clj
+++ test/clouseau/test_json_renderer.clj
@@ -0,0 +1,43 @@
+;;;
+;;;   Clouseau
+;;;
+;;;    Copyright (C) 2015 Pavel Tisnovsky <ptisnovs@redhat.com>
+;;;
+;;; Clouseau is free software; you can redistribute it and/or modify
+;;; it under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 2, or (at your option)
+;;; any later version.
+;;;
+;;; Clouseau 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
+;;; General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with Clouseau; see the file COPYING.  If not, write to the
+;;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+;;; 02110-1301 USA.
+;;;
+;;; Linking this library statically or dynamically with other modules is
+;;; making a combined work based on this library.  Thus, the terms and
+;;; conditions of the GNU General Public License cover the whole
+;;; combination.
+;;;
+;;; As a special exception, the copyright holders of this library give you
+;;; permission to link this library with independent modules to produce an
+;;; executable, regardless of the license terms of these independent
+;;; modules, and to copy and distribute the resulting executable under
+;;; terms of your choice, provided that you also meet, for each linked
+;;; independent module, the terms and conditions of the license of that
+;;; module.  An independent module is a module which is not derived from
+;;; or based on this library.  If you modify this library, you may extend
+;;; this exception to your version of the library, but you are not
+;;; obligated to do so. If you do not wish to do so, delete this
+;;; exception statement from your version.
+;;;
+
+(ns clouseau.test-core
+  (:require [clojure.test :refer :all]
+            [clouseau.json-renderer :refer :all]))
+
+


add files and images

add files and images

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

--- frontend/components/language_landing.cljs
+++ frontend/components/language_landing.cljs
@@ -0,0 +1,256 @@
+(ns frontend.components.language-landing
+  (:require [cljs.core.async :as async :refer [>! <! alts! chan sliding-buffer close!]]
+            [clojure.string :as str]
+            [frontend.async :refer [put!]]
+            [frontend.components.common :as common]
+            [frontend.components.plans :as plans-component]
+            [frontend.components.shared :as shared]
+            [frontend.state :as state]
+            [frontend.stefon :as stefon]
+            [frontend.utils :as utils :include-macros true]
+            [om.core :as om :include-macros true])
+  (:require-macros [frontend.utils :refer [defrender html]]))
+(def templates {"ruby" {:headline "CircleCI makes Continous Integration and Deployment for Ruby projects a breeze."
+                        :logo-path "/assets/img/outer/languages/ruby-logo.png"
+                        :ss-1 "/assets/img/outer/languages/ruby-ss-1.png"
+                        :ss-2 "/assets/img/outer/languages/ruby-ss-1.png"
+                        :ss-3 "/assets/img/outer/languages/ruby-ss-1.png"}})
+(defn language-landing [app owner]
+  (reify
+    om/IRender
+    (render [_]
+    (let [subpage (get-in app [:navigation-data :language])
+          template (get templates subpage)]
+      (html
+       [:div.jobs.page
+        [:div.jobs-head
+         [:img {:src (:logo-path template)}]
+         [:h1 (:headline template)]
+         [:img {:src (:ss-1 template)}]
+         [:img {:src (:ss-2 template)}]
+         [:img {:src (:ss-3 template)}]]
+        [:div.jobs-body
+         [:div.jobs-types
+         "Features"]
+         [:div.feature
+         "Feature 1"
+         [:img {:src "/assets/img/outer/languages/gear-icon.png"}]]
+         [:div.feature
+         "Feature 2"
+         [:img {:src "/assets/img/outer/languages/book-icon.png"}]]
+         [:div.feature
+         "Feature 3"
+         [:img {:src "/assets/img/outer/languages/file-icon.png"}]]
+         [:div "Read documentation on" ]]
+
+         [:div.jobs-intro
+          [:h2 "Who We Are"]
+          [:p
+           "CircleCI is a rapidly growing company with a great mission, a deeply technical team, and a focus on productivity for our customers and ourselves. We've a flat organization, a great culture, and a delightful product that's loved by thousands of developers. With significant revenue and funding, we're just getting started with taking developer tools to the next level."]]
+         [:div.jobs-values
+          [:h2 "Why you'll love working at CircleCI"]
+          [:p
+           [:strong "Our culture is customer-driven."]
+           " Our customers and our founders are engineers, and most of our employees are too. We are inspired by companies like "
+           [:a {:href "http://blog.alexmaccaw.com/stripes-culture"} "Stripe,"]
+           " "
+           [:a {:href "http://gigaom.com/2012/03/26/tales-from-the-trenches-github/"} "GitHub,"]
+           " "
+           [:a {:href "http://www.avc.com/a_vc/2012/02/the-management-team-guest-post-from-joel-spolsky.html"} "Fog Creek,"]
+           " and "
+           [:a {:href "http://www.valvesoftware.com/company/Valve_Handbook_LowRes.pdf"} "Valve."]]
+          [:p
+           [:strong "We have a flat organization."]
+           " There are no managers, no org-chart and no hierarchy, and we plan to keep it that way for as long as possible. Everyone gets access to all company information and can be involved in decision-making. By keeping communication open and transparent, we believe everybody is able to make good decisions about the best thing to work on."]
+          [:p
+           [:strong
+            "We have a very strong focus on productivity, and on shipping product."]
+           " This means you'll have a lot of days where you finish the day with the happy glow of having achieved something. We ship often, and shape our work lives around enabling that."]
+          [:p
+           [:strong "We spend a lot of time talking to customers."]
+           " We make it really easy for customers to reach out to us, and we reach out to them to ask for their feedback too. This means you'll probably spend significant time listening to and fixing their problems. We refer to that as \"support\", but really think of it as \"customer development\"."]
+          [:p
+           [:strong "We use cool technology."]
+           " Our backend is written in Clojure. Everything from managing LXC containers to package management to serving our REST API is all done in Clojure. This allows us to be really productive, handle concurrency with ease, and leads to beautiful manageable code. Clojure isn't just a fancy new language, it's the most productive, powerful and elegant language we've ever used. So much so, that we're in the process of switching our frontend over to ClojureScript."]
+          [:p
+           [:strong
+            "At a small growing company, your work has a disproportionate effect."]
+           " As well as improving our customers' lives, you'll also set a precedent for everyone who works for us in the future. You get to affect both the product and the company culture. Your opinions matter and are listened to, and that's why we hire you."]
+          [:p
+           [:strong "There's lots to learn."]
+           " We try to hire really, really high caliber people, which means you'll be able to learn a lot, and we hope to learn a lot from you too. We look for the very experienced, or the very talented. If you work at CircleCI, you know that you won't be on the team with slouches or slackers, or folks who will hold you back. (Curiously, we disproportionately hire folks with find it hard to believe they're as amazing as they are, and suffer from significant imposter syndrome. Go figure. If this matches you, we encourage you to apply anyway)."]]
+         [:div.jobs-where
+          [:h2 "Where We Work"]
+          [:p
+           [:strong "Local"]
+           [:span " — "]
+           "Our team is dedicated to creating the most productive environment possible. That means we ensure everyone is able to enjoy their own personal level of comfort and privacy. We work in San Francisco's beautiful Financial District, where you'll have a "
+           [:a
+            {:href "http://blog.circleci.com/silence-is-for-the-weak"}
+            "private office"]
+           ", catered lunch and lovely colleagues."]
+          [:p
+           [:strong "Remote"]
+           [:span
+            " — We have an asynchronous culture that is well suited to remote-working."]
+           " We use HipChat, Hangouts and email heavily, and roughly half of our engineers work remotely. We'll bring you on-site every 10 weeks or so to work closely with your colleagues, and can do this to fit your remote life."]]
+         [:div.jobs-what
+          [:h2 "What we're looking for"]
+          [:p
+           "Obviously, this is a very developer-focused company, so the most important thing is to understand how developers work and think. Here's how we think about the type of people we like to work with:"]]
+         [:div.jobs-listings
+          [:div#general
+           [:ul
+            [:li
+             "People who truly care about making developers more productive."]
+            [:li
+             "Folks who are easy to work with: we're not interested in solo artists, divas, know-it-alls, or assholes. We also tend to get on well with folks that do not identify with the words \"ninja\", \"pirate\", \"rock star\", or (especially) \"brogrammer\"."]
+            [:li "Great communicators."]
+            [:li
+             "People who feel strongly about tools and the software development process."]
+            [:li
+             [:a
+              {:href "http://blog.circleci.com/kindness-is-underrated"}
+              "Pleasant people"]
+             ", and good conversationalists - we'll be spending the next few years together after all."]
+            [:li
+             "Folks with an interest in the whole company, not just their job. Our transparent culture allows everyone to take a holistic view of the company. As a result, we really like people who enjoy getting familiar with the whole business, customers, product, culture, selling, etc."]]]
+
+          [:div#engineer
+           [:h3 [:span "Engineering roles"]]
+           [:p
+            "We're looking for great engineers: whether you've 10 years of experience shipping products, or are new to the industry with talent to burn and a fire in your belly, we need you to have amazing coding chops."]
+           [:h5 "We'd love to see"]
+           [:ul
+            [:li
+             "People who have used functional languages in anger (Clojure, Haskell, Scheme, Lisp, Clojure, Scala, OCaml, etc)."]
+            [:li "If you've built or scaled large distributed systems."]
+            [:li "People who love trying new, cutting-edge things."]
+            [:li
+             "If you've worked on significant projects that weren't in Java, JavaScript, Ruby or PHP."]]
+           [:h5 "With some of these skills"]
+           [:ul
+            [:li
+             "Good (possibly informal) knowledge of algorithmic design and CS theory (CS degree not required)."]
+            [:li "Clojure experts."]
+            [:li "Experience designing elegant APIs."]
+            [:li
+             "Broad knowledge of our customers' important languages; Python, Node, JS, Ruby, Java, and PHP."]
+            [:li "An understanding of scalable cloud and web services."]
+            [:li
+             "Dev-ops experience, including machine configuration and deployment on AWS."]
+            [:li
+             "Low-level Linux hacking knowledge (including file-systems, kernels, databases, LXC/Docker, etc)."]
+            [:li
+             "Experience building fat JS apps, stateful HTML5 apps, and data visualizations."]
+            [:li "Good product and user experience sensibilities."]]
+           [:a
+            {:role "button", :href "/jobs#apply"}
+            [:span "Apply for Engineering roles"]]]
+
+          [:div#designer
+           [:h3 [:span "Design roles"]]
+           [:p
+            "Our customers love great experiences, and so do we. We're looking for amazing designers who can provide them."]
+           [:h5 "We're looking for"]
+           [:ul
+            [:li
+             "An inspiring ability to create graceful solutions when confronted by complex design challenges."]
+            [:li
+             "An obsessive devotion to user-experience problem solving and a sharp understanding of its inherit imperfections."]
+            [:li
+             "An exceedingly confident resolve, built from an exceedingly diverse repertoire of skillsets."]
+            [:li
+             "An intimate love affair with learning and an equally essential appetite for ground-breakingly new ideas."]
+            [:li
+             "An exceptional talent for communicating efficiently in a developer-centric, fast-paced environment."]
+            [:li
+             "An understanding of how to engage with developers, both inside and outside the context of a team."]
+            [:li "Taste."]]
+           [:h5 "We'd love to see"]
+           [:ul
+            [:li "Any cool stuff you may have on dribbble, Behance, etc."]
+            [:li
+             "What kind of high-level or back-end programming knowledge you may have."]
+            [:li
+             "How you manage and traverse large, complex technology stacks."]
+            [:li
+             "You send — along with your coverletter — an image of a puppy, in formal wear, doing yoga."]
+            [:li
+             "If you've ever built or helped build any type of developer-oriented tools in the past."]]
+           [:h5 "With the ability to"]
+           [:ul
+            [:li "Write beautiful HTML and CSS."]
+            [:li
+             "Navigate JS/Coffee comfortably and fix things when they break."]
+            [:li
+             "Build your own mockups, prototypes, and production-ready concepts."]
+            [:li
+             "Ship, believing done is better than perfect and iteration is better than perfection."]
+            [:li
+             "Uphold and improve upon existing brand standards and guidelines."]
+            [:li
+             "Most importantly, relate to our customers; primarily developers."]]
+           [:a
+            {:role "button", :href "/jobs#apply"}
+            [:span "Apply for Design roles"]]]
+
+          [:div#business
+           [:h3 [:span "Business roles"]]
+           [:p
+            "We're looking for developer-focused individuals to help us achieve business objectives."]
+           [:h5 "You should have a few of:"]
+           [:ul
+            [:li "Deep and authentic knowledge of the developer space."]
+            [:li
+             "A technical background with the desire to learn more about the customer-facing parts of building a company."]
+            [:li
+             "Great analytical skills, with the ability to derive signal where others see noise."]
+            [:li
+             "Fantastic communication skills, writing ability and presentation skills."]
+            [:li
+             "An obsession with data-driven decision making, measuring results and automating repeatable processes."]
+            [:li "Proven success in previous projects."]]
+           [:h5
+            [:strong "Dev-awareness"]
+            " — Are you interested in telling customers about CircleCI? If so, we'd love to see:"]
+           [:ul
+            [:li
+             "Anything you may have written about or put into practice related to conversion rate optimization, A/B testing, SaaS metrics, lifecycle marketing, virality, or marketing automation."]
+            [:li
+             "An understanding of modern, low-touch, software-driven marketing techniques."]
+            [:li
+             "An ability to build industry relationships with other developer-tooling companies."]
+            [:li
+             "A love of crafting stories and communicating them to our customers and the industry at large."]]
+           [:h5
+            [:strong "Dev-success"]
+            " — Do you love problem solving and working with developers? If so, we'd love to talk if you:"]
+           [:ul
+            [:li "Have a combination of engineering and empathy."]
+            [:li
+             "Love talking to people, helping them solve problems, and building relationships."]
+            [:li "Really want to help developers be happy and successful."]
+            [:li
+             "Have significant technical ability, with an understanding of the developer mindset, tools and culture."]
+            [:li
+             "Love to solve problems fully so that they never happen to any customer again."]
+            [:li "Are supremely organized and resourceful."]
+            [:li "Have reasonable to strong coding ability."]]
+           [:a
+            {:role "button", :href "/jobs#apply"}
+            [:span "Apply for Business roles"]]]]
+
+         [:div.jobs-how
+          [:h2#apply "How to apply"]
+          [:p "Send an email to " [:a {:href "mailto:jobs@circleci.com"} "jobs@circleci.com"] ", including a resume."]
+          [:p
+           "We're mostly interested in seeing evidence that you're great at what you do. (Don't worry if you're not convinced about your abilities, just work to convince us.) This might include great projects you've worked on, a portfolio, wonderful references, open source you've contributed to, products you've built or scaled, your grades at MIT, that you got hired by Google, or anything that hints that you might be a particularly amazing individual. We're also interested in reading about technologies you've worked with in the past, and what you did with them."]
+          [:p
+           "The kind of people we want to work with tend to pitch us as to why they should work at CircleCI. This is both why you're interested, and why you think you'd be a good part of the team. If all goes well we're going to spend a lot of time together, so it's worth it for both of us to discuss this in advance."]
+          [:p
+           "Naturally, this goes both ways. We're happy to answer any questions you have about CircleCI, where we're going, why it's an amazing place to work, and what we're doing to keep it that way."]
+          [:p
+           "Interested? "
+           [:a {:href "mailto:jobs@circleci.com"} "Email us now!"]]]
+         [:p [:strong "No recruiters, thank you."]]]])))))


subsets

subsets

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

--- src/latte/subset.clj
+++ src/latte/subset.clj
@@ -0,0 +1,104 @@
+(ns latte.subset
+  "Set-theoretic notions based on the subset
+  approach of type theory.
+
+  The main idea is to consider a typed variant of
+  a mathematical set as a predicate over a given type.
+
+  In LaTTe what is called a **set** will be technically-speaking
+  a subset of a type, hence a predicate over a given type.
+
+  The main drawback of the approach is that sets
+  are not considered as types (hence type inhabitation
+  and set elemthood are distinct notions).
+
+  The advantage is that it is quite a workable approach in
+  practice,
+  and that it does not require any extension to the kernel
+  such as sigma-types."
+
+    (:refer-clojure :exclude [and or not set])
+
+  (:require [latte.core :as latte :refer [defterm defthm forall assume have proof lambda]])
+
+  (:require [latte.prop :as p :refer [<=> and or not]])
+
+  (:require [latte.equal :as eq :refer [equal]])
+  )
+
+(defterm set
+  "The set (or subset of a type) constructor."
+  [[T :type]]
+  (==> T :type))
+
+(defterm elem
+  "Set membership."
+  [[T :type] [x T] [s (set T)]]
+  (s x))
+
+(defterm subseteq
+  "Subset or equal relation."
+  [[T :type] [s1 (set T)] [s2 (set T)]]
+  (forall [x T]
+    (==> (elem T x s1)
+         (elem T x s2))))
+
+(defterm seteq
+  "Equality on sets."
+  [[T :type] [s1 (set T)] [s2 (set T)]]
+  (and (subseteq T s1 s2)
+       (subseteq T s2 s1)))
+
+(defterm union
+  "Set union."
+  [[T :type] [s1 (set T)] [s2 (set T)]]
+  (lambda [x T]
+    (or (elem T x s1)
+        (elem T x s2))))
+
+(defthm union-commute
+  "Set union commutes."
+  [[T :type] [s1 (set T)] [s2 (set T)]]
+  (seteq T
+         (union T s1 s2)
+         (union T s2 s1)))
+
+(proof union-commute :script
+  (assume [x T
+           H (elem T x (union T s1 s2))]
+    (have a1 (or (elem T x s1)
+                 (elem T x s2)) :by H)
+    (have a2 _ :by (p/or-sym (elem T x s1) (elem T x s2)))
+    (have a3 (or (elem T x s2)
+                (elem T x s1)) :by ((a2) (a1)))
+    (have a4 (elem T x (union T s2 s1)) :by (a3))
+    (have a5 (==> (elem T x (union T s1 s2))
+                  (elem T x (union T s2 s1))) :discharge [H (a4)])
+    (have a (subseteq T
+                      (union T s1 s2)
+                      (union T s2 s1)) :discharge [x (a5)]))
+  (assume [x T
+           H (elem T x (union T s2 s1))]
+    (have b1 (elem T x (union T s1 s2))
+          :by ((p/or-sym (elem T x s2) (elem T x s1)) H))
+    (have b2 (==> (elem T x (union T s2 s1))
+                  (elem T x (union T s1 s2))) :discharge [H (b1)])
+    (have b (subseteq T
+                      (union T s2 s1)
+                      (union T s1 s2)) :discharge [x (b2)]))
+  (have c (seteq T
+                 (union T s1 s2)
+                 (union T s2 s1))
+        :by ((p/and-intro (subseteq T (union T s1 s2) (union T s2 s1))
+                          (subseteq T (union T s2 s1) (union T s1 s2)))
+             (a) (b)))
+  (qed c))
+
+
+(defterm intersection
+  "Set intersection."
+  [[T :type] [s1 (set T)] [s2 (set T)]]
+  (forall [x T]
+    (and (elem T x s1)
+         (elem T x s2))))
+


Saioa hastean indexera

Saioa hastean indexera

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


Adding better error messages resources that don't exist

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

--- test/kioo/core_test.clj
+++ test/kioo/core_test.clj
@@ -0,0 +1,9 @@
+(ns kioo.core
+  (:require [clojure.test :as test :refer :all]
+            [kioo.core :as core :refer :all]))
+
+(deftest path-exists-test
+  (is (path-exists? "simple-div.html"))
+  (is (not (path-exists? "file-does-not-exist.txt")))
+  (is (path-exists? :not-a-path)))
+


make all scripts executable

make all scripts executable

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


Write zeros to outputs

Write zeros to outputs

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


tweak

tweak

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/jeelabs/jet.git/'


remove defstate teller, already mounted and seeded

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


remove devtools require

remove devtools require


Update collaboration roots in post-revisions* update-entities call


Refactor: concealed internal

Refactor: concealed internal

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/ben-biddington/solace.git/'


Address PR feedback

Address PR feedback

Use system SO_RCVBUF by default

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/jamtur01/riemann.git/'


[WM] allow text/plain responses

[WM] allow text/plain responses

/ping should be able to respond OK not "OK"

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


gogoko liburua baldin badago bakarrik erakutsi


add initial futzing around with the nanoKONTROL2. This is very experimental stuff. Expect things to change :-)

error: pathspec 'src/overtone/device/midi/nanoKONTROL2.clj' did not match any file(s) known to git

--- src/overtone/device/midi/nanoKONTROL2.clj
+++ src/overtone/device/midi/nanoKONTROL2.clj
@@ -0,0 +1,270 @@
+(ns overtone.device.midi.nanoKONTROL2
+  (:use [overtone.midi]
+        [overtone.libs.event :only [event]]))
+
+(defrecord NanoKontrol2 [name in out interfaces state])
+
+(def event-handle "/overtone/midi/nanokontrol2")
+
+(def config
+  {:name "nanoKONTROL2"
+   :interfaces {:input-controls {:name "Input Controls"
+                                 :type :midi-in
+                                 :midi-handle "nanoKONTROL2"
+                                 :control-defaults {:chan 0 :cmd 176 :type :button}
+                                 :controls {:track-left {:note 58}
+                                            :track-right {:note 59}
+                                            :cycle {:note 46}
+                                            :marker-set {:note 60}
+                                            :marker-left {:note 61}
+                                            :marker-right {:note 62}
+                                            :rewind {:note 43}
+                                            :fast-forward {:note 44}
+                                            :stop {:note 42}
+                                            :play {:note 41}
+                                            :record {:note 45}
+                                            :s0 {:note 32}
+                                            :m0 {:note 48}
+                                            :r0 {:note 64}
+                                            :slider0 {:note 0 :type :slider}
+                                            :pot0 {:note 16 :type :pot}
+
+                                            :s1 {:note 33}
+                                            :m1 {:note 49}
+                                            :r1 {:note 65}
+                                            :slider1 {:note 1 :type :slider}
+                                            :pot1 {:note 17 :type :pot}
+
+                                            :s2 {:note 34}
+                                            :m2 {:note 50}
+                                            :r2 {:note 66}
+                                            :slider2 {:note 2 :type :slider}
+                                            :pot2 {:note 18 :type :pot}
+
+                                            :s3 {:note 35}
+                                            :m3 {:note 51}
+                                            :r3 {:note 67}
+                                            :slider3 {:note 3 :type :slider}
+                                            :pot3 {:note 19 :type :pot}
+
+                                            :s4 {:note 36}
+                                            :m4 {:note 52}
+                                            :r4 {:note 68}
+                                            :slider4 {:note 4 :type :slider}
+                                            :pot4 {:note 20 :type :pot}
+
+                                            :s5 {:note 37}
+                                            :m5 {:note 53}
+                                            :r5 {:note 69}
+                                            :slider5 {:note 5 :type :slider}
+                                            :pot5 {:note 21 :type :pot}
+
+                                            :s6 {:note 38}
+                                            :m6 {:note 54}
+                                            :r6 {:note 70}
+                                            :slider6 {:note 6 :type :slider}
+                                            :pot6 {:note 22 :type :pot}
+
+                                            :s7 {:note 39}
+                                            :m7 {:note 55}
+                                            :r7 {:note 71}
+                                            :slider7 {:note 7 :type :slider}
+                                            :pot7 {:note 23 :type :pot}}}
+                :leds {:name "LEDs"
+                       :type :midi-out
+                       :midi-handle "nanoKONTROL2"
+                       :control-defaults {:type :led}
+                       :controls {:cycle {:note 46}
+                                  :rewind {:note 43}
+                                  :fast-forward {:note 44}
+                                  :stop {:note 42}
+                                  :play {:note 41}
+                                  :record {:note 45}
+                                  :s0 {:note 32}
+                                  :m0 {:note 48}
+                                  :r0 {:note 64}
+                                  :s1 {:note 33}
+                                  :m1 {:note 49}
+                                  :r1 {:note 65}
+                                  :s2 {:note 34}
+                                  :m2 {:note 50}
+                                  :r2 {:note 66}
+                                  :s3 {:note 35}
+                                  :m3 {:note 51}
+                                  :r3 {:note 67}
+                                  :s4 {:note 36}
+                                  :m4 {:note 52}
+                                  :r4 {:note 68}
+                                  :s5 {:note 37}
+                                  :m5 {:note 53}
+                                  :r5 {:note 69}
+                                  :s6 {:note 38}
+                                  :m6 {:note 54}
+                                  :r6 {:note 70}
+                                  :s7 {:note 39}
+                                  :m7 {:note 55}
+                                  :r7 {:note 71}}}}})
+
+
+(defn- byte-seq-to-array
+  "Turn a seq of bytes into a native byte-array."
+  [bseq]
+  (let [ary (byte-array (count bseq))]
+    (doseq [i (range (count bseq))]
+      (aset-byte ary i (nth bseq i)))
+    ary))
+
+;; Magic sysex messages (recorded from Korg Kontrol Editor output)
+(def start-sysex [-16 126 127 6 1 -9])
+(def second-sysex [-16 66 64 0 1 19 0 31 18 0 -9])
+(def main-sysex [-16 66 64 0 1 19 0 127 127 2 3 5 64 0 0 0 1 16 1 0 0
+                 0 0 127 0 1 0 16 0 0 127 0 1 0 32 0 127 0 0 1 0 48 0
+                 127 0 0 1 0 64 0 127 0 16 0 1 0 1 0 127 0 1 0 0 17 0
+                 127 0 1 0 0 33 0 127 0 1 0 49 0 0 127 0 1 0 65 0 0
+                 127 0 16 1 0 2 0 0 127 0 1 0 18 0 127 0 0 1 0 34 0
+                 127 0 0 1 0 50 0 127 0 1 0 0 66 0 127 0 16 1 0 0 3 0
+                 127 0 1 0 0 19 0 127 0 1 0 35 0 0 127 0 1 0 51 0 0
+                 127 0 1 0 67 0 127 0 0 16 1 0 4 0 127 0 0 1 0 20 0
+                 127 0 0 1 0 36 0 127 0 1 0 0 52 0 127 0 1 0 0 68 0
+                 127 0 16 1 0 0 5 0 127 0 1 0 21 0 0 127 0 1 0 37 0 0
+                 127 0 1 0 53 0 127 0 0 1 0 69 0 127 0 0 16 1 0 6 0
+                 127 0 0 1 0 22 0 127 0 1 0 0 38 0 127 0 1 0 0 54 0
+                 127 0 1 0 70 0 0 127 0 16 1 0 7 0 0 127 0 1 0 23 0 0
+                 127 0 1 0 39 0 127 0 0 1 0 55 0 127 0 0 1 0 71 0 127
+                 0 16 0 1 0 58 0 127 0 1 0 0 59 0 127 0 1 0 0 46 0 127
+                 0 1 0 60 0 0 127 0 1 0 61 0 0 127 0 1 0 62 0 127 0 0
+                 1 0 43 0 127 0 0 1 0 44 0 127 0 1 0 0 42 0 127 0 1 0
+                 0 41 0 127 0 1 0 45 0 0 127 0 127 127 127 127 0 127 0
+                 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -9])
+(def end-sysex [-16 66 64 0 1 19 0 31 17 0 -9])
+
+(defn set-external-led-mode!
+  "External led mode allows you to control each of the nanoKontrol2's
+  leds independently to button presses. This gives you much more
+  control over the device.
+
+  To enable external led mode, we need to send send the magical sysex
+  incantation to the nanoKontrol2 midi-out object nko (this was
+  determined by recording the sysex messages that the official Korg
+  Kontrol Editor sends to perform this task.)"
+  [nko]
+  (midi-sysex nko (byte-seq-to-array start-sysex))
+  (midi-sysex nko (byte-seq-to-array second-sysex))
+  (midi-sysex nko (byte-seq-to-array start-sysex))
+  (midi-sysex nko (byte-seq-to-array main-sysex))
+  (midi-sysex nko (byte-seq-to-array start-sysex))
+  (midi-sysex nko (byte-seq-to-array end-sysex)))
+
+(defn leds-on-test
+  [nko]
+  (dotimes [n 100] (midi-control nko n 127)))
+
+(defn- led-on-
+  [out id]
+  (let [led-id  (-> config :interfaces :leds :controls id :note)]
+    (midi-control out led-id 127)))
+
+(defn- led-off-
+  [out id]
+  (let [led-id (-> config :interfaces :leds :controls id :note)]
+    (midi-control out led-id 0)))
+
+(defn led-on
+  "Turn a led on. Usage: (led-on nk :r2)"
+  [nk id]
+  (let [out (:out nk)]
+    (led-on- out id)))
+
+(defn led-off
+  "Turn a led off. Usage: (led-off nk :r2)"
+  [nk id]
+  (let [out (:out nk)]
+    (led-off- out id)))
+
+(defn- smr-col-on
+  [out col-num]
+  (let [s (keyword (str "s" col-num))
+        m (keyword (str "m" col-num))
+        r (keyword (str "r" col-num))]
+    (led-on- out s)
+    (led-on- out m)
+    (led-on- out r)))
+
+(defn- smr-col-off
+  [out col-num]
+  (let [s (keyword (str "s" col-num))
+        m (keyword (str "m" col-num))
+        r (keyword (str "r" col-num))]
+    (led-off- out s)
+    (led-off- out m)
+    (led-off- out r)))
+
+(defn intromation
+  ([out]
+     (let [intro-times (repeat 75)]
+       (doseq [id (range 8)]
+         (smr-col-on out id)
+         (Thread/sleep (nth intro-times id)))
+       (Thread/sleep 750)
+       (doseq [id (reverse (range 8))]
+         (smr-col-off out id)
+         (Thread/sleep (nth intro-times id))))))
+
+(defn- merge-control-defaults
+  "Returns config map where control info maps are merged
+  with :control-defaults map."
+  [config]
+  (assoc config
+    :interfaces
+    (into {}
+          (map (fn [[i-name i-info]]
+                 [i-name (assoc (dissoc i-info :control-defaults)
+                           :controls (into {}
+                                           (map (fn [[c-name c-info]]
+                                                  [c-name (merge (:control-defaults i-info)
+                                                                 c-info)])
+                                                (:controls i-info))))])
+               (:interfaces config)))))
+
+(defn note-controls-map
+  [config]
+  (let [controls (-> config :interfaces :input-controls :controls)]
+    (into {}
+          (map (fn [[k v]] [(:note v) k])
+               controls))))
+
+(defn mk-midi-in-handler
+  [config state event-name]
+  (let [ncm (note-controls-map config)]
+    (fn [msg ts]
+      (let [note   (:note msg)
+            vel    (:vel msg)
+            at-key (get ncm note)
+            atm    (get state at-key)]
+        (reset! atm vel)
+        (event event-name :msg msg :ts ts :val vel :id at-key)))))
+
+(defn connect
+  "Connect to a connected nanoKONTROL2 midi device. By default, it
+  places the deviced into 'external led mode' which allows you to
+  control the leds remotely giving you more control. If your device
+  doesn't have the midi-handle \"nanoKONTROL2\" for both the input
+  controls and leds (perhaps if you are connecting more than one
+  simulataneously) you may also specify these identifiers directly."
+  ([] (connect true))
+  ([force-external-led-mode?]
+     (connect force-external-led-mode?
+              (-> config :interfaces :input-controls :midi-handle)
+              (-> config :interfaces :leds :midi-handle)))
+  ([midi-in-str midi-out-str] (connect true midi-in-str midi-out-str))
+  ([force-external-led-mode? midi-in-str midi-out-str]
+     (let [in         (midi-in midi-in-str)
+           out        (midi-out midi-out-str)
+           config     (merge-control-defaults config)
+           interfaces (-> config :interfaces)
+           state      (into {} (map (fn [[k v]] [k (atom nil)]) (-> config :interfaces :input-controls :controls)))]
+       (when force-external-led-mode?
+         (set-external-led-mode! out))
+       (midi-handle-events in (mk-midi-in-handler config state event-handle))
+       (intromation out)
+       (NanoKontrol2. (:name config) in out interfaces state))))


Fixed word split regex

Fixed word split regex

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


add q15

add q15

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

--- src/puzzule/q15.clj
+++ src/puzzule/q15.clj
@@ -0,0 +1 @@
+(ns puzzule.q15)


adding test profiles for int-tests

adding test profiles for int-tests

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


fixing project.clj for clojars deploy

fixing project.clj for clojars deploy

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


Bump restql-core

Bump restql-core

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


Latest noir async

Latest noir async

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


Update deps

Update deps

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


Remove test and notify commands

Remove test and notify commands

--- project.clj
+++ project.clj
@@ -27,7 +27,6 @@
                  :pretty-print true
                  :source-map true
                  :verbose true}
-                :notify-command ["bin/phantomjs" "none"]
                 :source-paths ["src" "test"]}
                {:id "advanced"
                 :compiler
@@ -38,8 +37,7 @@
                  :pretty-print true
                  :externs ["externs/hickory.js"]
                  :verbose true}
-                :source-paths ["src" "test"]}]
-              :test-commands {"phantom" ["bin/phantomjs"]}}
+                :source-paths ["src" "test"]}]}
   :deploy-repositories [["releases" :clojars]]
   :profiles {:dev {:dependencies [[cljsjs/jquery "2.1.4-0"]
                                   [crate "0.2.5"]


drop test support for 1.2.1 (it's still supported, just not tested by default)

--- project.clj
+++ project.clj
@@ -20,8 +20,8 @@
                                   [ring/ring-devel "1.1.0"]]}
              :1.2 {:dependencies [[org.clojure/clojure "1.2.1"]]}
              :1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]}
-             :1.5 {:dependencies [[org.clojure/clojure "1.5.0-master-SNAPSHOT"]]}}
-  :aliases {"all" ["with-profile" "dev,1.2:dev,1.3:dev:1.5,dev"]}
+             :1.5 {:dependencies [[org.clojure/clojure "1.5.0-RC4"]]}}
+  :aliases {"all" ["with-profile" "dev,1.3:dev:1.5,dev"]}
   :plugins [[codox "0.6.3"]]
   :test-selectors {:default  #(not (:integration %))
                    :integration :integration


Version 48

Version 48

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


Bump koan-engine for doc/code alternation check

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


Upgrade outdated libraries.

Upgrade outdated libraries.

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


Release 0.12.4

Release 0.12.4

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


lein-release plugin: bumped version from 0.1.5 to 0.1.6-SNAPSHOT for next development cycle

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


Add api route to upload income verification files

It also updates the application to include the income files


Brought in old DSU pattern

Brought in old DSU pattern

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

--- src/cljs/repodoc/utils.cljs
+++ src/cljs/repodoc/utils.cljs
@@ -0,0 +1,14 @@
+(ns repodoc.utils)
+
+(defn dsu-sort
+  "Decorate - sort - undecorate
+  from http://gettingclojure.wikidot.com/cookbook:sequences
+  Also used in Python Cookbook
+  This version sorts only on decorated values directly"
+  [sortable decorator]
+  (map last
+     (sort (fn [[v1 a] [v2 b]]
+             (< v1 v2))
+           (map (fn [x]
+                  [(decorator x) x])
+                sortable))))


Move the predicate functions in to their own ns -- it seems likely that we'll wind up with a bunch of these. Also, remove the note about expecting a java.io.File from the docstrings -- our schmancy multimethod `is-type` obviates that.

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

--- src/doctopus/files/predicates.clj
+++ src/doctopus/files/predicates.clj
@@ -0,0 +1,32 @@
+(ns doctopus.files.predicates
+  "We've got a loooot of filtering to do.
+
+  Like, a lot.")
+
+(defmulti is-type?
+  "Returns true if the type of the file matches the type given."
+  (fn [fobj regex] (class fobj)))
+
+(defmethod is-type? java.lang.String
+  [file-string type-regex]
+  (if (re-find type-regex file-string)
+    true
+    false))
+
+(defmethod is-type? java.io.File
+  [file-handle type-regex]
+  (is-type? (.getPath file-handle) type-regex))
+
+
+(defn markdown?
+  "returns true only for type files."
+  [file-handle]
+  (is-type? file-handle #"(?i)md|markdown|mdown$"
+            ))
+
+
+(defn restructured-text?
+  "returns true only for type files."
+  [file-handle]
+  (is-type? #"(?i)rst|rest$" (.getPath file-handle)
+            ))


Added Redis support for use in DB component.

error: pathspec 'src/dragon/data/sources/redis.clj' did not match any file(s) known to git

--- src/dragon/data/sources/redis.clj
+++ src/dragon/data/sources/redis.clj
@@ -0,0 +1,63 @@
+(ns dragon.data.sources.redis
+  (:require [clojure.java.shell :as shell]
+            [dragon.config :as config]
+            [dragon.data.sources.core :as db-core]
+            [taoensso.carmine :as car :refer [wcar]]
+            [taoensso.timbre :as log]))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;   Constants & Utility Functions   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(def redis-schemas
+  ;; Keys  & val types:
+  ;; * path-segment:content / string
+  ;; * path-segment:metadata / hash (binary)
+  ;; * path-segment:stats / hash (binary)
+  ;; * all-posts:metadata / hash (binary)
+  ;; * all-posts:stats / hash (binary)
+  )
+
+(defn cmd
+  "With this function we can do things like the following in the REPL (for
+  querying Redis):
+
+  ```clj
+  => (redis/cmd 'ping)
+  => (redis/cmd 'get \"testkey\")
+  => (redis/cmd 'set \"foo\" \"bar\")
+  ```
+
+  (Note that the escaped strings are for the docstring, and not what you'd
+  actually type in the REPL.)"
+  [component-or-system cmd & args]
+  (car/wcar (:conn (config/db-config component-or-system))
+            (apply (resolve (symbol (str "car/" cmd))) args)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;   Dragon DB API   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defn start-db!
+  [component]
+  (db-core/execute-db-command! component))
+
+(defn setup-schemas
+  [component]
+  )
+
+(defn setup-subscribers
+  [component]
+  )
+
+(defn add-connection
+  [component]
+  (assoc component :conn (config/db-conn component)))
+
+(defn stop-db!
+  [component]
+  (let [id-file (:container-id-file (config/db-config component))]
+    (->> (slurp id-file)
+         (shell/sh "docker" "stop" :in)
+         vec)
+    (shell/sh "rm" id-file)))


Retrieving permanent access token and logging it.