fixing namespace resolution issue.

fixing namespace resolution issue.

--- src/metabase/models/setting.clj
+++ src/metabase/models/setting.clj
@@ -4,8 +4,10 @@
             [clojure.string :as s]
             [environ.core :as env]
             [korma.core :as k]
+            [metabase.config :as config]
             [metabase.db :refer [sel del]]
-            [metabase.models.interface :refer :all]
+            [metabase.models [common :as common]
+                             [interface :refer :all]]
             [metabase.setup :as setup]
             [metabase.util :as u]))

@@ -157,8 +159,8 @@
    :intercom_code         "gqfmsgf1"
    :password_complexity   (metabase.util.password/active-password-complexity)
    :setup_token           (setup/token-value)
-   :timezones             metabase.models.common/timezones
-   :version               (metabase.config/mb-version-info)
+   :timezones             common/timezones
+   :version               (config/mb-version-info)
    ;; all of these values are dynamic settings controlled at runtime
    :anon_tracking_enabled (= "true" (get :anon-tracking-enabled))
    :site_name             (get :site-name)


Note, TODO.

Note, TODO.

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


Fix test

Fix test

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


moving to the proper directory-suggested namespace

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


Adds failing dag test.

Adds failing dag test.

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

--- test/onyx/peer/dag_test.clj
+++ test/onyx/peer/dag_test.clj
@@ -0,0 +1,260 @@
+(ns onyx.peer.dag-test
+  (:require [com.stuartsierra.component :as component]
+            [onyx.system :refer [onyx-development-env]]
+            [midje.sweet :refer :all]
+            [onyx.queue.hornetq-utils :as hq-util]
+            [onyx.peer.task-lifecycle-extensions :as l-ext]
+            [onyx.api]))
+
+(def id (java.util.UUID/randomUUID))
+
+(def config (read-string (slurp (clojure.java.io/resource "test-config.edn"))))
+
+(def env-config
+  {:hornetq/mode :udp
+   :hornetq/server? true
+   :hornetq.server/type :embedded
+   :hornetq.udp/cluster-name (:cluster-name (:hornetq config))
+   :hornetq.udp/group-address (:group-address (:hornetq config))
+   :hornetq.udp/group-port (:group-port (:hornetq config))
+   :hornetq.udp/refresh-timeout (:refresh-timeout (:hornetq config))
+   :hornetq.udp/discovery-timeout (:discovery-timeout (:hornetq config))
+   :hornetq.embedded/config (:configs (:hornetq config))
+   :zookeeper/address (:address (:zookeeper config))
+   :zookeeper/server? true
+   :zookeeper.server/port (:spawn-port (:zookeeper config))
+   :onyx/id id
+   :onyx.coordinator/revoke-delay 5000})
+
+(def peer-config
+  {:hornetq/mode :udp
+   :hornetq.udp/cluster-name (:cluster-name (:hornetq config))
+   :hornetq.udp/group-address (:group-address (:hornetq config))
+   :hornetq.udp/group-port (:group-port (:hornetq config))
+   :hornetq.udp/refresh-timeout (:refresh-timeout (:hornetq config))
+   :hornetq.udp/discovery-timeout (:discovery-timeout (:hornetq config))
+   :zookeeper/address (:address (:zookeeper config))
+   :onyx/id id
+   :onyx.peer/inbox-capacity (:inbox-capacity (:peer config))
+   :onyx.peer/outbox-capacity (:outbox-capacity (:peer config))
+   :onyx.peer/job-scheduler :onyx.job-scheduler/round-robin})
+
+(def dev (onyx-development-env env-config))
+
+(def env (component/start dev))
+
+(def n-queued-messages 15000)
+
+(def batch-size 1320)
+
+(def echo 1000)
+
+(def hq-config {"host" (:host (:non-clustered (:hornetq config)))
+                "port" (:port (:non-clustered (:hornetq config)))})
+
+(def a-queue (str (java.util.UUID/randomUUID)))
+
+(def b-queue (str (java.util.UUID/randomUUID)))
+
+(def c-queue (str (java.util.UUID/randomUUID)))
+
+(def j-queue (str (java.util.UUID/randomUUID)))
+
+(def k-queue (str (java.util.UUID/randomUUID)))
+
+(def l-queue (str (java.util.UUID/randomUUID)))
+
+(def a-segments
+  (map (fn [n] {:n n})
+       (range n-queued-messages)))
+
+(def b-segments
+  (map (fn [n] {:n n})
+       (range n-queued-messages (* 2 n-queued-messages))))
+
+(def c-segments
+  (map (fn [n] {:n n})
+       (range (* 2 n-queued-messages) (* 3 n-queued-messages))))
+
+(hq-util/create-queue! hq-config a-queue)
+
+(hq-util/create-queue! hq-config b-queue)
+
+(hq-util/create-queue! hq-config c-queue)
+
+(hq-util/create-queue! hq-config j-queue)
+
+(hq-util/create-queue! hq-config k-queue)
+
+(hq-util/create-queue! hq-config l-queue)
+
+(hq-util/write-and-cap! hq-config a-queue a-segments echo)
+
+(hq-util/write-and-cap! hq-config b-queue b-segments echo)
+
+(hq-util/write-and-cap! hq-config c-queue c-segments echo)
+
+(def d identity)
+
+(def e identity)
+
+(def f identity)
+
+(def g identity)
+
+(def h identity)
+
+(def i identity)
+
+(def catalog
+  [{:onyx/name :A
+    :onyx/ident :hornetq/read-segments
+    :onyx/type :input
+    :onyx/medium :hornetq
+    :onyx/consumption :concurrent
+    :hornetq/queue-name a-queue
+    :hornetq/host (:host (:non-clustered (:hornetq config)))
+    :hornetq/port (:port (:non-clustered (:hornetq config)))
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :B
+    :onyx/ident :hornetq/read-segments
+    :onyx/type :input
+    :onyx/medium :hornetq
+    :onyx/consumption :concurrent
+    :hornetq/queue-name b-queue
+    :hornetq/host (:host (:non-clustered (:hornetq config)))
+    :hornetq/port (:port (:non-clustered (:hornetq config)))
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :C
+    :onyx/ident :hornetq/read-segments
+    :onyx/type :input
+    :onyx/medium :hornetq
+    :onyx/consumption :concurrent
+    :hornetq/queue-name c-queue
+    :hornetq/host (:host (:non-clustered (:hornetq config)))
+    :hornetq/port (:port (:non-clustered (:hornetq config)))
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :D
+    :onyx/fn :onyx.peer.dag-test/d
+    :onyx/type :function
+    :onyx/consumption :concurrent
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :E
+    :onyx/fn :onyx.peer.dag-test/e
+    :onyx/type :function
+    :onyx/consumption :concurrent
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :F
+    :onyx/fn :onyx.peer.dag-test/f
+    :onyx/type :function
+    :onyx/consumption :concurrent
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :G
+    :onyx/fn :onyx.peer.dag-test/g
+    :onyx/type :function
+    :onyx/consumption :concurrent
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :H
+    :onyx/fn :onyx.peer.dag-test/h
+    :onyx/type :function
+    :onyx/consumption :concurrent
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :I
+    :onyx/fn :onyx.peer.dag-test/i
+    :onyx/type :function
+    :onyx/consumption :concurrent
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :J
+    :onyx/ident :hornetq/write-segments
+    :onyx/type :output
+    :onyx/medium :hornetq
+    :onyx/consumption :concurrent
+    :hornetq/queue-name j-queue
+    :hornetq/host (:host (:non-clustered (:hornetq config)))
+    :hornetq/port (:port (:non-clustered (:hornetq config)))
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :K
+    :onyx/ident :hornetq/write-segments
+    :onyx/type :output
+    :onyx/medium :hornetq
+    :onyx/consumption :concurrent
+    :hornetq/queue-name k-queue
+    :hornetq/host (:host (:non-clustered (:hornetq config)))
+    :hornetq/port (:port (:non-clustered (:hornetq config)))
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :L
+    :onyx/ident :hornetq/write-segments
+    :onyx/type :output
+    :onyx/medium :hornetq
+    :onyx/consumption :concurrent
+    :hornetq/queue-name l-queue
+    :hornetq/host (:host (:non-clustered (:hornetq config)))
+    :hornetq/port (:port (:non-clustered (:hornetq config)))
+    :onyx/batch-size batch-size}])
+
+;;; A    B       C
+;;;  \  /        |
+;;;   D- >       E
+;;;   |  \     / | \
+;;;   F   \-> G  H  I
+;;;  / \       \ | /
+;;; J   K        L
+
+(def workflow
+  [[:A :D]
+   [:B :D]
+   [:D :F]
+   [:F :J]
+   [:F :K]
+   [:C :E]
+   [:E :G]
+   [:E :H]
+   [:E :I]
+   [:G :L]
+   [:H :L]
+   [:I :L]
+   [:D :G]])
+
+(def v-peers (onyx.api/start-peers! 6 peer-config))
+
+(onyx.api/submit-job (:log env)
+                     {:catalog catalog :workflow workflow
+                      :task-scheduler :onyx.task-scheduler/round-robin})
+
+(def j-results (hq-util/consume-queue! hq-config j-queue echo))
+
+(def k-results (hq-util/consume-queue! hq-config k-queue echo))
+
+(def l-results (hq-util/consume-queue! hq-config l-queue echo))
+
+(doseq [v-peer v-peers]
+  ((:shutdown-fn v-peer)))
+
+(component/stop env)
+
+(fact (last j-results) => :done)
+
+(fact (last k-results) => :done)
+
+(fact (last l-results) => :done)
+
+(fact (into #{} (concat a-segments b-segments))
+      => (into #{} (butlast j-results)))
+
+(fact (into #{} (concat a-segments b-segments))
+      => (into #{} (butlast k-results)))
+
+(fact (into #{} (concat a-segments b-segments c-segments))
+      => (into #{} (butlast l-results)))
+


add config tests

add config tests

error: pathspec 'test/bract/core/config_test.clj' did not match any file(s) known to git

--- test/bract/core/config_test.clj
+++ test/bract/core/config_test.clj
@@ -0,0 +1,59 @@
+;   Copyright (c) Shantanu Kumar. 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 bract.core.config-test
+  (:require
+    [clojure.test :refer :all]
+    [bract.core.config :as config]))
+
+
+(deftest context-test
+  (testing "happy cases"
+    (let [good-context {:bract.core/config {"foo" "bar"}
+                        :bract.core/launch? true}]
+      (is (= {"foo" "bar"} (config/ctx-config good-context)))
+      (is (= true (config/ctx-launch? good-context)))
+      (is (false? (config/ctx-launch? {})) "missing/default value")))
+  (testing "missing/bad context keys"
+    (let [bad-context {:bract.core/config "foobar"
+                        :bract.core/launch? 10}]
+      (is (thrown? IllegalArgumentException (config/ctx-config  bad-context)) "invalid value")
+      (is (thrown? IllegalArgumentException (config/ctx-config  {}))          "missing value")
+      (is (thrown? IllegalArgumentException (config/ctx-launch? bad-context)) "invalid value"))))
+
+
+(deftest config-test
+  (testing "happy tests"
+    (doseq [good-context [{"bract.core.inducers" ["foo.bar.baz.qux/fred"
+                                                  "mary.had.a.little/lamb"]
+                           "bract.core.exports" ["foo"
+                                                 "bar"]
+                           "bract.core.launcher" "bract.core.config/apply-inducer-by-name"}
+                          {"bract.core.inducers" "[\"foo.bar.baz.qux/fred\"
+                                                   \"mary.had.a.little/lamb\"]"
+                           "bract.core.exports"  "[\"foo\"
+                                                   \"bar\"]"
+                           "bract.core.launcher" "bract.core.config/apply-inducer-by-name"}]]
+      (is (= ["foo.bar.baz.qux/fred"
+              "mary.had.a.little/lamb"]
+            (config/cfg-inducer-names good-context)))
+      (is (= ["foo" "bar"]
+            (config/cfg-exports good-context)))
+      (is (some?
+            (config/cfg-launcher good-context)))))
+  (testing "missing/bad context keys"
+    (let [bad-context {"bract.core.inducers" {:foo :bar}
+                       "bract.core.exports"  20
+                       "bract.core.launcher" false}]
+      (is (thrown? IllegalArgumentException (config/cfg-inducer-names bad-context)))
+      (is (thrown? IllegalArgumentException (config/cfg-inducer-names {})) "missing key")
+      (is (thrown? IllegalArgumentException (config/cfg-exports       bad-context)))
+      (is (thrown? IllegalArgumentException (config/cfg-exports       {})) "missing key")
+      (is (thrown? IllegalArgumentException (config/cfg-launcher      bad-context)))
+      (is (thrown? IllegalArgumentException (config/cfg-launcher      {})) "missing key"))))


remove unnecessary comments

remove unnecessary comments

--- src/clj/backtype/storm/daemon/common.clj
+++ src/clj/backtype/storm/daemon/common.clj
@@ -96,16 +96,6 @@
         (log-error t# "Error on initialization of server " ~(str name))
         (halt-process! 13 "Error on initialization")
         )))))
-
-
-;; lets spouts subscribe to streams of other components, includes all implicit relationships... there should be no special cases for ackers, spouts, direct groupings, etc.
-;;   - everything has input streams
-;;   - output stream declarations
-;;   - the component object
-;;   - normalized parallelism
-;;   - just a single map from id -> stuff
-
-;; need to generalize acking so that it can be used by multiple kinds of spout implementations

 (defn- validate-ids! [^StormTopology topology]
   (let [sets (map #(.getFieldValue topology %) thrift/STORM-TOPOLOGY-FIELDS)


log when a transition isn't possible

log when a transition isn't possible

--- src/clj/backtype/storm/daemon/nimbus.clj
+++ src/clj/backtype/storm/daemon/nimbus.clj
@@ -145,11 +145,13 @@
            (let [get-event (fn [m e]
                              (if (contains? m e)
                                (m e)
-                               (when error-on-no-transition?
-                                 (throw-runtime "No transition for event: " event
-                                                ", status: " status,
-                                                " storm-id: " storm-id)
-                                 )))
+                               (let [msg (str "No transition for event: " event
+                                              ", status: " status,
+                                              " storm-id: " storm-id)]
+                                 (if error-on-no-transition?
+                                   (throw-runtime msg)
+                                   (log-message msg)
+                                   ))))
                  transition (-> (state-transitions nimbus storm-id status)
                                 (get (:type status))
                                 (get-event event))


add common.cljs

add common.cljs

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

--- src/cfg/common.cljs
+++ src/cfg/common.cljs
@@ -0,0 +1,16 @@
+(ns cfg.common
+  (:require [om.next :as om]
+            [cljs.pprint]))
+
+(defn pp
+  "via: http://stackoverflow.com/a/32108640/87207"
+  [s]
+  (with-out-str (cljs.pprint/pprint s)))
+
+(defn d
+  "
+    Log a debug message to the console.
+    With cljs-devtools installed, things are formatted nicely.
+  "
+  [msg]
+  (.log js/console msg))


added leiningen task.

added leiningen task.

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

--- leiningen/midje.clj
+++ leiningen/midje.clj
@@ -0,0 +1,70 @@
+;; -*- indent-tabs-mode: nil -*-
+
+(ns leiningen.midje
+  (:refer-clojure :exclude [test])
+  (:use [leiningen.util.ns :only [namespaces-in-dir]]
+        [leiningen.compile :only [eval-in-project]]))
+
+(defn require-namespaces-form [namespaces]
+  `(do
+     (require 'clojure.test)
+     (require 'clojure.string)
+
+     ;; This turns off "Testing ...." lines, which I hate, especially
+     ;; when there's no failure output.
+     (defmethod clojure.test/report :begin-test-ns [m#])
+
+     (alter-var-root (var clojure.test/*report-counters*)
+		     (fn [_#] (ref clojure.test/*initial-report-counters*)))
+     (doseq [n# '~namespaces] (require n#))
+
+     (let [midje-passes#    (:pass @clojure.test/*report-counters*)
+	   midje-fails#     (:fail @clojure.test/*report-counters*)
+           midje-failure-message#
+	      (condp = midje-fails#
+		  0 (format "All claimed facts (%d) have been confirmed." midje-passes#)
+		  1 (format "FAILURE: %d fact was not confirmed." midje-fails#)
+		  (format "FAILURE: %d facts were not confirmed." midje-fails#))
+	   potential-consolation#
+	       (condp = midje-passes#
+		   0 ""
+		   1 "(But 1 was.)"
+		   (format "(But %d were.)" midje-passes#))
+	   midje-consolation#
+	           (if (> midje-fails# 0) potential-consolation# "")
+
+	   ; Stashed clojure.test output
+	   clojure-test-output-catcher#
+	           (java.io.StringWriter.)
+	   clojure-test-result#
+   	           (binding [clojure.test/*test-out* clojure-test-output-catcher#]
+		     (apply ~'clojure.test/run-tests '~namespaces))
+	   clojure-test-output#
+    	           (-> clojure-test-output-catcher# .toString clojure.string/split-lines)]
+
+
+       (when (> (+ (:fail clojure-test-result#) (:error clojure-test-result#))
+		0)
+	 ;; For some reason, empty lines are swallowed, so I use >>> to
+         ;; demarcate sections.
+	 (println ">>> Output from clojure.test tests:")
+	 (dorun (map println (drop-last 2 clojure-test-output#))))
+
+       (when (> (:test clojure-test-result#) 0)
+	 (println ">>> clojure.test summary:")
+	 (dorun (map println (take-last 2 clojure-test-output#)))
+	 (println ">>> Midje summary:"))
+
+       (println midje-failure-message# midje-consolation#)
+
+       ;; A non-nil return value is printed, so I'll just exit here.
+       (System/exit (+ midje-fails#
+                       (:error clojure-test-result#)
+                       (:fail clojure-test-result#))))))
+
+(defn midje [project & namespaces]
+  (let [desired-namespaces  (if (empty? namespaces)
+                              (concat (namespaces-in-dir (:test-path project))
+                                      (namespaces-in-dir (:source-path project)))
+                              (map symbol namespaces))]
+    (eval-in-project project (require-namespaces-form desired-namespaces))))


removing a prn statement

removing a prn statement

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


add test for rendering

add test for rendering

error: pathspec 'sass-dsl/test/sass_dsl/render_test.clj' did not match any file(s) known to git

--- sass-dsl/test/sass_dsl/render_test.clj
+++ sass-dsl/test/sass_dsl/render_test.clj
@@ -0,0 +1,21 @@
+(ns sass-dsl.render-test
+  (:require [clojure.test :refer :all]
+            [sass-dsl.render :as render]
+            [sass-dsl.transform :as transform]
+            [sass-dsl.transform-test :as transform-test]))
+
+(deftest basic-css-render-test
+  (testing "Ensure to get CSS output."
+    (is (=
+         (render/output-css
+          transform-test/sass-denested-simpler-nesting-flattened-colons "")
+         "table.hl {\n margin: 2em 0;\n}\n\ntable.hl td.ln {\n text-align: right;\n}\n\nli {\n font-size: 1.2em;\n font-weight: bold;\n font-family: serif;\n}\n\n"))))
+
+(deftest constant-replacement-render-test
+  (testing "Ensure we get CSS."
+    (is (=
+         (render/output-css
+          (transform/replaced-constants-structure-vec-zip-vz transform-test/sass-constants-stripped-nested-tree transform-test/constants-map)
+          "")
+         ".content-navigation {\n border-color: #3bbfce;\n color: darken(#3bbfce, 9%);\n}\n\n.border {\n padding: 16px / 2;\n margin: 16px / 2;\n border-color: #3bbfce;\n}\n\n"))))
+


only run payments query when a customer exists

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


80-columnify


[EN] Realias kehaar.wire-up

[EN] Realias kehaar.wire-up

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


add a unit test for GET /api/meta/table/:id/fks

--- test/metabase/api/meta/table_test.clj
+++ test/metabase/api/meta/table_test.clj
@@ -4,6 +4,7 @@
             [metabase.db :refer :all]
             [metabase.http-client :as http]
             (metabase.models [field :refer [Field]]
+                             [foreign-key :refer [ForeignKey]]
                              [table :refer [Table]])
             [metabase.test-data :refer :all]
             [metabase.test.util :refer [match-$ expect-eval-actual-first]]))
@@ -152,3 +153,66 @@
        ((user->client :crowberto) :get 200 (format "meta/table/%d" (table->id :users))))
    ;; Now reset the Table to it's original state
    (upd Table (table->id :users) :entity_name nil :entity_type nil :description nil)])
+
+
+;; ## GET /api/meta/table/:id/fks
+;; We expect a single FK from CHECKINS.USER_ID -> USERS.ID
+(expect-let [checkins-user-field (sel :one Field :table_id (table->id :checkins) :name "USER_ID")
+             users-id-field (sel :one Field :table_id (table->id :users) :name "ID")]
+  [(match-$ (sel :one ForeignKey :destination_id (:id users-id-field))
+     {:id $
+      :origin_id (:id checkins-user-field)
+      :destination_id (:id users-id-field)
+      :relationship "Mt1"
+      :created_at $
+      :updated_at $
+      :origin (match-$ checkins-user-field
+                {:id $
+                 :table_id $
+                 :name "USER_ID"
+                 :description nil
+                 :base_type "IntegerField"
+                 :preview_display $
+                 :position $
+                 :field_type "info"
+                 :active true
+                 :special_type "fk"
+                 :created_at $
+                 :updated_at $
+                 :table (match-$ (sel :one Table :id (table->id :checkins))
+                          {:description nil
+                           :entity_type nil
+                           :name "CHECKINS"
+                           :rows 1000
+                           :updated_at $
+                           :entity_name nil
+                           :active true
+                           :id $
+                           :db_id $
+                           :created_at $})})
+      :destination (match-$ users-id-field
+                     {:id $
+                      :table_id $
+                      :name "ID"
+                      :description nil
+                      :base_type "IntegerField"
+                      :preview_display $
+                      :position $
+                      :field_type "info"
+                      :active true
+                      :special_type "id"
+                      :created_at $
+                      :updated_at $
+                      :table (match-$ (sel :one Table :id (table->id :users))
+                               {:description nil
+                                :entity_type nil
+                                :name "USERS"
+                                :rows 15
+                                :updated_at $
+                                :entity_name nil
+                                :active true
+                                :id $
+                                :db_id $
+                                :created_at $})})})]
+  ((user->client :rasta) :get 200 (format "meta/table/%d/fks" (table->id :users))))
+


Hundred door puzzle soln in clojure

Hundred door puzzle soln 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/ananthmv/stream.git/'


Changing cache count.

Changing cache count.

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


Render a trivial version of Marley's train schedule.

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


fix system dependency

fix system dependency

--- sidecar/src/figwheel_sidecar/system.clj
+++ sidecar/src/figwheel_sidecar/system.clj
@@ -23,7 +23,7 @@
 (defn css-watcher [opts]
   (component/using
    (css-watch/css-watcher opts)
-   {:figwheel-system :figwheel-server}))
+   {:figwheel-server :figwheel-system}))

 (def nrep-server-component nrepl-comp/nrepl-server-component)

@@ -164,7 +164,7 @@
   [{:keys [figwheel-options all-builds build-ids]
     :as options}]
   (-> (component/system-map
-       :figwheel-server (figwheel-system options))
+       :figwheel-system (figwheel-system options))
       (add-css-watcher  (:css-dirs figwheel-options))
       (add-nrepl-server (select-keys figwheel-options [:nrepl-port
                                                        :nrepl-host


add additional benchmark query types

add additional benchmark query types

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


Add tests for character escaping for VCF string fields

error: pathspec 'test/cljam/io/vcf/reader_test.clj' did not match any file(s) known to git

--- test/cljam/io/vcf/reader_test.clj
+++ test/cljam/io/vcf/reader_test.clj
@@ -0,0 +1,14 @@
+(ns cljam.io.vcf.reader-test
+  (:require [clojure.test :refer [deftest is]]
+            [cljam.io.vcf.reader :as vcf-reader]))
+
+(deftest parse-structured-line-test
+  (is (= {:id "ID", :description "\"This\" is a description",
+          :note "You can use \" in string fields by escaping it with \\"}
+       (#'vcf-reader/parse-structured-line "ID=ID,Description=\"\\\"This\\\" is a description\",Note=\"You can use \\\" in string fields by escaping it with \\\\\"")))
+  (is (thrown-with-msg? RuntimeException
+                        #"Unexpected end of string field"
+                        (#'vcf-reader/parse-structured-line "x=\"unbalanced double quote")))
+  (is (thrown-with-msg? RuntimeException
+                        #"Either '\\' or '\"' was expected immediately after '\\', but got 'x'"
+                        (#'vcf-reader/parse-structured-line "x=\"unknown \\x escape sequence\""))))


Adding in table components.

Adding in table components.

error: pathspec 'src/hatti/table/components.cljs' did not match any file(s) known to git

--- src/hatti/table/components.cljs
+++ src/hatti/table/components.cljs
@@ -0,0 +1,256 @@
+(ns hatti.table.components
+  (:require-macros [cljs.core.async.macros :refer [go go-loop]])
+  (:require [cljs.core.async :refer [<! chan put! timeout]]
+            [om.core :as om :include-macros true]
+            [om.dom :as dom :include-macros true]
+            [sablono.core :as html :refer-macros [html]]
+            [hatti.forms :as forms :refer [get-label format-answer]]
+            [hatti.record.components :refer [submission-view]]
+            [hatti.shared :as shared]
+            [hatti.utils :refer [click-fn safe-regex]]))
+
+;; DIVS
+
+(def table-id "submission-grid")
+(def pager-id "pager")
+
+;; FIELDS
+
+(def extra-fields
+  "Extra fields that will be displayed on the table."
+  [{:full-name "_rank" :label "#"
+    :name "_rank" :type "integer"}
+   forms/submission-time-field])
+
+(defn all-fields [form]
+  "Given a (flat-)form, returns fields for table display.
+   Puts extra fields in the beginning, metadata at the end of the table,
+   and drops fields that have no data (eg. group/note)."
+  (->> (concat extra-fields
+               (forms/non-meta-fields form)
+               (forms/meta-fields form))
+       (filter forms/has-data?)))
+
+;; SLICKGRID HELPER FUNCTIONS
+
+(defn compfn [args]
+  "Comparator function for the slickgrid dataview.
+   args.sortCol is the column being sorted, a and b are rows to compare.
+   Claims a is bigger (return 1) if value for a > b, or a is null / empty."
+  (fn [a b]
+    (let [col (aget args "sortCol")
+          lower #(if (string? %) (clojure.string/lower-case %) %)
+          aval (lower (aget a (aget col "field")))
+          bval (lower (aget b (aget col "field")))]
+      (if (or (nil? aval) (> aval bval)) 1 -1))))
+
+(defn filterfn [form item args]
+  "Filter function for the slickgrid dataview, use as (partial filterfn form)
+   item is the row, args contains query.
+   Return value of false corresponds with exclusion, true with inclusion."
+  (if-not args
+    true ; don't filter anything if args is undefined
+    (let [indexed-form (zipmap (map :full-name form) form)
+          query (aget args "query")
+          fmt-subitem (fn [[fname answer]]
+                        (format-answer (get indexed-form fname) answer))
+          filtered (->> item
+                        js->clj
+                        (map fmt-subitem)
+                        (map #(re-find (safe-regex query) (str %)))
+                        (remove nil?))]
+      (not (empty? filtered)))))
+
+(defn formatter [field language row cell value columnDef dataContext]
+  "Formatter for slickgrid columns takes row,cell,value,columnDef,dataContext.
+   Get one with (partial formatter field language)."
+  (let [clj-value (js->clj value :keywordize-keys true)]
+    (forms/format-answer field clj-value language :compact? true)))
+
+(defn- flat-form->sg-columns
+   "Get a set of slick grid column objects when given a flat form."
+  ([form] (flat-form->sg-columns form true))
+  ([form get-label?] (flat-form->sg-columns form get-label? nil))
+  ([form get-label? language]
+   (clj->js
+    (for [field (all-fields form)]
+      (let [{:keys [name type full-name]} field
+            label (if get-label? (get-label field language) name)]
+        {:id name :field full-name :type type
+         :name label :toolTip label :sortable true
+         :formatter (partial formatter field language)})))))
+
+(def sg-options
+  "Options to feed the slickgrid constructor."
+  #js {:enableColumnReorder false
+       :autoHeight true
+       :rowHeight 24
+       :enableTextSelectionOnCells true})
+
+(defn sg-init [data form]
+  "Creates a Slick.Grid backed by Slick.Data.DataView from data and fields.
+   Most events are handled by slickgrid. On double-click, event is put on chan.
+   Returns [grid dataview]."
+  (let [columns (flat-form->sg-columns form)
+        SlickGrid (.. js/Slick -Grid)
+        DataView (.. js/Slick -Data -DataView)
+        Pager (.. js/Slick -Controls -Pager)
+        dataview (DataView.)
+        grid (SlickGrid. (str "#" table-id) dataview columns sg-options)
+        pager (Pager. dataview grid (js/jQuery (str "#" pager-id)))]
+    ;; dataview / grid hookup
+    (.subscribe (.-onRowCountChanged dataview)
+                (fn [e args]
+                  (.updateRowCount grid)
+                  (.render grid)))
+    (.subscribe (.-onRowsChanged dataview)
+                (fn [e args]
+                  (.invalidateRows grid (aget args "rows"))
+                  (.render grid)))
+    ;; sort / double-click handlers
+    (.subscribe (.-onSort grid)
+                (fn [e args]
+                  (.sort dataview (compfn args) (aget args "sortAsc"))))
+    (.subscribe (.-onDblClick grid)
+                (fn [e args]
+                  (let [rank (aget (.getItem dataview (aget args "row")) "_rank")]
+                    (put! shared/event-chan {:submission-to-rank rank}))))
+    ;; page, filter, and data set-up on the dataview
+    (.setPagingOptions dataview #js {:pageSize 25})
+    (.setFilter dataview (partial filterfn form))
+    (.setItems dataview (clj->js data) "_id")
+    [grid dataview]))
+
+;; EVENT LOOPS
+
+(defn handle-table-events
+  [cursor grid dataview]
+  "Event loop for the table view. Processes a tap of share/event-chan,
+   and updates cursor/dataview/grid as needed."
+  (let [event-chan (shared/event-tap)]
+    (go
+     (while true
+       (let [e (<! event-chan)
+             {:keys [submission-to-rank submission-clicked submission-unclicked
+                     filter-by new-columns re-render]} e
+             update-data! (partial om/update! cursor
+                                   [:table-page :submission-clicked :data])]
+         (when submission-to-rank
+           (let [rank submission-to-rank
+                 submission (-> (filter #(= rank (get % "_rank"))
+                                        (get-in @cursor [:table-page :data]))
+                                first)]
+             (update-data! submission)))
+         (when submission-clicked
+           (update-data! submission-clicked))
+         (when submission-unclicked
+           (update-data! nil))
+         (when new-columns
+           (.setColumns grid new-columns)
+           (.render grid))
+         (when filter-by
+           (.setFilterArgs dataview (clj->js {:query filter-by}))
+           (.refresh dataview))
+         (when (= re-render "table")
+           ;; need tiny wait (~16ms requestAnimationFrame delay) to re-render table
+           (go (<! (timeout 20))
+               (.resizeCanvas grid)
+               (.invalidateAllRows grid)
+               (.render grid))))))))
+
+;; OM COMPONENTS
+
+(defn label-changer
+  [cursor owner]
+  (reify
+    om/IInitState
+    (init-state [_] {:name-or-label :label})
+    om/IRenderState
+    (render-state [_ {:keys [name-or-label language]}]
+      (let [options {:label [:span "Show: " [:strong "Label"]]
+                     :name [:span "Show: " [:strong "Name"]]}
+            {:keys [flat-form]} (om/get-shared owner)
+            new-language (:current (om/observe owner (shared/language-cursor)))
+            colset! #(put! shared/event-chan
+                           {:new-columns
+                            (flat-form->sg-columns flat-form
+                                                   (= :label %)
+                                                   new-language)})
+            choose (fn [k] (om/set-state! owner :name-or-label k)
+                           (colset! k))]
+        (when (not= new-language language)
+          (om/set-state! owner :language new-language)
+          (colset! name-or-label))
+        (html
+         [:div {:class "drop-hover" :id "header-display-dropdown"}
+          [:a {:href "#"}  (options name-or-label) [:i.fa.fa-angle-down]]
+          [:ul {:class "submenu no-dot"}
+           (for [[ok ov] options]
+             [:li [:a {:on-click (click-fn #(choose ok)) :href "#"} ov]])]])))))
+
+(defn delayed-search
+  "Delayed search fires a query-event on event-chan if the value of the input
+   doesn't change within 150 ms (ie, user is still typing).
+   Call on-change or on-key-up, with (.-target event) as first argument."
+  [input query-event-key]
+  (let [query (.-value input)]
+    ;; Wait 150 ms for input value to stabilize. Empirically felt good, plus
+    ;; 200 ms wait is when people start noticing change in interfaces
+    (go (<! (timeout 150))
+        (when (= query (.-value input))
+          (put! shared/event-chan {query-event-key query})))))
+
+(defn- init-grid!
+  [data owner]
+  "Initializes grid + dataview, and stores them in owner's state."
+  (when (seq data)
+    (let [{:keys [flat-form]} (om/get-shared owner)
+          [grid dataview] (sg-init data flat-form)]
+      (om/set-state! owner :grid grid)
+      (om/set-state! owner :dataview dataview)
+      [grid dataview])))
+
+(defn table-page
+  [cursor owner opts]
+  "Om component for the table grid.
+   Renders empty divs via om, hooks up slickgrid to these divs on did-mount."
+  (reify
+    om/IRenderState
+    (render-state [_ _]
+      (let [no-data? (empty? (get-in cursor [:table-page :data]))
+            with-info #(merge % {:dataset-info (:dataset-info cursor)})]
+        (html
+         [:div.table-view
+          (om/build (submission-view :table)
+                    (with-info (get-in cursor [:table-page :submission-clicked]))
+                    {:opts (select-keys opts #{:delete-record! :role})})
+          (if no-data?
+            [:h3 "No Data"]
+            [:div {:class "topbar"}
+             [:div {:id pager-id}]
+             (om/build label-changer nil)
+             [:div.table-search
+              [:i.fa.fa-search]
+              [:input {:type "text" :placeholder "Search"
+                       :on-change #(delayed-search (.-target %) :filter-by)}]]
+             [:div {:style {:clear "both"}}]])
+            [:div {:id table-id :class "slickgrid"}]])))
+    om/IDidMount
+    (did-mount [_]
+      (let [data (get-in cursor [:table-page :data])]
+        (when-let [[grid dataview] (init-grid! data owner)]
+          (handle-table-events cursor grid dataview))))
+    om/IWillReceiveProps
+    (will-receive-props [_ next-props]
+      "will-recieve-props resets slickgrid data if the table data has changed."
+      (let [old-data (get-in (om/get-props owner) [:table-page :data])
+            new-data (get-in next-props [:table-page :data])
+            {:keys [grid dataview]} (om/get-state owner)]
+        (when (not= old-data new-data)
+          (if (empty? old-data)
+            (when-let [[grid dataview] (init-grid! new-data owner)]
+              (handle-table-events cursor grid dataview))
+            (do ; data has changed
+              (.invalidateAllRows grid)
+              (.setItems dataview (clj->js new-data) "_id")
+              (.render grid))))))))


Test to get a feel for new data structure.

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

--- test/onyx/peer/lifecycles_test.clj
+++ test/onyx/peer/lifecycles_test.clj
@@ -0,0 +1,112 @@
+(ns onyx.peer.lifecycles-test
+  (:require [clojure.core.async :refer [chan >!! <!! close! sliding-buffer]]
+            [midje.sweet :refer :all]
+            [onyx.peer.task-lifecycle-extensions :as l-ext]
+            [onyx.plugin.core-async :refer [take-segments!]]
+            [onyx.test-helper :refer [load-config]]
+            [onyx.api]))
+
+(def id (java.util.UUID/randomUUID))
+
+(def config (load-config))
+
+(def env-config (assoc (:env-config config) :onyx/id id))
+
+(def peer-config (assoc (:peer-config config) :onyx/id id))
+
+(def env (onyx.api/start-env env-config))
+
+(def peer-group (onyx.api/start-peer-group peer-config))
+
+(def n-messages 100)
+
+(def batch-size 20)
+
+(defn my-inc [{:keys [n] :as segment}]
+  (assoc segment :n (inc n)))
+
+(def catalog
+  [{:onyx/name :in
+    :onyx/ident :core.async/read-from-chan
+    :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 :onyx.peer.lifecycles-test/my-inc
+    :onyx/type :function
+    :onyx/batch-size batch-size}
+
+   {:onyx/name :out
+    :onyx/ident :core.async/write-to-chan
+    :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"}])
+
+(def workflow [[:in :inc] [:inc :out]])
+
+(def lifecycles
+  [{:lifecycle/task :inc
+    :lifecycle/pre :onyx.peer.lifecycles-test/start-lifecycle
+    :lifecycle/pre-batch :onyx.peer.lifecycles-test/pre-batch
+    :lifecycle/post-batch :onyx.peer.lifecycles-test/post-batch
+    :lifecycle/post :onyx.peer.lifecycles-test/stop-lifecycle}])
+
+(defn counter (atom 0))
+
+(defn start-lifecycle [event lifecycle]
+  (swap! counter inc)
+  {})
+
+(defn stop-lifecycle [event lifecycle]
+  (swap! counter inc)
+  {})
+
+(defn pre-batch [event lifecycle]
+  (swap! counter inc)
+  {})
+
+(defn post-batch [event lifecycle]
+  (swap! counter inc)
+  {})
+
+(def in-chan (chan (inc n-messages)))
+
+(def out-chan (chan (sliding-buffer (inc n-messages))))
+
+(defmethod l-ext/inject-lifecycle-resources :in
+  [_ _] {:core.async/chan in-chan})
+
+(defmethod l-ext/inject-lifecycle-resources :out
+  [_ _] {:core.async/chan out-chan})
+
+(doseq [n (range n-messages)]
+  (>!! in-chan {:n n}))
+
+(>!! in-chan :done)
+(close! in-chan)
+
+(def v-peers (onyx.api/start-peers 3 peer-group))
+
+(onyx.api/submit-job
+ peer-config
+ {:catalog catalog
+  :workflow workflow
+  :task-scheduler :onyx.task-scheduler/balanced})
+
+(def results (take-segments! out-chan))
+
+(let [expected (set (map (fn [x] {:n (inc x)}) (range n-messages)))]
+  (fact (set (butlast results)) => expected)
+  (fact (last results) => :done))
+
+(doseq [v-peer v-peers]
+  (onyx.api/shutdown-peer v-peer))
+
+(onyx.api/shutdown-peer-group peer-group)
+
+(onyx.api/shutdown-env env)


Add test for quitting in interactive mode

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

--- test/app/test/interactive.clj
+++ test/app/test/interactive.clj
@@ -0,0 +1,10 @@
+(ns app.test.interactive
+  (:use [app.interactive]
+        [conjure.core]
+        [clojure.test]))
+
+(deftest can-quit
+  (let [input-command "quit\r"]
+    (with-in-str
+      input-command
+      (interactive []))))


Skip self route if `id` is null

Skip self route if `id` is null

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


a bit

a bit

error: pathspec 'Ugly-Number/UN.clj' did not match any file(s) known to git

--- Ugly-Number/UN.clj
+++ Ugly-Number/UN.clj
@@ -0,0 +1,12 @@
+(defn is-ugly [num]
+  (cond (contains? [0 -1] num) true
+        (contains? [1 2 3 5] num) true
+        (= 0 (mod num 2)) (recur (/ num 2))
+        (= 0 (mod num 3)) (recur (/ num 3))
+        (= 0 (mod num 5)) (recur (/ num 5))
+        :else false))
+
+
+(is-ugly 6)
+(is-ugly 8)
+(is-ugly 14)


cljs file

cljs file

error: pathspec 'src/clojure/nossal/data.cljc' did not match any file(s) known to git

--- src/clojure/nossal/data.cljc
+++ src/clojure/nossal/data.cljc
@@ -0,0 +1,89 @@
+(ns nossal.data
+  (:require #?(:clj [environ.core :refer [env]])
+            [clojure.string :as str])
+  #?(:cljs (:require-macros [nossal.data :refer [ga-tracking-id]])))
+
+
+
+#?(:clj (defmacro ga-tracking-id [] (env :ga-tracking-id)))
+
+
+(def allowed-image-sizes #{16 32 48 72 76 96 120 144 150 152 180 192 196 512 1024})
+
+
+(def pwa-manifest
+    {:name "Nossal, Rodrigo Nossal"
+     :short_name "NOSSAL"
+     :description "Rodrigo Nossal Personal Website"
+     :display "fullscreen"
+     :theme_color "#747f90"
+     :background_color "#747f90"
+     :orientation "portrait"
+     :start_url "https://noss.al/#utm_source=web_app_manifest"
+     :icons (map (fn [s]
+                   {:src (str "image/icon-" s ".png") :sizes (str s "x" s) :type "image/png"})
+                 (keep #(if (> % 32) %) allowed-image-sizes))})
+
+(def public-profiles {"Facebook"   "https://facebook.com/nossal"
+                      "Twitter"    "https://twitter.com/nossal"
+                      "Instagram"  "https://instagram.com/nossal"
+                      "GitHub"     "https://github.com/nossal"
+                      "linkedin"   "https://linkedin.com/in/nossal"
+                      "Spotify"    "https://open.spotify.com/user/nossal"
+                      "SoundCloud" "https://soundcloud.com/nossal"
+                      "Last.fm"    "https://last.fm/user/nossal"
+                      "Medium"     "https://medium.com/@nossal"
+                      "Flickr"     "https://flickr.com/photos/nossal"
+                      "SlideShare" "https://slideshare.net/nossal"
+                      "Google+"    "https://google.com/+RodrigoNossal"
+                      "Ello"       "https://ello.co/nossal"
+                      "About.me"   "https://about.me/nossal"
+                      "myspace"    "https://myspace.com/nossal"
+                      "Pinterest"  "https://pinterest.com/thenossal"})
+
+(def data-person {"@context" "https://schema.org"
+                  "@type" "Person"
+                  :name "Rodrigo Nossal"
+                  :url "https://noss.al"
+                  :sameAs (vals public-profiles)})
+
+(def data-website {"@context" "https://schema.org"
+                   "@type" "WebSite"
+                   :name "Nossal's"
+                   :alternateName "Rodrigo Nossal"
+                   :url "https://noss.al"})
+
+(def data-analytics
+  {"vars" {:gtag_id (ga-tracking-id)}
+   :triggers {:trackPageview {:on "visible" :request "pageview"}
+              :outboundLinks {:on "click"
+                              :selector "a.out"
+                              :request "event"
+                              :vars {:eventCategory "outbound"
+                                     :eventLabel "${outboundLink}"
+                                     :eventAction "click"}}
+              :trackClickOnCoupom {:on "click"
+                                   :selector "#get-coupom"
+                                   :request "event"
+                                   :vars {:eventCategory "ui-components"
+                                          :eventAction "get-coupom"}}
+              :trackClickOnPI {:on "click"
+                               :selector "a#tnet"
+                               :request "event"
+                               :vars {:eventCategory "ui-components"
+                                      :eventAction "the-net"}}
+
+              :trackPWAInstall {:on "beforeinstallprompt"
+                                :request "event"
+                                :vars {:eventCategory "ui-components"
+                                       :eventAction "PWA Install"}}}})
+
+#?(:clj (defn breadcrumbs [path]
+          {"@context" "http://schema.org"
+           "@type" "BreadcrumbList"
+           "itemListElement" (map-indexed (fn [idx item]
+                                           {"@type" "ListItem"
+                                            "position" (+ idx 1)
+                                            "name" item
+                                            "item" (str "https://noss.al/" (subs path 0 (str/index-of path item)) item)})
+                                          (str/split path #"\/"))}))


mesos: small fixes

mesos: small fixes

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


[TH] use finally to ensure delete occurs

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


epub fitxategia den egiaztatu

epub fitxategia den egiaztatu

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


set Content-Disposition header

set Content-Disposition header

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/20centaurifux/my-website.git/'


Refactor fingagle-clojure.scala/Function to prevent reflection

there were reflection warnings on the proxy-super call to Function#isDefinedAt
since the macro implementation couldn't put a type hint on this.

--- core/src/finagle_clojure/scala.clj
+++ core/src/finagle_clojure/scala.clj
@@ -32,6 +32,18 @@
   [scala-seq]
   (into [] (JavaConversions/seqAsJavaList scala-seq)))

+(defn ^com.twitter.util.Function Function*
+  ([apply-fn] (Function* apply-fn nil))
+  ([apply-fn defined-at-class]
+    (proxy [com.twitter.util.Function] []
+      (apply [arg]
+        (apply-fn arg))
+      (isDefinedAt [v]
+        (if defined-at-class
+          (instance? defined-at-class v)
+          (let [^com.twitter.util.Function this this]
+            (proxy-super isDefinedAt v)))))))
+
 (defmacro Function
   "Create a new com.twitter.util.Function.
   It can be used a scala.Function1 or scala.PartialFunction.
@@ -40,13 +52,7 @@
   The apply method will be implemented with body."
   [[arg-name] & body]
   (let [arg-tag (-> arg-name meta :tag)]
-    `(proxy [com.twitter.util.Function] []
-       (apply [~arg-name]
-         ~@body)
-       (isDefinedAt [~'v]
-         (if ~arg-tag
-           (instance? ~arg-tag ~'v)
-           (proxy-super isDefinedAt ~'v))))))
+    `(Function* (fn [~arg-name] ~@body) ~arg-tag)))

 (defmacro Function0
   "Create a new scala.Function0.


Implemented the random bitwise and instruction

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

--- test/chip8_clj/test_CXNN.clj
+++ test/chip8_clj/test_CXNN.clj
@@ -0,0 +1,14 @@
+(ns chip8-clj.test-CXNN
+  (:require [chip8-clj.machine-state :as machine-state])
+  (:require [clojure.test :refer :all]
+            [chip8-clj.core :refer :all]))
+
+(deftest random-bitwise-and-test
+  (with-redefs-fn {#'clojure.core/rand-int (fn [n] 0xAA)}
+    #(let [pre-machine-state (-> (machine-state/initialise)
+                                 (machine-state/set-pc 0)
+                                 (machine-state/set-instr 0 0xC10F))
+           post-machine-state (step pre-machine-state)]
+       (is (= (machine-state/get-register post-machine-state 1) 0x0A))
+       (is (= (machine-state/get-pc post-machine-state) 2)))))
+


FIXUP

FIXUP

error: pathspec 'test/neovim-client/nvim_test.clj' did not match any file(s) known to git

--- test/neovim-client/nvim_test.clj
+++ test/neovim-client/nvim_test.clj
@@ -0,0 +1,52 @@
+(ns neovim-client.nvim-test
+  (:require [clojure.test :as test :refer [deftest use-fixtures is]]
+            [neovim-client.nvim :as client.nvim]))
+
+(defn- neovim
+  "Make a neovim subprocess."
+  []
+  (let [p (.exec (Runtime/getRuntime) "nvim --embed")]
+    {:process p
+     :in (.getInputStream p)
+     :out (.getOutputStream p)}))
+
+(defn- stop-neovim
+  [{:keys [process]}]
+  (.destroy process))
+
+(defmacro with-neovim
+  [& body]
+  `(let [~'*neovim* (neovim)]
+     (try
+       ~@body
+       (finally (stop-neovim ~'*neovim*)))))
+
+;; TODO - this one will be hard to test. From the client-library's perspective,
+;; it will always have access to standard out. If it runs at all, standard
+;; out will exist. So is this worth testing?
+(deftest connect-fail-not-running
+  (is true))
+
+(deftest connect
+  (with-neovim
+    (let [{:keys [in out]} *neovim*]
+      (is (not (client.nvim/version-supported?
+                 (client.nvim/new* -1 in out false))))))
+
+  (with-neovim
+    (let [{:keys [in out]} *neovim*]
+      (is (not (client.nvim/version-supported?
+                 (client.nvim/new* 2 in out false))))))
+
+  (with-neovim
+    (let [{:keys [in out]} *neovim*]
+      (is (client.nvim/version-supported?
+            (client.nvim/new* 0 in out false)))))
+
+  (with-neovim
+    (let [{:keys [in out]} *neovim*]
+      (is (client.nvim/version-supported?
+            (client.nvim/new* 1 in out false))))))
+
+#_(clojure.tools.namespace.repl/refresh)
+#_(clojure.test/run-tests 'neovim-client.nvim-test)


[jepsen] make kudu-master-see-tservers more robust

Updated kudu-master-see-tservers function to be less fragile.
The prior implementation depended on the format of the output of the
'kudu cluster ksck' sub-command.  The updated implementation uses
'kudu tserver list' and relies only on the number of output lines
by the latter sub-command.

Also, dropped redundant 'node' parameter of the kudu-cli function.

Change-Id: I8b9ff0b7c145e5235a94de27bbedea1fe36f5e60
Reviewed-on: http://gerrit.cloudera.org:8080/10290
Reviewed-by: Will Berkeley <c74686ab413a71926fc1bc9d16ebfa30e619336a@gmail.com>
Tested-by: Alexey Serbin <864f6b82bd94e8dda64141d4274519ee66e0102e@cloudera.com>

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


Eskatutakoak bakarrik sartu dokumentazioan


Bump koan-engine

Bump koan-engine

refs #29

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


Add project.clj

Add project.clj

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

--- project.clj
+++ project.clj
@@ -0,0 +1,20 @@
+(defproject org.clojure/clojurescript "0.0-SNAPSHOT"
+  :description "ClojureScript compiler and core runtime library"
+  :parent [org.clojure/pom.contrib "0.1.2"]
+  :url "https://github.com/clojure/clojurescript"
+  :license {:name "Eclipse Public License"
+            :url "http://www.eclipse.org/legal/epl-v10.html"}
+  :source-paths ["src/clj"]
+  :resource-paths ["src/cljs"]
+  :test-paths ["test/cljs"]
+  :dependencies [[org.clojure/clojure "1.5.1"]
+                 [org.clojure/data.json "0.2.2"]
+                 [org.clojure/tools.reader "0.7.6"]
+                 [org.clojure/google-closure-library "0.0-20130212-95c19e7f0f5f"]
+                 [com.google.javascript/closure-compiler "v20130603"]
+                 [org.mozilla/rhino "1.7R4"]]
+  :profiles {:1.5 {:dependencies [[org.clojure/clojure "1.5.1"]]}
+             :1.6 {:dependencies [[org.clojure/clojure "1.6.0-master-SNAPSHOT"]]}}
+  :aliases {"test-all" ["with-profile" "test,1.5:test,1.6" "test"]
+            "check-all" ["with-profile" "1.5:1.6" "check"]}
+  :min-lein-version "2.0.0")


Beta 3

Beta 3

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


Upgrade to latest raven-clj (1.6.0)

Upgrade to latest raven-clj (1.6.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/tobias/clojars-web.git/'


projec file

projec file

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


Added licence into project file project.clj

--- project.clj
+++ project.clj
@@ -0,0 +1,21 @@
+;
+;  (C) Copyright 2015  Pavel Tisnovsky
+;
+;  All rights reserved. This program and the accompanying materials
+;  are made available under the terms of the Eclipse Public License v1.0
+;  which accompanies this distribution, and is available at
+;  http://www.eclipse.org/legal/epl-v10.html
+;
+;  Contributors:
+;      Pavel Tisnovsky
+;
+
+(defproject clj-jenkins-api "0.1.0-SNAPSHOT"
+  :description "FIXME: write description"
+  :url "http://example.com/FIXME"
+  :license {:name "Eclipse Public License"
+            :url "http://www.eclipse.org/legal/epl-v10.html"}
+  :dependencies [[org.clojure/clojure "1.6.0"]]
+  :main ^:skip-aot clj-jenkins-api.core
+  :target-path "target/%s"
+  :profiles {:uberjar {:aot :all}})


Update & clean up deps

Update & clean up deps

Added some exclusions to make datomic-pro 0.9.5385 happy.

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


Comments

Comments

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/rcarmo/yaki-clj.git/'


bump clojure 1.5 version

bump clojure 1.5 version

--- project.clj
+++ project.clj
@@ -18,7 +18,7 @@
                                   [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-alpha2"]]}}
+             :1.5 {:dependencies [[org.clojure/clojure "1.5.0-alpha3"]]}}
   :aliases {"all" ["with-profile" "dev,1.2:dev,1.3:dev:1.5,dev"]}
   :test-selectors {:default  #(not (:integration %))
                    :integration :integration


Release 0.8.10.

Release 0.8.10.

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


Version 1.15.8-SNAPSHOT

Version 1.15.8-SNAPSHOT

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


Turn on G1 garbage collector in production profile


Update deps

Update deps

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


lein-release plugin: bumped version from 0.2.7 to 0.2.8-SNAPSHOT for next development cycle

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


Implemented General-Sorted-Set

Implemented General-Sorted-Set

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

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

--- src/conexp/contrib/dl/playground.clj
+++ src/conexp/contrib/dl/playground.clj
@@ -0,0 +1,116 @@
+;; 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.dl.playground
+  (:use conexp.main)
+  (:use [clojure.contrib.seq :only (seq-on)]))
+
+(update-ns-meta! conexp.contrib.dl.playground
+  :doc "Playground for some more or less creative work for DL.")
+
+;;; sorted-set for non-total orderings
+
+(deftype General-Sorted-Set [order-fn maximal-elements minimal-elements])
+
+(declare add-to-gss remove-from-gss)
+
+(defn make-general-sorted-set
+  "Constructs a general sorted set for the given order function."
+  [order-fn]
+  (General-Sorted-Set order-fn (ref #{}) (ref #{})))
+
+(defmethod print-method ::General-Sorted-Set [gss out]
+  (.write out (print-str (seq-on gss))))
+
+(defmethod seq-on ::General-Sorted-Set [gss]
+  (let [runner (fn runner [have]
+		 (let [next-have (distinct (for [x have,
+						 y @(:uppers x),
+						 :when (and (not (some #(= y %) have))
+							    (forall [z @(:lowers y)]
+								    (some #(= z %) have)))]
+					     y))]
+		   (if (empty? next-have)
+		     have
+		     (recur (concat have next-have)))))]
+    (map :node (runner (vec @(:minimal-elements gss))))))
+
+;;
+
+(defn- find-neighbours
+  ;; auxilliary algorithm for finding neighbours
+  [gss test-fn neigh-fn current previous]
+  (let [next (filter test-fn current)]
+    (if (empty? next)
+      previous
+      (let [next-neighs (map neigh-fn next)]
+	(recur gss test-fn neigh-fn
+	       (if (every? empty? next-neighs)
+		 #{}
+		 (set (apply intersection next-neighs)))
+	       (set next))))))
+
+(defn- find-upper-neighbours
+  "Finds all upper neighbours of x in gss."
+  [gss x]
+  (find-neighbours gss #((:order-fn gss) x (:node %)) (comp deref :lowers) @(:maximal-elements gss) #{}))
+
+(defn- find-lower-neighbours
+  "Finds all lower neighbours of x in gss."
+  [gss x]
+  (find-neighbours gss #((:order-fn gss) (:node %) x) (comp deref :uppers) @(:minimal-elements gss) #{}))
+
+(defn add-to-gss
+  "Adds the element elt to the general sorted set gss returning the
+  result."
+  [gss elt]
+  (dosync
+   (let [order-fn (:order-fn gss),
+
+	 uppers (find-upper-neighbours gss elt),
+	 lowers (find-lower-neighbours gss elt),
+
+	 new-elt {:node elt,
+		  :uppers (ref uppers),
+		  :lowers (ref lowers)}]
+
+     ;; check if element is already there
+     (when-not (or (some #(order-fn (:node %) elt) uppers)
+		   (some #(order-fn elt (:node %)) lowers))
+
+       ;; update neighbours
+       (doseq [u uppers]
+	 (alter (:lowers u) conj new-elt))
+       (doseq [l lowers]
+	 (alter (:uppers l) conj new-elt))
+
+       ;; remove redundant edges
+       (doseq [u uppers,
+	       l lowers]
+	 (when (contains? @(:uppers l) u)
+	   (alter (:uppers l) disj u)
+	   (alter (:lowers u) disj l)))
+
+       ;; update maximal and minimal elements
+       (ref-set (:maximal-elements gss)
+		(set-of x [x (conj @(:maximal-elements gss) new-elt)
+			   :when (empty? @(:uppers x))]))
+       (ref-set (:minimal-elements gss)
+		(set-of x [x (conj @(:minimal-elements gss) new-elt)
+			   :when (empty? @(:lowers x))])))
+
+     gss)))
+
+(defn remove-from-gss
+  "Removes the element elt from the general sorted set gss."
+  [gss elt]
+  (unsupported-operation "Removing elements from a general sorted set has not been thought of!"))
+
+;;;
+
+nil


added p15.clj

added p15.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/drcabana/euler-fp.git/'


reorg source

reorg source

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


Implemented dump of png image for reports

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

--- src/machine_learning/report/image.clj
+++ src/machine_learning/report/image.clj
@@ -0,0 +1,24 @@
+(ns machine-learning.report.image
+  (:require [clojure.java.io :as io])
+  (:import (java.awt.image BufferedImage)
+           (java.awt Color)
+           (javax.imageio ImageIO)
+           (java.io File)))
+
+(defn as-rgb [intensity]
+  (let [gray (Math/round ^Float (* (- 1 intensity) 255.0))]
+    (.getRGB (Color. gray gray gray))))
+
+(defn set-pixel [b_image pos pixel]
+  (.setRGB b_image (quot pos 28) (mod pos 28) (as-rgb pixel)))
+
+(defn image-for [image]
+  (let [bi (BufferedImage. 28 28 BufferedImage/TYPE_INT_RGB)]
+    (dorun (map  #(set-pixel bi %1 (first %2)) (range 0 784) image))
+    bi))
+
+(defn save-image-png [image filename]
+  (let [^BufferedImage bi (image-for image)
+        g (.createGraphics bi)]
+    (ImageIO/write bi "png" ^File (io/as-file filename))))
+


add mocked out handlers for access keys (Add, Read All)

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

--- src/wombats/handlers/access_keys.clj
+++ src/wombats/handlers/access_keys.clj
@@ -0,0 +1,32 @@
+(ns wombats.handlers.access-keys
+  (:require [io.pedestal.interceptor.helpers :as interceptor]))
+
+(def ^:swagger-spec get-access-keys-spec
+  {"/api/v1/access_keys"
+   {:get {:description "Returns a collection of all access keys in the system"
+          :tags ["access-key"]
+          :operationId "get-access-keys"
+          :responses {:200 {:description "get-access-keys response"}}}}})
+
+(def get-access-keys
+  (interceptor/before
+   ::get-access-keys
+   (fn [{:keys [response] :as context}]
+     (assoc context :response (assoc response
+                                     :status 200
+                                     :body [])))))
+
+(def ^:swagger-spec add-access-key-spec
+  {"/api/v1/access_keys"
+   {:post {:description "Creates and returns a new access key"
+           :tags ["access-key"]
+           :operationId "add-access-keys"
+           :responses {:200 {:description "add-access-key response"}}}}})
+
+(def get-access-keys
+  (interceptor/before
+   ::get-access-keys
+   (fn [{:keys [response] :as context}]
+     (assoc context :response (assoc response
+                                     :status 200
+                                     :body [])))))


[WM] attach VBM appl forms to signup emails

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


Clojure day 14 solution.

Clojure day 14 solution.

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

--- clojure/src/advent2016/day14.clj
+++ clojure/src/advent2016/day14.clj
@@ -0,0 +1,32 @@
+(ns advent2016.day14
+  (:require [advent2016.core :refer [md5]]))
+
+(def example "abc")
+(def puzzle "cuanljph")
+
+(def triple (comp second (partial re-find #"([0-9a-f])\1{2}")))
+(defn quintuple? [^String digit ^String hash]
+  (clojure.string/index-of hash (str digit digit digit digit digit)))
+
+(defn key? [stream ^String hash]
+  (if-let [digit (triple hash)]
+    (some #(quintuple? digit %) (take 1000 stream))))
+
+(defn hash-stream [f ^String salt]
+  (map (fn [n] (list n (f (str salt n)))) (range)))
+
+(defn key-stream [stream]
+  (filter (fn [[n hash]] (key? (drop (inc n) stream) hash)) stream))
+
+(defn stretched-md5 [^String hash]
+  (nth (iterate md5 hash) 2017))
+
+(def solution1-key-stream (->> puzzle
+                               (hash-stream md5)
+                               key-stream))
+(def solution1 (take 64 solution1-key-stream))
+
+(def solution2-key-stream (->> puzzle
+                               (hash-stream stretched-md5)
+                               key-stream))
+(def solution2 (take 64 solution2-key-stream))


Force garbage collection on game pause.

Force garbage collection on game pause.

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


if other is selected party option party should be left blank

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


Add new impl for testing better levenshtein distance.

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

--- src/clj/clj_diff/miller_ld.clj
+++ src/clj/clj_diff/miller_ld.clj
@@ -0,0 +1,217 @@
+(ns clj-diff.miller-ld
+  "Algorithm from 'An O(NP) Sequence Comparison Algorithm' by
+   Sun Wu, Udi Manber, Gene Myers and Web Miller.
+
+   Please refer to the above paper while reading this code."
+  (:require [clj-diff [optimizations :as opt]]))
+
+(defn- next-x
+  "Get the next farthest x value by looking at previous farthest values on the
+  diagonal above and below diagonal k. Choose the greater of the farthest x on
+  the above diagonal and the farthest x on the diagonal below plus one. fp is
+  a map of diagonals => farthest points."
+  [k fp]
+  (max (inc (get fp (dec k) -1))
+       (get fp (inc k) -1)))
+
+(defn- snake
+  "Starting at the farthest point on diagonal k, return the x value of the
+  point at the end of the longest snake on this diagonal. A snake is a
+  sequence of diagonal moves connecting match points on the edit graph."
+  [a b n m k fp]
+  {:pre [(and (vector? a) (vector? b))]}
+  (let [x (next-x k fp)
+        y (- x k)]
+    (loop [x x
+           y y]
+      (if (and (< x n) (< y m) (= (get a (inc x)) (get b (inc y))))
+        (recur (inc x) (inc y))
+        x))))
+
+(defn- search-p-band
+  "Given a p value, search all diagonals in the p-band for the furthest
+  reaching endpoints. Record the furthest reaching endpoint for each p value
+  in the map fp. Returns an updated fp map for p. a and b are the two
+  sequences and n and m are their lengths respectively. delta is the
+  diagonal of the sink and is equal to n - m."
+  [a b n m delta p fp]
+  (reduce (fn [fp next-k]
+            (assoc fp next-k (snake a b n m next-k fp)))
+          fp
+          (concat (range (* -1 p) delta)
+                  (reverse (range (inc delta) (+ delta (inc p))))
+                  [delta])))
+
+(defn ses
+  "Find the size of the shortest edit script (ses). Returns a 3-tuple of the
+  size of the ses, the delta value (which is the diagonal of the sink)
+  and the fp map. The optimal path from source to sink can be constructed from
+  this information."
+  [a b]
+  {:pre [(>= (count a) (count b))]}
+  (let [n (dec (count a))
+        m (dec (count b))
+        delta (- n m)]
+    (loop [p 0
+           fp {}]
+      (if (= (-> (get fp (dec p) {})
+                 (get delta))
+             n)
+        [(dec p) delta fp]
+        (recur (inc p)
+               (assoc fp p
+                      (search-p-band a b n m delta p (get fp (dec p) {}))))))))
+
+;;
+;; Build the edit script from the map of farthest endpoints.
+;;
+
+(defn- edit-dist
+  "Given a delta, p and k value, calculate the edit distance."
+  [delta p k]
+  (if (> k delta)
+    (+ (* 2 (- p (- k delta))) k)
+    (+ (* 2 p) k)))
+
+(defn- p-value-up
+  "Calculate the p value that will be used to look up the farthest reaching
+  end point for the diagonal above k."
+  [delta p k]
+  (if (> (inc k) delta) p (dec p)))
+
+(defn- p-value-left
+  "Calculate the p value that will be used to look up the farthest reaching
+  end point for the diagonal below k."
+  [delta p k]
+  (if (< (dec k) delta) p (dec p)))
+
+(defn- look-up
+  "Get information about the vertex above the one at x on k. If this vertex
+  is chosen, it will represent an insertion."
+  [graph delta p x k]
+  (when (> (- x k) 0)
+    (let [up-k (inc k)
+          up-p (p-value-up delta p k)
+          x* (-> graph
+                 (get up-p {})
+                 (get up-k -1))]
+      (when (and (>= x* 0) (= x x*))
+        {:edit :insert
+         :x x*
+         :p up-p
+         :k up-k
+         :d (edit-dist delta up-p up-k)}))))
+
+(defn- look-left
+  "Get information about the vertex to the left of the one at x on k. If this
+  vertex is chosen, it will represent an deletion."
+  [graph delta p x k]
+  (when (> x 0)
+    (let [left-k (dec k)
+          left-p (p-value-left delta p k)
+          x* (-> graph
+                 (get left-p {})
+                 (get left-k -1))]
+      (when (and (>= x* 0) (= (dec x) x*))
+        {:edit :delete
+         :x x*
+         :p left-p
+         :k left-k
+         :d (edit-dist delta left-p left-k)}))))
+
+(defn- backtrack-snake
+  "Find the x value at the head of the longest snake ending at (x, y)."
+  [a b x y]
+  {:pre [(and (>= x 0) (>= y 0))]}
+  (loop [x x
+         y y]
+    (if (or (= x y 0) (not (= (get a x) (get b y))))
+      x
+      (recur (dec x) (dec y)))))
+
+(defn- next-edit
+  "Find the next move through the edit graph which will decrease the
+  edit distance by 1."
+  [a b graph delta p x k]
+  {:post [(= (dec (edit-dist delta p k)) (:d %))]}
+  (let [d (edit-dist delta p k)
+        head-x (backtrack-snake a b x (- x k))]
+    (loop [head-x head-x]
+      (let [move (first (filter #(and (not (nil? %))
+                                      (= (:d %) (dec d)))
+                                (map #(% graph delta p head-x k)
+                                     [look-left look-up])))]
+        (if (and (< head-x x) (nil? move))
+          (recur (inc head-x))
+          move)))))
+
+(defn- edits
+  "Calculate the sequence of edits from the map of farthest reaching end
+  points."
+  [a b p delta graph]
+  (let [next-fn (partial next-edit a b graph delta)]
+    (loop [edits '()
+           prev {:x (count a) :p p :k delta
+                 :d (edit-dist delta p delta)}]
+      (if (= (:d prev) 0)
+        edits
+        (let [next (next-fn (:p prev) (:x prev) (:k prev))]
+          (recur (conj edits next) next))))))
+
+(defn- diff*
+  "Calculate the sequence of edits required to transform a into b  using the
+  miller algorithm. This algorithm requires that a >= b."
+  [a b]
+  {:pre [(>= (count a) (count b))]}
+  (apply edits a b (ses a b)))
+
+(defn- transpose
+  "If a is shorter than b, then the diff is calculated from b to a and this
+  function is used to transpose the results into a diff from a to b."
+  [edit]
+  (-> edit
+      (assoc :edit (if (= :insert (:edit edit)) :delete :insert))
+      (assoc :x (- (:x edit) (:k edit)))
+      (assoc :k (- (:k edit)))))
+
+(defn- edits->script
+  "Convert a sequence of edits into an edit script."
+  [b edits f]
+  (reduce (fn [script edit]
+            (let [{:keys [edit x k]} (f edit)
+                  y (inc (- x k))
+                  insertions (:+ script)
+                  last-insert (last insertions)]
+              (if (= edit :delete)
+                (assoc script :- (conj (:- script) x))
+                (assoc script :+ (let [index (dec x)]
+                                   (if (= index (first last-insert))
+                                     (conj (vec (butlast insertions))
+                                           (conj last-insert (get b y)))
+                                     (conj insertions [(dec x) (get b y)])))))))
+          {:+ []
+           :- []}
+          edits))
+
+(defn seq-diff
+  [a b]
+  (let [a (vec (cons nil a))
+        b (vec (cons nil b))
+        [a* b*] (if (> (count b) (count a)) [b a] [a b])
+        edits (diff* a* b*)]
+    (edits->script b edits (if (= a* a) identity transpose))))
+
+(defmulti ^{:arglists '([a b])} diff
+  "Create an edit script that may be used to transform a into b. See doc string
+  for clj-diff.core/diff. This function will ensure that diff* is called with
+  arguments a and b where a >= b. If the passed values of a and b need to be
+  swapped then the resulting path with will transposed."
+  (fn [a b] (when (and (string? a) (string? b)) :string)))
+
+(defmethod diff :default
+  [a b]
+  (seq-diff a b))
+
+(defmethod diff :string
+  [a b]
+  (opt/diff a b seq-diff))


add multiinsertR

add multiinsertR

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/carolove/clojure-ring-app.git/'


finished simplified drpc, added test of local workflow

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

--- test/clj/backtype/storm/drpc_test.clj
+++ test/clj/backtype/storm/drpc_test.clj
@@ -0,0 +1,37 @@
+(ns backtype.storm.drpc-test
+  (:use [clojure test])
+  (:import [backtype.storm.drpc ReturnResults DRPCSpout])
+  (:import [backtype.storm LocalDRPC LocalCluster])
+  (:use [backtype.storm bootstrap testing])
+  (:use [backtype.storm.daemon common])
+  (:use [backtype.storm clojure])
+  )
+
+(bootstrap)
+
+(defbolt exclamation-bolt ["result" "return-info"] [tuple collector]
+  (emit-bolt! collector
+              [(str (.getString tuple 0) "!!!") (.getValue tuple 1)]
+              :anchor tuple)
+  )
+
+(deftest test-drpc-flow
+  (let [drpc (LocalDRPC.)
+        spout (DRPCSpout. "test" drpc)
+        cluster (LocalCluster.)
+        topology (topology
+                  {1 (spout-spec spout)}
+                  {2 (bolt-spec {1 :shuffle}
+                                exclamation-bolt)
+                   3 (bolt-spec {2 :shuffle}
+                                (ReturnResults.))})]
+    (.submitTopology cluster "test" {TOPOLOGY-DEBUG true} topology)
+
+    (is (= "aaa!!!") (.execute drpc "test" "aaa"))
+    (is (= "b!!!") (.execute drpc "test" "b"))
+    (is (= "c!!!") (.execute drpc "test" "c"))
+
+
+    (.shutdown cluster)
+    (.shutdown drpc)
+    ))


avoid really long strings.

avoid really long strings.

--- test/metabase/email/messages_test.clj
+++ test/metabase/email/messages_test.clj
@@ -4,5 +4,8 @@

 (expect
-  "
Welcome to Metabase test!

Your account is setup and ready to go, you just need to set a password so you can login.  Follow the link below to reset your account password.

http://localhost/some/url
"
+  (str "
Welcome to Metabase test!
"
+    "
Your account is setup and ready to go, you just need to set a password so you can login.  "
+    "Follow the link below to reset your account password.
"
+    "
http://localhost/some/url
")
   (send-new-user-email "test" "test@test.com" "http://localhost/some/url"))


Adding namespace ability in comments, cleaning up message

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


util/courts.clj: copied from v4, for www/SearchResource.clj

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

--- src/org/altlaw/util/courts.clj
+++ src/org/altlaw/util/courts.clj
@@ -0,0 +1,24 @@
+(ns org.altlaw.util.courts)
+
+(def *court-names* {
+"http://id.altlaw.org/courts/us/fed/supreme" "United States Supreme Court"
+"http://id.altlaw.org/courts/us/fed/app/1" "United States Court of Appeals for the First Circuit"
+"http://id.altlaw.org/courts/us/fed/app/2" "United States Court of Appeals for the Second Circuit"
+"http://id.altlaw.org/courts/us/fed/app/3" "United States Court of Appeals for the Third Circuit"
+"http://id.altlaw.org/courts/us/fed/app/4" "United States Court of Appeals for the Fourth Circuit"
+"http://id.altlaw.org/courts/us/fed/app/5" "United States Court of Appeals for the Fifth Circuit"
+"http://id.altlaw.org/courts/us/fed/app/6" "United States Court of Appeals for the Sixth Circuit"
+"http://id.altlaw.org/courts/us/fed/app/7" "United States Court of Appeals for the Seventh Circuit"
+"http://id.altlaw.org/courts/us/fed/app/8" "United States Court of Appeals for the Eighth Circuit"
+"http://id.altlaw.org/courts/us/fed/app/9" "United States Court of Appeals for the Ninth Circuit"
+"http://id.altlaw.org/courts/us/fed/app/10" "United States Court of Appeals for the Tenth Circuit"
+"http://id.altlaw.org/courts/us/fed/app/11" "United States Court of Appeals for the Eleventh Circuit"
+"http://id.altlaw.org/courts/us/fed/app/fed" "United States Court of Appeals for the Federal Circuit"
+"http://id.altlaw.org/courts/us/fed/app/dc" "United States Court of Appeals for the District of Columbia Circuit"
+"http://id.altlaw.org/courts/us/fed/app/af" "United States Court of Appeals for the Armed Forces"
+"http://id.altlaw.org/courts/us/fed/eca" "Emergency Court of Appeals"
+"http://id.altlaw.org/courts/us/fed/teca" "Temporary Emergency Court of Appeals"
+"http://id.altlaw.org/courts/us/fed/customs-patents" "United States Court of Customs and Patent Appeals"
+"http://id.altlaw.org/courts/us/fed/court-of-claims" "United States Court of Claims"
+"http://id.altlaw.org/courts/us/fed/claims" "United States Court of Federal Claims"
+})


Add problem70.clj

Add problem70.clj

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

--- euler_clojure/src/euler/problem70.clj
+++ euler_clojure/src/euler/problem70.clj
@@ -0,0 +1,32 @@
+(ns euler.problem70
+  "https://projecteuler.net/problem=70
+
+  Euler's Totient function, φ(n) [sometimes called the phi function], is used
+  to determine the number of positive numbers less than or equal to n which are
+  relatively prime to n. For example, as 1, 2, 4, 5, 7, and 8, are all less
+  than nine and relatively prime to nine, φ(9)=6. The number 1 is considered to
+  be relatively prime to every positive number, so φ(1)=1.
+
+  Interestingly, φ(87109)=79180, and it can be seen that 87109 is a permutation
+  of 79180.
+
+  Find the value of n, 1 < n < 10**7, for which φ(n) is a permutation of n and
+  the ratio n/φ(n) produces a minimum."
+  (:require [euler.toolset :refer [get-primes phi]]))
+
+(defn problem70 []
+  ;; The search space is too large for brute-force. So, note that we are
+  ;; seeking roughly the inverse of the previous problem -- to minimize
+  ;; n/phi(n). Therefore, we want to maximize phi(n), which is acheived for
+  ;; numbers with the fewest and largest unique prime factors. But the number
+  ;; cannot simply be prime because in that case phi(n) == n-1 which is not a
+  ;; permutation of n. Therefore, the best candidates should have two unique
+  ;; prime factors.
+  (let [permutation? (fn [x y] (= (sort (str x))
+                                  (sort (str y))))
+        ;; Since we are seeking large values for both prime factors, we can search
+        ;; among numbers close to the value of sqrt(1e7) ~ 3162
+        ps (take-while #(< % 4000) (get-primes 2000))
+        ns (for [x ps, y ps :when (and (not= x y) (< (* x y) 1e7))] (* x y))
+        candidates (filter #(permutation? % (phi %)) ns)]
+    (apply min-key #(/ % (phi %)) candidates)))


split out laziness test to correspond to src structure

error: pathspec 'test/midje/util/t_laziness.clj' did not match any file(s) known to git

--- test/midje/util/t_laziness.clj
+++ test/midje/util/t_laziness.clj
@@ -0,0 +1,24 @@
+(ns midje.util.t-laziness
+  (:use [midje.sweet]
+	[midje.util laziness]
+	[midje.test-util]))
+
+;; Justification for use of eagerly
+(def counter (atom 1))
+(def mocked-function-produces-next-element inc)
+
+(defn function-under-test-produces-a-lazy-list []
+  (iterate mocked-function-produces-next-element 1))
+
+(defn mock-use []
+  (binding [mocked-function-produces-next-element (fn [n] (swap! counter inc) (inc n))]
+    (eagerly (take 5 (function-under-test-produces-a-lazy-list)))))
+
+(fact "eagerly forces evaluation"
+  (mock-use)
+  @counter => 5)
+
+(fact "eagerly allows non-sequences"
+  (eagerly 3) => 3)
+
+


Cache templates by URI instead

Cache templates by URI instead

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


Further simplification of Constitutional role validation.

--- spec/freefrog/governance_circles_spec.clj
+++ spec/freefrog/governance_circles_spec.clj
@@ -66,22 +66,20 @@
   (should-not-update-missing-or-empty-roles g/convert-to-role
                                             "convert to role"))

-(defn should-not-change-constitutional [desc fn role-name & params]
-  (it (format "doesn't let you %s the %s role" desc role-name)
+(defn should-not-change-constitutional [desc fn role-name params]
+  (it (format "doesn't %s the %s role" desc role-name)
     (should-throw IllegalArgumentException
       (format "'%s' role is defined in the Constitution." role-name)
       (apply fn (into [sample-anchor role-name] params)))))

 (describe "Constitutional Roles"
-  (for [role [g/lead-link g/rep-link g/secretary g/facilitator]]
-    (describe role
-      (for [op [["Add" g/add-role]
-                ["Remove" g/remove-role]]]
-        (should-not-change-constitutional (first op) (second op) role))
-      (should-not-change-constitutional "Rename" g/rename-role role "stuff")
-      (should-not-change-constitutional "Update the purpose of"
-                                        g/update-role-purpose
-                                        role "stuff"))))
+  (for [role [g/lead-link g/rep-link g/secretary g/facilitator]
+        op [["Add" g/add-role]
+            ["Remove" g/remove-role]
+            ["Rename" g/rename-role "stuff"]
+            ["Update the purpose of" g/update-role-purpose "Stuff"]]]
+    (should-not-change-constitutional (first op) (second op) role
+                                      (drop 2 op))))

 ;; Section 2.2.3
 (describe "Lead Link Role"


removes data-source/dataSource comment

removes data-source/dataSource comment

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


Spoof content-type to force Chrome to save PDFs.

--- export-server/src/export_server/core.clj
+++ export-server/src/export_server/core.clj
@@ -23,7 +23,7 @@
 	"-d" (.getPath pdf-temp)
 	(.getPath svg-temp)))
     {:status 200
-     :headers {"Content-Type" "application/pdf"}
+     :headers {"Content-Type" "application/binary"}
      :body pdf-temp}))

 (defroutes exporter


Make nav item icons clickable

Make nav item icons clickable


testing code for trying to explain to user why difficult to make it tail-recursive

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

--- src/adventofcode1/recur1.clj
+++ src/adventofcode1/recur1.clj
@@ -0,0 +1,32 @@
+(ns adventofcode1.recur1
+  "tail-recursion"
+  (:require
+   [clojure.spec :as s]
+   [clojure.spec.gen :as gen]
+   [clojure.spec.test :as stest]
+
+   [clojure.core.match :refer [match]]
+
+   spyscope.core
+   )
+  )
+
+(def function-table (zipmap '(+ - * pd)
+                            '(2 2 2 2)))
+
+(defn random-function
+  []
+  (rand-nth (keys function-table)))
+
+(defn random-terminal
+  []
+  (rand-nth (list 'x (- (rand 10) 5))))
+
+(defn random-code
+  [depth]
+  (if (or (zero? depth)
+          )
+    (random-terminal)
+    (let [f (random-function)]
+      (cons f (doall (repeatedly (get function-table f)
+                                 #(random-code (dec depth))))))))


Spec int literals

Spec int literals

error: pathspec 'src/atom_finder/ast-spec.clj' did not match any file(s) known to git

--- src/atom_finder/ast-spec.clj
+++ src/atom_finder/ast-spec.clj
@@ -0,0 +1,28 @@
+(ns atom-finder.spec
+
+(:import [org.eclipse.cdt.core.dom.ast IASTNode IASTBinaryExpression IASTUnaryExpression]
+         [org.eclipse.cdt.internal.core.dom.parser.cpp CPPASTBinaryExpression CPPASTLiteralExpression])
+(:require [clojure.spec :as s]
+          [clojure.spec.gen :as gen]
+          [clojure.spec.test :as test]
+          [clojure.string :as str]
+          [atom-finder.util :refer :all]
+          )
+)
+
+(defn ast-node? [node] (instance? IASTNode node))
+(s/def ::ast-node ast-node2?)
+(s/fdef leaves :args ::ast-node :ret (s/coll-of ::ast-node))
+;(s/exercise leaves)
+
+(s/def ::binary-expression (s/and ast-node? (partial instance? CPPASTBinaryExpression)))
+(s/def ::literal-expression (s/and ast-node? (partial instance? CPPASTLiteralExpression)))
+
+(defn gen-int-literal-expression
+  []
+  (->> (s/gen (s/int-in -2147483648 2147483647))
+       (gen/fmap #(->> (str %)
+                       (.toCharArray)
+                       (CPPASTLiteralExpression. CPPASTLiteralExpression/lk_integer_constant)))))
+
+(map (comp write-ast first) (s/exercise ::literal-expression 10 {::literal-expression gen-int-literal-expression}))


Config namespace added

Config namespace added

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

--- src/clj/hellhound/config.clj
+++ src/clj/hellhound/config.clj
@@ -0,0 +1,15 @@
+(ns hellhound.config
+  "This namespace contains several helpers functions to load a `edn`
+  configuration file from classpath.
+
+  ## why not to use `environ` and `project.clj`?
+  Because `environ` convert the values to string and also it's hard
+  to fit a hash-map into a environment variable in production."
+  (:require [clojure.edn     :as edn]
+            [clojure.java.io :as io]))
+
+(defn read-config
+  "Read the content of the config file with the given `config-name`
+  and return a clojure data structure."
+  [config-name]
+  (edn/read-string (slurp (io/resource config-name))))


Work around OpenJDK/OpenSSL PKCS11 TLSv1 issue

http://stackoverflow.com/questions/9586162/openjdk-and-php-ssl-connection-fails
https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/948875

This issue prevents clients using OpenSSL 1.0.1 from connecting to a
PuppetDB running on OpenJDK, with the PKCS11 security provider enabled.
So we disable the security provider, which isn't actually necessary
anyway.

--- src/com/puppetlabs/jetty.clj
+++ src/com/puppetlabs/jetty.clj
@@ -4,11 +4,26 @@
   (:import (org.mortbay.jetty Server)
            (org.mortbay.jetty.bio SocketConnector)
            (org.mortbay.jetty.security SslSocketConnector))
-  (:require [ring.adapter.jetty :as jetty]))
+  (:require [ring.adapter.jetty :as jetty])
+  (:use [clojure.tools.logging :as log]))

 ;; We need to monkey-patch `add-ssl-connector!` in order to set the
 ;; appropriate options for Client Certificate Authentication, and use
 ;; an ssl-specific host for the socket listener.
+
+;; Work around an issue with OpenJDK's PKCS11 implementation preventing TLSv1
+;; connections from working correctly
+;;
+;; http://stackoverflow.com/questions/9586162/openjdk-and-php-ssl-connection-fails
+;; https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/948875
+(if (re-find #"OpenJDK" (System/getProperty "java.vm.name"))
+  (try
+    (let [blacklist (filter #(instance? sun.security.pkcs11.SunPKCS11 %) (java.security.Security/getProviders))]
+      (doseq [provider blacklist]
+        (log/info (str "Removing buggy security provider " provider))
+        (java.security.Security/removeProvider (.getName provider))))
+    (catch Throwable e
+      (log/error e "Could not remove security providers; HTTPS may not work!"))))

 (defn add-ssl-connector!
   "Add an SslSocketConnector to a Jetty Server instance."


Remove pprint call from tests

Remove pprint call from tests

Seems like a debugging leftover

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


[WM DC] Add election-day voter reg. tests

...that fail in this commit b/c we're about to write the code to make
them pass. Yay TDD!


add notes to all order creation again

add notes to all order creation again


use deref notation

use deref notation

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/AustinC/persistent-internals.git/'


Add a loop to simplify the trees

Add a loop to simplify the trees

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


Add overtone.helpers.ref ns with swap-returning-prev! fn

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

--- src/overtone/helpers/ref.clj
+++ src/overtone/helpers/ref.clj
@@ -0,0 +1,15 @@
+(ns overtone.helpers.ref)
+
+(defn swap-returning-prev!
+  "Similar to swap! except returns vector containing the previous and new values
+
+  (def a (atom 0))
+  (swap-returning-prev! a inc) ;=> [0 1]"
+  [atom f & args]
+  (loop []
+    (let [old-val  @atom
+          new-val  (apply f (cons old-val args))
+          success? (compare-and-set! atom old-val new-val)]
+      (if success?
+        [old-val new-val]
+        (recur)))))


Use forms instead of strings where possible in answer sheet.

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