Add document_date to be updated on the update function

--- src-cljs/pepa/api.cljs
+++ src-cljs/pepa/api.cljs
@@ -9,7 +9,8 @@
             [pepa.data :as data]

             [clojure.browser.event :as event])
-  (:import [goog.net XhrIo XmlHttp XmlHttpFactory EventType])
+  (:import [goog.net XhrIo XmlHttp XmlHttpFactory EventType]
+           [goog.i18n DateTimeFormat])
   (:require-macros [cljs.core.async.macros :refer [go go-loop]]))

 (def +xhr-timeout+ (* 5 1000))
@@ -185,7 +186,7 @@
 (defn update-document!
   "Diffs the document with the same id on the server with DOCUMENT and
   updates it to match DOCUMENT. Will also update the application
-  state (wether DOCUMENT is a cursor or not)."
+  state (whether DOCUMENT is a cursor or not)."
   [document]
   (go
     (println "saving document" (:id document))
@@ -194,6 +195,9 @@
           title (when-not (= (:title document)
                              (:title server))
                   (:title document))
+          date (when-not (= (:document_date document)
+                            (:document_date server))
+                 (.format (DateTimeFormat. "dd.MM.yyyy HH:mm") (:document_date document)))
           tags {:added (remove (set (:tags server)) (:tags document))
                 :removed (remove (set (:tags document)) (:tags server))}]
       (when-not server
@@ -201,10 +205,10 @@
                         {:document document
                          :document/id (:id document)
                          :response server})))
-      (if (or title (seq (:added tags)) (seq (:removed tags)))
+      (if (or title date (seq (:added tags)) (seq (:removed tags)))
         (let [response (<! (xhr-request! (str "/documents/" (:id document))
                                          :post
-                                         {:title title, :tags tags}))]
+                                         {:title title, :document_date date :tags tags}))]
           (if (= 200 (:status response))
             (let [new-document (-> response
                                    :response/transit


Set proper default page background.

Set proper default page background.

--- frontend/src/uxbox/main/ui/workspace/canvas.cljs
+++ frontend/src/uxbox/main/ui/workspace/canvas.cljs
@@ -38,7 +38,7 @@
    {:x 0 :y 0
     :width "100%"
     :height "100%"
-    :fill (or background "#000000")}])
+    :fill (or background "#ffffff")}])

 ;; --- Canvas


Little bit of styling for uploads page

Little bit of styling for uploads page

--- src/braid/core/client/uploads/views/uploads_page_styles.cljs
+++ src/braid/core/client/uploads/views/uploads_page_styles.cljs
@@ -8,6 +8,9 @@
   [:>.page.uploads

    [:>.content
+
+    [:button
+     (mixins/settings-button)]

     [:>table.uploads
      {:width "100%"
@@ -20,13 +23,21 @@

       [:>tr.upload

+       ["&:nth-child(odd)"
+        {:background-color "#f9f9f9"}]
+
+       ["&:nth-child(even)"
+        {:background-color "white"}]
+
        [:>td.delete
+
         [:>button
          {:font-family "fontawesome"
           :color "red"}]]
+
        [:>td.uploaded-file

-        [:>.embed
+        [:img :video
          {:width (rem 5)
           :margin 0}]


try to speed up with pmap

try to speed up with pmap

--- src/leiningen/leinsync/commands.clj
+++ src/leiningen/leinsync/commands.clj
@@ -11,7 +11,7 @@

 (defn pull-rebase-all! [_ projects _]
   (-> #(u/run-command-on (pr/->target-project-path %) git/pull-rebase! %)
-      (map projects)
+      (pmap projects)
       (git/log-git-status)))

 (defn push-all! [_ projects _]
@@ -32,26 +32,25 @@
                         (u/ask-user))
         projects-desc (pr/read-all-target-project-clj projects)]
     (-> #(u/run-command-on (pr/->target-project-path %) git/commit-project! % commit-msg ((keyword %) projects-desc))
-        (map projects)
+        (pmap projects)
         (git/log-git-status "\n*To push        : lein sync" projects-str "--push"))))

 (defn status-all [_ projects _]
   (let [projects-desc (pr/read-all-target-project-clj projects)]
     (-> #(u/run-command-on (pr/->target-project-path %) git/details-status % ((keyword %) projects-desc))
-        (map projects)
+        (pmap projects)
         (git/log-git-status))))

 (defn reset-all! [_ projects _]
   (-> #(u/run-command-on (pr/->target-project-path %) git/reset-project! %)
-      (map projects)
+      (pmap projects)
       (git/log-git-status)))

 (defn list [_ target-projects {source-project :name}]
   (let [all-projects-desc (-> target-projects
                               (conj source-project)
                               (pr/read-all-target-project-clj))]
-    (l/list-resources all-projects-desc ns/namespace-def)
-    (l/list-resources all-projects-desc ns/resource-def)))
+    (pmap #(l/list-resources all-projects-desc %) [ns/namespace-def ns/resource-def])))

 (defn update-projects! [_ target-projects source-project-desc]
   (let [target-projects-desc (pr/read-all-target-project-clj target-projects)
@@ -64,11 +63,9 @@
   (let [all-projects-desc (-> target-projects
                               (conj source-project)
                               (pr/read-all-target-project-clj))]
-    (cond (= :global arg)
-          (deps/check-dependencies-of all-projects-desc [:dependencies])
-
-          :else
-          (deps/check-dependencies-of all-projects-desc [:profiles arg :dependencies]))))
+    (cond
+      (= :global arg) (deps/check-dependencies-of all-projects-desc [:dependencies])
+      :else (deps/check-dependencies-of all-projects-desc [:profiles arg :dependencies]))))

 (def SYNC-COMMANDS {:default {:update "" :test ""}
                     :deps    deps


XML exporter

XML exporter

--- src/zg/server.clj
+++ src/zg/server.clj
@@ -162,6 +162,16 @@
     [words]
     (clojure.string/join "\n" words))

+(defn words->xml
+    [words]
+    (with-out-str
+        (xml/emit {:tag :whitelist :content (for [word words]
+                                             {:tag :word :attrs {
+                                                             :added-by     (:user word)
+                                                             :date-time (:datetime word)
+                                                             :deleted  (:deleted word)}
+                                                             :content  [(:word word)]})})))
+
 (defn process-wordlist-json
     [request]
     (let [search-results (db-interface/read-all-words)
@@ -175,6 +185,13 @@
           text-output    (words->text search-results)]
         (-> (http-response/response text-output)
             (http-response/content-type "text/plain"))))
+
+(defn process-wordlist-xml
+    [request]
+    (let [search-results (db-interface/read-all-words)
+          xml-output     (words->xml search-results)]
+        (-> (http-response/response xml-output)
+            (http-response/content-type "text/xml"))))

 ;defn process-delete-word
 ;   [request]
@@ -220,6 +237,7 @@
             "/user"              (process-user-info     request)
             "/wordlist/json"     (process-wordlist-json request)
             "/wordlist/text"     (process-wordlist-text request)
+            "/wordlist/xml"      (process-wordlist-xml  request)
             ;"/delete-word"      (process-delete-word   request)
             ;"/undelete-word"    (process-undelete-word request)
             )))


Add sub-command "version"

Add sub-command "version"

--- src/cljam/cli.clj
+++ src/cljam/cli.clj
@@ -359,23 +359,33 @@
         (level/add-level r w))))
   nil)

+;; ### version command
+
+(defn version [args]
+  (let [ver (with-open [r (-> "META-INF/maven/cljam/cljam/pom.properties"
+                              (clojure.java.io/resource)
+                              (clojure.java.io/reader))]
+              (.getProperty (doto (java.util.Properties.) (.load r)) "version"))]
+    (exit 0 ver)))
+
 ;; Main command
 ;; ------------

 (defn run [args]
   (let [[opts cmd args help cands]
         (sub-command args
-                     "Usage: cljam {view,convert,sort,index,pileup,faidx,dict} ..."
+                     "Usage: cljam {view,convert,normalize,sort,index,pileup,faidx,dict,level,version} ..."
                      :options  [["-h" "--help" "Show help" :default false :flag true]]
                      :commands [["view"    "Extract/print all or sub alignments in SAM or BAM format."]
                                 ["convert" "Convert SAM to BAM or BAM to SAM."]
-                                ["normalize" "Normalize references of alignments"]
+                                ["normalize" "Normalize references of alignments."]
                                 ["sort"    "Sort alignments by leftmost coordinates."]
                                 ["index"   "Index sorted alignment for fast random access."]
                                 ["pileup"  "Generate pileup for the BAM file."]
                                 ["faidx"   "Index reference sequence in the FASTA format."]
                                 ["dict"    "Create a FASTA sequence dictionary file."]
-                                ["level"   "Add level of alignments."]])]
+                                ["level"   "Add level of alignments."]
+                                ["version" "Print version number."]])]
     (when (:help opts)
       (exit 0 help))
     (case cmd
@@ -388,6 +398,7 @@
       :faidx   (faidx args)
       :dict    (dict args)
       :level   (level args)
+      :version (version args)
       (do (println "Invalid command. See 'cljam --help'.")
           (when (seq cands)
             (newline)


simple repl implemented

simple repl implemented

--- src/selectscript/core.clj
+++ src/selectscript/core.clj
@@ -12,7 +12,8 @@

 (declare cli-options
          ss:execute
-         ss:compile)
+         ss:compile
+         ss:repl)

 (def cli-options
@@ -63,28 +64,42 @@
   (let [{:keys [options arguments errors summary]} (parse-opts args cli-options)]
     (if (:help options)
       (println summary))
-    (with-local-vars [code (slurp (first arguments))]
-      (var-set code (parse @code))
-      (if (:optimize options)
-        (var-set code (optimize @code)))
-      (if (:parse-tree options)
-        (println @code))
-      (var-set code (assemble @code))
-      (if (:interim options)
-        (println @code))
-      (var-set code (cmp @code))
-      (if (:assembly options)
-        (dis @code))
-      (if (:bytecode options)
-        (println @code))
-      (if (:debug options)
-        (ss:execute @code true))
-      (if (:execute options)
-        (ss:execute @code false))
-      (if (:repl options)
-        (println "repl")))))
+
+    (if (empty? arguments)
+      (ss:repl (:optimize options))
+      (with-local-vars [code (slurp (first arguments))]
+        (var-set code (parse @code))
+        (if (:optimize options)
+          (var-set code (optimize @code)))
+        (if (:parse-tree options)
+          (println @code))
+        (var-set code (assemble @code))
+        (if (:interim options)
+          (println @code))
+        (var-set code (cmp @code))
+        (if (:assembly options)
+          (dis @code))
+        (if (:bytecode options)
+          (println @code))
+        (if (:debug options)
+          (ss:execute @code true))
+        (if (:execute options)
+          (ss:execute @code false))))
+    (if (:repl options)
+      (ss:repl (:optimize options)))))

 ;(-main "-o" "test.bS2" "-d" "test.S2")
+
+(defn ss:repl [opt]
+  (let [env (vm:init 100 100 -1)]
+    (print ">>> ")
+    (flush)
+    (loop [code (read-line)]
+      ;(println)
+      (vm:exec env (vm:prog (ss:compile code opt)) 0)
+      (print (vm:rslt env) "\n>>> ")
+      (flush)
+      (recur (read-line)))))

 (defn ss:compile [string opt]
   (as-> string input


Copy format function from backend

Copy format function from backend

--- src-cljs/frontend/models/test.cljs
+++ src-cljs/frontend/models/test.cljs
@@ -13,7 +13,10 @@
 (defmulti format-test-name source)

 (defmethod format-test-name :default [test]
-  (:name test))
+  (->> [[(:name test)] [(:classname test) (:file test)]]
+       (map (fn [s] (some #(when-not (string/blank? %) %) s)))
+       (filter identity)
+       (string/join " - in ")))

 (defmethod format-test-name "lein-test" [test]
   (str (:classname test) "/" (:name test)))


Minor changes

Minor changes

--- src/main/clojure/clj_print/core.clj
+++ src/main/clojure/clj_print/core.clj
@@ -8,11 +8,14 @@
            (java.net URL)
            (javax.print Doc
                         DocPrintJob
+                        DocFlavor ;; Remove me!
                         PrintException
                         PrintService
                         PrintServiceLookup
                         SimpleDoc)
-           (javax.print.attribute AttributeSet
+           (javax.print.attribute Attribute
+                                  AttributeSet
+                                  DocAttributeSet
                                   HashAttributeSet
                                   HashPrintRequestAttributeSet)
            (javax.print.attribute.standard MediaTray
@@ -27,7 +30,7 @@
    With no arguments, returns a seq of all printers that
    PrintServiceLookup is aware of."
   {:added "1.0"}
-  ([& {:keys [^DocFlavor flavor ^AttributeSet attrs] :or [flavor nil attrs nil]}]
+  ([& {:keys [^DocFlavor flavor ^AttributeSet attrs]}]
      (seq (PrintServiceLookup/lookupPrintServices flavor attrs))))

 (defn printer
@@ -38,7 +41,7 @@
   ([name]
      (if (seq name)
        (let [attrs (doto (HashAttributeSet.) (.add (PrinterName. name nil)))]
-         (some (fn [^PrintService p] (if (= name (.getName p)) p)) (printers nil attrs)))
+         (some (fn [^PrintService p] (when (= name (.. p getName)) p)) (printers nil attrs)))
        (printer))))

 (defn status
@@ -52,7 +55,6 @@
   atributes, for all of its supported Attribute classes."
   {:added "1.0"}
   [^PrintService p]
-  ;; We don't care about DocFlavor or passing in AttributeSets, just use filter
   (let [unflattened (for [c (.. p getSupportedAttributeCategories)]
                       (.. p (getSupportedAttributeValues c nil nil)))]
     (->> unflattened
@@ -90,7 +92,7 @@
   (condp = (parse-source doc-source)
     :file (:autosense flavors/input-streams)
     :url (:autosense flavors/urls)
-    nil nil))
+    nil))

 (defn job-map
   "Returns a job-map that encapsulates the constituent parts of a print job.
@@ -114,14 +116,12 @@
                         doc-flavor
                         doc-attrs
                         job-attrs]
-                 :or {p-name nil
-                      doc-flavor (flavor doc-source)
-                      doc-attrs nil
+                 :or {doc-flavor (flavor doc-source)
                       job-attrs (doto (HashPrintRequestAttributeSet.) (.add MediaTray/MAIN))}}]
   (let [^PrintService p (printer p-name)
         job (job p)]
     {:doc-source doc-source
-     :printer (.getName p)
+     :printer (.. p getName)
      :job-attrs job-attrs
      :job job
      :doc-flavor doc-flavor


CLJS-1414: Only munge @param @return if type checking

--- src/main/clojure/cljs/compiler.cljc
+++ src/main/clojure/cljs/compiler.cljc
@@ -549,6 +549,11 @@

     :else line))

+(defn checking-types? []
+  (#{:error :warn}
+    (get-in @env/*compiler*
+      [:options :closure-warnings :check-types])))
+
 (defn emit-comment
   "Emit a nicely formatted comment string."
   ([doc jsdoc]
@@ -558,7 +563,9 @@
          docs (if jsdoc (concat docs jsdoc) docs)
          docs (remove nil? docs)]
      (letfn [(print-comment-lines [e]
-               (let [[x & ys] (map #(munge-param-return env %) (string/split-lines e))]
+               (let [[x & ys]
+                     (map #(if (checking-types?) (munge-param-return env %) %)
+                       (string/split-lines e))]
                  (emitln " * " (string/replace x "*/" "* /"))
                  (doseq [next-line ys]
                    (emitln " * "


Exercise 2.3'

Exercise 2.3'

--- src/sicp/chapter2/1_2.clj
+++ src/sicp/chapter2/1_2.clj
@@ -71,3 +71,38 @@

 (defn area [rect]
   (* (width rect) (height rect)))
+
+;; Exercise 2.3'
+(defn point [x y]
+  #:point{:x x
+          :y y})
+
+(defn vect [p1 p2]
+  #:vect{:x (- (:point/x p2) (:point/x p1))
+         :y (- (:point/y p2) (:point/y p1))})
+
+(defn dist [p1 p2]
+  (let [dx (- (:point/x p2) (:point/x p1))
+        dy (- (:point/y p2) (:point/y p1))]
+    (Math/sqrt (+ (Math/pow dx 2)
+                  (Math/pow dy 2)))))
+
+(defn rectangle [pa po pb]
+  #:rectangle{:len-a (dist po pa)
+              :len-b (dist po pb)
+              :vect-a (vect po pa)
+              :vect-b (vect po pb)})
+
+(defn perimeter* [{:rectangle/keys [len-a len-b]}]
+  (+ (* 2 len-a) (* 2 len-b)))
+
+(defn area* [{:rectangle/keys [vect-a vect-b]}]
+  (Math/abs (- (* (:vect/x vect-a) (:vect/y vect-b))
+               (* (:vect/y vect-a) (:vect/x vect-b)))))
+
+#_(let [p1 (point 0 0)
+        p2 (point -1 1)
+        p3 (point 0 2)
+        rect (rectangle p1 p2 p3)]
+    {:perimeter (perimeter* rect)
+     :area (area* rect)})


remove unneeded dag_unify.core/copy

remove unneeded dag_unify.core/copy

--- src/babel/english.cljc
+++ src/babel/english.cljc
@@ -17,9 +17,7 @@
    #?(:cljs [babel.logjs :as log])
    #?(:clj [clojure.tools.logging :as log])
    [dag_unify.core :refer [deserialize dissoc-paths
-                           fail? fail-path get-in serialize strip-refs
-                           ;;temporary
-                           copy]]))
+                           fail? fail-path get-in serialize strip-refs]]))

 (def lexicon (:lexicon (medium)))
 (def grammar (:grammar-map (medium)))


cleanup

cleanup

--- src/babel/lexicon.cljc
+++ src/babel/lexicon.cljc
@@ -1,20 +0,0 @@
-(ns babel.lexicon)
-
-;; mapping of predicates: e.g. :say, to lexical implications.
-;; e.g., if verb is :say, then :subj (i.e. the speaker) must
-;; be human, and :obj (i.e. what is spoken) must be speakable.
-;; TODO: consider simplifying this by stipulating that the
-;; constraint applies only to {:sem ...},
-;; not {:synsem { .. :sem .. }}.
-;; TODO: move to babel.encyclopedia
-(def universals
-  {:say {:synsem {:sem {:subj {:human true}
-                        :obj {:speakable true}}}}
-   :sleep {:synsem {:sem {:subj {:animate true}
-                          :discrete false}}}
-   :tell {:synsem {:sem {:subj {:human true}
-                         :obj {:human true}}}}})
-
-;; TODO: add other :pred -> constraints, and
-;; DRY stuff up by removing the same from language-specific lexicons,
-;; where it's present


A basic migration demo that creates three tables

--- src/blaagh/db/core.clj
+++ src/blaagh/db/core.clj
@@ -4,10 +4,19 @@
 (def db-conn {
     :classname "org.sqlite.JDBC"
     :subprotocol "sqlite"
-    :subname "resources/db/blaagh.sqlite3"})
+    :subname "resources/db/blaagh.sqlite3"}) ;; creates DB if not already present

 (defn get-names []
     (let [results (sql/query db-conn ["select name from foo"])]
         (cond
             (empty? results) {:status 404}
             :else results)))
+
+(defn create-tables []
+    (try
+        (sql/db-do-commands db-conn
+            "CREATE TABLE foo (name text); "
+            "CREATE TABLE bar (name text); "
+            "CREATE TABLE baz (name text); ")
+        (catch Exception e
+            (println e))))


CMR-6137: Fixed acl-search-permitted-concept-id-test.

--- common-app-lib/src/cmr/common_app/services/search/query_to_elastic.clj
+++ common-app-lib/src/cmr/common_app/services/search/query_to_elastic.clj
@@ -180,8 +180,9 @@
    [{:keys [operation conditions]} concept-type]
    ;; Performance enhancement: We should order the conditions within and/ors.
    (if (= :and operation)
-     (map #(condition->elastic % concept-type) conditions)
-     {:bool {:should (map #(condition->elastic % concept-type) conditions)}}))
+     {:bool {:must (map #(condition->elastic % concept-type) conditions)}}
+     {:bool {:should (map #(condition->elastic % concept-type) conditions)
+             :minimum_should_match 1}}))

   cmr.common_app.services.search.query_model.NestedCondition
   (condition->elastic
@@ -262,26 +263,29 @@
   cmr.common_app.services.search.query_model.NumericRangeIntersectionCondition
   (condition->elastic
    [{:keys [min-field max-field min-value max-value]} concept-type]
-   {:or [(range-condition->elastic (query-field->elastic-field min-field concept-type)
-                                   min-value
-                                   max-value
-                                   (numeric-range-execution-mode)
-                                   (numeric-range-use-cache))
-         (range-condition->elastic (query-field->elastic-field max-field concept-type)
-                                   min-value
-                                   max-value
-                                   (numeric-range-execution-mode)
-                                   (numeric-range-use-cache))
-         {:and [(range-condition->elastic (query-field->elastic-field min-field concept-type)
-                                          nil
-                                          min-value
-                                          (numeric-range-execution-mode)
-                                          (numeric-range-use-cache))
-                (range-condition->elastic (query-field->elastic-field max-field concept-type)
-                                          max-value
-                                          nil
-                                          (numeric-range-execution-mode)
-                                          (numeric-range-use-cache))]}]})
+   {:bool
+    {:should [(range-condition->elastic (query-field->elastic-field min-field concept-type)
+                                        min-value
+                                        max-value
+                                        (numeric-range-execution-mode)
+                                        (numeric-range-use-cache))
+              (range-condition->elastic (query-field->elastic-field max-field concept-type)
+                                        min-value
+                                        max-value
+                                        (numeric-range-execution-mode)
+                                        (numeric-range-use-cache))
+              {:bool
+               {:must [(range-condition->elastic (query-field->elastic-field min-field concept-type)
+                                                 nil
+                                                 min-value
+                                                 (numeric-range-execution-mode)
+                                                 (numeric-range-use-cache))
+                       (range-condition->elastic (query-field->elastic-field max-field concept-type)
+                                                 max-value
+                                                 nil
+                                                 (numeric-range-execution-mode)
+                                                 (numeric-range-use-cache))]}}]
+     :minimum_should_match 1}})

   cmr.common_app.services.search.query_model.StringRangeCondition
   (condition->elastic


Handle hover in response li's.

Handle hover in response li's.

--- src/cbfg/world/t1.cljs
+++ src/cbfg/world/t1.cljs
@@ -55,15 +55,15 @@
                               " complete")
                             "' onmouseenter='return onHoverEvt(this);'>"
                             "
"
-                            "
" ts " " request
+                            "
" request
                             "

"
                             "   <button id='replay-" ts "'>"
                             "    < replay requests to here</button>"
                             "
"
                             (map (fn [[response-ts response]]
-                                   ["
"
+                                   ["
"
                                     (-> (filter-r response)
                                         (dissoc :lane)
                                         (dissoc :delay)


Macros: Rename namespace alias.

Macros: Rename namespace alias.

--- test/com/nomistech/clojure_the_language/macros/syms_test.clj
+++ test/com/nomistech/clojure_the_language/macros/syms_test.clj
@@ -1,11 +1,11 @@
 (ns com.nomistech.clojure-the-language.macros.syms-test
-  (:require [com.nomistech.clojure-the-language.macros.syms :as defs]
+  (:require [com.nomistech.clojure-the-language.macros.syms :as syms]
             [midje.sweet :refer :all]))

 ;;;; ___________________________________________________________________________

 (fact
-  (macroexpand-1 '(defs/do-things-with-symbols-1 x-in-call))
+  (macroexpand-1 '(syms/do-things-with-symbols-1 x-in-call))
   => '{:unquote        x-in-call
        :quote-unquote 'x-in-call
        :force-capture  x-in-def
@@ -13,7 +13,7 @@
        :quote         'com.nomistech.clojure-the-language.macros.syms/x-in-def})

 (fact
-  (macroexpand-1 '(defs/do-things-with-symbols-2))
+  (macroexpand-1 '(syms/do-things-with-symbols-2))
   => '{:undecorated-value-symbol   clojure.core/*print-level*
        :undecorated-fun-symbol     clojure.core/+
        :undecorated-macro-symbol   clojure.core/cond


style changes: destructure maps, params on new line

--- src/chat/server/db.clj
+++ src/chat/server/db.clj
@@ -120,15 +120,18 @@
       ]))

-(defn uuid []
+(defn uuid
+  []
   (d/squuid))

-(defn- db->user [e]
+(defn- db->user
+  [e]
   {:id (:user/id e)
    :email (:user/email e)
    :avatar (:user/avatar e)})

-(defn- db->message [e]
+(defn- db->message
+  [e]
   {:id (:message/id e)
    :content (:message/content e)
    :user-id (:user/id (:message/user e))
@@ -150,7 +153,8 @@
     (->> (d/resolve-tempid db-after tempids new-id)
          (d/entity db-after))))

-(defn get-users-subscribed-to-thread [thread-id]
+(defn get-users-subscribed-to-thread
+  [thread-id]
   (d/q '[:find [?user-id ...]
          :in $ ?thread-id
          :where
@@ -160,24 +164,25 @@
        (d/db *conn*)
        thread-id))

-(defn create-message! [attrs]
+(defn create-message!
+  [{:keys [thread-id id content user-id created-at]}]
   (let [; show thread for all users subscribed to thread
         add-open-transactions (map (fn [user-id]
                                      [:db/add [:user/id user-id]
-                                      :user/open-thread [:thread/id (attrs :thread-id)]])
-                                   (get-users-subscribed-to-thread (attrs :thread-id)))
+                                      :user/open-thread [:thread/id thread-id]])
+                                   (get-users-subscribed-to-thread thread-id))
         ; upsert thread
         thread-data {:db/id (d/tempid :entities)
-                     :thread/id (attrs :thread-id)}
+                     :thread/id thread-id}
         ; upsert message
         msg-data {:db/id (d/tempid :entities)
-                  :message/id (attrs :id)
-                  :message/content (attrs :content)
-                  :message/user [:user/id (attrs :user-id)]
+                  :message/id id
+                  :message/content content
+                  :message/user [:user/id user-id]
                   :message/thread (:db/id thread-data)
-                  :message/created-at (attrs :created-at)}
+                  :message/created-at created-at}
         ; user who created message: show thread, subscribe to thread
-        subscribe-data {:db/id [:user/id (attrs :user-id)]
+        subscribe-data {:db/id [:user/id user-id]
                         :user/open-thread (thread-data :db/id)
                         :user/subscribed-thread (thread-data :db/id)}
         {:keys [db-after tempids]} @(d/transact *conn* (concat [thread-data
@@ -194,11 +199,11 @@

 (defn create-user!
   "creates a user, returns id"
-  [attrs]
-  (-> {:user/id (attrs :id)
-       :user/email (attrs :email)
-       :user/avatar (attrs :avatar)
-       :user/password-token (password/encrypt (attrs :password))}
+  [{:keys [id email avatar password]}]
+  (-> {:user/id id
+       :user/email email
+       :user/avatar avatar
+       :user/password-token (password/encrypt password)}
       create-entity!
       db->user))

@@ -217,7 +222,8 @@
          (when (and user-id (password/check password password-token))
            user-id))))

-(defn fetch-users []
+(defn fetch-users
+  []
   (->> (d/q '[:find (pull ?e [:user/id
                               :user/email
                               :user/avatar])
@@ -225,7 +231,8 @@
             (d/db *conn*))
        (map (comp db->user first))))

-(defn fetch-messages []
+(defn fetch-messages
+  []
   (->> (d/q '[:find (pull ?e [:message/id
                               :message/content
                               :message/created-at
@@ -235,7 +242,8 @@
             (d/db *conn*))
        (map (comp db->message first))))

-(defn get-open-thread-ids-for-user [user-id]
+(defn get-open-thread-ids-for-user
+  [user-id]
   (d/q '[:find [?thread-id ...]
                 :in $ ?user-id
                 :where
@@ -245,7 +253,8 @@
        (d/db *conn*)
        user-id))

-(defn- db->thread [thread]
+(defn- db->thread
+  [thread]
   {:id (thread :thread/id)
    :messages (map (fn [msg]
                     {:id (msg :message/id)
@@ -257,7 +266,8 @@
                    (tag :tag/id))
                  (thread :thread/tag))})

-(defn get-open-threads-for-user [user-id]
+(defn get-open-threads-for-user
+  [user-id]
   (->> (d/q '[:find (pull ?thread [:thread/id
                                    {:thread/tag [:tag/id]}
                                    {:message/_thread [:message/id
@@ -273,7 +283,8 @@
        (map first)
        (map db->thread)))

-(defn get-thread [thread-id]
+(defn get-thread
+  [thread-id]
   (-> (d/q '[:find (pull ?thread [:thread/id
                                   {:thread/tag [:tag/id]}
                                   {:message/_thread [:message/id
@@ -289,7 +300,8 @@
       first
       db->thread))

-(defn get-subscribed-thread-ids-for-user [user-id]
+(defn get-subscribed-thread-ids-for-user
+  [user-id]
   (d/q '[:find [?thread-id ...]
          :in $ ?user-id
          :where
@@ -299,30 +311,36 @@
        (d/db *conn*)
        user-id))

-(defn user-hide-thread! [user-id thread-id]
+(defn user-hide-thread!
+  [user-id thread-id]
   (d/transact
     *conn*
     [[:db/retract [:user/id user-id] :user/open-thread [:thread/id thread-id]]]))

-(defn- db->tag [e]
+(defn- db->tag
+  [e]
   {:id (:tag/id e)
    :name (:tag/name e)})

-(defn create-tag! [attrs]
-  (-> {:tag/id (attrs :id)
-       :tag/name (attrs :name)}
+(defn create-tag!
+  [{:keys [id name]}]
+  (-> {:tag/id id
+       :tag/name name}
     create-entity!
     db->tag))

-(defn user-subscribe-to-tag! [user-id tag-id]
+(defn user-subscribe-to-tag!
+  [user-id tag-id]
   (d/transact *conn* [[:db/add [:user/id user-id]
                        :user/subscribed-tag [:tag/id tag-id]]]))

-(defn user-unsubscribe-from-tag! [user-id tag-id]
+(defn user-unsubscribe-from-tag!
+  [user-id tag-id]
   (d/transact *conn* [[:db/retract [:user/id user-id]
                        :user/subscribed-tag [:tag/id tag-id]]]))

-(defn get-user-subscribed-tag-ids [user-id]
+(defn get-user-subscribed-tag-ids
+  [user-id]
   (d/q '[:find [?tag-id ...]
          :in $ ?user-id
          :where
@@ -332,7 +350,8 @@
        (d/db *conn*)
        user-id))

-(defn- get-users-subscribed-to-tag [tag-id]
+(defn- get-users-subscribed-to-tag
+  [tag-id]
   (d/q '[:find [?user-id ...]
          :in $ ?tag-id
          :where
@@ -342,7 +361,8 @@
        (d/db *conn*)
        tag-id))

-(defn thread-add-tag! [thread-id tag-id]
+(defn thread-add-tag!
+  [thread-id tag-id]
   (let [subscriber-transactions
         (mapcat (fn [user-id]
                [[:db/add [:user/id user-id]
@@ -354,7 +374,8 @@
                              [:db/add [:thread/id thread-id]
                               :thread/tag [:tag/id tag-id]]))))

-(defn get-thread-tags [thread-id]
+(defn get-thread-tags
+  [thread-id]
   (d/q '[:find [?tag-id ...]
          :in $ ?thread-id
          :where
@@ -364,7 +385,8 @@
        (d/db *conn*)
        thread-id))

-(defn fetch-tags []
+(defn fetch-tags
+  []
   (->> (d/q '[:find (pull ?e [:tag/id
                               :tag/name])
               :where [?e :tag/id]]


Formatted code.

Formatted code.

--- app/src/clj_web_example/message_api.clj
+++ app/src/clj_web_example/message_api.clj
@@ -21,8 +21,8 @@
 (defn save-message
   [{message :body-params
     database :database}]
-    (response/response
-      (mc/insert-and-return
-        database
-        "messages"
-        ((coerce/coercer SavableMessage message-matcher) message))))
+  (response/response
+    (mc/insert-and-return
+      database
+      "messages"
+      ((coerce/coercer SavableMessage message-matcher) message))))


Getting sheet data into @app-data

Getting sheet data into @app-data

--- scrape-n-mail/src/scrape_n_mail/core.cljs
+++ scrape-n-mail/src/scrape_n_mail/core.cljs
@@ -13,19 +13,35 @@

 (defonce app-data (atom {:signed-in? false
                          :sheet-data nil}))
+(defonce wellbeing-sheet "1bv6vgW-HMTz0uhKDkrJoTg387b-WK6IFkFd9y6N96hA")

-(defn get-google-token []
-  (.. js/gapi.auth2 getAuthInstance -currentUser get getAuthResponse -id_token))
+(defn get-wellbeing-data []
+  (->
+    (.get js/gapi.client.sheets.spreadsheets.values
+          (clj->js {:spreadsheetId wellbeing-sheet
+                     :range "Form Responses!A1:F"}) )
+    (.then #(swap! app-data assoc :sheet-data (.. % -result -values))) ))

+
+(defn update-after-auth [is-signed-in]
+  (swap! app-data assoc :signed-in? is-signed-in)
+  (if is-signed-in
+    (get-wellbeing-data)
+    (swap! app-data assoc :sheet-data nil) ))
+
+
+; This gets sent as a callback into the .load call for the gapi below in the "go" block
 (defn init-client [gapi_config]
   (-> (.init js/gapi.client gapi_config)
       (.then (let [is-signed-in (.. js/gapi.auth2 getAuthInstance -isSignedIn)]
                ; Set up a listener per Google's tutorial
-               (.listen is-signed-in #(swap! app-data assoc :signed-in? %))
+               (.listen is-signed-in update-after-auth)
                ; Also set the initial value
-               (->> (.get is-signed-in)
-                    (swap! app-data assoc :signed-in?) )))))
+               (update-after-auth  (.get is-signed-in)) ))))

+; In retrospect, this was not really useful (these keys aren't secret).
+; We're also hurting performance a little, but it's not relevant to our
+; use-case so I'm leaving it alone.
 (go (let [keys-resp (<! (http/get "keys.json"))]
       (if (:success keys-resp)
         (let [config-keys


revert to old stream

revert to old stream

--- src/clj/ceres/core.clj
+++ src/clj/ceres/core.clj
@@ -10,7 +10,7 @@
             [ceres.collector :refer [store set-db] :as collector]
             [ceres.curator :refer [get-articles-count get-news-diffusion get-news-frequencies] :as curator]
             [ceres.executor :refer [start-executor]]
-            [gezwitscher.core :refer [gezwitscher]]
+            [gezwitscher.core :refer [start-filter-stream]]
             [clojure.java.io :as io]
             [clojure.core.async :refer [close! put! timeout sub chan <!! >!! <! >! go go-loop] :as async]
             [taoensso.timbre :as timbre]))
@@ -85,7 +85,7 @@
                     (send! channel (str (dispatch (read-string data)))))))))

-(defn processed-tweets
+(defn stream-handler
   "React to incoming tweets"
   [state tweet]
   (let [articles (->> (store tweet)
@@ -97,19 +97,6 @@
       (doall (map #(put! % {:topic :new-article :data articles}) (-> @state :app :out-chans))))
     (swap! state update-in [:app :recent-tweets] (fn [old new] (vec (take 100 (into [new] old)))) tweet)))

-
-(defn tweet-processor [state]
-  (let [{{:keys [credentials track follow]} :app} @state
-        [in out] (gezwitscher credentials)]
-    (go
-      (>! in {:topic :start-stream :follow follow :track track})
-      (let [status-ch (:status-ch (<! out))]
-        (go-loop [status (<! status-ch)]
-          (when status
-            (processed-tweets state status)
-            (recur (<! status-ch))))))
-    (swap! state #(assoc-in %1 [:app :g-chans] %2) [in out])
-    [in out]))

 (defn initialize
@@ -145,7 +132,8 @@
   (info @server-state)
   (when (:http-server? @server-state)
     (run-server (site #'all-routes) {:port (:port @server-state) :join? false}))
-  (tweet-processor server-state)
+  (let [{:keys [follow track handler credentials]} (:app @server-state)]
+    (start-filter-stream follow track handler credentials))
   (when (:backup? @server-state)
     (start-executor (:backup-folder @server-state))))

@@ -154,13 +142,10 @@

   (initialize server-state "opt/server-config-1.edn")

-  (tweet-processor server-state)
-
-  (let [[in out] (-> @server-state :app :g-chans)]
-    (go
-      (>! in {:topic :stop-stream})
-      (println (<! out))))
-
+  (def stop-stream
+    (let [{:keys [follow track handler credentials]} (:app @server-state)]
+      (start-filter-stream follow track handler credentials)))
+  (stop-stream)

   (def stop-server
     (do


Define query function for running SQL queries

--- src/clj/cglossa/db.clj
+++ src/clj/cglossa/db.clj
@@ -1 +1,57 @@
-(ns cglossa.db)
+(ns cglossa.db
+  (:require [clojure.string :as str]
+            [clojurewerkz.ogre.core :as q])
+  (:import (com.tinkerpop.blueprints.impls.orient OrientGraphFactory)
+           (com.orientechnologies.orient.core.sql OCommandSQL)))
+
+(defn get-graph
+  ([] (get-graph true))
+  ([transactional?]
+   (let [factory (OrientGraphFactory. "remote:localhost/Glossa" "admin" "admin")]
+     (if transactional? (.getTx factory) (.getNoTx factory)))))
+
+(defn query
+  "Takes an SQL query and optionally a map of parameters, runs it against the
+  OrientDB database, and returns the query result as a seq. The params argument
+  is a hash map with the following optional keys:
+
+  * targets: A vertex ID, or a sequence of such IDs, to use as the target in the
+  SQL query (e.g. '#12:1' or ['#12:1' '#12:2']), replacing the placeholder #TARGET
+  or #TARGETS (e.g. 'select from #TARGETS').
+
+  * strings: Map with strings that will be interpolated into the SQL query, replacing
+  placeholders with the same name preceded by an ampersand. Restricted to
+  letters, numbers and underscore to avoid SQL injection. Use only in those
+  cases where OrientDB does not support 'real' SQL parameters (such as in the
+  specification of attribute values on edges and vertices, e.g. in()[name = &name],
+  with {:name 'John'} given as the value of the strings key).
+
+  * sql-params: parameters (positioned or named) that will replace question marks
+  in the SQL query through OrientDB's normal parameterization process.
+
+  A full example:
+  (query \"select out('&out') from #TARGETS where code = ?\"
+         {:targets    [\"#12:0\" \"#12:1\"]
+          :sql-params [\"bokmal\"]
+          :strings    {:out \"HasMetadataCategory\"}})"
+  ([sql]
+   (query sql {}))
+  ([sql params]
+   (let [graph      (get-graph)
+         targets    (if (:targets params)
+                      (-> (:targets params) vector flatten vec)
+                      [])
+         _          (doseq [target targets] (assert (re-matches #"#\d+:\d+" target)
+                                                    (str "Invalid target: " target)))
+         strings    (:strings params)
+         _          (assert (or (nil? strings) (map? strings))
+                            "String params should be provided in a map")
+         _          (doseq [s (vals strings)] (assert (not (re-find #"[\W]" s))
+                                                      (str "Invalid string param: " s)))
+         sql-params (into-array (:sql-params params))
+         sql*       (-> sql
+                        (str/replace #"\&(\w+)" #(get strings (keyword (second %))))
+                        (str/replace #"#TARGETS?" (str "[" (str/join ", " targets) "]")))
+         cmd        (OCommandSQL. sql*)
+         ]
+     (seq (.. graph (command cmd) (execute sql-params))))))


Rearrange game-id generation

Rearrange game-id generation

--- src/clj/ji/service.clj
+++ src/clj/ji/service.clj
@@ -27,9 +27,17 @@
 (defn accepting-clients? [game-envs]
   (< (num-clients game-envs) max-clients))

+(defn generate-game-id [game-envs]
+  (let [cs (vec "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
+        s (apply str (for [i (range 5)] (rand-nth cs)))]
+    (if (contains? @game-envs s)
+      (recur game-envs)
+      s)))
+
 (defn init-game-env!
   [game-envs game-id]
-  (let [game (new-game)
+  (let [game-id (or game-id (generate-game-id game-envs))
+        game (new-game)
         join-chan (chan)
         game-env (atom (game-env/create-game-env game-id game join-chan))
         game-chan (game/go-game game-env)]
@@ -38,13 +46,6 @@
           (println "Game finished" finshed-game)
           (swap! game-envs dissoc (:id finshed-game))))
     game-env))
-
-(let [cs (vec "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")]
-  (defn rand-game-id [game-envs]
-    (let [s (apply str (for [i (range 5)] (rand-nth cs)))]
-      (if (contains? @game-envs s)
-        (recur game-envs)
-        s))))

 (defn valid-game-id? [game-id]
   (boolean (re-find #"^[\w-]+$" game-id)))
@@ -95,7 +96,7 @@
                   (-> (resp/response "Game already exists") (resp/status 409))

                   :else
-                  (let [game-env (init-game-env! game-envs (or game-id (rand-game-id game-envs)))]
+                  (let [game-env (init-game-env! game-envs game-id)]
                     (resp/redirect-after-post (str "/games/" (:id @game-env)))))))
         (GET "/games" []
              (tmpl/lobby @game-envs))


store-action uses fact-index

store-action uses fact-index

--- src/clj/libx/util.cljc
+++ src/clj/libx/util.cljc
@@ -79,9 +79,6 @@
     []
     m))

-(defn action-insert! [m]
-  (cr/insert-all-unconditional! (gen-Tuples-from-map m)))
-
 (defn tuplize-into-vec
   "Returns [[]...].
   Arg may be {} [{}...] [] [[]...]"
@@ -187,6 +184,9 @@
       (cr/insert-all-unconditional! to-insert)
       (do (cr/insert-all-unconditional! to-insert)
           (doseq [x to-retract] (cr/retract!) x)))))
+
+(defn action-insert! [m]
+  (insert-unconditional! (gen-Tuples-from-map m)))

 (defn retract!
   "Wrapper around Clara's `retract!`.


Make the linters happy.

Make the linters happy.

--- src/oc/storage/resources/common.clj
+++ src/oc/storage/resources/common.clj
@@ -24,9 +24,9 @@
        (not (re-matches #".*\d(\s*)\d(\s*)\d(\s*)\d(\s*)\d.*" name)) ; don't allow any more than 4 numerals in a row
        (= (count name) (.codePointCount name 0 (count name))))) ; same # of characters as Unicode points

-(defn- allowed-board-name? [name]
-  (and (string? name)
-       (not (re-matches #".*\d\d\d\d.*" name)))) ; don't allow any more than 3 numerals in a row
+; (defn- allowed-board-name? [name]
+;   (and (string? name)
+;        (not (re-matches #".*\d\d\d\d.*" name)))) ; don't allow any more than 3 numerals in a row

 (def Slug "Valid slug used to uniquely identify a resource in a visible URL." (schema/pred slug/valid-slug?))


Renamings

Renamings

--- src/clj/algorithms_clj/huffman.clj
+++ src/clj/algorithms_clj/huffman.clj
@@ -58,22 +58,22 @@
       ))
   (get-bits-impl huffman-tree []))

-(defn tree->decoder
+(defn tree->encoder
   "Build a decoder with memoization"
   [huffman-tree]
   (memoize #(get-bits huffman-tree %)))

 (defn encode-with
   "Encode a stream of values with the decoder provided as first parameter"
-  [decoder values]
-  (transduce (mapcat decoder) conj [] values))
+  [encoder values]
+  (transduce (mapcat encoder) conj [] values))

 (defn encode
   "Encode a stream, using the stream frequences to build the huffman tree"
   [values]
   (-> (frequencies values)
       (make-tree)
-      (tree->decoder)
+      (tree->encoder)
       (encode-with values)))

@@ -109,7 +109,8 @@
 (def t (make-tree m))

 (defn tests []
-  (prn (encode-with (tree->decoder t) [:a :b]))
+  ;; TODO - Symetric testings with test.checks
+  (prn (encode-with (tree->encoder t) [:a :b]))
   (prn (encode [:a :b]))
   (prn (decode-bits t [0 1 0 0 1 1]))
   )


switch from :compojure to :bidi

switch from :compojure to :bidi

--- src/clj/om_next_leaflet/routes.clj
+++ src/clj/om_next_leaflet/routes.clj
@@ -1,33 +1,41 @@
 (ns om-next-leaflet.routes
   (:require [clojure.java.io :as io]
-            [compojure.core :refer [ANY GET PUT POST DELETE routes]]
-            [compojure.route :refer [resources not-found]]
-            [ring.util.response :refer [response]]
+            [bidi.bidi :as bidi]
+            [bidi.ring :refer [resources]]
+            [ring.util.response :refer [response resource-response]]
+            [taoensso.timbre :as timbre :refer [log trace debug info warn error fatal]]
             [cheshire.core :refer [generate-string]]
             [om-next-leaflet.geojson :as geojson]
             [om.next.server :as om]))
+
+(defn index-handler
+  [req]
+  (assoc (resource-response "index.html" {:root "public"})
+         :headers {"Content-Type" "text/html; charset=UTF-8"}))

 (defn generate-response-json [data & [status]]
   {:status  (or status 200)
    :headers {"Content-Type" "application/json; charset=UTF-8"}
    :body    (generate-string data)})

-(def state (atom {:app/title "initial server title"}))
+(defn lines-handler
+  [req]
+  (generate-response-json
+   (->> (geojson/get-lines)
+        (map (fn [{:keys [id line-name bounding-box geometry]}] [id line-name bounding-box geometry])))))

-(defn home-routes [endpoint]
-  (routes
-   (GET "/" _
-     (-> "public/index.html"
-         io/resource
-         io/input-stream
-         response
-         (assoc :headers {"Content-Type" "text/html; charset=utf-8"})))
-   (GET "/api2/lines" _
-     (generate-response-json
-      (->> (geojson/get-lines)
-           (map (fn [{:keys [id line-name bounding-box geometry]}] [id line-name bounding-box geometry])))))
-   (GET "/api2/lines/:line-id/stations" [line-id]
-     (generate-response-json
-      (geojson/get-stations (fn [m] (= (:line-id m) (Integer/parseInt line-id))))))
-   (resources "/")
-   (not-found "Not Found")))
+(defn stations-handler
+  [req]
+  (generate-response-json
+   (geojson/get-stations (fn [m] (= (:line-id m) (Integer/parseInt (get-in req [:params :line-id])))))))
+
+(def route ["/" {"" {:get index-handler}
+                 "index.html" {:get index-handler}
+                 "api2/lines" {"" {:get lines-handler}
+                               ["/" [#"\d+" :line-id]] {"/stations" {:get stations-handler}}}
+                 "css" {:get (resources {:prefix "public/css/"})}
+                 "js" {:get (resources {:prefix "public/js/"})}}])
+
+(defn home-routes
+  [endpoint]
+  route)


restructured morph ns

restructured morph ns

--- src/cljs/cljs_workspace/morph.cljs
+++ src/cljs/cljs_workspace/morph.cljs
@@ -7,13 +7,21 @@
             [om.dom :as dom :include-macros true]
             [goog.style :as gstyle]
             [goog.dom :as gdom]
-            [cljs-workspace.draggable :as draggable :refer [clicked-morph]]
-            [cljs-workspace.branch-merge :as branch-merge]
-            ; [clojure.browser.repl :as repl]
-            )
+            [cljs-workspace.draggable :as draggable :refer [clicked-morph]])
   (:import [goog.events EventType]))

 (enable-console-print!)
+
+(defn make-cursor
+  ([*atom]
+     (om/to-cursor @*atom *atom []))
+  ([*atom kws]
+     (om/to-cursor @*atom *atom kws)))
+
+(def html5TransformProperty "-webkit-transform")
+(def html5TransformOriginProperty "-webkit-transform-origin")
+
+; Event handling

 (def right-click-behavior (atom (fn [e state] (prn "No Right Click Behavior!"))))

@@ -27,6 +35,15 @@
       (prn (.-timeStamp event) " ... was not yet handled!")
       true)))

+(defn handle-click [e state]
+  ; add/remove morph from preserve list
+  ; (branch-merge/toggle-preserve state)
+  ; handle the custom behavior
+  (when (and (not-yet-handled e) (.-altKey e))
+    (@right-click-behavior e @state))
+  (when-let [cb (get-in @state [:morph :onClick])]
+              (cb state)))
+
 ; morph property to CSS property translators

 (defn get-fill-css [value]
@@ -42,34 +59,68 @@
    "width" (:x value)})

 (defn get-border-width-css [value]
-  {"border-width" value
-   "border-style" "solid"})
+  {"borderWidth" value
+   "borderStyle" "solid"})
+
+(defn get-opacity-css [value]
+  {"opacity" value})

 (defn get-border-color-css [value]
-  {"border-color" value
-   "border-style" "solid"})
+  {"borderColor" value
+   "borderStyle" "solid"})
+
+(defn get-border-radius-css [value])
+
+(defn get-border-style-css [value])
+
+(defn get-transform-css [{rotation :Rotation, scale :Scale, pivot :PivotPoint,
+                          :or {rotation 0, scale 1, pivot {:x 0, :y 0}}}]
+  {html5TransformProperty (str "rotation(" rotation ") scale(" scale ")")
+   html5TransformOriginProperty (str (:x pivot) "px " (:y pivot) "px")})

 ; translation from morph data to CSS style prop

 (defn dict->js [dict]
   (apply js-obj (apply concat (seq dict))))

-(defn extract-style [state]
+(defn extract-morph-css [->self]
   (apply merge
-        (map (fn [[prop value]]
-            (case prop
-              :Fill (get-fill-css value)
+     (let [morph-props (get ->self :morph)]
+       (map (fn [[prop value]]
+          (let [value value]
+             (case prop
               :Position (get-position-css value)
+              (:Scale :Rotation :PivotPoint) (get-transform-css morph-props)
+              ;; more to come...
+              nil))) morph-props))))
+
+(defn extract-shape-css [->self]
+  (apply merge
+       (map (fn [[prop value]]
+          (let [value value]
+             (case prop
               :Extent (get-extent-css value)
               :BorderWidth (get-border-width-css value)
               :BorderColor (get-border-color-css value)
+              :Fill (get-fill-css value)
+              :Opacity (get-opacity-css value)
+              :BorderRadius (get-border-radius-css value)
+              :BorderStyle (get-border-style-css value)
+;   _BorderStyle: {/*...*/},
+;   _ClipMode: {/*...*/},
+;   _PreviousBorderWidth: {/*...*/},
+;   _StyleClassNames: {/*...*/},
+;   _StyleSheet: {/*...*/},
+; }
               ;; more to come...
-              nil
-              )) state)))
+                nil))) (get ->self :shape))))

 ; morph component + rendering functions

+; multimethod for shape
 (defmulti shape (fn [app owner] (get-in app [:shape :ShapeClass])))
+
+; multimethod for morph
 (defmulti morph (fn [app owner] (get-in app [:morph :MorphClass])))

 ; utilities
@@ -77,7 +128,7 @@
 (defn render-submorphs [app]
   (dom/div #js {:className "originNode"}
     (apply dom/div nil
-      (om/build-all morph (:submorphs app)))))
+      (om/build-all morph (get app :submorphs) {:state {:owner-morph app}}))))

 ; property accessors

@@ -95,104 +146,76 @@
             (concat path [:submorphs %])) (range (count submorphs)))
           nil)))))

-(defn get-prop-path [model id attrPath]
-    (into [] (concat (find-morph-path @model id) attrPath)))
-
-(defn set-position [model id pos]
-  (let [prop-path (get-prop-path model id [:morph :Position])]
-    (swap! model assoc-in prop-path pos)))
-
-(defn add-morph [model id morph]
-  (let [prop-path (get-prop-path model id [:submorphs])
-        submorphs (get-in @model prop-path)]
-    (swap! model assoc-in prop-path (conj submorphs morph))))
-
-(defn remove-morph [model id morph-id]
-  (let [prop-path (get-prop-path model id [:submorphs])
-        submorphs (get-in @model prop-path)]
-    (swap! model assoc-in prop-path (into [] (filter #(not= (% :id) morph-id) submorphs)))))
-
-(defn set-fill [model id color]
-  (let [prop-path (get-prop-path model id [:shape :Fill])]
-    (swap! model assoc-in prop-path color)))
-
-(defn set-extent [model id extent]
-  (let [prop-path (get-prop-path model id [:shape :Extent])]
-    (swap! model assoc-in prop-path extent)))
-
-(defn set-border-color [model id fill]
-  (let [prop-path (get-prop-path model id [:shape :BorderColor])]
-    (swap! model assoc-in prop-path fill)))
-
-(defn toggle-halo [model id]
-  (let [prop-path (get-prop-path model id [:morph :Halo])]
-    (prn prop-path " before:" (get-in @model prop-path))
-    (swap! model (fn [m]
-                    (if (get-in m prop-path)
-                      (assoc-in m prop-path false)
-                      (assoc-in m prop-path true))))
-    (prn prop-path "Halo value after:" (get-in @model prop-path))))
-
-; multimethod for morph
-
-(defmethod morph "Text" [app owner]
-  (reify
-    om/IRender
-    (render [this]
-      (let [style (dict->js (extract-style (:morph app)))]
-        (dom/div  #js {:style style
-                       :className "morphNode" } (shape app owner))))))
-
-(defn handle-click [e state]
-  ; add/remove morph from preserve list
-  ; (branch-merge/toggle-preserve state)
-  ; handle the custom behavior
-  (when (and (not-yet-handled e) (.-altKey e))
-    (@right-click-behavior e state))
-  (when-let [cb (get-in state [:morph :onClick])]
-              (cb state)))
+(defn find-morph [*model id]
+  (make-cursor *model (find-morph-path @*model id)))
+
+(defn add-morph [->owner morph]
+  (let [submorphs (or (get @->owner :submorphs) [])
+        morph-owner (assoc morph :owner ->owner)]
+    (om/update! ->owner :submorphs (conj submorphs morph-owner))))
+
+(defn remove-morph [->owner morph-id]
+  (let [submorphs (get @->owner :submorphs)]
+    (om/update! ->owner :submorphs (into [] (filter #(not= (% :id) morph-id) submorphs)))))
+
+(defn set-position [->morph pos]
+  (om/update! ->morph [:morph :Position] pos))
+
+(defn set-fill [->morph color]
+  (om/update! ->morph [:shape :Fill] color))
+
+(defn set-extent [->morph extent]
+  (om/update! ->morph [:shape :Extent] extent))
+
+(defn set-border-color [->morph fill]
+  (om/update! ->morph [:shape :BorderColor] fill))
+
+(defn toggle-halo [->morph]
+  (om/transact! ->morph [:morph :Halo]
+     (fn [halo]
+        (if halo
+            false
+            true))))

 ; render based on ad hoc definition of morph like frame
 ; to visualize the halo
-(defn render-halo [app owner]
-  (let [css {:Extent (get-in app [:shape :Extent])
-             :BorderWidth 1
-             :Position {:x 0 :y 0}
-             :BorderColor "red"}]
-    (dom/div #js {:style (dict->js (extract-style css))})))
+(defn render-halo [app owner])

 (defmethod morph :default [app owner]
   (reify
     om/IRender
     (render [this]
-        (let [style (dict->js (extract-style (:morph app)))]
+        (let [style (dict->js (extract-morph-css app))]
           (dom/div  #js {:style style
                        :className "morphNode"
-                       :onClick #(handle-click % @app)
+                       :onClick #(handle-click % app)
                        :onMouseDown #(draggable/start-dragging % app owner)
-                       :onMouseUp #(draggable/stop-dragging % app)
-                      }
+                       :onMouseUp #(draggable/stop-dragging % app owner)}
                    (when (get-in app [:morph :Halo])
                       (render-halo app owner))
                    (shape app owner))))))

 ;; multi method for shape
-(defn handle-input [e owner app]
-  (let [span (om/get-node owner "myInput")]
-    (prn (.-innerText span))
-    (om/update! app [:morph :TextString] (.-innerText span) :update)))
-
-(defn save-input [e owner app]
-  (prn (.-key e))
-  false)
-
-(defn create-text-node [app owner]
-    (dom/div #js {:className "visible Selection"
-                  :contentEditable (nil? (get-in app [:morph :AllowInput]))
-                  :onMouseDown #(swap! clicked-morph (fn [_] @app :id))
-                  :onInput #(handle-input % owner app)
-                  ; :onKeyDown #(when (.-metaKey %) (save-input % owner app))} (dom/span #js {
-                    :ref "myInput"} (get-in app [:morph :TextString])))
+
+(defmethod shape "Image" [app owner]
+  (let [style (dict->js (extract-shape-css app))]
+    (dom/img #js {:style style
+                  :draggable false
+                  :src (get-in app [:shape :url])})))
+
+
+(defmethod shape "Ellipse" [app owner]
+  (let [style (extract-shape-css app)]
+    ;; we apply some customizations to the style, to make the shape elliptical
+    (let [ellipse-style (assoc style
+                          "border-radius" (str (style "width") " /" (style "height")))]
+      (dom/div #js {:style (dict->js ellipse-style)} (render-submorphs app)))))
+
+(defmethod shape :default [app owner]
+  (let [style (extract-shape-css app)]
+    (dom/div #js {:style (dict->js style)} (render-submorphs app))))
+
+; PATH MORPH

 (defn handle-path-element [e]
   (case (e :type)
@@ -233,34 +256,89 @@
                    :stroke (get-in app [:shape :Fill])
                    :d (to-svg-attr (get-in app [:shape :PathElements]))}))))

-(defmethod shape "Image" [app owner]
-  (let [style (dict->js (extract-style (:shape app)))]
-    (dom/img #js {:style style
-                  :draggable false
-                  :src (get-in app [:shape :url])})))
-
 (defmethod shape "Path" [app owner]
-  (let [style (extract-style (:shape app))]
+  (let [style (extract-shape-css app)]
       (dom/div #js {:style (dict->js style) :className "Morph Path"}
         ; we render a svg sub-tag into which we place a
         ; <path> that covers the given PathElements
         (render-path-node app owner)
         (render-submorphs app))))
-
-(defmethod shape "Ellipse" [app owner]
-  (let [style (extract-style (:shape app))]
-    ;; we apply some customizations to the style, to make the shape elliptical
-    (let [ellipse-style (assoc style
-                          "border-radius" (str (style "width") " /" (style "height")))]
-      (dom/div #js {:style (dict->js ellipse-style)} (render-submorphs app)))))
+
+; TEXT MORPH
+
+;;; spec-property -> css translation
+
+(defn get-font-family-css [family-name]
+  {"fontFamily" family-name})
+
+(defn get-font-size-css [size]
+  {"fontSize" (str size "pt")})
+
+(defn get-max-text-height-css [height]
+  {"maxHeight" (str height "px")})
+
+(defn get-max-text-width-css [width])
+
+(defn get-min-text-height-css [height])
+
+(defn get-min-text-width-css [height])
+
+(defn get-text-color-css [color]
+  {"textColor" color})
+
+(defn extract-text-css [->self]
+     (apply merge
+       (map (fn [[prop value]]
+          (let [value value]
+             (case prop
+               :FontFamily (get-font-family-css value)
+               :FontSize (get-font-size-css value)
+               :MaxTextHeight (get-max-text-height-css value)
+               :MaxTextWidth (get-max-text-width-css value)
+               :MinTextHeight (get-min-text-height-css value)
+               :MinTextWidth (get-min-text-width-css value)
+               :TextColor (get-text-color-css value)
+               ; :Padding ... this is actually default?
+               :WordBreak ()
+                ;   _WhiteSpaceHandling: {/*...*/},
+               ;; more to come...
+                nil))) (get @->self :morph))))
+
+;;; event handling
+
+(defn handle-input [e owner app]
+  (let [span (om/get-node owner "myInput")]
+    (prn (.-innerText span))
+    (om/update! app [:morph :TextString] (.-innerText span) :update)))
+
+(defn save-input [e owner app]
+  (prn (.-key e))
+  false)
+
+;;; rendering
+
+(defn create-text-node [->text-morph owner]
+    (dom/span #js {:className "visible Selection"
+                  :contentEditable (nil? (get-in ->text-morph [:morph :AllowInput]))
+                  :onMouseDown #(swap! clicked-morph (fn [_] @->text-morph :id))
+                  :onInput #(handle-input % owner ->text-morph)
+                  :style (dict->js (extract-text-css ->text-morph))
+                  ; :onKeyDown #(when (.-metaKey %) (save-input % owner app))} (dom/span #js {
+                    :ref "myInput"} (get-in ->text-morph [:morph :TextString])))

 (defmethod shape "Text" [app owner]
   (prn "Rendering Text Shape")
-  (let [style (extract-style (:shape app))]
+  (let [style (extract-shape-css app)]
     (let [text-style (assoc style "cursor" "default")]
       (dom/div #js {:style (dict->js text-style)
                     :className "Morph Text"} (create-text-node app owner)))))

-(defmethod shape :default [app owner]
-  (let [style (extract-style (:shape app))]
-    (dom/div #js {:style (dict->js style)} (render-submorphs app))))+(defmethod morph "Text" [app owner]
+  (reify
+    om/IRender
+    (render [this]
+            (let [style (dict->js (extract-morph-css app))]
+        (dom/div  #js {:style style
+                       :className "morphNode" } (shape app owner))))))
+
+


update site

update site

--- src/cljs/good/production/core.cljs
+++ src/cljs/good/production/core.cljs
@@ -75,7 +75,6 @@

 (defn contacts []
   [:div
-   [:h1.text-center.portfolio (t/label :contacts)]
    [:div.row.featurette.vertical-align
     [:div.col-md-7.col-md-push-5
      [:div.row
@@ -108,21 +107,20 @@
   (.getElementById js/document "app"))

 (defn hide-spinner []
-  (when-let [rd (root-div)]
-    (set! (.-className rd) "")))
-
-(hide-spinner)
+  (set! (.-className (root-div)) "app")) ; TODO function name not fully corresponds its functionality

 (defn mount-it []
   (prn "mount-it")
   (reagent/render-component
-    (fn [] [app])
-    (.-body js/document)
+    (fn []
+      (hide-spinner)
+      [app])
+    (root-div)
     (fn [])))

 (defn unmount-it []
   (prn "unmount-it")
   (reagent/unmount-component-at-node
-    (.-body js/document)))
+    (root-div)))

-(mount-it)+(mount-it)


on-close! listener extends ChannelCloseAdapter instead of ChannelListener now

--- src/clojure/nginx/clojure/core.clj
+++ src/clojure/nginx/clojure/core.clj
@@ -3,7 +3,7 @@
             NginxRequest NginxHttpServerChannel ChannelListener
             AppEventListenerManager AppEventListenerManager$Listener
             AppEventListenerManager$Decoder AppEventListenerManager$PostedEvent
-            MessageAdapter WholeMessageAdapter])
+            MessageAdapter WholeMessageAdapter ChannelCloseAdapter])
   (:import [nginx.clojure.net NginxClojureAsynChannel NginxClojureAsynChannel$CompletionListener
             NginxClojureAsynSocket])
   (:import [nginx.clojure.clj Constants])
@@ -177,7 +177,7 @@
   (send-response! [ch resp]
     (.sendResponse ch resp))
   (on-close! [ch attachment listener]
-    (.addListener ch attachment (proxy [ChannelListener] []
+    (.addListener ch attachment (proxy [ChannelCloseAdapter] []
                        (onClose [att]
                          (listener att)))))


Fixed sample error

Fixed sample error

--- samples/controls.clj
+++ samples/controls.clj
@@ -15,7 +15,7 @@
 	  (ssh "date"))

 (task :deploy "scp files to remote machines"
-	  (scp "release.tar.gz" "/home/alogin/"))
+	  (scp ("release.tar.gz") "/home/alogin/"))

 (begin)


tweaking!

tweaking!

--- src/doctopus/files.clj
+++ src/doctopus/files.clj
@@ -17,16 +17,16 @@
 (defn filter-the-docs
   "Vector Triple of (path, directories, files), and function that filters relevant doc-types"
   [[path directories files] doc-type-fn]
+  (println directories)
   (if-let [matched-files (filter doc-type-fn files)]
     [path matched-files]
-    nil
-    ))
+    nil))

 (declare truncate-str)
 (defn assemble-the-results
   "More stuff"
-  [doc-root path matched-files]
+  [doc-root [path matched-files]]
   (let [str-path (.getPath path)
         str-rel-path (truncate-str doc-root str-path)
         ]
@@ -45,8 +45,8 @@
   "Walk the docs"
   [doc-root]
   (let [docs-all (fs/walk vector doc-root) ;; Triple of directory path, directory name, file name
-        filtered-docs (filter-the-docs docs-all)
-        assembled-result (assemble-the-results filtered-docs)
+        filtered-docs (filter-the-docs docs-all markdown-type)
+        assembled-result (assemble-the-results doc-root filtered-docs)
         ]
     assembled-result
     ))


fix(backend): raise proper exception on input is binary data on svgparse

--- backend/src/uxbox/services/svgparse.clj
+++ backend/src/uxbox/services/svgparse.clj
@@ -67,8 +67,13 @@
       (ex/raise :type :validation
                 :code ::invalid-input
                 :message "Input does not seems to be a valid svg."))
+
+    (catch org.jsoup.UncheckedIOException e
+      (ex/raise :type :validation
+                :code ::invalid-input
+                :message "Input does not seems to be a valid svg."))
+
     (catch Exception e
-      (.printStackTrace e)
       (ex/raise :code ::unexpected))))

 ;; --- Public Api


Couldn't get this test to fail, though example was failing running elsewhere; for now will leave in

--- test/pca_test.clj
+++ test/pca_test.clj
@@ -21,19 +21,19 @@

       (testing "from scratch"
                (is (= true (almost-equal? (pc-from-start nil) expected))))
-
       (testing "from scratch"
                (is (almost-equal? (pc-from-start [1 1 1]) expected)))
+      (testing "from scratch"
+               (is (almost-equal? (pc-from-start [1 1]) expected)))))

-      (testing "from scratch"
-               (is (almost-equal? (pc-from-start [1 1]) expected))))))
+         )

 (deftest wrapped-pca-test
-  (letfn [(right-shape [data]
-            (let [res (wrapped-pca (m/matrix data) 2)]
-              (and (:center res) (:comps res))))]
-    (testing "Should not fail and have the right shape for for"
+  (testing "Should not fail and have the right shape for for"
+    (letfn [(right-shape [data]
+              (let [res (wrapped-pca (m/matrix data) 2)]
+                (and (:center res) (:comps res))))]
       (testing "1x1"
         (is (right-shape [[1]])))
       (testing "1x2"
@@ -41,6 +41,15 @@
       (testing "2x1"
         (is (right-shape [[1] [0]])))
       (testing "2x2"
-        (is (right-shape [[1 0] [-1 1]]))))))
+        (is (right-shape [[1 0] [-1 1]])))))
+
+  (testing "when initital start value is a zero eigenvector"
+    (let [data (m/matrix [[1 -1  1 -1]
+                          [0 0 -1  1]
+                          [1 1 -1  0]])]
+      (testing "should try another eigenvector"
+        (is (not (almost-equal?
+                   (wrapped-pca data 2)
+                   [0 0 0 0]))))))


quikfix

quikfix

--- src/latte_compiler/compilation.clj
+++ src/latte_compiler/compilation.clj
@@ -327,7 +327,8 @@
     (println (str "\t" "subl" "\t" (const (* 4 (+ 1 nargs))) ", " esp))

     (print-stmt name block 0)
-
+    (if (= type [:void])
+      (print-return))
     ))


Point to the actual Shopify logo.

Point to the actual Shopify logo.


add tese cases helper function

add tese cases helper function

--- src/lrun/core.clj
+++ src/lrun/core.clj
@@ -1,6 +1,22 @@
-(ns lrun.core)
+(ns lrun.core
+  (:require [clojure.string :as string]))

-(defn foo
-  "I don't do a whole lot."
-  [x]
-  (println x "Hello, World!"))
+(defn- join-test-cases [list option]
+;  "-> join-cmd [1 2 3] "--op"
+;   => "--op 1 --op 2 --op 3"
+;  "
+  (string/join " " (reduce #(conj %1 %2 option) '() list)))
+
+(defn- construct-test-cases [inputs outpus]
+  (let [inputstr "--input"
+        outputstr "--output"]
+    (str (join-test-cases inputs inputstr) " " (join-test-cases outpus outputstr))))
+
+(defn judge
+  "max-cpu: max time of cpu use (such as 1.0)
+   max-mem: max memory that program can use  (such as 32m)
+   user-code: (such as 1000.c)
+   test-case-input: A list of test cases input file name (such as [1.in]])
+   test-case-output: Same as test-case-input."
+  [ & {:keys [max-cpu max-mem user-code test-case-input test-case-output]}]
+  ())


fix reflection warnings

fix reflection warnings

--- src/main/clojure/org/dada/core.clj
+++ src/main/clojure/org/dada/core.clj
@@ -29,6 +29,7 @@
 	      )
 	     (org.dada.demo Client)
 	     (org.springframework.context.support ClassPathXmlApplicationContext)
+	     (org.springframework.beans.factory BeanFactory)
 	     (org.dada.asm ClassFactory)
 	     (org.slf4j Logger LoggerFactory)
 	     ))
@@ -44,8 +45,8 @@
 (defn start-server [#^String name]
   (System/setProperty "server.name" name)
   (def #^ClassPathXmlApplicationContext *spring-context* (ClassPathXmlApplicationContext. "application-context.xml"))
-  (def #^ServiceFactory *internal-view-service-factory* (.getBean *spring-context* "internalViewServiceFactory"))
-  (.getBean *spring-context* "metaModel"))
+  (def #^ServiceFactory *internal-view-service-factory* (.getBean #^BeanFactory *spring-context* "internalViewServiceFactory"))
+  (.getBean #^BeanFactory *spring-context* "metaModel"))

 (defn start-client [#^String name]
   (Client/main (into-array String (list name))))


Pass in full response data to handling function.

--- src/frmr/dstt.clj
+++ src/frmr/dstt.clj
@@ -54,7 +54,7 @@
           response (request-invoker)
           stop (System/nanoTime)
           elapsed-time-in-ms (int (/ (- stop start) 1000000))]
-      (handler elapsed-time-in-ms (:body response)))))
+      (handler elapsed-time-in-ms response))))

 (defn- load-test-url
   "Execute number-of-requests requests using the request-invoker with a pause-between-requests pause between


pass along any additional program kv's

pass along any additional program kv's

--- src/gamma/program.cljs
+++ src/gamma/program.cljs
@@ -71,10 +71,12 @@
    (let [{:keys [vertex-shader fragment-shader precision]} x
          vs (shader vertex-shader precision)
          fs (shader fragment-shader precision)]
-     {:tag             :program
-      :vertex-shader   vs
-      :fragment-shader fs
-      :inputs          (program-inputs vs fs)})))
+     (merge
+       x
+       {:tag             :program
+       :vertex-shader   vs
+       :fragment-shader fs
+       :inputs          (program-inputs vs fs)}))))


Add function to prefix parsed property and join source names

--- src/main/workflo/macros/query.cljc
+++ src/main/workflo/macros/query.cljc
@@ -37,6 +37,28 @@
         :workflo.macros.specs.conforming-query/recursive-join
         :properties-join
         :workflo.macros.specs.conforming-query/properties-join))
+
+(s/fdef prefix-child-name
+  :args (s/cat :base symbol?
+               :child :workflo.macros.specs.parsed-query/typed-property)
+  :ret  :workflo.macros.specs.parsed-query/typed-property
+  :fn   (s/and #(= (-> % :ret :name)
+                   (symbol (name (-> % :args :base))
+                           (name (-> % :args :child :name))))
+               #(if (-> % :args :child :join-source :name)
+                  (= (-> % :ret :join-source :name)
+                     (symbol (name (-> % :args :base))
+                             (name (-> % :args :child
+                                       :join-source :name))))
+                  true)))
+
+(defn prefix-child-name
+  [base child]
+  (letfn [(prefix-sym [sym]
+            (symbol (name base) (name sym)))]
+    (cond-> child
+      (child :join-source) (update-in [:join-source :name] prefix-sym)
+      (child :name)        (update :name prefix-sym))))

 (s/fdef parse-subquery
   :args (s/cat :query ::subquery)


Can specify an initially selected node on startup

--- src/graphito/core.cljs
+++ src/graphito/core.cljs
@@ -384,7 +384,7 @@
 (defn load-graph [json-file callback]
   (.json d3 json-file
          (fn [js-graph]
-           (callback (parse-js-graph js-graph)))))
+           (callback js-graph))))

 ;; Reactive

@@ -647,27 +647,34 @@
                         opts]
   (let [{graph-file "graphFile"
          gilbert-graph "gilbertGraph"
-         graph-object "graphObject"} (js->clj opts)
+         graph-object "graphObject"
+         initial-selection "initialSelection"} (js->clj opts)
         svg (setup-svg! container-selector)
         detail-button (.select d3 detail-button-selector)
         gesture-manager (hammer-manager svg)
         animation-subject (animation-subject)
         current-state (atom (initial-state svg
                                            detail-button
-                                           animation-subject))]
+                                           animation-subject))
+        set-state-for-graph-fn
+        (fn [js-graph]
+          (set-graph! current-state (parse-js-graph js-graph))
+          (when initial-selection
+            (select-and-zoom-to-node! current-state
+                                      ((:nodes @current-state) initial-selection))))]
     (prevent-focus-on-detail-button! detail-button)
     (sync-on-window-size! current-state)
     (cond
       gilbert-graph
       (let [[num-nodes p] gilbert-graph
             js-graph (clj->js (gen/gilbert-graph num-nodes p))]
-        (set-graph! current-state (parse-js-graph js-graph)))
+        (set-state-for-graph-fn js-graph))

       graph-file
-      (load-graph graph-file (partial set-graph! current-state))
+      (load-graph graph-file set-state-for-graph-fn)

       graph-object
-      (set-graph! current-state (parse-js-graph (clj->js graph-object))))
+      (set-state-for-graph-fn (clj->js graph-object)))
     (respond-to-resize! current-state)
     (move-camera-on-arrow-keys! current-state animation-subject)
     (move-camera-on-pan! gesture-manager current-state animation-subject)


Increase node hitbox size

Increase node hitbox size

A node now responds to a tap if its center is within 48 units of the
tap.

--- src/graphito/core.cljs
+++ src/graphito/core.cljs
@@ -38,6 +38,7 @@
 (def max-radius 32)
 (def label-font "Verdana")
 (def label-font-size 24)
+(def hitbox-size 96)

 (def label-y 42)
 (def label-y-transform (str "translate(0," label-y ")"))
@@ -159,9 +160,7 @@
                 links
                 camera-pos
                 view-size
-                animation-subject
-                node-tap-subject
-                link-tap-subject]} state
+                animation-subject]} state
         {:keys [project-displacement
                 project-scale
                 project-opacity
@@ -184,10 +183,7 @@
           (.append "line")
           (.attr "class" "link")
           (.style "stroke" "#C9CBCB")
-          (.style "stroke-width" 3)
-          (.each
-            (fn [link]
-              (this-as elem (add-tap-listener elem #(.onNext link-tap-subject link))))))
+          (.style "stroke-width" 3))
       (-> link-selection
           maybe-transition
           (.attr "x1" #(-> % :source positions v/x))
@@ -202,10 +198,7 @@
       (-> new-node-selection (.append "circle")
           (.attr "class" "node-dot")
           (.style "fill" "#777A7A")
-          (.attr "r" max-radius)
-          (.each
-            (fn [node]
-              (this-as elem (add-tap-listener elem #(.onNext node-tap-subject node))))))
+          (.attr "r" max-radius))
       ; Having too many labels at once hurts performance. Add/remove labels as
       ; they move in and out of view.
       (-> node-selection
@@ -247,18 +240,15 @@

 ;; State management

-(defn initial-state [svg width height
-                     animation-subject node-tap-subject link-tap-subject]
+(defn initial-state [svg width height animation-subject]
   {:svg svg
    :view-size (v/create width height)
    :camera-pos (v/create 0 0)
    :nodes []
    :edges []
    :projection :fisheye ; Can be :fisheye or :zoom-out
-   ; subjects are part of state because they are needed to render the graph.
-   :animation-subject animation-subject
-   :node-tap-subject node-tap-subject
-   :link-tap-subject link-tap-subject})
+   ; Subject is part of state because it is needed to render the graph.
+   :animation-subject animation-subject})

 (defn swap-state! [current-state f & args]
   (apply swap! current-state f args)
@@ -561,16 +551,44 @@
          (zoom-in-to-pos! current-state
                           (zoom-out->world-pos @current-state %))))))

+(defn svg-element-position [svg elem]
+  (let [box (.getBoundingClientRect elem)
+        center-x (+ (.-left box) (/ (.-width box) 2))
+        center-y (+ (.-top box) (/ (.-height box) 2))
+        svg-box (-> svg .node .getBoundingClientRect)
+        svg-x (.-left svg-box)
+        svg-y (.-top svg-box)]
+    (v/create (- center-x svg-x) (- center-y svg-y))))
+
 ;; Gestures - tap on node

-(defn focus-node-on-tap! [current-state
-                          node-tap-observable
-                          animation-observable]
-  (-> node-tap-observable
-      (suppress-while-animating animation-observable)
-      (.subscribe (fn [node]
-                    (if (= (:projection @current-state) :fisheye)
-                      (zoom-in-to-pos! current-state (:pos node)))))))
+(defn closest-node
+  "Returns the node closest to the given position and its distance"
+  [state pos]
+  (let [closest-node (atom nil)
+        closest-distance-sq (atom js/Infinity)
+        svg (:svg state)]
+    (-> svg (.selectAll ".node-dot")
+        (.each
+          (fn [node]
+            (this-as elem
+                     (let [elem-pos (svg-element-position svg elem)
+                           distance-sq (v/distance-sq pos elem-pos)]
+                       (when (< distance-sq @closest-distance-sq)
+                         (reset! closest-distance-sq distance-sq)
+                         (reset! closest-node node)))))))
+    {:node @closest-node
+     :distance (js/Math.sqrt @closest-distance-sq)}))
+
+(defn focus-node-on-tap-2! [manager current-state animation-observable]
+  (let [taps (tap-observable manager)]
+    (-> taps
+        (suppress-while-animating animation-observable)
+        (.map #(closest-node @current-state %))
+        (.filter #(< (:distance %) (/ hitbox-size 2)))
+        (.subscribe (fn [{:keys [node]}]
+                      (if (= (:projection @current-state) :fisheye)
+                        (zoom-in-to-pos! current-state (:pos node))))))))

 ;; Exported function to do magic

@@ -581,14 +599,10 @@
         svg (setup-svg! selector)
         gesture-manager (hammer-manager svg)
         animation-subject (animation-subject)
-        node-tap-subject (js/Rx.Subject.)
-        link-tap-subject (js/Rx.Subject.)
         current-state (atom (initial-state svg
                                            width
                                            height
-                                           animation-subject
-                                           node-tap-subject
-                                           link-tap-subject))]
+                                           animation-subject))]
     (sync-on-container-size! current-state selector)
     (load-graph "miserables.json"
                 (fn [graph]
@@ -601,4 +615,4 @@
     (switch-zoom-on-spacebar! current-state animation-subject)
     (zoom-on-pinch! gesture-manager current-state animation-subject)
     (zoom-in-on-tap! gesture-manager current-state animation-subject)
-    (focus-node-on-tap! current-state node-tap-subject animation-subject)))
+    (focus-node-on-tap-2! gesture-manager current-state animation-subject)))


Fixed ns.

Fixed ns.

--- src/midje/parsing/lexical_maps.clj
+++ src/midje/parsing/lexical_maps.clj
@@ -22,7 +22,7 @@

 (comment ; --------------------------------------------------------
   (clojure.core/merge
-   {:position (midje.parsing.util.file-pointer/line-number-known ...),
+   {:position (pointer/line-number-known ...),
     :expected-result-form '(just a 2),
     :expected-result (just a 2),
     :check-expectation :expect-match,
@@ -31,7 +31,7 @@
    {:arrow '=>, :call-form '(cons a [2])}
    (commons.maps/hash-map-duplicates-ok
     :position
-    (midje.parsing.util.file-pointer/line-number-known 2)))
+    (pointer/line-number-known 2)))
 ) ; ---------------------------------------------------------------

 ;;;                                             Checkable maps


revert to old code

revert to old code

--- src/open_company/api/companies.clj
+++ src/open_company/api/companies.clj
@@ -143,7 +143,7 @@
                                  (company/add-placeholder-sections)
                                  (company/create-company!))})

-  :handle-ok (fn [{:keys [companies]}] (company-rep/render-company-list companies))
+  :handle-ok (fn [ctx] (company-rep/render-company-list (:companies ctx)))
   :handle-created (fn [ctx] (company-location-response (:company ctx)))
   :handle-options (fn [ctx] (if (common/authenticated? ctx)
                               (common/options-response [:options :get :post])


Console output from lein build-pages.

Console output from lein build-pages.

--- src/posthere/static_templating.clj
+++ src/posthere/static_templating.clj
@@ -13,11 +13,14 @@
   ["index" "faq" "terms" "privacy"])

 (defn partial-for [page-partial]
-  (slurp (clojure.java.io/resource (str template-dir "_" page-partial ".html"))))
+  (str template-dir "_" page-partial ".html"))
+
+(defn partial-content [page-partial]
+  (slurp (clojure.java.io/resource (partial-for page-partial))))

 (deftemplate layout-page layout [page-partial]
   ;; use Enlive to combine the layout and the page partial into a HTMl page
-  [:#page-partial-container] (html-content (partial-for page-partial)))
+  [:#page-partial-container] (html-content (partial-content page-partial)))

 (defn- export-page
   "Combine the contents of the layout.html template and the page partial template
@@ -28,8 +31,10 @@
   URLs.
   "
   [page-partial]
-  (let [output-dir (if (= page-partial "index") resources-dir target-dir)]
-    (spit (str output-dir page-partial) (apply str (layout-page page-partial)))))
+  (let [output-dir (if (= page-partial "index") resources-dir target-dir)
+        output-file (str output-dir page-partial)]
+    (spit output-file (apply str (layout-page page-partial)))
+    (println "Rendered:" output-file "from layout:" layout "and page partial:" (partial-for page-partial))))

 (defn export
   "


Forgot to allow :get :(

Forgot to allow :get :(

--- src/clj/mokkameister/resources/button.clj
+++ src/clj/mokkameister/resources/button.clj
@@ -24,7 +24,7 @@

 (defresource coffee-button
   :available-media-types ["text/plain"]
-  :allowed-methods [:post]
+  :allowed-methods [:post :get]
   :authorized? valid-button-token?
   :post! handle-old-button-post
   :handle-ok handle-button-get)


Minor ui improvement

Minor ui improvement

--- src/cljs/salava/badge/ui/endorsement.cljs
+++ src/cljs/salava/badge/ui/endorsement.cljs
@@ -834,7 +834,7 @@
                                                        :disabled (< (count @request-comment) 15)}
             [:i.fa.fa-users.fa-fw.fa-3x] (t :badge/Selectusers)])
          (when (and (= context "endorsement_selfie") (empty? @selected-users))
-           [:button.btn.btn-danger.btn-bulky
+           [:button.btn.btn-danger
             {:href "#" :on-click #(do (.preventDefault %) (mo/previous-view))}
             [:i.fa.fa-remove {:style {:color "white"}}] (t :core/Cancel)])]]])))


fix hpass policy

fix hpass policy

--- src/cljs/salava/extra/hpass/ui/block.cljs
+++ src/cljs/salava/extra/hpass/ui/block.cljs
@@ -184,7 +184,7 @@
       [:p "London"]
       [:p "EC1M 4AR."]
       ]
-     [:p "or email at compliance@humanitarian.academy"]
+     [:p "or email at" [:a {:href "mailto:compliance@humanitarian.academy"} " compliance@humanitarian.academy"]]
      ]
     [:p "The Academy is responsible for all Personal Information under its control and has designated a privacy officer who is accountable to Management for the Academy’s compliance with this Privacy Policy."]
     [:div


Fix wrong reference to privkey argument on token backend.

--- src/clojure/buddy/auth/backends/token.clj
+++ src/clojure/buddy/auth/backends/token.clj
@@ -37,7 +37,7 @@
     (parse [_ request]
       (parse-authorization-header request))
     (authenticate [_ request data]
-      (assoc request :identity (loads data pkey {:max-age max-age})))
+      (assoc request :identity (loads data privkey {:max-age max-age})))

     proto/IAuthorization
     (handle-unauthorized [_ request metadata]


http polling work

http polling work

--- figwheel-repl/src/figwheel/repl.cljc
+++ figwheel-repl/src/figwheel/repl.cljc
@@ -51,6 +51,9 @@
                        c))
 (defonce init-logger (do (.setCapturing log-console true) true))

+;; dev
+(.setLevel logger goog.debug.Logger.Level.FINE)
+
 ;; --------------------------------------------------------------
 ;; Bootstrap goog require reloading
 ;; --------------------------------------------------------------
@@ -325,7 +328,7 @@
                          (fn [e]
                            (when-let [msg (gobj/get e "message")]
                              (try
-                               (glog/info logger msg)
+                               (glog/fine logger msg)
                                (message (assoc
                                          (js->clj (js/JSON.parse msg) :keywordize-keys true)
                                          :websocket websocket))
@@ -345,21 +348,24 @@
                                     (succ (.getResponseJson xhr))
                                     (err xhr))))))))

-;; TODO this has to try more than once
-;; perhaps borrow exponential backoff from websocket?
-(defn http-connect [& [websocket-url']]
-  (js/setInterval
-   #(let [url (make-url websocket-url')]
-      (-> (http-get url)
-          (.then
+(defn http-connect [& [connect-url']]
+  (let [url (make-url connect-url')
+        surl (str url)
+        msg-fn (fn [msg]
+                 (try
+                   (glog/fine logger (pr-str msg))
+                   (message (assoc (js->clj msg :keywordize-keys true)
+                                   :http-url surl))
+                   (catch js/Error e
+                     (glog/error logger e))))]
+    (doto (.getQueryData url)
+      (.add "fwinit" "true"))
+    (.then (http-get url)
            (fn [msg]
-             (try
-               (glog/fine logger (pr-str msg))
-               (message (assoc (js->clj msg :keywordize-keys true)
-                               :http-url url))
-               (catch js/Error e
-                 (glog/error logger e)))))))
-   1000))
+             (msg-fn msg)
+             (js/setInterval
+              #(.then (http-get (make-url connect-url')) msg-fn)
+              1000)))))

 ))

@@ -455,9 +461,9 @@
          (fnil conj []) data))

 (defn http-polling-connect [ring-request]
-  (let [sess-id (-> ring-request :query-string parse-query-string :fwsid)]
+  (let [{:keys [fwsid fwinit]} (-> ring-request :query-string parse-query-string)]
     ;; new connection create the connection
-    (if-not (get @*connections* sess-id)
+    (if-not (get @*connections* fwsid)
       (let [conn (create-connection! ring-request
                                      {:type :http-polling
                                       :send-fn http-polling-send})]
@@ -466,8 +472,8 @@
          :body (naming-response conn)})
       ;; otherwise we are polling
       (let [messages (volatile! [])]
-        (swap! *connections* update sess-id
-               #(-> %
+        (swap! *connections* update fwsid
+               #(-> (cond-> % fwinit (assoc :created-at (System/currentTimeMillis)))
                     (update ::messages (fn [msgs] (vreset! messages (or msgs [])) []))
                     (assoc ::alive-at (System/currentTimeMillis))))
         {:status 200
@@ -573,8 +579,8 @@

 (def server-fn
   (-> not-found
-      #_(http-polling-middleware)
       (websocket-middleware)
+      (http-polling-middleware)
       (cors/wrap-cors
        :access-control-allow-origin #".*"
        :access-control-allow-methods [:head :options :get :put :post :delete :patch])))
@@ -635,7 +641,7 @@
 ;;  mostly for use from the REPL

 (defn list-connections []
-  (let [conns (map second (connections-available cljs.repl/*repl-env*))
+  (let [conns (connections-available cljs.repl/*repl-env*)
         longest-name (apply max (cons (count "Session Name")
                                       (map (comp count :session-name) conns)))]
     (println (format (str "%-" longest-name "s %7s %s")
@@ -646,15 +652,13 @@
       (println (format (str "%-" longest-name "s %6sm %s")
                        session-name
                        (Math/round (/ (- (System/currentTimeMillis) created-at) 60000.0))
-                       (str uri (when query-string
-                                  (str "?" query-string))))))))
+                       uri)))))

 (defn will-eval-on []
   (if-let [n @(:focus-session-name cljs.repl/*repl-env*)]
     (println "Focused On: " n)
     (println "Will Eval On: " (->> (connections-available cljs.repl/*repl-env*)
                                   first
-                                  second
                                   :session-name))))

 (defn conns* []
@@ -665,7 +669,7 @@
   (conns*))

 (defn focus* [session-name]
-  (let [names (map :session-name (map second (connections-available cljs.repl/*repl-env*)))
+  (let [names (map :session-name (connections-available cljs.repl/*repl-env*))
         session-name (name session-name)]
     (if ((set names) session-name)
       (str "Focused On: " (reset! (:focus-session-name cljs.repl/*repl-env*) session-name))
@@ -680,7 +684,6 @@
 ;; - make http polling connection as backup
 ;; - make http polling connection a ring handler

-
 (comment

   (def re (repl-env* {}))
@@ -689,7 +692,7 @@

   (connections-available re)

-  (evaluate re "44")
+  (evaluate re "47")

   (negotiate-id (:ring-request @scratch) @*connections*)

@@ -701,7 +704,7 @@

   (binding [cljs.repl/*repl-env* re]
     (conns*)
-    #_(focus* 'Korey))
+    #_(focus* 'Judson))

   )


repl can start server if not started yet

--- figwheel-repl/src/figwheel/repl.cljc
+++ figwheel-repl/src/figwheel/repl.cljc
@@ -1,7 +1,9 @@
 (ns figwheel.repl
   (:require
+   [clojure.string :as string]
    #?@(:cljs [[goog.object :as gobj]
-              [goog.storage.mechanism.mechanismfactory :as storage-factory]]
+              [goog.storage.mechanism.mechanismfactory :as storage-factory]
+              [goog.userAgent.product :as product]]
        :clj [[clojure.data.json :as json]
              [clojure.set :as set]
              [clojure.edn :as edn]
@@ -26,27 +28,77 @@

            (def state (atom {}))
            (def storage (storage-factory/createHTML5SessionStorage "figwheel.repl"))
+           (defn session-name []
+             (.get storage (str ::session-name)))
+
+           (defn response-for [{:keys [uuid]} response-body]
+             {:uuid uuid
+              :session-name (session-name)
+              :response response-body})
+
+           (defn respond-to [{:keys [websocket] :as old-msg} response-body]
+             (let [response (response-for old-msg response-body)]
+               (.send websocket (pr-str response))))

            (defmulti message :op)
            (defmethod message "naming" [msg]
              (.set storage (str ::session-name) (:session-name msg)))

+           (def ^:dynamic *eval-js* (fn [code] (js* "eval(~{code})")))
+
+           (let [ua-product-fn
+                 #(cond
+                    (not (nil? goog/nodeGlobalRequire)) :chrome
+                    product/SAFARI    :safari
+                    product/CHROME    :chrome
+                    product/FIREFOX   :firefox
+                    product/IE        :ie)]
+             (defn eval-javascript** [code]
+               (let [ua-product (ua-product-fn)]
+                 (try
+                   (let [sb (js/goog.string.StringBuffer.)]
+                     (binding [cljs.core/*print-newline* false
+                               cljs.core/*print-fn* (fn [x] (.append sb x))]
+                       (let [result-value (*eval-js* code)]
+                         {:status :success
+                          :out (str sb)
+                          :ua-product ua-product
+                          :value result-value})))
+                   (catch js/Error e
+                     {:status :exception
+                      :value (pr-str e)
+                      :ua-product ua-product
+                      :stacktrace (.-stack e)})
+                   (catch :default e
+                     {:status :exception
+                      :ua-product ua-product
+                      :value (pr-str e)
+                      :stacktrace "No stacktrace available."})))))
+
+           (defmethod message "eval" [{:keys [code] :as msg}]
+             (let [result (eval-javascript** code)]
+               (respond-to msg result)))
+
            (defn connect [websocket-url]
-             (doto (goog.net.WebSocket.)
-               (.addEventListener goog.net.WebSocket.EventType.MESSAGE
-                                  (fn [e]
-                                    (when-let [msg (gobj/get e "message")]
-                                      (try
-                                        (prn msg)
-                                        (message (js->clj (js/JSON.parse msg) :keywordize-keys true))
-                                        (catch js/Error e
-                                          (js/console.error e))))))
-               (.addEventListener goog.net.WebSocket.EventType.OPENED
-                                  (fn [e]
-                                    (js/console.log "OPENED")
-                                    (js/console.log e)))
-               (.open websocket-url)
-               ))
+             (let [websocket (goog.net.WebSocket.)]
+               (doto websocket
+                 (.addEventListener goog.net.WebSocket.EventType.MESSAGE
+                                    (fn [e]
+                                      (when-let [msg (gobj/get e "message")]
+                                        (try
+                                          (prn msg)
+                                          (js/console.log msg)
+                                          (message (assoc
+                                                    (js->clj (js/JSON.parse msg) :keywordize-keys true)
+                                                    :websocket websocket))
+                                          (catch js/Error e
+                                            (js/console.error e))))))
+                 (.addEventListener goog.net.WebSocket.EventType.OPENED
+                                    (fn [e]
+                                      (js/console.log "OPENED")
+                                      (js/console.log e)))
+                 (.open websocket-url)
+                 )))
            (js/console.log (.get storage (str ::session-name)))
            (js/console.log (nil? (.get storage (str ::session-name))))
            (connect (str "ws://localhost:9500/fargot" (when-let [n (.get storage (str ::session-name))]
@@ -138,16 +190,16 @@
 (defn send-for-eval [connections js]
   (let [prom (promise)]
     (doseq [[channel channel-data] connections]
-      (let [uuid (java.util.UUID/randomUUID)
+      (let [uuid (str (java.util.UUID/randomUUID))
             listener (fn listen [msg]
                        (when (= uuid (:uuid msg))
-                         (when-let [result (:result msg)]
+                         (when-let [result (:response msg)]
                            (deliver prom (vary-meta
                                           result
                                           assoc ::message msg)))
                          (remove-listener listen)))]
         (add-listener listener)
-        (hkit/send!
+        (hkit/send! ;; if we abstract this we can use other servers
          channel
          (json/write-str {:uuid uuid
                           :session-name (:session-name channel-data)
@@ -157,14 +209,13 @@

 (let [timeout-val (Object.)]
   (defn evaluate [{:keys [focus-session-name ;; just here for consideration
-                          last-session-name
                           repl-timeout
                           broadcast] :as repl-env} js]
     ;; TODO if focus session is set
     ;; if it is available send eval to it otherwise
     ;; choose next best session and send message to it
     ;; and the set the focus session to the new session name
-    (wait-for-connection)
+    (wait-for-connection repl-env)
     (let [connections (connections-available repl-env)
           youngest-connection (first connections)
           result (let [v (deref (send-for-eval (if broadcast
@@ -173,11 +224,6 @@
                                                js)
                                 (or repl-timeout 8000)
                                 timeout-val)]
-                   (some->> v
-                            meta
-                            ::message
-                            :session-name
-                            (reset! last-session-name))
                    (if (= timeout-val v)
                      {:status :exception
                       :value "Eval timed out!"
@@ -191,48 +237,52 @@
 (defrecord FigwheelReplEnv []
   cljs.repl/IJavaScriptEnv
   (-setup [this opts]
-    (binding [*connections* (:connections this)]
-      (wait-for-connection (get this :connection-filter))))
-  (-evaluate [this _ _  js] (evaluate this js))
+    (when (and
+           (or (not (bound? #'*server*))
+               (nil? *server*))
+           (nil? @(:server-kill this)))
+      (let [server-kill (hkit/run-server (bound-fn [ring-req] (async-handler ring-req))
+                                         (select-keys this [:ip :port :thread :worker-name-prefix :query-size :max-body :max-line]))]
+        (reset! (:server-kill this) server-kill)))
+    (wait-for-connection this))
+  (-evaluate [this _ _  js]
+    (evaluate this js))
   (-load [this provides url]
     ;; load a file into all the appropriate envs
     (when-let [js-content (try (slurp url) (catch Throwable t))]
-      (evaluate (assoc repl-env :broadcast true) js-content)))
-  (-tear-down [this])
+      (evaluate this js-content)))
+  (-tear-down [{:keys [server-kill]}]
+    (when-let [kill-fn @server-kill]
+      (reset! server-kill nil)
+      (kill-fn)))
   cljs.repl/IReplEnvOptions
   (-repl-options [this])
   cljs.repl/IParseStacktrace
   (-parse-stacktrace [this st err opts]
     (cljs.stacktrace/parse-stacktrace this st err opts)))

-(defn repl-env* [{:keys [host port] :or {host "localhost" port 3449} :as opts}]
+(defn repl-env* [{:keys [port worker-name-prefix connection-filter ring-handler]
+                  :or {connection-filter identity
+                       port 9500
+                       worker-name-prefix "figwh-worker-"} :as opts}]
   (merge (FigwheelReplEnv.)
-         ;; TODO choose-connections not connection filter
-         {:connection-filter (atom (or connection-filter identity))
+         {:server-kill (atom nil)
+          :connection-filter (atom connection-filter)
           :focus-session-name (atom nil)
-          :last-session-name (atom nil)
-          :broadcast false}
+          :broadcast false
+          :port port
+          :worker-name-prefix worker-name-prefix}
          opts))

-;; these are only for development right now
-(defonce servers (atom []))
-
-(defn start-server []
-  (swap! servers conj (hkit/run-server async-handler {:port 9500})))
-
-(defn stop-server []
-  (doseq [srv @servers]
-    (srv :timeout 100))
-  (reset! servers []))
-
-
-
 (comment
-  (start-server)
-  (stop-server)
-
+  (def re (repl-env* {}))
+  (cljs.repl/-setup re {})
+  (cljs.repl/-tear-down re)
+
+  (connections-available re)
+
+  (evaluate re "1")
   *connections*
-  (mapv hkit/open? (keys @connections))
   )

 (def name-list