simple record api

simple record api

supporting compound keys

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

--- src/er_cassandra/record.clj
+++ src/er_cassandra/record.clj
@@ -0,0 +1,79 @@
+(ns er-cassandra.record
+  (:require
+   [plumbing.core :refer :all]
+   [qbits.alia.manifold :as aliam]
+   [qbits.hayt :as h]
+   [clj-uuid :as uuid]))
+
+(defn make-sequential
+  [v]
+  (cond (nil? v) v
+        (sequential? v) v
+        :else [v]))
+
+(defn extract-key-clause
+  ([key record] (extract-key-clause key record {}))
+  ([key record {:keys [key-value]}]
+   (let [key (make-sequential key)
+         use-key-value (or (make-sequential key-value)
+                           (repeat nil))
+         use-key-value (map (fn [k dv]
+                              (let [kv (or dv (get record k))]
+                                (when-not kv
+                                  (throw (ex-info "no key value"
+                                                  {:key key
+                                                   :record record
+                                                   :key-value key-value})))
+                                kv))
+                            key
+                            use-key-value)]
+     (mapv (fn [k v]
+             [:= k v])
+           key
+           use-key-value))))
+
+(defn select
+  ([session table key record-or-key-value]
+   (select session table key record-or-key-value {}))
+  ([session table key record-or-key-value {:keys [key-value] :as opts}]
+   (let [key-value (or key-value
+                       (when-not (map? record-or-key-value)
+                         record-or-key-value))
+         record (when (map? record-or-key-value)
+                  record-or-key-value)
+         key-clause (extract-key-clause key record {:key-value key-value})]
+     (aliam/execute
+      session
+      (h/->raw
+       (h/select table
+                 (h/where key-clause)))))))
+
+(defn upsert
+  "upsert a single record"
+  ([session table key record]
+   (upsert session table key record {}))
+  ([session table key record {:keys [key-value] :as opts}]
+   (let [key-clause (extract-key-clause key record opts)
+         set-cols (apply dissoc record (make-sequential key))]
+     (aliam/execute
+      session
+      (h/->raw
+       (h/update table
+                 (h/set-columns set-cols)
+                 (h/where key-clause)))))))
+
+(defn delete
+  ([session table key record-or-key-value]
+   (delete session table key record-or-key-value {}))
+  ([session table key record-or-key-value {:keys [key-value] :as opts}]
+   (let [key-value (or key-value
+                       (when-not (map? record-or-key-value)
+                         record-or-key-value))
+         record (when (map? record-or-key-value)
+                  record-or-key-value)
+         key-clause (extract-key-clause key record {:key-value key-value})]
+     (aliam/execute
+      session
+      (h/->raw
+       (h/delete table
+                 (h/where key-clause)))))))


fix up tests, and add a few more around searching

set up multiple identifiers scenarios, both with
and without UUIDs.

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


adding back notify command

adding back notify command

This command is only run after a successful compile.

--- sidecar/src/figwheel_sidecar/auto_builder.clj
+++ sidecar/src/figwheel_sidecar/auto_builder.clj
@@ -8,7 +8,22 @@
    [clj-stacktrace.repl]
    [clojurescript-build.core :as cbuild]
    [clojurescript-build.auto :as auto]
-   [clojure.java.io :as io]))
+   [clojure.java.io :as io]
+   [cljsbuild.util :as util]))
+
+(defn notify-cljs [command message]
+  (when (seq (:shell command))
+    (try
+      (util/sh (update-in command [:shell] (fn [old] (concat old [message]))))
+      (catch Throwable e
+        (println (auto/red "Error running :notify-command:"))
+        (clj-stacktrace.repl/pst+ e)))))
+
+(defn notify-on-complete [{:keys [build-options parsed-notify-command]}]
+  (let [{:keys [output-to]} build-options]
+    (notify-cljs
+     parsed-notify-command
+     (str "Successfully compiled " output-to))))

 (defn check-changes [figwheel-server build]
   (let [{:keys [additional-changed-ns build-options id old-mtimes new-mtimes]} build]
@@ -29,8 +44,9 @@
     (auto/warning (auto/warning-message-handler
                    (partial fig/compile-warning-occured figwheel-server)))
     auto/time-build
-    (auto/after auto/compile-success)
+    (auto/after auto/compile-success)
     (auto/after (partial check-changes figwheel-server))
+    (auto/after notify-on-complete)
     (auto/error (partial handle-exceptions figwheel-server))
     (auto/before auto/compile-start)))

@@ -51,6 +67,7 @@
         _ (mkdirs logfile-path)
         log-writer (io/writer logfile-path :append true)]
     (println "Server output being sent to logfile:" logfile-path "\n")
+
     (binding [*out* log-writer
               *err* log-writer]
       ;; blocking build to ensure code exists before repl starts


Added Sum of Squares problem

Added Sum of Squares problem

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

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


improvements to markov shit

improvements to markov shit

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


Kontrolatu egilerik gehitzen den

Kontrolatu egilerik gehitzen den

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


Cleaning up some route documentation

Cleaning up some route documentation

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


covering

covering

error: pathspec 'cljx/plongeur-clj/src/plongeur_clj/covering.clj' did not match any file(s) known to git

--- cljx/plongeur-clj/src/plongeur_clj/covering.clj
+++ cljx/plongeur-clj/src/plongeur_clj/covering.clj
@@ -0,0 +1,21 @@
+(ns plongeur-clj.covering)
+
+;; scala> Stream.continually(5).scanLeft(1)(_ + _).take(10).force
+;; res2: scala.collection.immutable.Stream[Int] = Stream(1, 6, 11, 16, 21, 26, 31, 36, 41, 46)
+
+(defn uniform-covering-intervals
+  [boundary-min boundary-max length-pct overlap-pct x]
+  (let [interval-length (-> (- boundary-max boundary-min) (* length-pct))
+        increment       (-> (- 1 overlap-pct) (* interval-length))
+        diff            (-> (- x boundary-min) (mod increment))
+        base            (- x diff)
+        q       (quot interval-length increment)
+        r       (mod  interval-length increment)
+        factor  (if (= r 0) (dec q) q)
+        start   (-> (- base increment) (* factor))
+        end     (-> (+ base increment) )]
+
+    (->> (repeat increment)
+         (reductions + start)
+         (take-while #(< %1 end)))
+    ))


add simple fixtures to benchmarks

add simple fixtures to benchmarks

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/JetBrains/imperative-nodejs.git/'


Refactor of file-response functions

Refactor of file-response functions

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


Remove unused imports

Remove unused imports

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/lobodin/slack-translate.git/'


starting work on editable checking

starting work on editable checking

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

--- src/cljs/greffe/analyze.cljs
+++ src/cljs/greffe/analyze.cljs
@@ -0,0 +1,32 @@
+(ns greffe.analyze
+  (:require [clojure.zip :as zip]))
+
+(def max-attr-count 2)
+(def max-child-count 2)
+
+(defn attributes-text-editable? [node]
+  (if (and
+        {:attrs node}
+        (> (count {:attrs node}) max-attr-count))
+    false
+    true))
+
+
+(defn too-complicated? [node]
+  (let [new-loc (zip/xml-zip node)]
+    (when
+        (first
+         (keep
+           #(when (> (count (zip/path %)) max-child-count) true)
+           (take-while (complement zip/end?) (iterate zip/next new-loc))))
+      true)))
+
+
+(defn editable-type [loc]
+  (let [n (zip/node loc)]
+   (cond
+     (not (attributes-text-editable? n))
+     :no-text)))
+
+
+


Beginning migration to vendored SJCL.

Beginning migration to vendored SJCL.

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


Q macro shouldn't

Q macro shouldn't

--- test/metabase/driver/query_processor_test.clj
+++ test/metabase/driver/query_processor_test.clj
@@ -401,9 +401,9 @@
 ;; Check that we're checking for non-nil values, not just logically true ones.
 ;; There's only one place (out of 3) that I don't like
 (qp-expect-with-all-datasets
- [[1]]
+ 1
  (Q run against places-cam-likes
-    return :data :rows
+    return :data :rows first first
     aggregate count of places
     filter = liked false))


update to better with-fresh-db

update to better with-fresh-db


DRY up supported languages set in handlers

This had been repeated across a few schema defs. Now it's one set at the
top of the 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/democracyworks/election-authority-works.git/'


introduce core.scheduler

introduce core.scheduler

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

--- src/busa_server/core/scheduler.clj
+++ src/busa_server/core/scheduler.clj
@@ -0,0 +1,16 @@
+(ns busa-server.core.scheduler
+  (:require
+    [clj-time.core :as t]
+    [clj-time.local :as l]
+    [clj-time.periodic :as p]
+    [chime :refer [chime-at]])
+  (:import [org.joda.time DateTimeZone]))
+
+(defn- after-midnight-seq []
+  (rest
+    (p/periodic-seq
+      (.. (l/local-now) (withTime 0 5 0 0)) (t/days 1))))
+
+(defn run-everyday-after-midnight [func]
+  (chime-at (after-midnight-seq)
+  (fn [time] (func))))


conditionally render headings in admin service field card

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


Thinking about index

Thinking about index

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

--- reimann/src/reimann/index.clj
+++ reimann/src/reimann/index.clj
@@ -0,0 +1,14 @@
+(ns reimann.index)
+
+; The index accepts states and maintains a table of the most recent state for each unique [host, service].
+
+(defrecord Index [table]
+  (clear [this]
+         "Wipe all states"
+         (.clear (:table this)))
+
+  (update [this state]
+          "Update this index with the given state."
+          (.put (:table this)
+                [(:host state) (:service state)]
+                state)))


Updated irefweb binary interactions rule to work with ccp ext ontology

error: pathspec 'resources/rules/post_identifier_merge/temp/irefweb/irefweb_binary_interactions.clj' did not match any file(s) known to git

--- resources/rules/post_identifier_merge/temp/irefweb/irefweb_binary_interactions.clj
+++ resources/rules/post_identifier_merge/temp/irefweb/irefweb_binary_interactions.clj
@@ -0,0 +1,105 @@
+;; -----------------------------------------------
+;; --------- IRefWeb Binary Interactions ---------
+;; -----------------------------------------------
+`{:name "irefweb-binary-interactions"
+  :description "This rule generates bio-representations for all binary protein interactions cataloged by IRefWeb"
+  :head (;; create subclasses of interaction type and id
+         (?/interaction rdfs/subClassOf ?/interaction_type_id) ;interaction
+         (?/interaction rdfs/label ?/interaction_type_label) ; transfer label to the subclass
+
+         ;; create subclasses of the proteins
+         (?/protein1_sc rdfs/subClassOf ?/protein1)
+         (?/protein1_sc rdfs/label ?/protein1_label) ; transfer label to the subclass
+         (?/protein2_sc rdfs/subClassOf ?/protein2)
+         (?/protein2_sc rdfs/label ?/protein2_label) ; transfer label to the subclass
+
+         ;; create restriction for protein interators
+         (?/protein1_sc_restriction rdf/type owl/Restriction)
+         (?/protein1_sc_restriction owl/onProperty obo/RO_0000057) ; RO:has_participant
+         (?/protein1_sc_restriction owl/someValuesFrom ?/protein1_sc)
+         (?/protein2_sc_restriction rdf/type owl/Restriction)
+         (?/protein2_sc_restriction owl/onProperty obo/RO_0000057) ; RO:has_participant
+         (?/protein2_sc_restriction owl/someValuesFrom ?/protein2_sc)
+
+         ;; create a cardinality restriction of 2 on the has_participant property
+         (?/card_restriction rdf/type owl/Restriction)
+         (?/card_restriction owl/onProperty obo/RO_0000057) ; RO:has_participant
+         (?/card_restriction owl/cardinality 2) ; binary interactions must have 2 participants.
+
+         ;; join interaction restrictions
+         (?/interaction rdfs/subClassOf ?/protein1_sc_restriction)
+         (?/interaction rdfs/subClassOf ?/protein2_sc_restriction)
+         (?/interaction rdfs/subClassOf ?/card_restriction))
+
+  :body (
+        ;; get binary interaction records
+        (?/interaction_record rdf/type ccp/IAO_EXT_0000064) ; ccp:IRefWeb_interaction_record
+        (?/interaction_record obo/BFO_0000051 ?/edge_type_field_value) ; BFO:has_part
+
+        ;; get interaction edge type
+        (?/edge_type_field_value rdf/type ccp/IAO_EXT_0000741) ; ccp:IRefWeb_interaction_record__edge_type_field_value
+        (?/edge_type_field_value rdf/type ?/edge_type_ice_id)
+        (?/edge_type_ice_id obo/IAO_0000219 ?/edge_type) ; IAO:denotes
+        (= ?/edge_type "X") ; "X" signifies binary interaction
+
+        ;; there is a "super" record in IRefWeb that contains references to the interaction record and interactor record(s)
+        (?/super_record obo/BFO_0000051 ?/interaction_record) ; BFO:has_part
+
+        ;; select the other interactor
+        (?/super_record obo/BFO_0000051 ?/interactor_record1) ; BFO:has_part
+
+        ;; get the bioentity (protein) corresponding to interactor 1
+        (?/interaction_record1 rdf/type ccp/IAO_EXT_0000065) ; ccp:IRefWeb_interactor_record
+        (?/interaction_record1 obo/BFO_0000051 ?/id_field1) ; BFO:has_part
+        (?/id_field1 rdf/type ccp/IAO_EXT_0000755) ; ccp:IRefWeb_interactor_record__unique_identifier_field_value
+        (?/id_field1 rdf/type ?id1)
+        (?/id1 obo/IAO_0000219 ?/protein1) ; IAO:denotes
+
+        ;; get the bioentity (protein) corresponding to interactor 2
+        (?/interaction_record2 rdf/type ccp/IAO_EXT_0000065) ; ccp:IRefWeb_interactor_record
+        (?/interaction_record2 obo/BFO_0000051 ?/id_field2) ; BFO:has_part
+        (?/id_field2 rdf/type ccp/IAO_EXT_0000755) ; ccp:IRefWeb_interactor_record__unique_identifier_field_value
+        (?/id_field2 rdf/type ?id1)
+        (?/id2 obo/IAO_0000219 ?/protein2) ; IAO:denotes
+
+        ;; get the unique interaction identifier
+        (?/interaction_record obo/BFO_0000051 ?/interaction_checksum_field_value) ; BFO:has_part
+        (?/interaction_checksum_field_value rdf/type ccp/IAO_EXT_0000735) ; ccp:IRefWeb_interaction_record__check_sum_interaction_field_value
+        (?/interaction_checksum_field_value rdf/type ?/edge_type_ice_id)
+        (?/edge_type_ice_id obo/IAO_0000219 ?/unique_interaction_id) ; IAO:denotes
+
+        ;; get the interaction type name and ID
+        (?/interaction_type_record rdf/type ccp/IAO_EXT_0000716) ; ccp:IRefWeb_interaction_type_record
+        (?/interaction_type_record obo/BFO_0000051 ?/int_type_id_field) ; BFO:has_part
+        (?/int_type_id_field rdf/type ccp/IAO_EXT_0000753) ; ccp:IRefWeb_interaction_type_record__interaction_type_identifier_field_value
+        (?/int_type_id_field rdf/type ?/int_type_id_ice)
+        (?/int_type_id_ice obo/IAO_0000219 ?/int_type_id) ; IAO:denotes
+        (?/int_type_id rdfs/label ?/int_type_label)
+        ;; retrieve the interaction type name
+        (?/interaction_type_record obo/BFO_0000051 ?/int_type_name_field) ; BFO:has_part
+        (?/int_type_name_field rdf/type ccp/IAO_EXT_0000754) ; ccp:IRefWeb_interaction_type_record__interaction_type_name_field_value
+        (?/int_type_name_field rdfs/label ?/int_type_name)
+
+        ;; get the detection method
+        (?/interaction_record rdf/type ccp/IAO_EXT_0000715) ; ccp:IRefWeb_interaction_detection_method_record
+        (?/interaction_record obo/BFO_0000051 ?/interaction_detection_method_record) ; BFO:has_part
+        (?/interaction_detection_method_record rdf/type ccp/IAO_EXT_0000748) ; ccp:IRefWeb_interaction_detection_method_record__detection_method_identifier_field_value
+        (?/interaction_detection_method_record rdf/type ?/detection_method_id_field)
+        (?/detection_method_id_field obo/IAO_0000219 ?/detection_method_id)) ; IAO:denotes
+
+  :reify ([?/interaction {:ln (:sha-1 ?/unique_interaction_id)
+                          :ns "ccp" :prefix "I_"}]
+          [?/protein1_sc_restriction {:ln (:restriction)
+                 :ns "ccp" :prefix "R_"}]
+          [?/protein2_sc_restriction {:ln (:restriction)
+                 :ns "ccp" :prefix "R_"}]
+          [?/card_restriction {:ln (:restriction)
+                               :ns "ccp" :prefix "R_"}]
+          [?/protein1_sc {:ln (:sha-1 ?/interaction ?/protein1)
+                          :ns "ccp" :prefix "P_"}]
+          [?/protein2_sc {:ln (:sha-1 ?/interaction ?/protein2)
+                          :ns "ccp" :prefix "P_"}])
+
+  :options {:magic-prefixes [["franzOption_clauseReorderer" "franz:identity"]
+                             ["franzOption_chunkProcessingAllowed" "franz:yes"]]}
+  }


update interval in add-job

update interval in add-job

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


changed main function

changed main function

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


Added multimethod placeholder.

Added multimethod placeholder.

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


fix cors 3 :(

fix cors 3 :(

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


fix position of dropdown options in service detail view


Add first class to synopsis

Add first class to synopsis

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


Add more NR tracing for deletes

Add more NR tracing for deletes

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


swap in a read-only cache, if it's available (needs work to make the steps more efficient)

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


Worker thread script

Worker thread script

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

--- src/cljs_workers/worker.cljs
+++ src/cljs_workers/worker.cljs
@@ -0,0 +1,45 @@
+(ns cljs-workers.worker)
+
+(def handlers
+  (atom {}))
+
+(defn register
+  [id fun]
+  (swap! handlers assoc id fun))
+
+(defn- do-respond!
+  [handler arguments]
+  (try
+    (let [handler
+          (@handlers handler)
+
+          message
+          (-> (handler arguments)
+              (merge {:state :success}))
+
+          transfer
+          (->> (:transfer message)
+               (map keyword))]
+
+      (if (seq transfer)
+        (.postMessage js/self (clj->js message) (clj->js (vals (select-keys message transfer))))
+        (.postMessage js/self (clj->js message))))
+    (catch js/Object e
+      (->> {:state :error, :message (.toString e)}
+           clj->js
+           (.postMessage js/self)))))
+
+(defn- handle-request!
+  [event]
+  (let [data
+        (.-data event)
+
+        handler
+        (keyword (.-handler data))
+
+        arguments
+        (js->clj (.-arguments data) :keywordize-keys true)]
+
+    (do-respond! handler arguments)))
+
+(aset js/self "onmessage" handle-request!)


notes re: letwarp macro idea

notes re: letwarp macro idea


Minor docstring improvement on protocols ns.

--- src/cljx/cats/protocols.cljx
+++ src/cljx/cats/protocols.cljx
@@ -103,6 +103,7 @@
      the result of applying the aforementioned function to the log as the new log."))

 (defprotocol MonadTrans
+  "A common abstraction for all monad transformers."
   (base [mt] "Return the base monad of this transformer.")
   (inner [mt] "Return the monad that this transformer wraps.")
   (lift [m mv]


Updated DB interface to update connection

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


auto license

auto license


New module: file-utils

New module: file-utils

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

--- src/emender_service/file_utils.clj
+++ src/emender_service/file_utils.clj
@@ -0,0 +1,71 @@
+(ns emender-service.file-utils)
+
+(def temporary-name-prefix
+    "emender-service-")
+
+(defn print-slurp-exception
+    "Print warning message to the standard output."
+    ([filename]
+        (println "Warning: cannot read content of the following file: " filename))
+    ([directory filename]
+        (println "Warning: cannot read content of the following file: " directory "/" filename)))
+
+(defn slurp-
+    "Alternative (slurp) implementation that does not throw an exception, but returns nil instead."
+    ([filename]
+        (try
+            (slurp filename)
+            (catch Exception e (print-slurp-exception filename))))
+    ([directory filename]
+        (try
+            (slurp (str directory "/" filename))
+            (catch Exception e (print-slurp-exception directory filename)))))
+
+(defn silent-slurp
+    "Alternative (slurp) implementation that does not throw an exception, but returns nil instead."
+    ([filename]
+        (try
+            (slurp filename)
+            (catch Exception e)))
+    ([directory filename]
+        (try
+            (slurp (str directory "/" filename))
+            (catch Exception e))))
+
+(defn new-file
+    "Just a shortcut for (new java.io.File filename)."
+    ( [filename]
+    (new java.io.File filename))
+    ( [path filename]
+    (new java.io.File path filename)))
+
+(defn make-temporary-log-file-name
+    []
+    (let [basedir-name (new java.io.File (System/getProperty "java.io.tmpdir"))
+          base-name    temporary-name-prefix
+          temp-file    (java.io.File/createTempFile base-name ".log" basedir-name)]
+          (.getAbsolutePath temp-file)))
+
+(defn make-temporary-directory
+    "Make temporary directory that would reside in /tmp (at least on Linux)."
+    []
+    (let [basedir-name (System/getProperty "java.io.tmpdir")
+          base-name    (str temporary-name-prefix (System/currentTimeMillis))
+          temp-dir     (new java.io.File basedir-name base-name)]
+        (.mkdir temp-dir)
+        temp-dir))
+
+(defn move-file
+    "Move or rename one file. On the same filesystem the rename should be atomic."
+    [filename1 filename2]
+    (let [file1 (new java.io.File filename1)
+          file2 (new java.io.File filename2)]
+          (.renameTo file1 file2)))
+
+(defn mv-file
+    "Move or rename one file. On the same filesystem the rename should be atomic."
+    [filename1 filename2]
+    (let [file1 (new java.io.File filename1)
+          file2 (new java.io.File filename2)]
+          (.renameTo file1 file2)))
+


[TH DG] Cover all them error handling bases

No trebbles

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


Problem 0131.

Problem 0131.

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

--- src/project_euler/problem_0131.clj
+++ src/project_euler/problem_0131.clj
@@ -0,0 +1,34 @@
+(ns project-euler.problem_0131)
+
+;; There are some prime values, p, for which there exists a positive integer, n,
+;; such that the expression n^3 + n^2p is a perfect cube.
+
+;; For example, when p = 19, 8^3 + 8^2×19 = 12^3.
+
+;; What is perhaps most surprising is that for each prime with this property
+;; the value of n is unique, and there are only four such primes below one-hundred.
+
+;; How many primes below one million have this remarkable property?
+
+;; From problem 0010 :
+;; -------------------
+(defn prime?
+  [n]
+  {:pre [(integer? n) (> n 0)]}
+  (or (== 2 n)
+      (let [mmax (+ (Math/sqrt n) 1)]
+        (not (some #(== 0 (rem n %)) (concat [2] (range 3 mmax 2))))
+        )))
+;;------------------------------------------------------------------------
+
+(defn cube [x] (* x x x))
+
+(defn solution []
+  (->> (iterate inc 1)
+       (map (fn [x] (- (cube (inc x)) (cube x))))
+       (filter prime?)
+       (take-while (fn [p] (< p 1000000)))
+       (count)
+       ))
+
+;;-> 173


Merging to master

Merging to master

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

--- src/tropic/parser.clj
+++ src/tropic/parser.clj
@@ -0,0 +1,252 @@
+(ns tropic.parser
+  (:require [instaparse.core :as insta]
+            [clojure.string :as str]))
+
+(def tropical
+  (insta/parser
+   "narrative = rule+
+    <rule> = tropedef | situationdef | taskdef | roledef | storydef | initialdef | tracedef
+
+    tropedef =
+        tropename (<'\\n' whitespace> event <'\\n'>) (<whitespace 'Then '> event <'\\n'>)* (<whitespace 'Finally, '> event <'\\n'>?)
+
+    <tropename> =
+        <'The '?> trope <' is a trope where:'>
+
+    situation =
+        <'When '> event <':'>
+
+    situationdef = situation <'\\n'> norms+ <'\\n'?>
+    roledef = rolehead power+
+
+    <rolehead> = <('The ' / 'A ')> role <' can:\\n'>
+
+    power = <whitespace> verb <' the '?> character <'\\n'?>
+
+    role = word | word <' '> word
+
+    initialdef = <'Initially:'> (<'\\n'> <whitespace> (event / norms))+ <'\\n'?>
+
+    tracedef = <'In story '> label <':'> (<'\\n'> <whitespace> event)+
+
+    label = word
+
+    norms = permission | obligation
+
+    conditional =
+        <' if '> <'they '?> event
+
+    event =
+        character <' '> task
+
+    place = name
+
+    character = name
+
+    taskdef =
+        taskname condition <'\\nOtherwise, '> <'the '?> event <'.'?> <'\\n'?>
+
+    condition =
+        <'\\nTo complete it, '> item <' must be '> state <'.'?>
+
+    <taskname> =
+        task <' is a task' '.'?>
+
+    permission = <whitespace> character <' may '> task conditional?
+    obligation = <whitespace> character <' must '> task <' before '> deadline <'\\n' whitespace 'Otherwise, '> <'the '?> violation <'.'?> <'\\n'?>
+
+    violation = event
+
+    deadline = consequence
+
+    task = verb | verb <(' the ' / ' a ')> item | verb <' '> item | visit
+    visit = ('leave' <' '>) | ('return' (<' '> 'to')? <' '>) | ('go' / 'goes') (<' '> 'to')? <' '> | ('visit' <' '>) place
+    verb = word
+    place = word
+
+    consequence =
+        [<'The ' / 'the '>] item <' '> verb
+        | [<'The ' / 'the '>] character <' will '> task
+
+    item = [<'The ' / 'the '>] (word / word <' '> word)
+    state = word
+    storydef =
+        storyname (<'\\n'> (storytrope / storyrole))+ <'\\nThe end' '.'?> <'\\n'?>
+    <storyname> =
+        story <' is a story' '.'?>
+    <storytrope> =
+        <'It contains the '> trope <' trope' '.'?>
+    storyrole =
+        character <' is its '> role <'.'?>
+
+    story = [<'The ' / 'the '>] (word / word <' '> word)
+    role = word
+    trope = [<'The ' / 'the '>] (word / word <' '> word)
+    <name> = (<'The ' | 'the '>)? word | (word <' '> !'gets ' word)
+    <whitespace> = #'\\s\\s+'
+    <words> = word (<whitespace> word)*
+    <word> = #'[0-9a-zA-Z\\-\\_\\']*'"
+   ;; :output-format :enlive
+))
+
+(defn parse
+  [text]
+  (insta/add-line-and-column-info-to-metadata
+   text
+   (tropical text)))
+
+
+(defn strip-name
+  "Takes character name list, strips off 'the', makes lowercase"
+  [n]
+  (let [the (remove #(or (= "the" %) (= "The" %)) n)
+        camel (if (> (count the) 1)
+                (cons (str/lower-case (first the)) (map str/capitalize (rest the)))
+                (map str/lower-case the))
+        cat (reduce str camel)
+        san (str/replace cat #"\"" "")
+        ]
+    san))
+
+(defn event-str
+  "Takes list of strings, converts to intExampleEvent format"
+  [{:keys [params name]}]
+  (let [sanstrings (map #(str/replace % #"'" "") name)
+        sparams (reduce str (interpose ", " params))
+        svec (cons (str/lower-case (first sanstrings)) (map str/capitalize (rest sanstrings)))
+        pstr (str "(" sparams ")")
+        outvec (conj (vec svec) pstr)
+        ]
+    (reduce str outvec)
+    ))
+
+(defn inst-str
+  [sym]
+  (let [s (str sym)
+        caps (apply str (str/upper-case (first s)) (rest s))]
+    (str "int" caps)))
+
+(defn vio-str
+  [sym]
+  (let [s (str sym)
+        caps (apply str (str/upper-case (first s)) (rest s))]
+    (str "vio" caps)))
+
+(defn inst-event-str
+  "Takes list of strings, converts to intExampleEvent format"
+  [argm]
+  (let [estr (event-str argm)]
+    (inst-str estr)
+    ))
+
+(defn inst-tree
+  [x xs]
+  (inst-event-str {:params [x] :name xs}))
+
+
+(defn m
+  [old new]
+  (with-meta new (meta old)))
+
+(defn event-tree
+  [x xs]
+  (m xs (symbol (event-str {:params [x] :name xs}))))
+
+(defn get-line
+  [obj]
+  (- (:instaparse.gll/start-line (meta obj)) 1))
+
+(defn get-comment
+  [text data]
+  (let [line (get-line data)]
+    (str "; % " (nth (str/split-lines text) line) "\n")))
+
+(defn get-next-comment
+  [text data]
+  (let [line (+ (get-line data) 1)]
+    (str "; % " (nth (str/split-lines text) line) "\n")))
+
+(defn get-prev-comment
+  [text data]
+  (let [line (- (get-line data) 1)]
+    (str "; % " (nth (str/split-lines text) line) "\n")))
+
+(defn perm-tree
+  [x xs]
+  (let [args (event-tree x xs)]
+    (str "perm(" args ")")))
+
+(defn obl-tree
+  [char task deadline consequence]
+  (let [args (event-tree char task)
+        vio (vio-str args)
+        body (str "obl(" args ", " deadline ", " vio ")")
+        ]
+    body
+    ))
+
+(defn vio-tree
+  [char task deadline consequence]
+  (let [args (event-tree char task)
+        vio (vio-str args)
+        vio-event (str vio " generates " consequence)]
+    vio-event))
+
+(defn tropedef-tree
+  [text name & args]
+  (let [header "%% TROPES ---------------------\n"
+        evs (map inst-str args)
+        comments (map #(get-comment text %) args)
+        firstcomment (str/replace (get-comment text name) "; " "")
+        firstline (str name " generates " (first evs) (first comments))
+        gens (map #(interpose " generates " %) (partition 2 1 evs))
+        cgens (map (fn [x y] (conj (vec x) y)) gens (rest comments))
+        genstr (apply str (flatten cgens))
+        ]
+    (str header firstcomment firstline genstr)
+    ))
+
+(defn sitdef-tree
+  [name & args]
+  (let [header "%% SCENES ---------------------\n"
+        genstr (map #(str name " initiates " %) args)]
+    (str header (reduce str genstr))
+    ))
+
+(defn add-comment
+  [line]
+  (str "  %" (meta line) "\n" line)
+  )
+
+(defn narrative-tree
+  [& args]
+    (reduce str (interpose "\n" args)))
+
+
+(defn obl-text
+  [text args]
+  (str (apply obl-tree args) (get-comment text (second args)) (apply vio-tree args) (get-next-comment text (second args))))
+
+
+(defn transform
+  [ptree text]
+  (insta/transform
+   {
+    :trope (fn [& args] (m (first args) (symbol (inst-event-str {:name args}))))
+    :verb (fn [& args] args)
+    :item (fn [& args] args)
+    :character (fn [& args] (strip-name args))
+    :task (partial concat)
+    :event event-tree
+    :consequence (fn [s v] (event-str {:params [(strip-name s)] :name v}))
+    :violation str
+    :deadline str
+    :norms str
+    :situation (fn [& args] args)
+    :permission (fn [& args] (str (apply perm-tree args) (get-comment text (second args))))
+    :obligation (fn [& args] (obl-text text args))
+    :tropedef (partial tropedef-tree text)
+    :situationdef sitdef-tree
+    :narrative narrative-tree
+    } ptree))
+


Merging prerelease into master (and adding a missing file)

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

--- src/brevis/shape/cylinder.clj
+++ src/brevis/shape/cylinder.clj
@@ -0,0 +1,63 @@
+#_"This file is part of brevis.
+
+    brevis is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    brevis is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with brevis.  If not, see <http://www.gnu.org/licenses/>.
+
+Copyright 2012, 2013 Kyle Harrington"
+
+(ns brevis.shape.cylinder
+  (:import [brevis BrShape])
+  (:use [penumbra opengl compute]
+        [penumbra.opengl core]
+        [brevis.physics.vector]
+        [brevis.shape.core]))
+
+(defn create-cylinder
+  "Create a cone object."
+  ([]
+     (create-cylinder 1 1))
+  ([length radius]
+    (BrShape/createCylinder length radius)))
+
+#_(defn gen-cone-faces
+  [length lod]
+  (let [interval (/ 360 lod)
+        base (range 0 361 interval)]
+    (for [theta (rest base)]
+      (let [p1 (Math/sin (- theta interval))
+            p2 (Math/sin theta)]
+            ;p2 (Math/cos (- theta interval))]
+        [(vec3 0 0 length) (vec3 p1 p2 0) (vec3 p2 p1 0)]))))
+
+#_(defn init-cone
+  []
+  (def cone-mesh
+    (create-display-list
+      (doseq [first-vertex [[0 0 1] [0 0 0]]]
+	      (draw-triangle-fan
+		      (let [stepsize (/ java.lang.Math/PI 8)
+		            radius 0.25]
+		        (apply vertex first-vertex)
+		        (doseq [angle (range 0 (+ (* 2 java.lang.Math/PI) (/ stepsize 2)) stepsize)];; overcompensate to ensure cones wrap in spite of floating points
+		            (let [x (* (Math/cos angle) radius)
+		                  y (* (Math/sin angle) radius)
+                      px (* (Math/cos (- angle stepsize)) radius)
+                      py (* (Math/sin (- angle stepsize)) radius)]
+                  (when-not (zero? angle)
+                    (apply normal (compute-normal [(apply vec3 first-vertex) (vec3 x y 0) (vec3 px py 0)])))
+		              (vertex x y 0)))))))))
+
+#_(defn draw-cone
+  []
+  (cone-mesh))
+


tweak

tweak

--- labs/architecture-examples/om/src/todomvc/app.cljs
+++ labs/architecture-examples/om/src/todomvc/app.cljs
@@ -51,7 +51,7 @@
                                #js {})}
       (dom/input #js {:id "toggle-all" :type "checkbox"
                       :onChange #(toggle-all % app)
-                      :checked (every? #(:completed %) todos)})
+                      :checked (every? :completed todos)})
       (dom/ul #js {:id "todo-list"}
         (om/build-all item/todo-item todos
           {:opts opts :key :id


type cast

type cast

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/hongfei/DataBase-Course-Work.git/'


EFCT seems to basically associate a HLSL vertex/pixel shader (vertex/fragment shader in openGL shader jargon) with some sort of texture, most likely for bump mapping and other effects

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


Fail on bad resource

Fail on bad resource

--- src/yada/resource.clj
+++ src/yada/resource.clj
@@ -88,9 +88,9 @@
   (as-resource [this] this))

 (defn resource [m]
-  (->> m
-       ys/resource-coercer
-       map->Resource))
+  (let [r (ys/resource-coercer m)]
+    (when (su/error? r) (throw (ex-info "Cannot turn map into resource, because it doesn't conform to a resource schema" {:input-map m :error (:error r)})))
+    (map->Resource r)))

 (extend-protocol p/ResourceCoercion
   nil


Fix promote tests to run under test profile.

fatal: unable to access 'https://github.com/clojars/clojars-web.git/': The requested URL returned error: 403


Update handler.clj

Update handler.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/yokalona/threen.git/'


Update jar-copier to 0.4.0

Update jar-copier to 0.4.0

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


expand comment re: yourkit symlink

expand comment re: yourkit symlink


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,8 @@
+(defproject thi.ng/ws-ldn-1 "0.1.0-SNAPSHOT"
+  :description   "thi.ng workshop #1"
+  :url           "http://thi.ng"
+  :license       {:name "Apache Software License 2.0"
+                  :url "http://www.apache.org/licenses/LICENSE-2.0"}
+  :dependencies  [[org.clojure/clojure "1.7.0"]
+                  [org.clojure/clojurescript "1.7.122"]
+                  [thi.ng/geom "0.0.881"]])


Update deps

Update deps


Bump to snapshot again.

Bump to snapshot again.

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


Release 0.14.11

Release 0.14.11

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


test sources also in test/cljs

test sources also in test/cljs

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


Version 0.7.2

Version 0.7.2

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


Set release version.

Set release version.

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


Update to 1.3.0-alpha2.

Update to 1.3.0-alpha2.

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


Update ClojureScript and jQuery

Update ClojureScript and jQuery

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


Pure streams thinking out loud

Pure streams thinking out loud

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

--- src/riemann/streams/pure.clj
+++ src/riemann/streams/pure.clj
@@ -0,0 +1,121 @@
+(ns riemann.streams.pure
+  "Riemann streams have performed exceptionally well, but their design scope
+  was intentionally limited. Users consistently request:
+
+  - Consistent behavior with respect to time intervals
+  - Persisting stream state across reloads and process restarts
+  - Replicating streams across multiple nodes
+
+  These suggest:
+
+  - Streams should be atomically coerceable to data structures for storage and
+    exchange between nodes.
+
+  - Streams need globally unique identifiers so we can handle multiple streams
+    feeding into the same child stream.
+
+  - Streams should be deterministic functions of their input events, instead of
+    depending on wall-clock time.
+
+  - Streams should be as pure as possible--side effect should be explicitly
+    identified and controlled for distribution and replayability.
+
+
+  And we wish to preserve:
+
+  - Performance: tens of millions of events per second is nice.
+
+  - Implicit parallelism: it's easy to get determinism in a single thread, but
+    we can and should do better.
+
+  - The existing stream syntax, including macros like (by).
+
+
+  Useful existing assumptions:
+
+  - Events are roughly time-ordered, and we have no problem rejecting events
+  that appear too far outside our latency window.
+
+
+  New assumptions:
+
+  - Events are uniquely identified by [host, service, time, seq] identifiers.
+
+  - Events are deterministically partitioned into time windows. Windows are
+  monotonically advancing; all streams see windows in strictly sequential
+  order.
+
+  ## Ideas on Time
+
+  Peter Alvaro has convinced me of the obvious (lol) idea that a distributed
+  stream processor must have some way to *seal* the events--to tell when a
+  given stream has seen all inputs for a particular interval, so that it can in
+  turn send state downstream.
+
+  Presently, sealing is performed as a global side effect from the
+  riemann.time scheduler, which causes weird latency anomalies--for instance,
+  chaining 3 windows together introduces 3x window latency, and if multiple
+  streams are recombined we'll happily interleave events from different times.
+  Also, this fucks with determinism.
+
+  I think the right move is to thread sealing information through the same
+  paths that connect streams to one another, but this introduces a new problem.
+  Right now, Riemann streams only have links to their children, not their
+  parents. In order for a stream to know it's received all its inputs, it must
+  know how many producers are sending it messages.
+
+  We could do this by sending an 'initiation pulse' through the topology, where
+  each parent informs its child that it exists. Happily, producer relationships
+  are local, not global: a stream only has to know about its immediate
+  producers.
+
+  A difficulty: (by) creates producers dynamically. I THINK this is the only
+  place where Riemann topologies shift at runtime. Can we figure out a solution
+  that works for (by)?
+
+  A specific case: (by) has one child stream c0, which has events for the
+  current window w0. (by) receives an event e which creates a new child stream
+  c0. All child streams unify at a final stream f.
+
+
+        /--- c0 ---\
+      by            f
+        \--- c1 ---/
+
+
+  Case 1: e falls in w0. Create child c1 and inform it that the current window
+  is w0. c1 sends an initiation pulse for w0 to f, causing f to increment its
+  producer count for w0. If by can only seal w0 once c1's initiation pulse has
+  completely propagated, f will not seal w0 until c1 has had a chance to
+  forward its w0 events to f as well.
+
+  Case 2: e falls in w1. Seal w0 and inform c0 as usual. Move to window w1,
+  create c1 and proceed as in Case 1.
+
+  Implication: initiation and sealing pulses require synchronous
+  acknowledgement--we have to wait for the initiation to propagate all the way
+  downstream to make sure that every downstream node is aware of its new
+  producer. It's fine to emit events concurrently (cuz the stream may be able
+  to do parallel processing) so long as sealing is strictly ordered.
+
+  Another implication: Sealing pulses must be ordered w.r.t the event stream.
+  We have to acquire something like a ReaderWriterLock to ensure no threads are
+  operating on our children while we seal them. That means acquiring a readlock
+  on every. single. event. Fuck.
+
+  Alternate strategy: queues between everything. We are going for CSP
+  invariants, after all, and that's what Akka does! That means locks AND
+  allocations and pointer chasing for every event. Fuck no.
+
+  Alternate strategy: most configs involve tens of branches. Branches can
+  execute in parallel: we could enforce a single-thread-per-branch rule. When
+  branches recombine, though, we gotta introduce a queue or a lock. Seems less
+  bad. OTOH, if only one thread can ever execute a given stream, we can stop
+  using atoms and move all stream state to volatile mutables, which could
+  dramatically reduce memory barriers. And the initiation pulses tell us when
+  we need locks: if you only have one producer, you don't need to lock.
+
+  If we use queues and enforce strict thread affinity for streams, we could get
+  away with unsynchronized mutables, not just volatile ones.
+
+  UGH")


project: update dependencies

project: update dependencies

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


:arrow_up: Upgrade dependencies

:arrow_up: Upgrade dependencies

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


Version bump

Version bump

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


ring/compojure 1.1.0 did not work in heroku, go back to 1.0.2

--- project.clj
+++ project.clj
@@ -3,12 +3,12 @@
   :dependencies
   [
    [org.clojure/clojure "1.3.0"]
-   [compojure "1.1.0"]
+   [compojure "1.0.2"]
    [ring-json-params "0.1.3"]
    [clj-json "0.5.0"]
-   [ring/ring-core "1.1.0"]
-   [ring/ring-servlet "1.1.0"]
-   [ring/ring-jetty-adapter "1.1.0"]
+   [ring/ring-core "1.0.2"]
+   [ring/ring-servlet "1.0.2"]
+   [ring/ring-jetty-adapter "1.0.2"]
    ;; [sandbar "0.4.0-SNAPSHOT"]
    ;; [enlive "1.0.0"]
    [org.clojure/tools.logging "0.2.3"
@@ -31,7 +31,7 @@
    ]
   :dev-dependencies
   [
-   [ring/ring-devel "1.1.0"]
+   [ring/ring-devel "1.0.2"]
    [lein-ring "0.6.1"]
    [midje "1.3.1"]
    [lein-midje "1.0.8"]


Don't pull in wagon-file explicitly.

Don't pull in wagon-file explicitly.

It conflicts with the version bundled with maven-ant-tasks.  Looks like
newer version of Leiningen create the uberjar in a different order
causing this extremetly cryptic error:

Error: org.apache.maven.wagon.providers.file.FileWagon.openConnection()V java.lang.AbstractMethodError:

--- project.clj
+++ project.clj
@@ -6,7 +6,6 @@
                  [org.apache.maven/maven-artifact-manager "2.2.1"]
                  [org.apache.maven/maven-model "2.2.1"]
                  [org.apache.maven/maven-project "2.2.1"]
-                 [org.apache.maven.wagon/wagon-file "1.0-beta-6"]
                  [compojure "0.5.2"]
                  [ring/ring-jetty-adapter "0.3.1"]
                  [hiccup "0.3.0"]


Begin work on next iteration.

Begin work on next iteration.

--- project.clj
+++ project.clj
@@ -1,4 +1,4 @@
-(defproject com.damballa/abracad "0.4.11"
+(defproject com.damballa/abracad "0.4.12-SNAPSHOT"
   :description "De/serialize Clojure data structures with Avro."
   :url "http://github.com/damballa/abracad"
   :licenses [{:name "Eclipse Public License"


Update kehaar dependency

Update kehaar dependency

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


Version 1.6.2-SNAPSHOT

Version 1.6.2-SNAPSHOT

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


Add project.clj

Add project.clj

--- project.clj
+++ project.clj
@@ -0,0 +1,15 @@
+(defproject obb-rules "1.0.0-SNAPSHOT"
+  :description "Orion's Belt Ranking System"
+  :url "https://github.com/orionsbelt-battlegrounds/obb-ranking"
+
+  :license {:name         "The MIT License"
+            :url          "file://LICENSE"
+            :distribution :repo
+            :comments     "Copyright 2011-2014 Pedro Santos All Rights Reserved."}
+  :dependencies [[org.clojure/clojure "1.6.0"]
+                 [org.clojure/math.numeric-tower "0.0.4"]]
+  :source-paths ["src"]
+  :test-paths ["test"]
+
+
+  )


bump version to 2.8.10

bump version to 2.8.10

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


Expand test

Expand test

fatal: unable to access 'https://github.com/leif47/immutabledb-experimental.git/': The requested URL returned error: 403


Fix search tests

Fix search tests

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


Add specs for the data format resulting from parsing queries

error: pathspec 'src/main/workflo/macros/specs/parsed_query.cljc' did not match any file(s) known to git

--- src/main/workflo/macros/specs/parsed_query.cljc
+++ src/main/workflo/macros/specs/parsed_query.cljc
@@ -0,0 +1,57 @@
+(ns workflo.macros.specs.parsed-query
+  (:require #?(:cljs [cljs.spec :as s]
+               :clj  [clojure.spec :as s])
+            #?(:cljs [cljs.spec.impl.gen :as gen]
+               :clj  [clojure.spec.gen :as gen])
+            [workflo.macros.props.util :as util]
+            [workflo.macros.specs.query]))
+
+(s/def ::type
+  #{:property :link :join})
+
+(s/def ::name
+  :workflo.macros.specs.query/property-name)
+
+(s/def ::link-id
+  :workflo.macros.specs.query/link-id)
+
+(s/def ::join-target
+  (s/with-gen
+    (s/or :model :workflo.macros.specs.query/model-name
+          :recursion :workflo.macros.specs.query/recursion
+          :properties ::query)
+    #(gen/one-of [(s/gen :workflo.macros.specs.query/model-name)
+                  (s/gen :workflo.macros.specs.query/recursion)
+                  (s/gen '#{[{:type :property :name name}]
+                            [{:type :property :name name}
+                             {:type :property :name email}]
+                            [{:type :property :name name}
+                             {:type :link :name current-user :link-id '_}
+                             {:type :join :name friends
+                              :join-target 'User}]})])))
+
+(s/def ::parameters
+  :workflo.macros.specs.query/parameters)
+
+(defmulti  typed-property :type)
+
+(defmethod typed-property :property [_]
+  (s/keys :req-un [::type ::name]
+          :opt-un [::parameters]))
+
+(defmethod typed-property :link [_]
+  (s/keys :req-un [::type ::name ::link-id]
+          :opt-un [::parameters]))
+
+(defmethod typed-property :join [_]
+  (s/keys :req-un [::type ::name ::join-target]
+          :opt-un [::parameters]))
+
+(s/def ::property
+  (s/multi-spec typed-property :type))
+
+(s/def ::query
+  (s/with-gen
+    (s/and vector? (s/+ ::property))
+    #(gen/vector (s/gen ::property)
+                 1 10)))


attempting to prevent clojure.browser.repl overflows

--- support/src/figwheel/client/file_reloading.cljs
+++ support/src/figwheel/client/file_reloading.cljs
@@ -174,6 +174,8 @@
       (name-to-parent! req prov))))

 (defn figwheel-require [src reload]
+  ;; require is going to be called
+  (set! (.-require js/goog) figwheel-require)
   (when (= reload "reload-all")
     (doseq [ns (get-all-dependencies src)] (unprovide! ns)))
   (when reload (unprovide! src))
@@ -183,9 +185,11 @@
   "Reusable browser REPL bootstrapping. Patches the essential functions
   in goog.base to support re-loading of namespaces after page load."
   []
-  ;; Monkey-patch goog.provide if running under optimizations :none - David
+  ;; The biggest problem here is that clojure.browser.repl might have
+  ;; patched this or might patch this afterward
   (when-not js/COMPILED
-    (set! (.-require_figwheel_backup_ js/goog) js/goog.require)
+    ;;
+    (set! (.-require_figwheel_backup_ js/goog) (or js/goog.require__ js/goog.require))
     ;; suppress useless Google Closure error about duplicate provides
     (set! (.-isProvided_ js/goog) (fn [name] false))
     ;; provide cljs.user
@@ -303,10 +307,11 @@
     (js-reload
      file-msg
      (fn [url]
-       (patch-goog-base)
+       #_(patch-goog-base)
        (put! out url)
        (close! out)))
     out))
+

 (defn load-all-js-files
   "Returns a chanel with one collection of loaded filenames on it."


need spec

need spec

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


Add a test for non-ASCII OCD-IDs

Add a test for non-ASCII OCD-IDs

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


Sort initially loaded files by timestamp too.

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


sample dataset

sample dataset

error: pathspec 'sample_dataset/metabase/sample_dataset/generate.clj' did not match any file(s) known to git

--- sample_dataset/metabase/sample_dataset/generate.clj
+++ sample_dataset/metabase/sample_dataset/generate.clj
@@ -0,0 +1,422 @@
+(ns metabase.sample-dataset.generate
+  "Logic for generating the sample dataset.
+   Run this with `lein generate-sample-dataset`."
+  (:require (clojure.java [io :as io]
+                          [jdbc :as jdbc])
+            [clojure.math.numeric-tower :as math]
+            [clojure.string :as s]
+            (faker [address :as address]
+                   [company :as company]
+                   [lorem :as lorem]
+                   [internet :as internet]
+                   [name :as name])
+            [incanter.distributions :as dist]
+            [metabase.db.spec :as dbspec]
+            [metabase.util :as u])
+  (:import java.util.Date))
+
+(def ^:private ^:const sample-dataset-filename
+  (str (System/getProperty "user.dir") "/resources/sample-dataset.db"))
+
+(defn- normal-distribution-rand [mean median]
+  (dist/draw (dist/normal-distribution mean median)))
+
+(defn- normal-distribution-rand-int [mean median]
+  (math/round (normal-distribution-rand mean median)))
+
+;;; ## PEOPLE
+
+(defn- random-latitude []
+  (-> (rand)
+      (* 180)
+      (- 90)))
+
+(defn- random-longitude []
+  (-> (rand)
+      (* 360)
+      (- 180)))
+
+(defn ^Date random-date-between [^Date min, ^Date max]
+  (let [min-ms (.getTime min)
+        max-ms (.getTime max)
+        range  (- max-ms min-ms)
+        d      (Date.)]
+    (.setTime d (+ (long (rand range)) min-ms))
+    d))
+
+(defn- random-person []
+  (let [first (name/first-name)
+        last  (name/last-name)]
+    {:name       (format "%s %s" first last)
+     :email      (internet/free-email (format "%s.%s" first last))
+     :password   (str (java.util.UUID/randomUUID))
+     :birth_date (random-date-between (u/relative-date :year -60) (u/relative-date :year -18))
+     :address    (address/street-address)
+     :city       (address/city)
+     :zip        (apply str (take 5 (address/zip-code)))
+     :state      (address/us-state-abbr)
+     :latitude   (random-latitude)
+     :longitude  (random-longitude)
+     :source     (rand-nth ["Google" "Twitter" "Facebook" "Organic" "Affiliate"])
+     :created_at (random-date-between (u/relative-date :year -1) (u/relative-date :year 1))}))
+
+;;; ## PRODUCTS
+
+(defn- random-company-name []
+  (first (company/names)))
+
+(defn- random-price [min max]
+  (let [range (- max min)]
+    (-> (rand-int (* range 100))
+        (/ 100.0)
+        (+ min))))
+
+(def ^:private ^:const product-names
+  {:adjective '[Small, Ergonomic, Rustic, Intelligent, Gorgeous, Incredible, Fantastic, Practical, Sleek, Awesome, Enormous, Mediocre, Synergistic, Heavy-Duty, Lightweight, Aerodynamic, Durable]
+   :material  '[Steel, Wooden, Concrete, Plastic, Cotton, Granite, Rubber, Leather, Silk, Wool, Linen, Marble, Iron, Bronze, Copper, Aluminum, Paper]
+   :product   '[Chair, Car, Computer, Gloves, Pants, Shirt, Table, Shoes, Hat, Plate, Knife, Bottle, Coat, Lamp, Keyboard, Bag, Bench, Clock, Watch, Wallet, Toucan]})
+
+(defn- random-product-name []
+  (format "%s %s %s"
+          (rand-nth (product-names :adjective))
+          (rand-nth (product-names :material))
+          (rand-nth (product-names :product))))
+
+(def ^:private ean-checksum
+  (let [^:const weights (flatten (repeat 6 [1 3]))]
+    (fn [digits]
+      {:pre [(= 12 (count digits))
+             (= 12 (count (apply str digits)))]
+       :post [(= 1 (count (str %)))]}
+      (as-> (reduce + (map (fn [digit weight]
+                             (* digit weight))
+                           digits weights))
+          it
+        (mod it 10)
+        (- 10 it)
+        (mod it 10)))))
+
+(defn- random-ean []
+  {:post [(= (count %) 13)]}
+  (let [digits (vec (repeatedly 12 #(rand-int 10)))]
+    (->> (conj digits (ean-checksum digits))
+         (apply str))))
+
+(defn- random-product []
+  {:ean        (random-ean)
+   :title      (random-product-name)
+   :category   (rand-nth ["Widget" "Gizmo" "Gadget" "Doohickey"])
+   :vendor     (random-company-name)
+   :price      (random-price 12 100)
+   :created_at (random-date-between (u/relative-date :year -1) (u/relative-date :year 1))})
+
+
+;;; ## ORDERS
+
+(def ^:private ^:const state->tax-rate
+  {"AK" 0.0
+   "AL" 0.04
+   "AR" 0.065
+   "AZ" 0.056
+   "CA" 0.075
+   "CO" 0.029
+   "CT" 0.0635
+   "DC" 0.0575
+   "DE" 0.0
+   "FL" 0.06
+   "GA" 0.04
+   "HI" 0.04
+   "IA" 0.06
+   "ID" 0.06
+   "IL" 0.0625
+   "IN" 0.07
+   "KS" 0.065
+   "KY" 0.06
+   "LA" 0.04
+   "MA" 0.0625
+   "MD" 0.06
+   "ME" 0.055
+   "MI" 0.06
+   "MN" 0.06875
+   "MO" 0.04225
+   "MS" 0.07
+   "MT" 0.0
+   "NC" 0.0475
+   "ND" 0.05
+   "NE" 0.055
+   "NH" 0.0
+   "NJ" 0.07
+   "NM" 0.05125
+   "NV" 0.0685
+   "NY" 0.04
+   "OH" 0.0575
+   "OK" 0.045
+   "OR" 0.0
+   "PA" 0.06
+   "RI" 0.07
+   "SC" 0.06
+   "SD" 0.04
+   "TN" 0.07
+   "TX" 0.0625
+   "UT" 0.047
+   "VA" 0.043
+   "VT" 0.06
+   "WA" 0.065
+   "WI" 0.05
+   "WV" 0.06
+   "WY" 0.04
+   ;; Territories / Associated States / Armed Forces - just give these all zero
+   ;; These might come back from address/us-state-abbr
+   "AA" 0.0 ; Armed Forces - Americas
+   "AE" 0.0 ; Armed Forces - Europe
+   "AP" 0.0 ; Armed Forces - Pacific
+   "AS" 0.0 ; American Samoa
+   "FM" 0.0 ; Federated States of Micronesia
+   "GU" 0.0 ; Guam
+   "MH" 0.0 ; Marshall Islands
+   "MP" 0.0 ; Northern Mariana Islands
+   "PR" 0.0 ; Puerto Rico
+   "PW" 0.0 ; Palau
+   "VI" 0.0 ; Virgin Islands
+   })
+
+(defn- max-date [& dates]
+  {:pre [(every? (partial instance? Date) dates)]
+   :post [(instance? Date %)]}
+  (doto (Date.)
+    (.setTime (apply max (map #(.getTime ^Date %) dates)))))
+
+(defn- min-date [& dates]
+  {:pre [(every? (partial instance? Date) dates)]
+   :post [(instance? Date %)]}
+  (doto (Date.)
+    (.setTime (apply min (map #(.getTime ^Date %) dates)))))
+
+(defn random-order [{:keys [state], :as ^Person person} {:keys [price], :as product}]
+  {:pre [(string? state)
+         (number? price)]
+   :post [(map? %)]}
+  (let [tax-rate (state->tax-rate state)
+        _        (assert tax-rate
+                   (format "No tax rate found for state '%s'." state))
+        tax      (u/round-to-decimals 2 (* price tax-rate))]
+    {:user_id    (:id person)
+     :product_id (:id product)
+     :subtotal   price
+     :tax        tax
+     :total      (+ price tax)
+     :created_at (random-date-between (min-date (:created_at person) (:created_at product)) (u/relative-date :year 1))}))
+
+
+;;; ## REVIEWS
+
+(defn random-review [product]
+  {:product_id (:id product)
+   :reviewer   (internet/user-name)
+   :rating     (rand-nth [1 1
+                          2 2 2
+                          3 3
+                          4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
+                          5 5 5 5 5 5 5 5 5 5 5 5 5])
+   :body       (first (lorem/paragraphs))
+   :created_at (random-date-between (:created_at product) (u/relative-date :year 1))})
+
+(defn- create-randoms [n f]
+  (vec (map-indexed (fn [id obj]
+                      (assoc obj :id (inc id)))
+                    (repeatedly n f))))
+
+(defn- product-add-reviews [product]
+  (let [num-reviews (max 0 (normal-distribution-rand-int 5 4))
+        reviews     (vec (for [review (repeatedly num-reviews #(random-review product))]
+                           (assoc review :product_id (:id product))))
+        rating      (if (seq reviews) (/ (reduce + (map :rating reviews))
+                                         (count reviews))
+                        0.0)]
+    (assoc product :reviews reviews, :rating (-> (* rating 10.0)
+                                                 int
+                                                 (/ 10.0)))))
+
+(defn- person-add-orders [products person]
+  {:pre [(sequential? products)
+         (map? person)]
+   :post [(map? %)]}
+  (let [num-orders (max 0 (normal-distribution-rand-int 5 10))]
+    (if (zero? num-orders)
+      person
+      (assoc person :orders (vec (repeatedly num-orders #(random-order person (rand-nth products))))))))
+
+(defn create-random-data [& {:keys [people products]
+                             :or   {people 2500 products 200}}]
+  {:post [(map? %)
+          (= (count (:people %)) people)
+          (= (count (:products %)) products)
+          (every? keyword? (keys %))
+          (every? sequential? (vals %))]}
+  (println (format "Generating random data: %d people, %d products..." people products))
+  (let [products (mapv product-add-reviews (create-randoms products random-product))
+        people   (mapv (partial person-add-orders products) (create-randoms people random-person))]
+    {:people   (mapv #(dissoc % :orders) people)
+     :products (mapv #(dissoc % :reviews) products)
+     :reviews  (vec (mapcat :reviews products))
+     :orders   (vec (mapcat :orders people))}))
+
+;;; # LOADING THE DATA
+
+(defn- create-table-sql [table-name field->type]
+  {:pre [(keyword? table-name)
+         (map? field->type)
+         (every? keyword? (keys field->type))
+         (every? string? (vals field->type))]
+   :post [(string? %)]}
+  (format "CREATE TABLE \"%s\" (\"ID\" BIGINT AUTO_INCREMENT, %s, PRIMARY KEY (\"ID\"));"
+          (s/upper-case (name table-name))
+          (apply str (->> (for [[field type] (seq field->type)]
+                            (format "\"%s\" %s NOT NULL" (s/upper-case (name field)) type))
+                          (interpose ", ")))))
+
+(def ^:private ^:const tables
+  {:people {:name       "VARCHAR(255)"
+            :email      "VARCHAR(255)"
+            :password   "VARCHAR(255)"
+            :birth_date "DATE"
+            :address    "VARCHAR(255)"
+            :zip        "CHAR(5)"
+            :city       "VARCHAR(255)"
+            :state      "CHAR(2)"
+            :latitude   "FLOAT"
+            :longitude  "FLOAT"
+            :source     "VARCHAR(255)"
+            :created_at "DATETIME"}
+   :products {:ean        "CHAR(13)"
+              :title      "VARCHAR(255)"
+              :category   "VARCHAR(255)"
+              :vendor     "VARCHAR(255)"
+              :price      "FLOAT"
+              :rating     "FLOAT"
+              :created_at "DATETIME"}
+   :orders {:user_id    "INTEGER"
+            :product_id "INTEGER"
+            :subtotal   "FLOAT"
+            :tax        "FLOAT"
+            :total      "FLOAT"
+            :created_at "DATETIME"}
+   :reviews {:product_id "INTEGER"
+             :reviewer   "VARCHAR(255)"
+             :rating     "SMALLINT"
+             :body       "TEXT"
+             :created_at "DATETIME"}})
+
+(def ^:private ^:const fks
+  [{:source-table "ORDERS"
+    :field        "USER_ID"
+    :dest-table   "PEOPLE"}
+   {:source-table "ORDERS"
+    :field        "PRODUCT_ID"
+    :dest-table   "PRODUCTS"}
+   {:source-table "REVIEWS"
+    :field        "PRODUCT_ID"
+    :dest-table   "PRODUCTS"}])
+
+(def ^:private ^:const metabase-metadata
+  {:orders   {:description "This is a confirmed order for a product from a user."
+              :columns     {:created_at {:description "The date and time an order was submitted."}
+                            :id         {:description "This is a unique ID for the product. It is also called the “Invoice number” or “Confirmation number” in customer facing emails and screens."}
+                            :product_id {:description "The product ID. This is an internal identifier for the product, NOT the SKU."}
+                            :subtotal   {:description "The raw, pre-tax cost of the order. Note that this might be different in the future from the product price due to promotions, credits, etc."}
+                            :tax        {:description (str "This is the amount of local and federal taxes that are collected on the purchase. Note that other governmental fees "
+                                                           "on some products are not included here, but instead are accounted for in the subtotal.")}
+                            :total      {:description "The total billed amount."}
+                            :user_id    {:description (str "The id of the user who made this order. Note that in some cases where an order was created on behalf "
+                                                           "of a customer who phoned the order in, this might be the employee who handled the request.")}}}
+   :people {:description "This is a user account. Note that employees and customer support staff will have accounts."
+            :columns     {:address    {:description "The street address of the account’s billing address"}
+                          :birth_date {:description "The date of birth of the user"}
+                          :city       {:description "The city of the account’s billing address"}
+                          :created_at {:description "The date the user record was created. Also referred to as the user’s \"join date\""}
+                          :email      {:description "The contact email for the account."}
+                          :id         {:description "A unique identifier given to each user."}
+                          :latitude   {:description "This is the latitude of the user on sign-up. It might be updated in the future to the last seen location."}
+                          :longitude  {:description "This is the longitude of the user on sign-up. It might be updated in the future to the last seen location."}
+                          :name       {:description "The name of the user who owns an account"}
+                          :password   {:description "This is the salted password of the user. It should not be visible"}
+                          :source     {:description "The channel through which we acquired this user. Valid values include: Affiliate, Facebook, Google, Organic and Twitter"}
+                          :state      {:description "The state or province of the account’s billing address"}
+                          :zip        {:description  "The postal code of the account’s billing address"
+                                       :special_type "type/ZipCode"}}}
+   :products {:description "This is our product catalog. It includes all products ever sold by the Sample Company."
+              :columns      {:category   {:description "The type of product, valid values include: Doohicky, Gadget, Gizmo and Widget"}
+                             :created_at {:description "The date the product was added to our catalog."}
+                             :ean        {:description "The international article number. A 13 digit number uniquely identifying the product."}
+                             :id         {:description "The numerical product number. Only used internally. All external communication should use the title or EAN."}
+                             :price      {:description "The list price of the product. Note that this is not always the price the product sold for due to discounts, promotions, etc."}
+                             :rating     {:description "The average rating users have given the product. This ranges from 1 - 5"}
+                             :title      {:description "The name of the product as it should be displayed to customers."}
+                             :vendor     {:description "The source of the product."}}}
+   :reviews  {:description "These are reviews our customers have left on products. Note that these are not tied to orders so it is possible people have reviewed products they did not purchase from us."
+              :columns     {:body       {:description  "The review the user left. Limited to 2000 characters."
+                                         :special_type "type/Description"}
+                            :created_at {:description "The day and time a review was written by a user."}
+                            :id         {:description "A unique internal identifier for the review. Should not be used externally."}
+                            :product_id {:description "The product the review was for"}
+                            :rating     {:description "The rating (on a scale of 1-5) the user left."}
+                            :reviewer   {:description "The user who left the review"}}}})
+
+(defn create-h2-db
+  ([filename]
+   (create-h2-db filename (create-random-data)))
+  ([filename data]
+   (println "Deleting existing db...")
+   (io/delete-file (str filename ".mv.db") :silently)
+   (io/delete-file (str filename ".trace.db") :silently)
+   (println "Creating db...")
+   (let [db (dbspec/h2 {:db         (format "file:%s;UNDO_LOG=0;CACHE_SIZE=131072;QUERY_CACHE_SIZE=128;COMPRESS=TRUE;MULTI_THREADED=TRUE;MVCC=TRUE;DEFRAG_ALWAYS=TRUE;MAX_COMPACT_TIME=5000;ANALYZE_AUTO=100"
+                                            filename)
+                        :make-pool? false})]
+     (doseq [[table-name field->type] (seq tables)]
+       (jdbc/execute! db [(create-table-sql table-name field->type)]))
+
+     ;; Add FK constraints
+     (println "Adding FKs...")
+     (doseq [{:keys [source-table field dest-table]} fks]
+       (jdbc/execute! db [(format "ALTER TABLE \"%s\" ADD CONSTRAINT \"FK_%s_%s_%s\" FOREIGN KEY (\"%s\") REFERENCES \"%s\" (\"ID\");"
+                                  source-table
+                                  source-table field dest-table
+                                  field
+                                  dest-table)]))
+
+     ;; Insert the data
+     (println "Inserting data...")
+     (doseq [[table rows] (seq data)]
+       (assert (keyword? table))
+       (assert (sequential? rows))
+       (let [table-name (s/upper-case (name table))]
+         (jdbc/insert-multi! db table-name (for [row rows]
+                                             (into {} (for [[k v] (seq row)]
+                                                        {(s/upper-case (name k)) v}))))))
+
+     ;; Insert the _metabase_metadata table
+     (println "Inserting _metabase_metadata...")
+     (jdbc/execute! db ["CREATE TABLE \"_METABASE_METADATA\" (\"KEYPATH\" VARCHAR(255), \"VALUE\" VARCHAR(255), PRIMARY KEY (\"KEYPATH\"));"])
+     (jdbc/insert-multi! db "_METABASE_METADATA" (reduce concat (for [[table-name {table-description :description, columns :columns}] metabase-metadata]
+                                                                  (let [table-name (s/upper-case (name table-name))]
+                                                                    (conj (for [[column-name kvs] columns
+                                                                                [k v]             kvs]
+                                                                            {:keypath (format "%s.%s.%s" table-name (s/upper-case (name column-name)) (name k))
+                                                                             :value   v})
+                                                                          {:keypath (format "%s.description" table-name)
+                                                                           :value table-description})))))
+
+     ;; Create the 'GUEST' user
+     (println "Preparing database for export...")
+     (jdbc/execute! db ["CREATE USER GUEST PASSWORD 'guest';"])
+     (doseq [table (conj (keys data) "_METABASE_METADATA")]
+       (jdbc/execute! db [(format "GRANT SELECT ON %s TO GUEST;" (s/upper-case (name table)))]))
+
+     (println "Done."))))
+
+(defn -main [& [filename]]
+  (let [filename (or filename sample-dataset-filename)]
+    (println (format "Writing sample dataset to %s..." filename))
+    (create-h2-db filename)
+    (System/exit 0)))


Added mbastian reducers solution.

Added mbastian reducers solution.

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

--- src/main/cljc/clojure_club/playground/mbastian.cljc
+++ src/main/cljc/clojure_club/playground/mbastian.cljc
@@ -0,0 +1,43 @@
+(ns clojure-club.playground.mbastian
+  (:require [clojure.core.reducers :as r]))
+
+(defn work-proxy [input]  (Thread/sleep input)  1)
+
+(def work-proxy-thunk (partial work-proxy 1000))
+
+(defn counter [thunk]
+  (thunk))
+
+;Think of work proxy as set amount of calculation we want to do.
+;What I was trying to do was get the reducers to run each thunk in parallel.
+; I can do this with pmap, but if I try to use transducers, it seems its immediately realized.
+
+;(time (count-state-reducer 40))
+;"Elapsed time: 40019.119145 msecs"
+;Note this is the same time as count-state, probably because the thunks aren't
+;execute in parallel, but during the r/map?
+(defn count-state-reducer [limit]
+  (->>  (repeat limit work-proxy-thunk)
+        ;http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html
+        ;You must use a vec or map to get free parallelism. No lists or generic seqs!
+        vec
+        ;(r/take limit)
+        (r/map counter)
+        (r/fold 8 + +)
+        ))
+
+;(time (count-state-better 40))
+;"Elapsed time: 4006.483026 msecs"
+(defn count-state-better [limit]
+  (->> (repeat work-proxy-thunk)
+       (take limit)
+       (pmap counter)
+       (reduce +)))
+
+;(time (count-state 40))
+;"Elapsed time: 40020.016874 msecs"
+(defn count-state [limit]
+  (->> (repeat work-proxy-thunk)
+       (take limit)
+       (map counter)
+       (reduce +)))


Add message parsing and signature verification stuff in sns.consume

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

--- src/fink_nottle/sns/consume.clj
+++ src/fink_nottle/sns/consume.clj
@@ -0,0 +1,74 @@
+(ns fink-nottle.sns.consume
+  (:require [camel-snake-kebab.core :as csk]
+            [cemerick.url :as url]
+            [cheshire.core :as json]
+            [clojure.core.async :as async :refer [go <!]]
+            [clojure.data.codec.base64 :as b64]
+            [clojure.java.io :as io]
+            [clojure.string :as str]
+            [eulalie.service-util :as service-util]
+            [eulalie.util :as util]
+            [glossop :refer [go-catching]])
+  (:import [java.security Signature PublicKey]
+           [java.security.cert CertificateFactory Certificate]))
+
+(defn adjust-message-values [{:keys [type] :as m}]
+  (assoc m :type (csk/->kebab-case-keyword type)))
+
+(defn string->message [x]
+  (-> (json/decode x csk/->kebab-case-keyword)
+      adjust-message-values))
+
+(defn stream->message [x & [{:keys [encoding] :or {encoding "UTF-8"}}]]
+  (-> x
+      (io/reader :encoding encoding)
+      (json/parse-stream csk/->kebab-case-keyword)
+      adjust-message-values))
+
+(defn verify-cert-url [url expected-region]
+  (let [url (cond-> url (string? url) url/url)
+        reference (service-util/region->endpoint
+                   expected-region {:service-name :sns})]
+    (and (= (:protocol url) "https")
+         (= (:host url) (:host reference)))))
+
+(defn make-key-cache [] (atom {}))
+
+(defn url->public-key! [url & [key-cache]]
+  (go-catching
+    (or (and key-cache (@key-cache url))
+        (let [{:keys [body error]}
+              (<! (util/channel-request! {:url (str url)}))]
+          (if error
+            error
+            (let [pk (-> (CertificateFactory/getInstance "X.509")
+                         (.generateCertificate body)
+                         (.getPublicKey))]
+              (when key-cache
+                (swap! key-cache assoc url pk))
+              pk))))))
+
+(let [attrs [:message :message-id :subscribe-url :timestamp :token :topic-arn :type]
+      renames {:subscribe-url "SubscribeURL"}]
+  (defn bytes-to-sign [{:keys [type] :as m}]
+    (let [m (cond-> m type (assoc :type (csk/->PascalCaseString type)))]
+      (-> ^String
+          (apply str
+                 (for [k attrs :when (m k)]
+                   (str (or (renames k) (csk/->PascalCaseString k))
+                        "\n"
+                        (m k)
+                        "\n")))
+          (.getBytes "UTF-8")))))
+
+(defn verify? [pk {:keys [signature] :as m}]
+  (let [sig (Signature/getInstance "SHA1withRSA")]
+    (.initVerify sig ^PublicKey pk)
+    (.update sig ^bytes (bytes-to-sign m))
+    (.verify sig (b64/decode (.getBytes ^String signature "UTF-8")))))
+
+(defn verify-message! [{:keys [signing-cert-url] :as m} region & [key-cache]]
+  (go-catching
+    (when (verify-cert-url signing-cert-url region)
+      (let [pk (<! (url->public-key! signing-cert-url key-cache))]
+        (verify? pk m)))))


timezone fixes

timezone fixes

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -30,9 +30,9 @@
   [achievement-id
    (fn [commit-info]
      (let [time (:time commit-info)
-           ; TODO Correct timezone
            cal (Calendar/getInstance)
            _ (.setTime cal time)
+           _ (.setTimeZone cal timezone)
            commit-day (.get cal Calendar/DAY_OF_MONTH)
            commit-month (.get cal Calendar/MONTH)]
        (when (= [month day] [commit-month commit-day])
@@ -180,9 +180,9 @@
   [:professional-pride
    (fn [commit-info]
      (let [time (:time commit-info)
-           ; TODO Correct timezone
            cal (Calendar/getInstance)
            _ (.setTime cal time)
+           _ (.setTimeZone cal timezone)
            commit-day (.get cal Calendar/DAY_OF_YEAR)]
        (when (= 1024 commit-day)
          {:username (:author commit-info)
@@ -192,9 +192,9 @@
   [:turkey-day
    (fn [commit-info]
      (let [time (:time commit-info)
-           ; TODO Correct timezone
            cal (Calendar/getInstance)
            _ (.setTime cal time)
+           _ (.setTimeZone cal timezone)
            commit-day (.get cal Calendar/DAY_OF_WEEK)
            commit-month (.get cal Calendar/MONTH)
            commit-month-day (.get cal Calendar/DAY_OF_MONTH)]


different meaning for changed >0

different meaning for changed >0

--- src-clj/acha/achievement.clj
+++ src-clj/acha/achievement.clj
@@ -143,12 +143,9 @@
         :time time}))])

 (def world-balance
-  [:world-balance
-   (fn [{:keys [loc author time changed-files]}]
-     (when (and ((fn [loc] (= (:added loc 0) (:deleted loc 0))) loc)
-          (> changed-files 0))
-       {:username author
-        :time time}))])
+  (make-loc-scanner
+    [:world-balance
+    (fn [loc] (and (= (:added loc 0) (:deleted loc 0)) (> (:added loc 0) 0)))]))

 (def eraser
   (make-loc-scanner